Что это значит, когда он дает обратную трассировку со следующим выводом?
#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. В частности, что есть ?? () ????
РЕДАКТИРОВАТЬ: в конечном итоге отследил сбой до стандартного недопустимого доступа к памяти в моем основном коде. Не объясняет, почему трассировка стека была повреждена, но это вопрос другого дня :)
Убедитесь, что вы компилируете с отладочными символами. (Для gcc я думаю, что это опция -g). Тогда вы сможете получить больше интересной информации из GDB. Не забудьте выключить его при компиляции производственной версии.
gdb не смог извлечь правильный адрес возврата из pthread_mutexattr_init; он получил адрес 0. Знак "??" является результатом поиска адреса 0 в таблице символов. Он не может найти символическое имя, поэтому выводит по умолчанию "??"
К сожалению, сразу я не знаю, почему он не смог извлечь правильный обратный адрес.
Может быть, ошибка, вызвавшая сбой, сломала стек (перезаписала части стека)? В этом случае обратная трассировка может оказаться бесполезной; не знаю, что делать в таком случае ...
Что-то, что вы сделали, привело к сбою библиотеки потоковой передачи. Поскольку сама библиотека потоковой передачи не скомпилирована с отладочными символами (-g), она не может отображать файл исходного кода или номер строки, в которой произошел сбой. Кроме того, поскольку это потоки, стек вызовов не указывает на ваш файл. К сожалению, эту ошибку будет сложно отследить, вам нужно будет пройтись по вашему коду и попытаться сузить область, когда именно произойдет сбой.
Я мог что-то упустить, но разве это не свидетельствует о том, что кто-то использует 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 немного устарели, но раньше были проблемы с этим.