Skip to content

Unexpected fmt::print flush behavior #4398

@tupaschoal

Description

@tupaschoal

(Opening this on behalf of @brenoguim who did all the heavy lifting of creating a reduced test)

We're seeing an issue when using fmt::print on Ubuntu 14.04 that does not happen on equivalent CentOS/RHEL, here's the snippet:

#include <cassert>
#include <fcntl.h>
#include <fmt/core.h>

int main()
{
    auto name  = "/tmp/some_file";
    // Remove old file and create new one
    system(fmt::format("rm {}", name).c_str());
    system(fmt::format("touch {}", name).c_str());

    // Open file descriptor
    int fd = open(name, O_WRONLY | O_RDONLY);
    assert(fd != -1);

    // Associate FILE with file descriptor
    auto file = fdopen(fd, "w");
    assert(file);

    // Write a lot of data
    for (int i = 0; i < 20001; ++i)
    {
        fmt::print(file, "{}\n", i);   // this fails
        // fmt::println(file, "{}", i);       // this works
    }

    // Close and expect it to flush, so the last line should be 20000
    fclose(file);

    // Print last lines and show that last chunk of file is missing
    system(fmt::format("tail {}", name).c_str());
}

Basically, it should print up to 20000, but on Ubuntu it stops at 19600. A few things we know:

  1. Started happening after upgrading from fmt 10.2.1 to 11.1.1
  2. Still fails on fmt 11.1.4
  3. Does not happen on later Ubuntu release (16, 18 and 20)
  4. Changing to fmt::println fixes the issue, as shared in the snippet above.
  5. Forcing the needs_flush to return true fixes the issue too

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions