简体   繁体   English

有什么作用?? 在 gdb 回溯中的意思是如何获得实际的堆栈帧?

[英]What does ?? in gdb backtrace mean and how to get the actual stack frames?

I was trying to learn how to use gdb on core dumps.我试图学习如何在核心转储上使用gdb

Here is the code:这是代码:

int main()
{
    return 1/0;
}

This is the gdb output, when I run gdb a.out core :这是gdb输出,当我运行gdb a.out core

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

What are ??什么是?? in the backtrace?在回溯中? How can I resolve them?我该如何解决?

Those ??那些?? are usually where the name of the function is displayed.通常是显示函数名称的地方。 GDB does not know the name of those functions and therefore displays ?? GDB 不知道这些函数的名称,因此显示?? . .

Now, why is this happening?现在,为什么会发生这种情况? Depends.要看。 GCC compiles including symbols (eg function names and similar) by default.默认情况下,GCC 编译包括符号(例如函数名和类似的)。 Most probably you are working with a stripped version, where symbols have been removed, or just with the wrong file.很可能您正在使用已删除符号的剥离版本,或者只是使用了错误的文件。

As @zwol suggests, the line you see warning: exec file is newer than core file is an indication of the fact that something else is going on that you don't show in your question.正如@zwol 所建议的那样,您看到warning: exec file is newer than core file的行warning: exec file is newer than core file表明正在发生其他事情而您没有在问题中显示这一事实。 You are working on a core dump file generated by the crashed executable, which is outdated.您正在处理由崩溃的可执行文件生成的core转储文件,该文件已过时。

I would suggest you to re-compile the program from scratch and make sure that you are opening the right file with GDB.我建议您从头开始重新编译程序,并确保使用 GDB 打开正确的文件。 First produce a new core dump by crashing the new program, then open it in GDB.首先通过崩溃新程序产生一个新的core转储,然后在 GDB 中打开它。

Assuming the following program.c :假设以下program.c

int main(void) { return 1/0; }

This should work:这应该有效:

$ rm -f core
$ gcc program.c -o program
$ ./program
Floating point exception (core dumped)

$ gdb program core
Reading symbols from program...(no debugging symbols found)...done.
[New LWP 11896]
Core was generated by `./program'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x000055d24a4cd790 in main ()
(gdb) bt
#0  0x000055d24a4cd790 in main ()
(gdb)

NOTE: if you don't see (core dumped) when running the process that means that a core dump was not generated (which leaves you with the old one).注意:如果您在运行进程时没有看到(core dumped) ,则意味着未生成核心转储(这让您保留旧的转储)。 If you are using Bash, try running the command ulimit -c unlimited before crashing the program.如果您使用的是 Bash,请在程序崩溃之前尝试运行命令ulimit -c unlimited

What does ??有什么作用?? in gdb backtrace mean在 gdb 回溯意味着

It means that GDB has no idea to which code the addresses in backtrace: 0x04004fc , 0x0400500 , etc. correspond.这意味着 GDB 不知道 backtrace 中的地址: 0x04004fc0x0400500等对应于哪个代码。

and how to get the actual stack frames?以及如何获得实际的堆栈帧?

That depends on why this is happening.这取决于为什么会发生这种情况。 There are two common scenarios:有两种常见的场景:

  1. You are debugging the wrong executable.您正在调试错误的可执行文件。

    One way this could happen is when you compile with optimization, eg gcc -O2 main.c -o crash , let the program dump core , then recompile with debugging (eg gcc -g main.c -o crash ) and try to debug "old" core dump with "new" executable.可能发生这种情况的一种方法是当您进行优化编译时,例如gcc -O2 main.c -o crash ,让程序转储core ,然后通过调试重新编译(例如gcc -g main.c -o crash )并尝试调试“带有“新”可执行文件的旧”核心转储。

    Don't do that.不要那样做。 Instead, compile with optimization and debugging: gcc -O2 -g main.c -o crash .相反,通过优化调试进行编译: gcc -O2 -g main.c -o crash

    PS This warning: warning: exec file is newer than core file is intended to warn you precisely about this case. PS 此警告: warning: exec file is newer than core file旨在准确地警告您这种情况。

  2. The other common cause is when you obtain a crash on a production system and try to debug it on a development one (given the addresses which you show this is unlikely to have happened here).另一个常见原因是当您在生产系统上遇到崩溃并尝试在开发系统上调试它时(鉴于您显示的地址在这里不太可能发生这种情况)。

    For that case, see this answer .对于这种情况,请参阅此答案

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM