关于-fno-omit-frame-pointer与-fomit-frame-pointer

转:  http://www.trueeyu.com/?p=1694

在GDB core的时候,经常去查看EBP,ESP寄存器,来查找一些有用的调用信息,但是感觉这个EBP,ESP中值的变化,并不是像书中描述的那种函数调用的标准流程。

在用perf做性能分析,打印函数的调用路径时,打印调用路径也有问题。

后来才清楚,原来是-fno-omit-frame-pointer这个优化导致的问题。

下面以一个实例来说明:

#include <stdio.h>

int add(int a, int b)
{
  return a + b;
}

int main(void)
{
  int sum = 0;
  sum = add(1, 2);
  printf("%d\n", sum);
  return 0;
}

gcc -o a.s -S a.c -fno-omit-frame-pointer

vim a.s

add函数汇编:
.LFB0:
  .cfi_startproc
  pushq %rbp             #保存栈基址
  .cfi_def_cfa_offset 16
  .cfi_offset 6, -16
  movq %rsp, %rbp       #将栈顶做为新的栈基址
  .cfi_def_cfa_register 6
  movl %edi, -4(%rbp)  
  movl %esi, -8(%rbp)
  movl -8(%rbp), %eax   #取参数1
  movl -4(%rbp), %edx   #取参数2
  leal (%rdx,%rax), %eax  #相加
  leave
  .cfi_def_cfa 7, 8
  ret #返回

gcc -o a.s -S a.c -fomit-frame-pointer

vim a.s

add函数汇编

add:

.LFB0:
  .cfi_startproc
  movl %edi, -4(%rsp)    #取参数1
  movl %esi, -8(%rsp)    #取参数2
  movl -8(%rsp), %eax
  movl -4(%rsp), %edx
  leal (%rdx,%rax), %eax #相加
  ret

从汇编结果可以看出,第二种少了几条切换栈基址的指令,会有性能提升,但会带来一个问题,由于没有存储rbp,那么从add函数并不能追溯整个函数的调用栈。

比如,当perf采样到add函数内的时候,它只能打印当前的指令是在哪个函数内,但不能打印整个调用函数栈。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值