VC2019 地址清理器无符号堆栈跟踪 64 位

VC2019 address sanitizer no symbolic stack trace 64bit

下面的简单程序

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

在 32 位和 64 位动态链接中使用 VC2019 16.8.2 构建良好,但是我只在 32 位中获得带有符号的堆栈跟踪。

32位:堆栈打印函数名(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\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 位:堆栈仅使用十六进制地址值打印。

@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)

知道为什么 64 位不同吗?

问题是我没有调用 vcvars64.bat (C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Auxiliary\Build\vcvars64.bat)

我确实手动设置了所有库路径,也确实将 PATH 设置为 llvm-symbolizer.exe (位于 C:\Program Files (x86)\Microsoft Visual Studio19\Community\VC\Tools\MSVC.28.29333\bin\HostX64\x64 )但显然 clang_rt.asan_dynamic... 库似乎在看另一个环境变量来执行符号化。

经过反复试验后发现,对于 64 位,符号化看起来 另外 PATH 中搜索 msdia140.dll(在 C:\Program Files (x86)\Microsoft Visual Studio19\Community\Team Tools\Performance Tools\x64 在我的 VC 安装中)。

总结是 PATH 需要指向包含 llvm-symbolizer.exemsdia140.dll 的目录才能让符号器正常工作。

第二个解决方案:我发现还可以使用环境变量 ASAN_SYMBOLIZER_PATH 覆盖 llvm-symbolizer.exe 的位置(此变量未在 vcvars64.bat 调用中设置链)。这会覆盖在 PATH.

中找到的位置

set ASAN_SYMBOLIZER_PATH=C:\Users\leo\llvm-symbolizer.exe 将设置自定义符号器:请注意名称 需要llvm-symbolizer.exe !

ASAN_SYMBOLIZER_PATH 也可以指向目录名称而不是可执行文件(运行时会尝试在该目录中找到 llvm-symbolizer.exe).

并且:仍然需要 PATHmsdia140.dll 来确保正确的符号化。