yibaini / thread-sanitizer

Automatically exported from code.google.com/p/thread-sanitizer
0 stars 0 forks source link

ThreadSanitizer breaks the order of destructors. #74

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Reported here: http://permalink.gmane.org/gmane.comp.compilers.clang.devel/38557

$ cat tmp/tsan/atexit.cc
#include <cstdio>
#include <cstdlib>
class Logger {
public:
    Logger() {
        std::printf("Logger ctor\n");
    }
    void log(const char* msg) {
        std::printf("%s", msg);
    }
    ~Logger() {
        std::printf("Logger dtor\n");
    }
};
Logger logger;
void log_from_atexit() {
    logger.log("In log_from_atexit\n");
}
int main(int argc, char* argv[]) {
    std::atexit(log_from_atexit);
    return EXIT_SUCCESS;
}
$ ./bin/clang++ -fsanitize=thread tmp/tsan/atexit.cc && ./a.out
Logger ctor
Logger dtor
In log_from_atexit

This is wrong according to standard:
3.6.3 [basic.start.term] / 3:
If the completion of the initialization of an object with static storage 
duration is sequenced before a call to std::atexit (see <cstdlib>, 18.5), the 
call to the function passed to std::atexit is sequenced before the call to the 
destructor for the object

The problem is in custom stack of atexit handlers maintained by TSan and its 
atexit/__cxa_atexit interceptors:

1) TSan registers its own __tsan::finalize function, which is supposed to run 
all atexit callbacks. This function is registered very early in initialization, 
and thus is run very late in termination.
2) Logger::~Logger is registered with the __cxa_atexit call generated by the 
compiler. But because the binary is linked as PIE, "dso_handle" argument of 
__cxa_atexit is non-zero, and TSan just redirects this call to __cxa_atexit 
from libc
3) log_from_atexit is registered with regular "atexit" call and is added to the 
TSan stack of destructors (which are invoked after all the destructors 
registered by libc version of __cxa_atexit).

Original issue reported on code.google.com by samso...@google.com on 21 Aug 2014 at 10:17

GoogleCodeExporter commented 9 years ago
Fixed by rev 216906.

Original comment by dvyu...@google.com on 2 Sep 2014 at 2:32

GoogleCodeExporter commented 9 years ago
Adding Project:ThreadSanitizer as part of GitHub migration.

Original comment by gli...@google.com on 30 Jul 2015 at 9:21