Понимание трассировки стека ошибки сегментации
Я делаю snprintf
и получить ошибку сегмента.
когда я загрузил основной файл на GDB, как это: gdb my_executable core
; и сделал bt
чтобы получить обратный след, я получил следующее:
Program terminated with signal 11, Segmentation fault.
#0 0x88207fc2 in memcpy () from /usr/lib/libc.so.6
(gdb) bt
#0 0x88207fc2 in memcpy () from /usr/lib/libc.so.6
#1 0x88205eb6 in __sfvwrite () from /usr/lib/libc.so.6
#2 0x881fbc95 in strchr () from /usr/lib/libc.so.6
#3 0xbfbe6c14 in ?? ()
#4 0xbfbe69d8 in ?? ()
#5 0x881ed91e in localeconv () from /usr/lib/libc.so.6
#6 0x881fec05 in __vfprintf () from /usr/lib/libc.so.6
#7 0x881f7d80 in snprintf () from /usr/lib/libc.so.6
#8 0x08052b64 in my_function (files=0xbfbed710, filename=<value optimized out>) at myfile.c:1102
#9 0x08053bfb in main (argc=4, argv=0xbfbedd90) at myfile.c:225
Я вижу такой стек много раз в случае ошибки сегмента, но никогда не понимаю правильно.
Просто проследив звонки, можем ли мы сказать, что происходит не так?
ПРИМЕЧАНИЕ: пожалуйста, не спрашивайте больше кода. Мой мотив - просто понять, что означает эта трассировка стека - независимо от кода. Я вижу, что сверху "memcpy" не работает. Я хочу понять, когда это может произойти в этой ситуации.
3 ответа
Вы действуете что-то в myfile.c:1102
, Это, в свою очередь, вводит стандартную библиотеку в незаконный доступ к памяти. Операционная система замечает и шлепает вашу программу sigsegv
,
Общие причины (как видно из Stackru:))):
- Запись в постоянную память
- Использование неинициализированных указателей
- Доступ к памяти после окончания выделенного блока
Длинный список функций показывает, кто это сделал. Так:
my_function
называетсяsnprintf
- который называется
__vfprintf
- ...
Я бы предложил вам запустить ваш исполняемый файл под Valgrind. Он может выводить дополнительные трассировки вызовов в случае проблем в вашем коде, таких как работа с уже освобожденной памятью. Обычно это помогает понять причину сбоя.
Это просто след звонков. Первый вызов функции в программе появится внизу, как правило, это будет main
и последующие вызовы других функций (изнутри main) появятся поверх него. Если новый вызов вызывает другую подпрограмму (функцию), она накладывается сверху и процесс продолжается.
GDB печатает некоторую полезную информацию, учитывая, что она доступна. Первый столбец - это позиции стека (сверху вниз). Второй столбец содержит адреса вызовов, а оставшаяся информация содержит название вызываемой функции и место ее расположения. Обратите внимание, что они сильно различаются. Иногда имя символа не может быть получено и ?? ()
будет отображаться как в #3 и #4 в вашей трассировке стека. Когда источник доступен, появится также строка, где определена функция, например at myfile.c:225
,