Как определить точку
У меня есть следующая проблема с моей программой на 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. Не могли бы вы загрузить это ядро в отладчик и проверить состояние стека?