GDB 损坏的堆栈帧 - 如何调试? [英] GDB corrupted stack frame - How to debug?

查看:46
本文介绍了GDB 损坏的堆栈帧 - 如何调试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下堆栈跟踪.是否有可能从中找出任何对调试有用的东西?

I have the following stack trace. Is it possible to make out anything useful from this for debugging?

Program received signal SIGSEGV, Segmentation fault.
0x00000002 in ?? ()
(gdb) bt
#0  0x00000002 in ?? ()
#1  0x00000001 in ?? ()
#2  0xbffff284 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) 

当我们遇到 Segmentation fault 并且堆栈跟踪不是那么有用时,从哪里开始查看代码?

Where to start looking at the code when we get a Segmentation fault, and the stack trace is not so useful?

注意:如果我发布代码,那么 SO 专家会给我答案.我想从 SO 那里得到指导并自己找到答案,所以我不在这里发布代码.道歉.

NOTE: If I post the code, then the SO experts will give me the answer. I want to take the guidance from SO and find the answer myself, so I'm not posting the code here. Apologies.

推荐答案

那些虚假地址(0x00000002 等)实际上是 PC 值,而不是 SP 值.现在,当您获得这种带有虚假(非常小的)PC 地址的 SEGV 时,99% 的时间是由于通过虚假函数指针进行调用.请注意,C++ 中的虚拟调用是通过函数指针实现的,因此虚拟调用的任何问题都可以以同样的方式表现出来.

Those bogus adresses (0x00000002 and the like) are actually PC values, not SP values. Now, when you get this kind of SEGV, with a bogus (very small) PC address, 99% of the time it's due to calling through a bogus function pointer. Note that virtual calls in C++ are implemented via function pointers, so any problem with a virtual call can manifest in the same way.

间接调用指令只是在调用后将 PC 压入堆栈,然后将 PC 设置为目标值(在这种情况下是假的),因此如果发生了这种,您可以轻松地通过手动从堆栈中弹出 PC 来撤消它.在 32 位 x86 代码中,您只需执行以下操作:

An indirect call instruction just pushes the PC after the call onto the stack and then sets the PC to the target value (bogus in this case), so if this is what happened, you can easily undo it by manually popping the PC off the stack. In 32-bit x86 code you just do:

(gdb) set $pc = *(void **)$esp
(gdb) set $esp = $esp + 4

您需要 64 位 x86 代码

With 64-bit x86 code you need

(gdb) set $pc = *(void **)$rsp
(gdb) set $rsp = $rsp + 8

然后,您应该能够执行 bt 并找出代码的真正位置.

Then, you should be able to do a bt and figure out where the code really is.

另外 1% 的时间,错误将是由于覆盖堆栈,通常是溢出存储在堆栈上的数组.在这种情况下,您可能可以通过使用诸如 valgrind

The other 1% of the time, the error will be due to overwriting the stack, usually by overflowing an array stored on the stack. In this case, you might be able to get more clarity on the situation by using a tool like valgrind

这篇关于GDB 损坏的堆栈帧 - 如何调试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆