Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
手臂皮质上的Stacktrace-M4_C_Arm_Cortex M - Fatal编程技术网

手臂皮质上的Stacktrace-M4

手臂皮质上的Stacktrace-M4,c,arm,cortex-m,C,Arm,Cortex M,当我在手臂cortex-M4(拇指)上遇到故障处理程序时,我会在故障发生之前得到CPU寄存器的快照。有了这些信息,我可以找到堆栈指针所在的位置。现在,我想要的是回溯它传递的所有函数。我在这里看到的唯一问题是,我没有帧指针,所以我无法真正看到某个子例程在哪里保存了LR,ad无穷大 如果r7中没有帧指针,如何解决这个问题?参考MIPS体系结构讨论了这个问题-这些原则可以很容易地适应ARM体系结构 简而言之,它描述了为给定SP和PC定位堆栈帧的三种可能性: 使用编译器生成的调试信息(不包括在可执行映

当我在手臂cortex-M4(拇指)上遇到故障处理程序时,我会在故障发生之前得到CPU寄存器的快照。有了这些信息,我可以找到堆栈指针所在的位置。现在,我想要的是回溯它传递的所有函数。我在这里看到的唯一问题是,我没有帧指针,所以我无法真正看到某个子例程在哪里保存了LR,ad无穷大

如果r7中没有帧指针,如何解决这个问题?

参考MIPS体系结构讨论了这个问题-这些原则可以很容易地适应ARM体系结构

简而言之,它描述了为给定SP和PC定位堆栈帧的三种可能性:

  • 使用编译器生成的调试信息(不包括在可执行映像中)来计算它
  • 使用编译器生成的堆栈展开(异常处理)信息(包括在可执行映像中)来计算它
  • 扫描调用站点以找到调整堆栈指针的序言或尾声代码,并从中推断堆栈帧地址

显然,它非常依赖于编译器和编译器选项,并且不能保证在所有情况下都能工作。

R7不是M4上的帧指针,它是R11。R7是Cortex-M0+/M1的FP,通常只有较低的寄存器可用。无论如何,当Cortex-M使用BL和变量调用函数时,它会将返回地址保存到LR(链接寄存器)中。在函数输入时,LR保存到堆栈上。所以从理论上讲,要获得呼叫跟踪,你需要“追踪”LRs链


不幸的是,堆栈上LR的保存位置不是由调用约定定义的,它的位置必须从DWARF记录(在.elf文件中)中该函数项的调试信息中推断出来。我不知道是否有一个实用程序可以从ELF文件中提取LR位置,但这应该不会太难。

ImageCraft的Richard是对的

可以找到更多信息


这适用于C代码。我更难将它应用到C++,但这不是不可能的。

反汇编代码,看看堆栈上的内容。你使用的是什么调试器?我知道Keil Uvision上有一个调用堆栈。你是不是被某种陷阱绊倒了?@KooroshHajiani我没有使用调试器,我的目标是免费运行的,并且具有日志记录(printf风格)功能。在某些情况下,无法返回的函数(因为
,而(1)
,或者其他原因)将不会推送LR,因为它永远不会再次使用它。在这些情况下,您可以在while(
while(dummy==0)
)中使用非常量对象全局变量来欺骗编译器,并使其认为函数可以返回。这和你的问题相匹配吗?关于尝试使用(gnu)工具检查堆栈跟踪,有无数的cortex-m问题,听起来像是失败了。只要看看代码和你在其中的位置,就知道如何展开堆栈(反汇编和当前pc和sp值)。@old_timer:第三种技术正是这样做的-根据OP,以编程方式,但手动检查应用相同的原则。虽然此链接可以回答问题,最好在这里包括答案的基本部分,并提供链接供参考。如果链接页面发生更改,则仅链接的答案可能无效。