532628838
圣骑士
圣骑士
  • 注册日期2011-06-10
  • 发帖数98
  • QQ
  • 火币517枚
  • 粉丝77
  • 关注39
阅读:3075回复:0

不使用调试器查看堆栈的调用情况的方法

楼主#
更多 发布于:2011-08-01 16:40
BS CSDN 写了半天居然说丢就丢了

这次直接帖代码了

程序不大,调了三个小时,自己有必要在强化下对指针的理解:(

原理:函数调用的时候会建立栈帧,其大致存放如下

压栈传入的参数2

压栈传入的参数1

------------------------

函数返回时的地址

------------------------

栈帧
-----------------------

局部变量1

局部变量2

注意:上面表示的内存方式为上面是高地址,下面为低地址。堆栈的生长方向向下。

ebp保存当前栈帧 ,当前栈帧指向的内存里面存放调用函数的栈帧,紧接着的就是返回地址

根据这个原则编写代码如下:


#define GetCurFrame( r )__asm mov r , ebp
#define GetNextFrame( m , r )r = ((void**)m)[0]
#define GetRetIns( m , r )r = ((void**)m)[1]

long Array[8];

void ShowFrame(long * npIns,int nDeep )
{
 int i =0;
 long* nCurFrame;
 long* nNextFrame;
 long* nRetIns;

 GetCurFrame(nCurFrame);

 for (i =0; i<nDeep; i++)
 {
  GetNextFrame(nCurFrame,nNextFrame);
  GetRetIns(nCurFrame,nRetIns);

  npIns[i*2] = (long)nNextFrame;
  npIns[i*2 +1] = (long)nRetIns;
  nCurFrame = nNextFrame;

  printf("\nStack Frame\t:0x%08x\r\n",npIns[i*2]);
  printf("\nIns Ret At\t:0x%08x\r\n",npIns[i*2+1]);
 }
 return;
}

栈帧存放在 npIns的偶索引,函数的返回地址存放在对应的奇索引。

由于程序中无法知道链接器和加载器所使用的符号表,无法在程序中

直接函数返回地址转换为函数名。需要使用外部工具,Addr2line 将函数返回地址转化为函数名。


喜欢0 评分0
游客

返回顶部