【问题标题】:stack parameters read from wrong memory address in the stack从堆栈中错误的内存地址读取堆栈参数
【发布时间】:2015-04-11 17:25:32
【问题描述】:

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

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

【问题讨论】:

  • 我们究竟应该为您提供哪些帮助?代码在哪里?你知道,我们不是espers。
  • 我正在寻找进一步调试的提示/方向。
  • 8 字节还是 8 位?但是p localParam_p 打印地址0x7ea5c774 的值是正确的,对吧?指针localParam_p 应该在0x7ea5c774 的下一个字节处打印值是什么意思
  • 如果你想要一个提示,也许你应该寻找一个使用错误参数调用的函数。如果你的原型/包含没有正确完成,编译器不会警告你。这就是为什么你总是把原型放在一个 .h 中,你同时包含在函数 .c 和调用者 .c 中。
  • 8 个字节。 p localParam_p 打印地址 0x7ea5c774 的值不正确。正确的值存储在0x7ea5c77c

标签: c gdb stack arm corruption


【解决方案1】:

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

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

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

maint set dwarf2 always-disassemble on

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

info addr localParm2

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

如果您不使用 DWARF - 好吧,这些天您应该使用,这是一个很好的起点。

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

也有可能是编译器的输出是正确的,而您发现了一个 gdb 错误。不过,我认为这不太可能,因为 gdb 中的位置表达式代码已经很好地执行了。

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

【讨论】:

  • 谢谢@Tom Tromey。您是说进程崩溃可能是由于完全不同的原因,而 gdb 结果可能是红鲱鱼。无论如何,我会继续尝试您的建议。再次感谢!
  • 抱歉,我以为您想知道 gdb 给出错误答案的原因。很难说这些问题是否与坠机有关。但我怀疑不会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2023-03-20
  • 2012-11-02
  • 2011-10-15
  • 2021-10-28
相关资源
最近更新 更多