C 什么是??在gdb中,回溯平均值和如何获得实际堆栈帧?

C 什么是??在gdb中,回溯平均值和如何获得实际堆栈帧?,c,linux,debugging,gdb,C,Linux,Debugging,Gdb,我试图学习如何在核心转储上使用gdb 代码如下: int main() { return 1/0; } 这是我运行gdb a.out core时的gdb输出: warning: exec file is newer than core file. [New LWP 3121] Core was generated by `./crash'. Program terminated with signal SIGFPE, Arithmetic exception. #0 0x000000

我试图学习如何在核心转储上使用
gdb

代码如下:

int main()
{
    return 1/0;
}
这是我运行
gdb a.out core
时的
gdb
输出:

warning: exec file is newer than core file.
[New LWP 3121]
Core was generated by `./crash'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x00000000004004fc in ?? ()
(gdb) bt
#0  0x00000000004004fc in ?? ()
#1  0x0000000000400500 in ?? ()
#2  0x00007f6ea0945b97 in ?? ()
#3  0x0000000000000000 in ?? ()

回溯中的
是什么?如何解决这些问题?

您没有使用调试符号编译-尝试向编译行添加
-g

您没有使用调试符号编译-尝试向编译行添加
-g

这些
??
通常是显示函数名称的位置。GDB不知道这些函数的名称,因此显示
??

为什么会这样?视情况而定。默认情况下,GCC编译包括符号(例如函数名和类似符号)。最可能的情况是,您使用的是剥离版本,其中的符号已被删除,或者只是使用了错误的文件


正如所建议的那样,您看到的
警告:exec file比core file更新
这一行表明您的问题中没有显示其他内容。您正在处理崩溃的可执行文件生成的
core
转储文件,该文件已过时

我建议您从头开始重新编译程序,并确保使用GDB打开正确的文件。首先通过使新程序崩溃来生成一个新的
core
dump,然后在GDB中打开它

假设以下
程序.c

int main(void) { return 1/0; }
这应该起作用:

$rm-f核心
$gcc程序.c-o程序
美元/程序
浮点异常(内核转储)
$gdb计划核心
正在从程序中读取符号…(未找到调试符号)…已完成。
[新LWP 11896]
核心是由“./程序”生成的。
程序以信号SIGFPE终止,算术异常。
#0 0x000055d24a4cd790主管道()
(gdb)英国电信
#0 0x000055d24a4cd790主管道()
(gdb)

注意:如果在运行进程时没有看到
(内核转储)
,则表示未生成内核转储(这将留下旧的转储)。如果您使用的是Bash,请在程序崩溃之前尝试运行命令
ulimit-c unlimited

那些
通常是显示函数名称的地方。GDB不知道这些函数的名称,因此显示
??

为什么会这样?视情况而定。默认情况下,GCC编译包括符号(例如函数名和类似符号)。最可能的情况是,您使用的是剥离版本,其中的符号已被删除,或者只是使用了错误的文件


正如所建议的那样,您看到的
警告:exec file比core file更新
这一行表明您的问题中没有显示其他内容。您正在处理崩溃的可执行文件生成的
core
转储文件,该文件已过时

我建议您从头开始重新编译程序,并确保使用GDB打开正确的文件。首先通过使新程序崩溃来生成一个新的
core
dump,然后在GDB中打开它

假设以下
程序.c

int main(void) { return 1/0; }
这应该起作用:

$rm-f核心
$gcc程序.c-o程序
美元/程序
浮点异常(内核转储)
$gdb计划核心
正在从程序中读取符号…(未找到调试符号)…已完成。
[新LWP 11896]
核心是由“./程序”生成的。
程序以信号SIGFPE终止,算术异常。
#0 0x000055d24a4cd790主管道()
(gdb)英国电信
#0 0x000055d24a4cd790主管道()
(gdb)
注意:如果在运行进程时没有看到
(内核转储)
,则表示未生成内核转储(这将留下旧的转储)。如果您使用的是Bash,请在程序崩溃之前尝试运行命令
ulimit-c unlimited

什么是??在gdb回溯平均值中

这意味着GDB不知道回溯中的地址对应于哪个代码:
0x04004fc
0x0400500
,等等

如何获得实际的堆栈帧

这取决于为什么会发生这种情况。有两种常见的情况:

  • 您正在调试错误的可执行文件

    一种可能发生这种情况的方法是,使用优化进行编译,例如,
    gcc-O2 main.c-o崩溃
    ,让程序转储
    core
    ,然后重新编译调试(例如,
    gcc-g main.c-o崩溃
    ),并尝试使用“新”可执行文件调试“旧”内核转储

    不要那样做。相反,使用优化和调试进行编译:
    gcc-O2-gmain.c-o crash


    注意:此警告:
    警告:exec文件比核心文件更新
    旨在准确地警告您此情况

  • 另一个常见的原因是当您在生产系统上获得崩溃,并尝试在开发系统上调试它时(考虑到您显示的地址,这种情况在这里不太可能发生)

    对于这种情况,请参见

  • 什么是??在gdb回溯平均值中

    这意味着GDB不知道回溯中的地址对应于哪个代码:
    0x04004fc
    0x0400500
    ,等等

    如何获得实际的堆栈帧

    这取决于为什么会发生这种情况。有两种常见的情况:

  • 您正在调试错误的可执行文件

    一种可能发生这种情况的方法是,使用优化进行编译,例如,
    gcc-O2 main.c-o崩溃
    ,让程序转储
    core
    ,然后重新编译调试(例如,
    gcc-g main.c-o崩溃
    ),并尝试使用“新”可执行文件调试“旧”内核转储

    不要那样做。相反,使用优化和调试进行编译:
    gcc-O2-gmain.c-o crash


    注意:此警告:
    警告:exec文件比核心文件更新
    旨在准确地警告您此情况

  • 另一个常见的原因是当您在生产系统上获得崩溃,并尝试在devel上调试它时