C++获得程序的调用栈的几种方法

C++获得程序的调用栈的几种方法,第1张

gcc提供了一个内置的函数,可以打印出一个函数的调用堆栈, __builtin_return_address(level) 打印出一个函数的堆栈地址

其中 level代表是堆栈中第几层调用地址,__builtin_return_address(0)表示第一层调用地址,即当前函数,__builtin_return_address(1)表示第二层。

写一个测试程序运行一下看看结果

对于打印出来的地址,可以使用addr2line查看到对应的文件:

addr2line可以看到对应的符号名,但是对应的文件名和函数名就看不到。看了一下原因,应该是编译的时候,没有带上调试信息。带上-g重新编译一次,效果就正常了。

当然,常见的获得函数调用栈的方法是backtrace函数,比起backtrace函数,__builtin_return_address的性能要好太多。

具体性能对比:

除了上面介绍的两种打印bt的方法,libunwind库也提供了相关的方法。看文档unwind使用了栈指针遍历的方式去获得bt(性能也许会更好?文档里面也没说 不过文档里面说这种方式可以打印出调用的每层函数里面的寄存器值)

__builtin_return_address() 是一个比较轻量的方法去获得调用的函数栈,性能比backtrace_symbols好太多(backtrace_symbols这个函数啊,如果调用的频次稍高一些,很容易cpu100%),这个函数可以加入debug工具箱。

分类: 电脑/网络 >>程序设计 >>其他编程语言

问题描述:

初学微机,每次编写程序时总要加入堆栈段,但是我不知道它在程序运行起什么作用。望指教!

解析:

因为CPU要使用堆栈,主要是子程序调用call和ret指令,使用堆栈来存储返回地址,调用子程序的时候,后调用的子程序先返回,而且还可能嵌套调用甚至递归调用,所以必须使用先进后出的数据结构stack来实现返回地址的存储。

没有堆栈stack,就无法实现函数/子程序调用,

还有高级语言都用stack来存储局部变量和参数,汇编也可以用,但是比较麻烦。汇编经常使用stack来保存寄存器的值,PUSH和POP指令比较好用

存储数据,指令地址等

栈:

在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。

当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

全文见百科

http://baike.baidu.com/view/93201.htm


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12099457.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存