内核中dump_stack()的实现,并在用户态模拟dump_stack()

内核中的dump_stack()

获得内核中当前进程的栈回溯信息需要用到的最重要的三个内容就是:

栈指针:sp寄存器,用来跟踪程序执行过程。

返回地址:ra寄存器,用来获取函数的返回地址。

程序计数器:epc,用于定位当前指令的位置。

本文的内容都是基于mips体系架构的,如果你不搞mips,就只看个大致流程就可以了,不然可能会被某些内容误导。在ARM中,这三个寄存器分别为SP、LR和PC寄存器。

dump_stack()用于回溯函数调用关系,他需要做的工作很简单:

1.   从进程栈中找到当前函数(callee)的返回地址。

2.   根据函数返回地址,从代码段中定位该地址位于哪个函数中,找到的函数即为caller函数。

3.   打印caller函数的函数名。

4.   重复前3个步骤。直到返回值为0或不在内核记录的符号表范围内。

在编译程序的时候,所有函数所需要的栈空间的大小都已经计算出来,如果函数需要保存返回地址,返回地址在该函数的栈空间中保存的位置也都计算出来了。所以,我们想得到返回地址,只需得到每个函数栈即可,而所有函数栈都放在进程的栈中,栈顶为sp。

返回地址是caller函数中将要执行的指令,是指向代码段的,这个更容易得到,因为代码段在编译时就确定了。

当前函数的位置通过pc的值可以得到。

例如,现在有func0调用func1,func1又调用func2,在func2执行过程中,进程栈空间大致如下:

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值