从堆栈中错误的内存地址读取堆栈参数
stack parameters read from wrong memory address in the stack
我正在尝试调试 ARM 架构上的进程核心转储。
C语言编写的电信栈软件,进程为单线程。
通过 gdb 进行的一些调试表明堆栈参数(局部变量或函数参数)正在从与正确位置相距固定偏移量(8 字节)的内存位置读取。
调试信息如下:
(gdb) p localParam_p
= (UInt8 *) 0xbe <Address 0xbe out of bounds>
(gdb) x /16wx &localParam_p
0x7ea5c774: 0x000000be 0x00000010 0x94dc788c 0x00000000
正确的(预期)值是 0x94dc788c,存储在内存位置 0x7ea5c77c(上面输出中的第三个字)
这是另一个例子:
(gdb) p localParam2
= 0
(gdb) x /16wx &localParam2
0x7ea5c770: 0x00000000 0x000000be 0x00000010 0x94dc788c
addrLen 的预期值为 0x10(上面的第三个字)。
我发现跨堆栈帧的其他局部变量也存在同样的问题。
求助!
Valgrind 无法在此系统上使用。
进程几天内只崩溃过一次,重现步骤未知
我对这类事情的反应是怀疑编译器调试信息错误。它也可能是一个 gdb 错误。如果我有这个问题,我会这样做:
首先,确保我有最新版本的 gdb;如果没有升级到最新版本。
如果这不起作用,请启用 DWARF 位置反汇编:
maint set dwarf2 always-disassemble on
然后询问相关变量的位置:
info addr localParm2
这将转储一个 DWARF 表达式,显示 gdb 认为变量所在的位置。 DWARF 表达式使用简单的堆栈机器语言,您将不得不深入研究 DWARF 标准和一些 GCC 扩展文档(在 GCC wiki 上)才能理解这一点。
如果您不使用 DWARF —— 那么,现在您应该使用,这是一个很好的起点。
这是我希望找到错误的地方。而且,如果是这样,唯一的答案是您需要通过升级或调试那里的问题来修复编译器。
也有可能编译器输出是正确的并且您发现了 gdb 错误。不过,我认为这不太可能,因为 gdb 中的位置表达式代码已经得到很好的运用。
还值得仔细检查调试信息是否与您正在调试的程序相匹配。而且,可能值得看看您使用的编译器是否在这方面有任何已知错误。
我正在尝试调试 ARM 架构上的进程核心转储。
C语言编写的电信栈软件,进程为单线程。
通过 gdb 进行的一些调试表明堆栈参数(局部变量或函数参数)正在从与正确位置相距固定偏移量(8 字节)的内存位置读取。
调试信息如下:
(gdb) p localParam_p
= (UInt8 *) 0xbe <Address 0xbe out of bounds>
(gdb) x /16wx &localParam_p
0x7ea5c774: 0x000000be 0x00000010 0x94dc788c 0x00000000
正确的(预期)值是 0x94dc788c,存储在内存位置 0x7ea5c77c(上面输出中的第三个字)
这是另一个例子:
(gdb) p localParam2
= 0
(gdb) x /16wx &localParam2
0x7ea5c770: 0x00000000 0x000000be 0x00000010 0x94dc788c
addrLen 的预期值为 0x10(上面的第三个字)。
我发现跨堆栈帧的其他局部变量也存在同样的问题。
求助!
Valgrind 无法在此系统上使用。
进程几天内只崩溃过一次,重现步骤未知
我对这类事情的反应是怀疑编译器调试信息错误。它也可能是一个 gdb 错误。如果我有这个问题,我会这样做:
首先,确保我有最新版本的 gdb;如果没有升级到最新版本。
如果这不起作用,请启用 DWARF 位置反汇编:
maint set dwarf2 always-disassemble on
然后询问相关变量的位置:
info addr localParm2
这将转储一个 DWARF 表达式,显示 gdb 认为变量所在的位置。 DWARF 表达式使用简单的堆栈机器语言,您将不得不深入研究 DWARF 标准和一些 GCC 扩展文档(在 GCC wiki 上)才能理解这一点。
如果您不使用 DWARF —— 那么,现在您应该使用,这是一个很好的起点。
这是我希望找到错误的地方。而且,如果是这样,唯一的答案是您需要通过升级或调试那里的问题来修复编译器。
也有可能编译器输出是正确的并且您发现了 gdb 错误。不过,我认为这不太可能,因为 gdb 中的位置表达式代码已经得到很好的运用。
还值得仔细检查调试信息是否与您正在调试的程序相匹配。而且,可能值得看看您使用的编译器是否在这方面有任何已知错误。