有没有办法在使用g++
编译的C++中进行数组边界检查?
Valgrind的Memcheck无法检测在堆栈上分配的数组溢出。
理想情况下,源代码不应被修改。使用std::vector
,std::tr1::array
或boost::array
并不是一个选项,因为代码库很大,这样的转变是不可行的。
有没有办法在使用g++
编译的C++中进行数组边界检查?
Valgrind的Memcheck无法检测在堆栈上分配的数组溢出。
理想情况下,源代码不应被修改。使用std::vector
,std::tr1::array
或boost::array
并不是一个选项,因为代码库很大,这样的转变是不可行的。
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上的更多信息。
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兼容应该相当容易。