堆栈参数从堆栈中错误的内存地址读取

时间:2015-02-11 11:01:58

标签: c gdb stack arm corruption

我正在尝试在ARM体系结构上调试进程核心转储。

这是一个用C语言编写的电信堆栈软件。该过程是单线程的。

通过gdb进行的一些调试表明,堆栈参数(局部变量或函数参数)是从与正确位置固定偏移(8个字节)的内存位置读取的。

以下是一些调试信息:

(gdb) p localParam_p
$16 = (UInt8 *) 0xbe <Address 0xbe out of bounds>

(gdb) x /16wx &localParam_p
0x7ea5c774:     0x000000be      0x00000010      0x94dc788c     0x00000000

正确(预期)值为0x94dc788c,存储在内存位置0x7ea5c77c(上面输出中的第三个字)

这是另一个例子:

(gdb) p localParam2
$18 = 0

(gdb) x /16wx &localParam2
0x7ea5c770:     0x00000000      0x000000be      0x00000010     0x94dc788c

addrLen的预期值为0x10(上面的第三个字)。

我可以在堆栈帧中看到与其他局部变量相同的问题。

请帮忙!

Valgrind不能在此系统上使用。

该过程仅在几天的时间内崩溃一次,并且复制步骤尚不清楚。

1 个答案:

答案 0 :(得分:0)

我对此类事情的反应是怀疑编译器debuginfo错误。它也可能是一个gdb错误。如果我遇到这个问题,我会这样做:

首先,确保我有最新版本的gdb;如果没有,请升级到最新版本。

如果不起作用,请启用DWARF位置反汇编:

maint set dwarf2 always-disassemble on

然后询问相关变量的位置:

info addr localParm2

这将转储一个DWARF表达式,显示gdb认为变量所在的位置。 DWARF表达式使用简单的堆栈机器语言,您将不得不深入研究DWARF标准以及一些GCC扩展文档(在GCC维基上)来理解这一点。

如果你没有使用DWARF - 那么,你应该这些天,这是一个很好的起点。

这是我期望找到错误的地方。如果是这样,唯一的答案是您需要通过升级或调试问题来修复编译器。

编译器输出也可能是正确的,并且您发现了gdb错误。我认为这不太可能,因为gdb中的位置表达式代码运行得相当好。

还值得仔细检查debuginfo是否与您正在调试的程序匹配。并且,可能值得查看您使用的编译器是否在此区域中存在任何已知错误。