17

当它给出具有以下输出的回溯时,这意味着什么?

#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 库。特别是,什么是??()????

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

4

5 回答 5

13

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

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

于 2008-09-23T14:32:34.973 回答
8

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

于 2008-09-23T14:50:38.643 回答
4

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

于 2008-09-23T14:31:55.130 回答
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 知识有点过时了,但曾经有过这方面的问题。

于 2008-11-29T19:25:50.217 回答
1

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

于 2008-09-23T14:42:00.270 回答