2009-10-28 67 views
1

GDB似乎永远只是为C程序的工作,但对于C++我经常得到这些神秘的堆栈:调试C++从GDB的核心文件

(gdb) bt 
#0 0x08055fa4 in std::runtime_error::what() 
#1 0x080576c8 in std::runtime_error::what() 
#2 0x08057dda in std::runtime_error::what() 
#3 0x080580d2 in std::runtime_error::what() 
#4 0x08058662 in std::runtime_error::what() 
#5 0x08058725 in std::runtime_error::what() 
#6 0x0806ef7a in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>() 
#7 0x00c0adec in __libc_start_main() from /lib/libc.so.6 
#8 0x0804d011 in std::runtime_error::what() 

从而在表面提供绝对没有线索,问题出在哪里发生。无论如何,从这样的核心文件中获取更多信息 - 或者让程序转储更有用的东西?

+0

只是一些进一步的信息,有问题的Makefile有-g选项,但也有-s,它去除了调试信息... grrrrr。所以希望消除那个愚蠢的旗帜会让我下一次更好的核心。 – 2009-10-29 02:23:59

回答

5

std::runtime_error::what()的文本实际上不可能覆盖从回溯建议的从0x0804d011到0x08058725的范围。这将超过45KB的代码。

它更可能是正在尝试符号查找代码来解决0x08055fa4,0x080576c8等被简单地定位std::runtime_error::what()因为之前这些地址的最后一个可用的符号,这往往是剥离可执行文件的结果(因为你有通过将-s切换到链接程序完成)。

我将重点放在堆栈帧#6上。由于这是一个相当简单的类的ctor,我的SWAG将会是你已经传入了一个NULL指针或一个指向非NULL终止字符串的指针。

编辑:请注意,如果你只是从重建完全相同的源可执行没有-s开关,你会从GDB得到一个更有用的堆栈,使用core文件你已经离开。没有必要等待新建的可执行文件再次转储core

2

我一直使用GDB作为C++,并且通常没有堆栈回溯问题,当然,这个堆栈并没有被某些缓冲区溢出所粉碎。

关于C++程序中的堆栈回溯与C程序之间没有任何内在差异,这会使您更难解释回溯。你确定:

A)你的程序不是以某种方式粉碎堆栈? B)你正在用-g标志编译?

0

首先,确保你已经设置-pg -ggdb编译器标志:

g++ -pg -ggdb prog.cpp -o prog

第一个生成gprof的分析信息(你可能需要它),而第二个包含调试的可执行文件的信息。

要检查核心文件,使用这样的:

gdb -quiet -se=prog -c prog.core

这应该始终提供足够的信息来解决核心转储:)
干杯!