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



我正在尝试调试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不能在此系统上使用。

这一过程在几天内只崩溃过一次,繁殖步骤尚不清楚。

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

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

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

maint set dwarf2 always-disassemble on

然后询问有问题的变量的位置:

info addr localParm2

这将转储一个DWARF表达式,显示gdb认为变量的位置。DWARF表达式使用一种简单的堆栈机器语言,您必须深入了解DWARF标准,也许还有一些GCC扩展文档(在GCC wiki上)才能理解这一点。

如果你没有使用DWARF——好吧,现在你应该使用,这是一个很好的开始。

这是我希望找到错误的地方。如果是这样的话,唯一的答案就是你需要修复编译器,要么升级,要么调试那里的问题。

编译器输出也可能是正确的,并且您发现了gdb错误。不过,我认为这种可能性较小,因为gdb中的位置表达式代码已经得到了很好的执行。

同样值得仔细检查debuginfo是否与正在调试的程序匹配。而且,可能值得一看你使用的编译器是否在这方面有任何已知的错误。

最新更新