在使用 Clang 的 AddressSanitizer 调试我的程序时,我遇到了一个奇怪的问题。完全相同的代码适用于另一个 64 位系统,但在另一个系统上会出现堆缓冲区溢出错误。
两台机器使用相同的工具链等运行相同的操作系统(BSD 10 64 位),除了工作的那台被编译为 64 位(因此在 64 位系统上运行的 64 位应用程序)并且给出问题的那台被编译为64 位系统上的 32 位应用程序。
没有太多代码可以显示,因为问题仅存在于这个调用中:
struct ifaddrs * ifAddrStruct = NULL;
getifaddrs(&ifAddrStruct);
这是 ASan 转储的堆栈跟踪:
==19706==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x2e603e78 at pc 0x0832bbb2 bp 0xffff3288 sp 0xffff2e60
READ of size 256 at 0x2e603e78 thread T0
#0 0x832bbb1 in memcpy /home/dim/llvm-3.8.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:438:3
#1 0x2bdbed49 in getifaddrs (/usr/lib32//libc.so.7+0xecd49)
0x2e603e78 is located 0 bytes to the right of 1528-byte region [0x2e603880,0x2e603e78)
allocated by thread T0 here:
#0 0x8337df0 in __interceptor_malloc /home/dim/llvm-3.8.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52:3
#1 0x2bdbe87f in getifaddrs (/usr/lib32//libc.so.7+0xec87f)
#2 0x8325799 in getifaddrs /home/dim/llvm-3.8.0/final/llvm.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:4368:13
#3 0x8f1a443 in GetIPInfo(void) ...../src/config.cpp:243:2
#4 0x8f22837 in config_init(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) ...../src/config.cpp:329:7
#5 0xadf1cf9 in start(int, char**) (app+0xadf1cf9)
#6 0xade5a6c in main (app+0xade5a6c)
#7 0x82db629 in _start1 (app+0x82db629)
#8 0x82db4e7 in _start (app+0x82db4e7)
#9 0x0 (<unknown module>)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/dim/llvm-3.8.0/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc:438:3 in memcpy
Shadow bytes around the buggy address:
0x45cc0770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x45cc0780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x45cc0790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x45cc07a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x45cc07b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x45cc07c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[fa]
0x45cc07d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x45cc07e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x45cc07f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x45cc0800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x45cc0810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
我在两台机器上使用完全相同的 CFLAGS,相同的编译器(Clang 3.8),相同的库版本。一段时间以来一直在 Google 和 StackOverflow 上寻找,但这似乎是一个孤立的案例,因为我找不到其他人遇到我同样的问题。
希望有人对这件事有更多的了解。
提前感谢任何可以帮助我的人。
Edit1:我刚刚意识到我一直在系统上使用 Clang 3.8.1,一切正常(64 位系统中的 64 位应用程序),而另一个仍然有 3.8.0。我不确定,但此时我怀疑这是编译器中的错误。现在升级到 3.8.1,以及所有相关的 32 位库(ASan 等),当我有消息时会报告。