GDB回溯信息中的“0x0000000000000000 in ?? ()”是什么意思?

19

当它给出以下输出的回溯(backtrace)时,这意味着什么?

#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库。具体来说,??()????是什么?
编辑:最终将崩溃追踪到主代码中的标准无效内存访问。虽然这并不能解释为什么堆栈跟踪会损坏,但这是另一个问题 :)
5个回答

13

gdb 无法从 pthread_mutexattr_init 中提取正确的返回地址,它得到了一个 0 的地址。"??" 是在符号表中查找地址 0 的结果。它无法找到符号名称,因此打印默认的 "??"。

很遗憾,我目前不知道为什么无法提取正确的返回地址。


8

您所做的某些操作导致了线程库崩溃。由于线程库本身没有使用调试符号(-g)进行编译,因此它无法显示发生崩溃的源代码文件或行号。另外,由于涉及到线程,调用堆栈不会指向您的文件。不幸的是,这将是一个难以跟踪的错误,您需要逐步检查代码并尝试缩小崩溃发生的确切时间。


4

请确保使用调试符号进行编译(对于gcc,我认为这是-g选项)。然后,您应该能够从GDB中获取更有趣的信息。在编译生产版本时,请不要忘记关闭它。


3

我可能漏掉了一些东西,但这不是某个人将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知识有点过时,但以前存在这样的问题。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接