无帧指针获取调用堆栈 [英] Getting call stack without frame pointers

查看:167
本文介绍了无帧指针获取调用堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取调用堆栈回溯。不能包含execinfo.h因此不能使用 int backtrace(void ** buffer,int size);
另外,尝试使用 __ builtin_return_address(),但是按照: http://codingrelic.geekhold.com/2009/05/pre-mortem-backtracing.html


...在某些体系结构中,包括我喜欢的MIPS,只有__builtin_return_address(0)有效.MIPS没有帧指针,因此难以走回堆栈。


如何获得完整的通话记录?


<我已经成功地使用了@Erki A所建议的方法,并且描述了 解决方案

stack-without-a-frame-pointer.htmlrel =nofollow noreferrer> here
以下是该方法的简短摘要:

问题:

无需调用堆栈一个帧指针。
解决方案的主要思想:
从汇编代码中得出调试器从调试信息中理解的内容。
我们需要的信息
1.保留返回地址。
2.堆栈指针减少的数量



要重现整个堆栈跟踪,需要:

  1.获取当前的$ sp和$ ra 
2.扫描函数的开头并查找addui
sp,sp,spofft 命令(spofft <0)
3. Reprodece prev。 $ sp(sp-spofft)
4.向前扫描并查找sw r31,raofft(sp)
5.上一页。返回地址存储在[sp + raofft]

上面我描述了一次迭代。
如何获得第一个$ ra?

  __builtin_return_address(0)

如何获得第一个$ sp?

 寄存器unsigned sp asm(29); 
asm(:= r(sp));

***由于我的大多数文件是使用微型mips优化编译的,所以我不得不处理micro- MIPS-ISA。
当我试图分析使用microMips优化编译的代码时,出现了很多问题(请记住,每一步的目标是重现prev。ra和prev。sp):
它让事情变得更多一点复杂:

  1. ra($ 31)寄存器包含未对齐的返回地址。 
您可以在链接问题中找到更多信息。
unaligned ra帮助你理解你运行在不同的
ISA(micro-mips-isa)
上2.有些函数不会移动sp。你可以找到更多的
信息[这里] [3]。
(如果leaf函数只修改临时寄存器并将
返回给其调用者代码中的返回语句,则不需要更改
$ ra,并且存在不需要
函数的堆栈框架。)
3.不存储ra
的函数4. MicroMips指令可以是 - 16位和32位:运行在
通讯使用不存在的短*。
5.有一些函数执行addiu sp,sp,spofft不止一次
6. micro-mips-isa对于相同命令
有几个变体,例如:addiu,addiusp 。

我决定忽略部分问题,这就是为什么95% 。


I am trying to get call stack backtrace. Can't include "execinfo.h" therefore can't use int backtrace(void **buffer, int size);. Also, tried to use __builtin_return_address() but acording to :http://codingrelic.geekhold.com/2009/05/pre-mortem-backtracing.html

...Also on some architectures, including my beloved MIPS, only __builtin_return_address(0) works.MIPS has no frame pointer, making it difficult to walk back up the stack. Frame 0 can use the return address register directly.

How can I get full call satck?

解决方案

I have successfully used the method suggested by @Erki A and described here. Here is a short summary of the method:

The problem:
get a call stack without a frame pointer. Solution main idea: conclude from the assembly code what the debugger understood from debug info. The information we need: 1. Where the return address is kept. 2. What amount the stack pointer is decremented.

To reproduce the whole stack trace one need to:

 1. Get the current $sp and $ra 
 2. Scan towards the beginning of the function and look for "addui 
    sp,sp,spofft" command (spofft<0) 
 3. Reprodece prev. $sp (sp- spofft) 
 4. Scan forward and look for "sw r31,raofft(sp)" 
 5. Prev. return address stored at [sp+ raofft] 

Above I described one iteration. You stop when the $ra is 0. How to get the first $ra?

 __builtin_return_address(0) 

How to get the first $sp?

 register unsigned sp asm("29");
 asm("" : "=r" (sp));

***Since most of my files compiled with micro-mips optimisation I had to deal with micro-mips-ISA. A lot of issues arose when I tried to analyze code that compiled with microMips optimization(remember that the goal at each step is to reproduce prev. ra and prev. sp): It makes things a bit more complicated:

 1. ra ($31) register contain unaligned return address.
    You may find more information at Linked questions.
    The unaligned ra helps you understand that you run over different 
    ISA(micro-mips-isa) 
 2. There are functions that do not move the sp. You can find more           
    information [here][3].
    (If a "leaf" function only modifies the temporary registers and returns 
    to a return statement in its caller's code, then there is no need for 
    $ra to be changed, and there is no need for a stack frame for that 
    function.)
 3. Functions that do not store the ra 
 4. MicroMips instructions can be both - 16bit and 32bit: run over the 
    commnds using unsinged short*.
 5. There are functions that perform "addiu sp, sp, spofft" more than once
 6. micro-mips-isa has couple variations for the same command
    for example: addiu,addiusp.

I have decided to ignore part of the issues and that is why it works for 95% of the cases.

这篇关于无帧指针获取调用堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆