Что означает сообщение 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 может оказаться бесполезным; не знаю, что делать в этом случае...