--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: std::filesystem::weakly_canonical throws if the file disappears during its execution
- From: Enrico Zini <enrico@enricozini.org>
- Date: Sun, 26 Jan 2025 17:41:43 +0100
- Message-id: <173790970381.2071514.3951928056712808207.reportbug@vidgeina.enricozini.org>
Package: libstdc++-14-dev
Version: 14.2.0-12
Severity: normal
Hello,
thank you for maintaining libstdc++.
The function std::filesystem::weakly_canonical is defined as working
even if the path points to a file that does not exist.
If however the path disappears while weakly_canonical does its thing, we
surprisingly get an exception.
I'm attaching a reproducer:
$ g++ weakly_canonical.cc -o weakly_canonical
$ ./weakly_canonical
Canonicalized path for missing file: "…/tmp/does-not-exist"
weakly_canonical failed at iteration 36: filesystem error: cannot make canonical path: No such file or directory [tmp/test]
Enrico
-- System Information:
Debian Release: trixie/sid
APT prefers testing
APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Kernel: Linux 6.12.6-amd64 (SMP w/16 CPU threads; PREEMPT)
Kernel taint flags: TAINT_WARN
Locale: LANG=en_IE.UTF-8, LC_CTYPE=en_IE.UTF-8 (charmap=UTF-8), LANGUAGE=en_IE:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages libstdc++-14-dev depends on:
ii gcc-14-base 14.2.0-12
ii libc6-dev 2.40-5
ii libgcc-14-dev 14.2.0-12
ii libstdc++6 14.2.0-12
libstdc++-14-dev recommends no packages.
Versions of packages libstdc++-14-dev suggests:
pn libstdc++-14-doc <none>
-- no debconf information
#include <filesystem>
#include <thread>
#include <iostream>
std::filesystem::path workdir("tmp");
auto oddpath = workdir / "test";
bool done = false;
void glitch()
{
while (! done)
{
std::filesystem::remove(oddpath);
std::filesystem::create_directory(oddpath);
}
}
void canonical()
{
unsigned iteration = 0;
try {
while (true)
{
++iteration;
(void)std::filesystem::weakly_canonical(oddpath);
}
} catch (std::exception& e) {
done = true;
std::cerr << "weakly_canonical failed at iteration " << iteration << ": " << e.what() << std::endl;
}
}
int main(int argc, const char* argv[])
{
std::filesystem::create_directory(workdir);
auto missing = std::filesystem::weakly_canonical(workdir / "does-not-exist");
std::cerr << "Canonicalized path for missing file: " << missing << std::endl;
std::thread glitcher(glitch);
canonical();
glitcher.join();
std::filesystem::remove_all(workdir);
return 0;
}
--- End Message ---