AddressSanitizer 仅在 OS X 上发现溢出
AddressSanitizer only finds overflow on OS X
我们的一位开发人员在他的机器 (OS X) 上发现了 AddressSanitizer 的问题,但我们的 CI(Jenkins 在 Linux 上)没有发现这些问题。
示例代码:
#include <vector>
#include <iostream>
int main() {
{
std::vector<int> tmp_vec{1, 2, 3};
tmp_vec.resize(1);
if(tmp_vec[1] == 123) std::cout << "#1" << std::endl;
}
}
在 OS X 上输出 clang 6:
==9387==ERROR: AddressSanitizer: container-overflow on address 0x6020000000f4 at pc 0x00010fb5e4aa bp 0x7ffee00a2b90 sp 0x7ffee00a2b88
READ of size 4 at 0x6020000000f4 thread T0
#0 0x10fb5e4a9 in main (a.out:x86_64+0x1000024a9)
#1 0x7fff7eaa7014 in start (libdyld.dylib:x86_64+0x1014)
[...]
在 Linux 上使用 clang 6,没有任何反应。
为什么 Linux 上的 clang 没有捕捉到这些错误,作为我们 CI 流程的一部分,我们可以做些什么来发现这些问题?
这与编译器或 OS 并没有太多关系。如果两台机器有两种不同的 std 实现,结果可能会有所不同。在 Linux 机器上显式设置 clang++-6.0 -stdlib=libc++ -fsanitize=address sanitizer.cpp
会导致 ASan 发现相同的问题。
因此,CI 中的 clang 构建应该明确使用 libc++
.
添加到 mrks 答案中,libstdc++
默认情况下不检测容器溢出(因为它可能导致 Asan 发出误报警告,请查看 wiki 了解更多详细信息)。您需要通过 -D_GLIBCXX_SANITIZE_VECTOR
明确启用它(您需要足够新的 libstdc++
)。
我们的一位开发人员在他的机器 (OS X) 上发现了 AddressSanitizer 的问题,但我们的 CI(Jenkins 在 Linux 上)没有发现这些问题。
示例代码:
#include <vector>
#include <iostream>
int main() {
{
std::vector<int> tmp_vec{1, 2, 3};
tmp_vec.resize(1);
if(tmp_vec[1] == 123) std::cout << "#1" << std::endl;
}
}
在 OS X 上输出 clang 6:
==9387==ERROR: AddressSanitizer: container-overflow on address 0x6020000000f4 at pc 0x00010fb5e4aa bp 0x7ffee00a2b90 sp 0x7ffee00a2b88
READ of size 4 at 0x6020000000f4 thread T0
#0 0x10fb5e4a9 in main (a.out:x86_64+0x1000024a9)
#1 0x7fff7eaa7014 in start (libdyld.dylib:x86_64+0x1014)
[...]
在 Linux 上使用 clang 6,没有任何反应。
为什么 Linux 上的 clang 没有捕捉到这些错误,作为我们 CI 流程的一部分,我们可以做些什么来发现这些问题?
这与编译器或 OS 并没有太多关系。如果两台机器有两种不同的 std 实现,结果可能会有所不同。在 Linux 机器上显式设置 clang++-6.0 -stdlib=libc++ -fsanitize=address sanitizer.cpp
会导致 ASan 发现相同的问题。
因此,CI 中的 clang 构建应该明确使用 libc++
.
添加到 mrks 答案中,libstdc++
默认情况下不检测容器溢出(因为它可能导致 Asan 发出误报警告,请查看 wiki 了解更多详细信息)。您需要通过 -D_GLIBCXX_SANITIZE_VECTOR
明确启用它(您需要足够新的 libstdc++
)。