Address Sanitizer issues on Windows

I have struggled a bit to get ASAN working on windows, but I have figured some things out so I wanted to share my findings.

Note: I have tried a number of MSVC versions (and also LLVM clang builds) but for the moment, lets keep this to Visual Studio 2022, and only using the version of clang/LLVM that comes with that install.

This is simple.cpp

#include <stdio.h>
char s[2];
int main () {
    s[2] = 0;
    return 0;

First, the obvious (MSVC) thing: cl /ZI /fsanitize=address simple.cpp /Fe:build\simple.exe simply just doesn’t work, it just crashes, and doesn’t give any ASAN diagnostics

Second, the typical Linux/clang thing to do clang -g -O0 -fsanitize=address simple.cpp -o build\simple.exe kinda works, but only if you are running under a debugger (see Related:ASan init calls itself (but only when not running under a debugger)), and even then you hit some annoying int 3 breaks in GetInstructionSize(...) (best I can tell, is that its failing to calculate instruction size for some mov instructions??)

To work around these issues, I found that you can do this this:

clang-cl /Zi -fsanitize=address /c simple.cpp /Fobuild\simple.obj
cl /Zi /fsanitize=address build\simple.obj /Fe:build\simple.exe

I could only make wild speculations as to why that works while the more straightforward invocations have issues

So, I dug into this even deeper, and found a clearer workaround.

This works:

clang-cl -fuse-ld=lld /Zi "%VCToolsInstallDir%\lib\x64\clang_rt.asan_cxx-x86_64.lib" "%VCToolsInstallDir%\lib\x64\clang_rt.asan-x86_64.lib" build\simple.obj /Fe:build\simple.exe

Basically you cannot use -fsanitize=address when linking, you must instead explicitly specify the asan libs that are part of the windows SDK, and not the version of those libraries that are part of the LLVM distribution (Whether its a standalone LLVM install, or the one that ships with MSVC, and yes… much to my confusion, MSVC actually ships with two sets of the ASAN libs, one set works, the other doesn’t…)

It would be super cool if we figured out what the difference was between the MS version and the LLVM version, and incorporated those changes…