代码之家  ›  专栏  ›  技术社区  ›  Timothy Pratley

用GDB从核心文件调试C++

  •  1
  • Timothy Pratley  · 技术社区  · 15 年前

    GDB似乎总是只为C程序工作,但是对于C++,我经常得到这些神秘的堆栈:

    (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 ()
    

    从表面上看,这完全没有提供问题发生的线索。有没有办法从这样一个核心文件中获取更多的信息——或者让程序转储一些更有用的东西?

    3 回复  |  直到 15 年前
        1
  •  5
  •   Employed Russian    15 年前

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

    更可能的是,试图解析0x08055FA4、0x080576C8等的符号查找代码只是简单地定位 std::runtime_error::what()。 作为这些地址之前的最后一个可用符号,这通常是剥离可执行文件的结果(正如您通过传递 -s 切换到链接器)。

    我将重点放在堆栈帧6上。因为这是一个相当简单的类的ctor,所以我的swag应该是您传入了一个空指针或一个指向非空终止字符串的指针。

    编辑:请注意,如果只从完全相同的源代码重新生成可执行文件,而不使用 -S 切换,您将从 GDB ,使用 core 你已经有了文件。无需等待新生成的可执行文件转储 核心 再一次。

        2
  •  2
  •   Charles Salvia    15 年前

    我一直使用GDB用于C++,并且通常没有堆栈回溯的问题,当然,堆栈没有被一些缓冲区溢出破坏。

    C++程序中的堆栈回溯与C程序之间没有本质上的不同,这会使您更难解释回溯。您确定:

    a)您的程序没有以某种方式粉碎堆栈?
    b)您正在使用-g标志编译?

        3
  •  0
  •   kolypto    15 年前

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

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

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

    要检查核心文件,请使用以下命令:

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

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