如何检测堆栈溢出点

Man*_*uel 10 c linux stack-overflow callstack gdb

我的C程序有以下问题:某处是堆栈溢出.尽管编译没有优化和调试符号,程序退出此输出(在Linux上的gdb内部或外部):

程序因信号SIGSEGV,分段故障而终止.该计划已不复存在.

我能够检测到这实际上是堆栈溢出的唯一方法是通过valgrind运行程序.有什么方法可以以某种方式强制操作系统转储调用堆栈跟踪,这将帮助我找到问题?

可悲的是,gdb也不允许我轻松地使用该程序.

Dav*_*eas 17

如果您允许系统转储核心文件,您可以使用gdb分析它们:

$ ulimit -c unlimited # bash sentence to allow for infinite sized cores
$ ./stack_overflow
Segmentation fault (core dumped)
$ gdb -c core stack_overflow
gdb> bt
#0  0x0000000000400570 in f ()
#1  0x0000000000400570 in f ()
#2  0x0000000000400570 in f ()
...
Run Code Online (Sandbox Code Playgroud)

有时我看到一个生成错误的核心文件有不正确的堆栈跟踪,但在大多数情况下,bt会产生一堆对同一方法的递归调用.

核心文件可能有一个不同的名称,可能包含进程ID,它取决于当前系统中内核的默认配置,但可以使用(以root身份运行或使用sudo)进行控制:

$ sysctl kernel.core_uses_pid=1
Run Code Online (Sandbox Code Playgroud)


Bas*_*ard 8

有了GCC你可以试试这个:

-fstack-protector
发出额外的代码来检查缓冲区溢出,例如堆栈粉碎攻击.这是通过向具有易受攻击对象的函数添加保护变量来完成的.这包括调用alloca的函数,以及大于8字节的缓冲区的函数.输入功能时会初始化防护装置,然后在功能退出时进行检查.如果防护检查失败,则会打印错误消息并退出程序.

-fstack-protector-all
与-fstack-protector类似,但所有功能都受到保护.

http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Optimize-Options.html#Optimize-Options