2008-09-23 80 views
13

这是什么意思,当它回溯以下输出?GDB回溯消息“??()中的0x0000000000000000”是什么意思?

#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,分段故障。 我的应用程序是一个在FreeBSD 6.3上运行的多线程FastCGI C++程序,使用pthread作为线程库。

根据信息来源,它已经用-g编译并且我的源代码的所有符号表都被加载。

很明显,我的实际代码没有出现在跟踪中,而是错误似乎来自标准pthread库。特别是,什么是? ()?

编辑:最终在我的主代码中将崩溃追踪到一个标准的无效内存访问。没有解释为什么堆栈跟踪已损坏,但这是另一天的问题:)

回答

9

gdb无法从pthread_mutexattr_init中提取正确的返回地址;它的地址为0.“??”是在符号表中查找地址0的结果。它找不到符号名称,因此它会打印默认的“??”

不幸的是,我们不知道为什么它不能提取正确的返回地址。

3

确保您使用调试符号进行编译。 (对于gcc我认为这是-g选项)。那么你应该可以从GDB中获得更多有趣的信息。编译生产版本时不要忘记关闭它。

0

也许导致崩溃的错误已经破坏了堆栈(覆盖堆栈的一部分)?在这种情况下,回溯可能是无用的;不知道该怎么办...

5

你确实导致线程库崩溃。由于线程库本身没有使用调试符号(-g)编译,因此无法显示崩溃发生时的源代码文件或行号。另外,由于它是线程,调用栈不会指向您的文件。不幸的是,这将是一个棘手的错误追踪,你将需要通过你的代码,并尝试缩小时发生的崩溃。

2

我可能会错过一些东西,但这不是指示某人使用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知识有点过时,但过去一直存在这个问题。

相关问题