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库。特别是什么?? ()????
编辑:最终在我的主代码中将崩溃跟踪到了对标准无效内存的访问。没有解释为什么堆栈跟踪被损坏,但这是另一天的问题:)
解决方案
确保使用调试符号进行编译。 (对于gcc,我认为这是-g选项)。然后,我们应该能够从GDB中获得更多有趣的信息。编译生产版本时,请不要忘记将其关闭。
gdb无法从pthread_mutexattr_init中提取正确的返回地址;它的地址为0。" ??"是在符号表中查找地址0的结果。它找不到符号名称,因此会打印默认的" ??"
不幸的是,我不知道为什么它不能提取正确的寄信人地址。
也许导致崩溃的bug破坏了堆栈(堆栈的覆盖部分)?在这种情况下,回溯可能是无用的。不知道在那种情况下该怎么办...
我们所做的某些操作导致线程库崩溃。由于线程库本身未使用调试符号(-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的了解还有些过时,但是过去一直存在一些问题。