Как определить точку переполнения стека - PullRequest
10 голосов
/ 12 апреля 2009

У меня следующая проблема с моей программой на С: где-то переполнение стека. Несмотря на то, что компиляция выполняется без оптимизации и с использованием символов отладчика, программа завершает работу с таким выводом (в пределах или за пределами gdb в Linux):

Программа завершена с сигналом SIGSEGV, Ошибка сегментации. Программа больше не существует.

Единственный способ определить, что это на самом деле переполнение стека, - запустить программу через valgrind. Можно ли каким-то образом заставить операционную систему вывести дамп трассировки стека вызовов, что поможет мне найти проблему?

К сожалению, GDB не позволяет мне легко подключиться к программе.

Ответы [ 3 ]

17 голосов
/ 12 апреля 2009

Если вы разрешите системе выгружать файлы ядра, вы можете проанализировать их с помощью 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 ()
...

Иногда я видел плохо сгенерированный файл ядра, в котором была неправильная трассировка стека, но в большинстве случаев bt выдаст кучу рекурсивных вызовов одного и того же метода.

Файл ядра может иметь другое имя, которое может включать идентификатор процесса, это зависит от конфигурации ядра по умолчанию в вашей текущей системе, но может управляться с помощью (запуск от имени root или с помощью sudo):

$ sysctl kernel.core_uses_pid=1
8 голосов
/ 12 апреля 2009

С 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

4 голосов
/ 12 апреля 2009

Когда программа умирает с SIGSEGV, она обычно выгружает ядро ​​в Unix. Не могли бы вы загрузить это ядро ​​в отладчик и проверить состояние стека?

...