Я зарабатываю на C ++ и сталкиваюсь с этой проблемой чаще, чем хочу признаться. Ваше приложение разбивает ОГРОМНУЮ часть стека. Скорее всего, функция, которая портит стек, также дает сбой при возврате. Причина в том, что адрес возврата был перезаписан, и именно поэтому трассировка стека GDB испорчена.
Вот как я отлаживаю эту проблему:
1) Пройдите через приложение, пока оно не выйдет из строя. (Ищите функцию, которая падает при возврате).
2) Как только вы определили функцию, объявите переменную в ОЧЕНЬ ПЕРВОЙ ЛИНИИ функции:
int canary=0;
(Причина, по которой это должна быть первая строка, заключается в том, что это значение должно быть в самой верхней части стека. Этот «канарейка» будет перезаписан до адреса возврата функции.)
3) Установите переменную watch на canary, шагните через функцию и когда canary! = 0, тогда вы обнаружили переполнение буфера! Еще одна возможность - установить переменную точку останова для canary! = 0 и просто запустить программу нормально, это немного проще, но не во всех точках останова переменных поддержки IDE.
РЕДАКТИРОВАТЬ: Я говорил со старшим программистом в моем офисе, и чтобы понять дамп ядра, вам нужно разрешить адреса памяти, которые у него есть. Один из способов выяснить эти адреса - посмотреть на двоичный файл MAP, который удобочитаем для человека. Вот пример создания файла MAP с использованием gcc:
gcc -o foo -Wl,-Map,foo.map foo.c
Это часть головоломки, но все равно будет очень трудно получить адрес сбойной функции. Если вы используете это приложение на современной платформе, то ASLR, вероятно, сделает адреса в дампе ядра бесполезными. Некоторая реализация ASLR будет рандомизировать адреса функций вашего двоичного файла, что делает дамп ядра абсолютно бесполезным.