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

标签 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 无法在此系统上使用。

该进程在几天内只崩溃过一次,并且重现步骤尚不清楚。

最佳答案

我对这种事情的 react 是怀疑编译器调试信息错误。这也可能是 gdb 错误。如果我遇到这个问题,我会这样做:

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

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

maint set dwarf2 always-disassemble on

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

info addr localParm2

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

如果您没有使用 DWARF——那么,您现在应该使用 DWARF,这是一个很好的起点。

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

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

还值得仔细检查调试信息是否与您正在调试的程序相匹配。而且,可能值得查看您使用的编译器在该领域是否存在任何已知错误。

关于c - 从堆栈中错误的内存地址读取堆栈参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28452691/

相关文章:

计算阶乘的c程序不起作用

gdb - 如何在 gdb 中将 float 打印为指数?

macos - Homebrew GDB 无法在 Yosemite 10.10 上打开核心文件

java - Java 堆栈, "contains"问题

c++ - 堆栈(数据结构)实现

c - 随机化数组元素的序列

iphone - 使用 NEON 指令进行图像阈值处理

c - 这个条件语句里面发生了什么? while (a = foo(bar))

assembly - GDB 不从 NASM 加载源代码行

c - GCC - 如何重新对齐堆栈?