使用g++构建的C++中运行时数组边界检查

22

有没有办法在使用g++编译的C++中进行数组边界检查?

理想情况下,源代码不应被修改。使用std::vectorstd::tr1::arrayboost::array并不是一个选项,因为代码库很大,这样的转变是不可行的。

3个回答

13

Google的 AddressSanitizer 是一个编译器插装模块和运行时库,可以检查堆、栈和全局变量等访问是否越界。它可在Clang 3.1以上版本GCC 4.8以上版本中使用。

要使用它,将-fsanitize=address(或旧版Clang 3.1中的-faddress-sanitizer)传递给编译器和链接器之间的参数列表中(连接asan;不需要显式的-lasan)。为了在错误信息中获得更好的堆栈追踪, 请将-fno-omit-frame-pointer传递给编译器。

它最初用于Chromium测试,并且自2012年以来,也被Firefox开发人员所使用。有一篇很好的博客文章介绍了如何在Qt中运行它。您可能还想阅读Wikipedia上的更多信息


6

有一种名为SGCheck(以前称为Ptrcheck)的Valgrind工具,可以检查堆栈数组越界。

valgrind --tool=exp-sgcheck <program> <arguments>

该工具仍被标记为实验性,并且有一些限制。其中之一是:

平台:堆栈/全局检查在PowerPC、ARM或S390X平台上无法正常工作,只能在X86和AMD64目标上工作。这是因为堆栈和全局检查需要可靠地跟踪函数调用和退出,而在使用链接寄存器进行函数返回的ABI上没有明显的方法。


2

GCC mudflap-fmudflap)可以为C语言进行边界检查,但截至2012年中期无法处理所有的C++代码(例如std::vector)。它在2015年中期被GCC 4.9移除,由Address Sanitizer取代。mudflap选项仍然存在,但不起作用。

MIRO补丁 - Mudflap Improved with Referent Objects。请参阅其主页以获取更多信息。此外,还有一篇论文介绍了它。

我已经简单尝试了MIRO。它似乎非常不错,但也许不能与100%的C++代码兼容。我打算在开发过程中使用MIRO,然后在发布时关闭它(并使用常规编译器)。如果您正在编写自己的代码,那么使其与MIRO兼容应该相当容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接