免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7314 | 回复: 6
打印 上一主题 下一主题

[内核入门] 关于backtrace的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-09-11 10:09 |只看该作者 |倒序浏览
请问一下:当程序出现断错误的时候,系统会产生信号SIGSEGV,若程序初始化之后注册信号SIGSEGV并且定义入口函数,在入口函数中打印出backtrace(即堆栈),通过对当前堆栈的分析,找到其上层函数在栈中的帧地址,再分析上层函数的堆栈,再找再上层的帧地址……一直找到最顶层为止,帧地址指的是一块:在栈上存放局部变量,上层返回地址,及寄存器值的空间。

请问:backtrace(即堆栈)是基于ebp还是esp来计算的,backtrace又是怎么得到他们的?
        ebp上面就是eip,那逐层查找是基于什么,eip吗?难道eip就是上一层函数的ebp吗?
        系统会打出backtrace的一系列调用地址。请问这些地址到底是什么?是eip吗?这在编译的时候就已经定义好了,可以直接在.s文件中找到。

谢谢!!

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
2 [报告]
发表于 2012-09-11 22:15 |只看该作者
这个要看调用惯例。一般体系中都有一个frame pointer(fp)寄存器,在x86里就是ebp。call完了之后,栈上最后留下是return addr。一般编译器会将fp的值继续往下保存,这样,上一个栈帧的fp就在return addr下面。fp空出来后,再将当前栈指针的值(此时指向前一个fp存在栈上的地址)保存在fp里。

这个过程一层层往下发生,某一个时刻你想backtrace了,直接读取fp的值,从它可以得到两个信息:当前fp的内容是上一次栈帧存在栈上的地址,往上走一点是return address。于是:

    根据return address可以知道是从哪里call到这里来的。
    根据fp的值得到上一次fp的地址。

这时可以从这个旧个fp地址得到上上一次的return address于上上上一次fp的地址,如果递归下去,最终可以追溯到源头。当然,第一次fp的值是要捏造的,比如设为0。

有时候可以让编译器把这个fp释放出来,e.g.不把这个寄存专门用于此。好处是多了一个可用寄存器,坏处是无法准确的回溯。

论坛徽章:
0
3 [报告]
发表于 2012-09-13 10:56 |只看该作者
谢谢,那再确认两个问题:
1)ebp(fp)可以从专用寄存器中得到,表示当前执行的函数的ebp。ebp前面一个地址是eip,而实际calltrace中打印出来的都是eip的地址?
2)func1                ->                  func2            -> func3
     xxx                                         xxxx                  xxxx
     eip1                                        eip2                  eip3
     ebp1                                      ebp2                  ebp3
     xxx                                         xxxx                   xxxx
     esp1                                       esp2                  esp3
如上图的话,是不是说ebp的寄存器存储的是当前正在处理的函数func3的ebp3
通过ebp3可以得到eip3, eip3是如果找到ebp2的呢。是eip3=ebp2还是*eip3=ebp2或者其它的映射关系,这样逐层查找阿?

3)esp在这过程中起什么作用。esp和ebp之间到底是什么关系?

谢谢!!

论坛徽章:
0
4 [报告]
发表于 2012-09-17 16:56 |只看该作者
帮忙回答一下,谢谢!!

论坛徽章:
0
5 [报告]
发表于 2012-09-18 11:07 |只看该作者
进入到函数时 一般都是
push ebp
mov ebp,esp

退出函数之前
mov esp, ebp
pop ebp

你慢慢体会下

论坛徽章:
0
6 [报告]
发表于 2012-09-24 17:29 |只看该作者
我看了一下汇编代码,参数,ebp等都有对应的压栈操作,怎么没有发现“返回地址”的压栈操作阿?是在“call  function”中做了吗?

谢谢!!

论坛徽章:
0
7 [报告]
发表于 2012-09-25 17:52 |只看该作者
返回地址压栈,就是由call指令作的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP