This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer][win] Fix `Atexit()` on MinGW asan_dynamic runtime
ClosedPublic

Authored by alvinhochun on Apr 2 2023, 8:41 AM.

Details

Summary

Some functions of asan depends on Atexit() handlers. On Windows, this
is implemented in ad3ec82bb1c7217b0187a1e16bb22642e194ce94 to queue the
handlers in a vector then register them with atexit() only after the
CRT is fully initialized. However, this is broken on MinGW with
asan_dynamic runtime due to different initialization order. This change
fixes the issue by making sure that Atexit() can call atexit()
directly past the pre-initialization phase.

This fixes two asan test cases on MinGW.

Diff Detail

Event Timeline

alvinhochun created this revision.Apr 2 2023, 8:41 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 2 2023, 8:41 AM
Herald added a subscriber: Enna1. · View Herald Transcript
alvinhochun requested review of this revision.Apr 2 2023, 8:41 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 2 2023, 8:41 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript
mstorsjo added inline comments.Apr 2 2023, 2:48 PM
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
731

So... is the root issue that C++ global constructors are executed after the .CRT$XID initializer in MSVC environments, but before in mingw environments? I believe they're supposed to be compatible, so if there's such a discrepancy, maybe we should also consider trying to fix it in mingw-w64 crt?

alvinhochun added inline comments.Apr 3 2023, 2:08 AM
compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
731

No, C++ global constructors are called after .CRT$XID initializer on MinGW too. This is what I got from stepping through it:

  1. RunAtexit is called quite early.
  2. The AsanInitializer constructor is called quite late by __main -> __do_global_ctors (gccmain.c). This constructor calls AsanInitFromRtl -> AsanInitInternal -> Atexit(asan_atexit).

I do suspect on MSVC target there is something else other than the C++ global constructor that calls __asan_init early. Perhaps it may have something to do with linking with static vs dynamic CRT? (Static asan has other initializers.)

vitalybuka accepted this revision.Apr 3 2023, 2:02 PM
This revision is now accepted and ready to land.Apr 3 2023, 2:02 PM