понимание трассировки стека ошибки сегментации - PullRequest
5 голосов
/ 17 июля 2011

Я делаю 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 ]

7 голосов
/ 17 июля 2011

Ваша функция что-то делает на myfile.c:1102. Это, в свою очередь, вводит стандартную библиотеку в незаконный доступ к памяти. Операционная система замечает и шлепает вашу программу с помощью sigsegv.

Общие причины (как видно из Stackoverflow :))):

  • Запись в постоянную память
  • Использование неинициализированных указателей
  • Доступ к памяти после конца выделенного блока

Длинный список функций показывает, кто это сделал. Итак:

  • my_function называется snprintf
  • который называется __vfprintf
  • ...
2 голосов
/ 18 июля 2011

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

1 голос
/ 17 июля 2011

Это просто след звонков. Первый вызов функции в программе будет появляются внизу, как правило, это будет main и последующие вызовы других функции (изнутри main ) появятся поверх него. Если новый звонок звонит другая подпрограмма (функция), она накладывается сверху и процесс продолжается.

GDB печатает некоторую полезную информацию, учитывая, что она доступна. Первый столбец являются позициями стека (сверху вниз). Второй столбец содержит адреса звонков, а оставшаяся информация содержит название вызываемой функции и где это находится Обратите внимание, что они сильно различаются. Иногда название символ не может быть получен, и ?? () появится как в # 3 и # 4 в вашем стеке след. Когда источник доступен, также строка, где определена функция появится, как at myfile.c:225.

...