Что означает сообщение GDB backtrace "0x0000000000000000 in?()"?
Что это означает, когда он дает обратную трассировку со следующим выходом?
#0 0x00000008009c991c in pthread_testcancel () from /lib/libpthread.so.2
#1 0x00000008009b8120 in sigaction () from /lib/libpthread.so.2
#2 0x00000008009c211a in pthread_mutexattr_init () from /lib/libpthread.so.2
#3 0x0000000000000000 in ?? ()
Программа разбилась со стандартным сигналом 11, ошибка сегментации.
Мое приложение представляет собой многопоточную программу FastCGI С++, запущенную на FreeBSD 6.3, используя pthread в качестве библиотеки потоков.
Он был скомпилирован с -g, и все таблицы символов для моего источника загружены, согласно источникам информации.
Как ясно, ни один из моих фактических кодов не появляется в трассировке, но вместо этого ошибка возникает из стандартных библиотек pthread. В частности, что такое??()????
EDIT: в конечном итоге отследил сбой до стандартного недопустимого доступа к памяти в моем основном коде. Не объясняет, почему трассировка стека была повреждена, но вопрос на другой день:)
Ответы
Ответ 1
gdb не смог извлечь правильный адрес возврата из pthread_mutexattr_init; он получил адрес 0. "??" является результатом поиска адреса 0 в таблице символов. Он не может найти символическое имя, поэтому он печатает по умолчанию "??"
К сожалению, прямо сейчас я не знаю, почему он не смог извлечь правильный адрес возврата.
Ответ 2
То, что вы делали, вызвало сбои библиотеки потоков. Поскольку сама библиотека потоковой обработки не скомпилирована с помощью отладочных символов (-g), она не может отображать файл исходного кода или номер строки, в которой произошел сбой. Кроме того, поскольку он потоки, стек вызовов не указывает на ваш файл. К сожалению, это будет трудная ошибка для отслеживания, вам нужно будет пройти через свой код и попытаться сузиться, когда произойдет авария.
Ответ 3
Убедитесь, что вы компилируете символы отладки. (Для gcc я думаю, что это опция -g). Тогда вы сможете получить более интересную информацию из GDB. Не забудьте выключить его при компиляции производственной версии.
Ответ 4
Я мог бы что-то упустить, но разве это не означает, что кто-то использует NULL
как указатель на функцию?
#include <stdio.h>
typedef int (*funcptr)(void);
int
func_caller(funcptr f)
{
return (*f)();
}
int
main()
{
return func_caller(NULL);
}
Это создает тот же стиль backtrace, если вы запустите его в gdb:
rivendell$ gcc -g -O0 foo.c -o foo
rivendell$ gdb --quiet foo
Reading symbols for shared libraries .. done
(gdb) r
Starting program: ...
Reading symbols for shared libraries . done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x00001f9d in func_caller (f=0) at foo.c:8
#2 0x00001fb1 in main () at foo.c:14
Это довольно странная ошибка, хотя... pthread_mutexattr_init
редко делает что-то большее, чем распределение структуры данных и memset
. Я бы искал что-то еще. Есть ли возможность несогласованных библиотек потоков или что-то еще. Мои знания BSD немного устарели, но раньше были проблемы.
Ответ 5
Возможно, ошибка, вызвавшая сбой, сломала стек (перезаписанные части стека)? В этом случае backtrace может оказаться бесполезным; не знаю, что делать в этом случае...