ASan init calls itself (but only when not running under a debugger)

Anyone have any suggestions for how to debug an ASAN init failure on Windows (hitting the “ASan init calls itself!” assert)? Something as simple as hello world is failing. What’s particularly interesting is that if I run the program under windbg, it works as expected (after doing an ‘sxi av’ to let the intentional AVs pass through, and stepping over a couple of interception failure breakpoints), so I have no idea how to figure out what’s going on if I can’t observe the issue under a debugger.

It seems to be something to do with how the executable is being built, since if I take the generated binary and run it on a different machine I experience the same issue. But if I perform the same steps to build the code on another machine it’s working there… The inverse is also true in that I can take a binary generated on the working machine and run it on the non-working machine and it success there (without needing the debugger).

I’ve tried various tweaks to compiler/linker flags, SDK versions, etc. over the last couple of days to no avail. I’ve also tried disassembling and comparing the working vs broken binary in a disassembler but without the ability to observe the issue under a debugger and compare an execution trace I’m basically fumbling around in the dark.

One more note of interest is that it appears to work if I dynamically link the CRT (/MD), but I need to statically link the CRT in order to use libFuzzer per the documentation, so that’s not going to work as a solution for me since I’m specifically trying to build a fuzzer.

Any help would be greatly appreciated since this is blocking my ability to use ASAN (and by extension libFuzzer) on Windows.

Thanks for your time. Demonstration of the issue is shown below (note that when run under cdb you can see the “Hello world” printed, and there are no ASAN asserts raised):

PS E:\Dev\asantest> cat .\main.cpp
#include <cstdio>

int main()
{
  std::printf("Hello world!\n");
}
PS E:\Dev\asantest> clang-cl --version
clang version 12.0.1
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
PS E:\Dev\asantest> clang-cl /O1 /Zi -fsanitize=address .\main.cpp
   Creating library main.lib and object main.exp
PS E:\Dev\asantest> .\main.exe
==27172==AddressSanitizer CHECK failed: C:\src\llvm_package_1201-final\llvm-project\compiler-rt\lib\asan\asan_rtl.cpp:402 "((!asan_init_is_running && "ASan init calls itself!")) != (0)" (0x0, 0x0)
    <empty stack>

PS E:\Dev\asantest> & "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe" .\main.exe

Microsoft (R) Windows Debugger Version 10.0.22000.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: .\main.exe

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*c:\my\symbols*https://msdl.microsoft.com/download/symbols

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*c:\my\symbols*https://msdl.microsoft.com/download/symbols
Symbol search path is: srv*c:\my\symbols*https://msdl.microsoft.com/download/symbols
Executable search path is:
ModLoad: 00007ff6`1eca0000 00007ff6`1f64b000   main.exe
ModLoad: 00007ffa`f4fb0000 00007ffa`f51a5000   ntdll.dll
ModLoad: 00007ffa`f34c0000 00007ffa`f357d000   C:\Windows\System32\KERNEL32.DLL
ModLoad: 00007ffa`f2b40000 00007ffa`f2e09000   C:\Windows\System32\KERNELBASE.dll
(5198.7b4): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffa`f5080770 cc              int     3
0:000> sxi av
0:000> g
(5198.7b4): Break instruction exception - code 80000003 (first chance)
*** WARNING: Unable to verify checksum for main.exe
main!__interception::InterceptionFailed [inlined in main!__interception::GetInstructionSize+0x4c6]:
00007ff6`1ecbe456 cc              int     3
0:000> g
(5198.7b4): Break instruction exception - code 80000003 (first chance)
main!__interception::InterceptionFailed [inlined in main!__interception::GetInstructionSize+0x4c6]:
00007ff6`1ecbe456 cc              int     3
0:000> g
(5198.7b4): Break instruction exception - code 80000003 (first chance)
main!__interception::InterceptionFailed [inlined in main!__interception::GetInstructionSize+0x4c6]:
00007ff6`1ecbe456 cc              int     3
0:000> g
Hello world!
ModLoad: 00007ffa`f05d0000 00007ffa`f05e2000   C:\Windows\SYSTEM32\kernel.appcore.dll
ModLoad: 00007ffa`f33c0000 00007ffa`f345e000   C:\Windows\System32\msvcrt.dll
ModLoad: 00007ffa`f30b0000 00007ffa`f31da000   C:\Windows\System32\RPCRT4.dll
ntdll!NtTerminateProcess+0x14:
00007ffa`f504d3a4 c3              ret
0:000> q
quit:
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\atlmfc.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\ObjectiveC.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\concurrency.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\cpp_rest.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\stl.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Data.Json.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Devices.Geolocation.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Devices.Sensors.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Media.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\windows.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\winrt.natvis'
PS E:\Dev\asantest>

I’m getting this exact same issue, but even if I am running with a debugger… running with clang 13.0.0

I was able to work around the issue by linking with -MD

Unfortunately this won’t work for binaries which use libFuzzer (which is what I was trying to do when I originally got sent down this rabbit hole).

Per the libFuzzer docs:
“Building fuzzers with the /MD (dynamic runtime library) compile option is unsupported.”

To this day I still haven’t figured this out (I gave up after a week of tinkering and haven’t had time to return to it).

Hey, I think I found a solution, see this thread: Address Sanitizer issues on Windows - #2 by croepha (basically, don’t use -fsanitize=address and instead manually specify the ASAN libs that are part of the MSVC libs) I’d be very interested in whether or not that fixes your issue