Search code examples
cvisual-studioaddress-sanitizercl

VC2019 address sanitizer no symbolic stack trace 64bit


The following simple program

#include <malloc.h>
int main(int argc, char **argv)
{
    char* arr=malloc(10);
    arr[10]='\0';
    return 0;
}

builds fine with VC2019 16.8.2 in 32 and 64 bit dynamic linking, however I get only in 32bit a stack trace with symbols.

32 bit: the stack is printed with function names (main)

@echo off
rem small sample how to build a sample c prog with asan 32bit and the good stack trace
del /q *.pdb *.obj *.exe
cl -c -Zi -DDEBUG -D_DEBUG -DEBUG -MD -fsanitize=address -Fo:xx.obj xx.c
link /incremental:no /DEBUG:FULL /OUT:xx.exe /wholearchive:clang_rt.asan_dynamic-i386.lib /wholearchive:clang_rt.asan_dynamic_runtime_thunk-i386.lib xx.obj
xx.exe

>build_xx_32.bat
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29336 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

xx.c
Microsoft (R) Incremental Linker Version 14.28.29336.0
Copyright (C) Microsoft Corporation.  All rights reserved.

=================================================================
==5284==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x02c0075a at pc 0x00361060 bp 0x010ff7fc sp 0x010ff7f0
WRITE of size 1 at 0x02c0075a thread T0
    #0 0x36105f in main C:\Users\leo\w\gdc\misc\testprograms\asan\xx.c:5
    #1 0x3616c9 in _scrt_common_main_seh d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #2 0x760ffa28  (C:\windows\System32\KERNEL32.DLL+0x6b81fa28)
    #3 0x77cc75f3  (C:\windows\SYSTEM32\ntdll.dll+0x4b2e75f3)
    #4 0x77cc75c3  (C:\windows\SYSTEM32\ntdll.dll+0x4b2e75c3)

64 bit: the stack is only printed using hex address values.

@echo off
rem 64bit: no symbolication of the call stack
del /q *.pdb *.obj *.exe
cl -c -Zi  -DDEBUG -D_DEBUG -DEBUG -MD -fsanitize=address -Fo:xx.obj xx.c
link /incremental:no /DEBUG:FULL /OUT:xx.exe /wholearchive:clang_rt.asan_dynamic-x86_64.lib /wholearchive:clang_rt.asan_dynamic_runtime_thunk-x86_64.lib xx.obj
xx.exe

> build_xx_64.bat
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29336 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

xx.c
Microsoft (R) Incremental Linker Version 14.28.29336.0
Copyright (C) Microsoft Corporation.  All rights reserved.

=================================================================
==9804==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x11d16408003a at pc 0x7ff6038d107d bp 0x000892dafd30 sp 0x000892dafd38
WRITE of size 1 at 0x11d16408003a thread T0
    #0 0x7ff6038d107c  (C:\Users\leo\w\gdc\misc\testprograms\asan\xx.exe+0x14000107c)
    #1 0x7ff6038d17df  (C:\Users\leo\w\gdc\misc\testprograms\asan\xx.exe+0x1400017df)
    #2 0x7ffd5d137033  (C:\windows\System32\KERNEL32.DLL+0x180017033)
    #3 0x7ffd5ddbd0d0  (C:\windows\SYSTEM32\ntdll.dll+0x18004d0d0)

any clue why 64 bit is different ?


Solution

  • The problem was that I didn't call vcvars64.bat (C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat)

    I did set all library paths manually and also did set the PATH to the llvm-symbolizer.exe ( located in C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64 ) but apparently the clang_rt.asan_dynamic... libs seem to look at another environment variable to perform the symbolizing.

    It turned out after trial and error that for 64bit the symbolizing looks additionally in the PATH and searches msdia140.dll (found in C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Team Tools\Performance Tools\x64 in my VC installation ).

    The summary is that the PATH need to point to the directories containing llvm-symbolizer.exe and msdia140.dll in order to let the symbolizer work correctly.

    2nd solution: I discovered that there is also the ability to override the location of llvm-symbolizer.exe with the env variable ASAN_SYMBOLIZER_PATH (this variable isn't set in the vcvars64.bat call chain). This overrides the location found in the PATH.

    set ASAN_SYMBOLIZER_PATH=C:\Users\leo\llvm-symbolizer.exe would set a custom symbolizer: note that the name needs to be llvm-symbolizer.exe !

    ASAN_SYMBOLIZER_PATH can also point to a directory name instead of the executable (the runtime tries to find then llvm-symbolizer.exe in this directory) .

    And: still the PATH to msdia140.dll is needed to ensure proper symbolizing.