Consider the following library which can be preloaded before any program execution:
// g++ -std=c++11 -shared -fPIC preload.cpp -o preload.so
// LD_PRELOAD=.
ls
has atexit (close_stdout);
as its initialisation code. When it finishes, it closes stdout (i.e. close(1)
), so your cout
, printf
or write(1, ...
operations will not print anything. It doesn't mean destructor isn't called. You can verify this by e.g. creating a new file in your destructor.
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c#n1285 here is the line in GNU coreutils ls.
It is not just ls
, most of coreutils do that. Unfortunately, I don't know exact reason why they prefer to close it.
Side note on how this could be found (or at least what I did) - may help next time or with program with no source code access:
Destructor message is printed with /bin/true
(simplest program I could think of), but isn't printed with ls
or df
. I started with strace /bin/true
and strace /bin/ls
and compared latest system calls. It shown close(1)
and close(2)
for ls
, but none for true
. After that things started to make sense and I just had to verify that destructor is called.