Как определить точку

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

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

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

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

Ответ 1

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

Ответ 2

С помощью GCC вы можете попробовать следующее:

-fstack-protector
    Извлеките дополнительный код, чтобы проверить переполнение буфера, например атаки с разбивкой пакетов. Это делается путем добавления защитной переменной к функциям с уязвимыми объектами. Сюда входят функции, которые вызывают alloca, и функции с буферами размером более 8 байтов. Охранники инициализируются, когда функция вводится, а затем проверяется, когда функция выходит. Если проверка защиты не удалась, выводится сообщение об ошибке и программа выходит из системы.

-fstack-protector-all
    Как -fstack-протектор, за исключением того, что все функции защищены.

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

Ответ 3

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