Что означает сообщение обратной трассировки GDB "0x0000000000000000 in ?? ()"? - PullRequest
13 голосов
/ 23 сентября 2008

Что это значит, когда он дает обратную трассировку со следующим выводом?

#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 C ++, работающая на FreeBSD 6.3, использующая pthread в качестве библиотеки потоков.

Он был скомпилирован с -g и все таблицы символов для моего источника загружены, согласно источникам информации.

Как ясно, ни один из моих реальных кодов не появляется в трассировке, но вместо этого ошибка, кажется, происходит из стандартных библиотек pthread. В частности, что это такое? () ????

РЕДАКТИРОВАТЬ : в итоге отследил сбой до стандартного неверного доступа к памяти в моем основном коде. Не объясняет, почему трассировка стека была повреждена, но это вопрос для другого дня:)

Ответы [ 5 ]

9 голосов
/ 23 сентября 2008

GDB не смог извлечь правильный адрес возврата из pthread_mutexattr_init; он получил адрес 0. "??" является результатом поиска адреса 0 в таблице символов. Он не может найти символическое имя, поэтому печатает значение по умолчанию "??"

К сожалению, сразу я не знаю, почему не удалось извлечь правильный обратный адрес.

6 голосов
/ 23 сентября 2008

Что-то, что вы сделали, вызвало сбой библиотеки потоков. Поскольку сама библиотека потоков не скомпилирована с символами отладки (-g), она не может отобразить файл исходного кода или номер строки, в которой произошел сбой. Кроме того, поскольку это потоки, стек вызовов не указывает на ваш файл. К сожалению, это будет сложная ошибка для отслеживания, вам нужно будет пройтись по своему коду и попытаться сузить круг, когда именно произойдет сбой.

3 голосов
/ 23 сентября 2008

Убедитесь, что вы компилируете с отладочными символами. (Для gcc я думаю, что это опция -g). Тогда вы сможете получить более интересную информацию из GDB. Не забудьте отключить его при компиляции рабочей версии.

2 голосов
/ 29 ноября 2008

Я мог что-то упустить, но разве это не свидетельствует о том, что кто-то использует NULL в качестве указателя на функцию?

#include <stdio.h>

typedef int (*funcptr)(void);

int
func_caller(funcptr f)
{
    return (*f)();
}

int
main()
{
    return func_caller(NULL);
}

Это создает тот же стиль обратной трассировки, если вы запускаете его в 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 немного устарели, но раньше у них были проблемы.

0 голосов
/ 23 сентября 2008

Может быть, ошибка, вызвавшая сбой, сломала стек (перезаписали части стека)? В этом случае обратная трассировка может быть бесполезной; понятия не имею, что делать в этом случае ...

...