Red Hat Bugzilla – Bug 790837
Use of atexit to clean up handles is wrong in multithreaded programs
Last modified: 2013-03-29 17:00:55 EDT
Description of problem:
libguestfs registers an atexit handler to clean up handles.
This fails badly in multithreaded programs. If any thread calls
exit(3) then the atexit handler runs in that thread. This can
result in a segfault in (at least) two different ways:
(i) The other threads are still running while the atexit handler
is called, so if they have any libguestfs handles themselves and
are using them, these get abruptly freed from under them.
(ii) If two threads call exit simultaneously, the atexit handler
will run twice. POSIX notes (see exit(3p)) that programs that
call exit more than once can result in undefined behaviour. In
the case of libguestfs this will certainly result in a double-
Version-Release number of selected component (if applicable):
Very easily with a multithreaded test program that I have.
I studied this problem and I cannot see a simple way to fix this
and to clean up handles when a program exits suddenly.
In order to meaningfully clean up, we need to not just kill qemu,
but also free all temporary directories in use. The latter
essentially requires that we close the handles, but that is not
possible if threads are running and using those handles.
I also tried to use a gcc destructor instead of an atexit handler,
but these behave exactly the same way.
In libguestfs >= 1.21, both 'virt-df' and 'virt-alignment-scan'
are very prone to core dumping because of this bug.
The reason is that these programs are now highly multi-threaded.
If there is any error, they call exit(EXIT_FAILURE) which causes
close_handles() to be called, closing handles which are in use in