在c或c+程序里打印调用栈。转
我们知道,GDB的backtrace命令可以查看堆栈信息。但很多时候,GDB根本用不上。比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试。如果能让程序自己输出调用栈,那是最好不过了。本文介绍和调用椎栈相关的几个函数。
|
NAME SYNOPSIS int backtrace(void **buffer, int size); char **backtrace_symbols(void *const *buffer, int size); void backtrace_symbols_fd(void *const *buffer, int size, int fd); |
以上内容源自这几个函数的man手册。
先简单介绍一下这几个函数的功能:
l backtrace:获取当前的调用栈信息,结果存储在buffer中,返回值为栈的深度,参数size限制栈的最大深度,即最大取size步的栈信息。
l backtrace_symbols:把backtrace获取的栈信息转化为字符串,以字符指针数组的形式返回,参数size限定转换的深度,一般用backtrace调用的返回值。
l backtrace_symbols_fd:它的功能和backtrace_symbols差不多,只不过它不把转换结果返回给调用方,而是写入fd指定的文件描述符。
Man手册里,给出了一个简单的实例,我们看一下:
|
#include<execinfo.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h> void myfunc3(void) { int j, nptrs; #define SIZE 100 void *buffer[100]; char **strings; nptrs = backtrace(buffer, SIZE); printf("backtrace() returned %d addresses\n", nptrs); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) * would produce similar output to the following: */ strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { perror("backtrace_symbols"); exit(EXIT_FAILURE); } for (j = 0; j < nptrs; j++) printf("%s\n", strings[j]); free(strings); } staticvoid /* "static" means don't export the symbol... */ myfunc2(void) { myfunc3(); } void myfunc(int ncalls) { if (ncalls > 1) myfunc(ncalls - 1); else myfunc2(); } int main(int argc,char *argv[]) { if (argc != 2) { fprintf(stderr,"%s num-calls\n", argv[0]); exit(EXIT_FAILURE); } myfunc(atoi(argv[1])); exit(EXIT_SUCCESS); } |
编译:
|
# cc prog.c -o prog |
运行:
|
# ./prog 0 |
这样,是输出了调用栈,不过只是以十六进制输出函数地址而已,可读性很差。仔细看下man手册,原来很简单,编译时加上个参数:
重新编译:
|
# cc -rdynamic prog.c -o prog |
通过gcc手册,我们可以也解下参数的说明:
|
-rdynamic |
再执行:
|
# ./prog 0 backtrace() returned 6 addresses |
这回,可以看到函数名了。是不是很酷呢?
在c或c+程序里打印调用栈。转的更多相关文章
- 在C/C++程序里打印调用栈信息
我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如果能让程序自己输出调用栈,那是最好 ...
- android打印调用栈
在某些机器上,不能下断点,出现了某个诡异的问题,想到唯一的解决方式,就是打印调用栈了,google发现这个,记录下,以后备用 Log.d(",Log.getStackTraceString( ...
- kernel中,dump_stack打印调用栈,print_hex_dump打印一片内存,记录一下
kernel中,dump_stack打印调用栈,print_hex_dump打印一片内存,记录一下
- 利用backtrace和backtrace_symbols函数打印调用栈信息
在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include <execinfo.h> int backtrace(void * ...
- perf打印调用栈的过程
perf_prepare_sample-->perf_callchain-->get_perf_callchain 上面的调用栈会使用 perf_event_output--> 0x ...
- java 中打印调用栈
source-code: public class A { public A() {} private static void printStackTrace() { StackTra ...
- python 打印调用栈
import traceback def BBQ(): traceback.print_stack() 引入 traceback 包,在某个函数中执行 traceback.print_stack().
- arm平台的调用栈回溯(backtrace)
title: arm平台的调用栈回溯(backtrace) date: 2018-09-19 16:07:47 tags: --- 介绍 arm平台的调用栈与x86平台的调用栈大致相同,稍微有些区别, ...
- Lua中如何实现类似gdb的断点调试--03通用变量修改及调用栈回溯
在前面两篇01最小实现及02通用变量打印中,我们已经实现了设置断点.删除断点及通用变量打印接口. 本篇将继续新增两个辅助的调试接口:调用栈回溯打印接口.通用变量设置接口.前者打印调用栈的回溯信息,后者 ...
随机推荐
- BZOJ4668: 冷战
并查集,按秩合并,树高log,暴力查询. 果然bzoj新挂的题中过的人多的全是sb题. 写了一发秒WA,发现姿势不对.(@_@) 然后过了50min,开始怀疑人生.(*_*) 这么长时间我lct都写完 ...
- css007 margin padding border
css007 margin padding border 1.理解盒模型(盒模型:就是把一些东西,包括html各种标签都包含在一个 看不见的盒子里) 1/在web浏览器中任何标签都是一个盒子,内容的周 ...
- C#------DateTime自定义格式
var text = Convert.ToString(DateTime.Now.ToString("yyyy/MM/dd"));
- 2016 年 Python 开发者调查结果
1.在团队中工作 vs 独立工作 有趣的是,半数的受访者大部分时间在团队中工作,而另外半数的受访者则独立的做项目. 在公司中工作 vs 独立从事自己的项目 大约80%的受访者告诉我们,他们在公司里面工 ...
- CPU host-passthrough技术与应用
为了保证虚拟机在不同宿主机之间迁移的时候的兼容性,Libvirt对CPU提炼出标准的几种类型,在/usr/share/libvirt/cpu_map.xml中可以查到.cpu_map.xml不仅是CP ...
- day4之函数
很快就第4天了,原来人是有惰性的,博客现在就不想写了,真是悲催,坚持,憋住. 函数 def func(name): print(name) func("huihuang") 函数定 ...
- VirtualBox5中安装的CentOS6.7安装增强工具
1.安装编译内核的相关组件 yum install kernel-devel gcc 2.安装VirtualBox增强功能 sh ./VBoxLinuxAdditions.run 3.重启系统 reb ...
- Auto generating Entity classes with xsd.exe for XML Serialization and De-Serialization
More info here: http://blogs.msdn.com/b/yojoshi/archive/2011/05/14/xml-serialization-and-deserializa ...
- 硬盘安装win10
http://hd.ruanmei.com/
- [转] MemCached 的 stats 命令
Memcached有个stats命令,通过它可以查看Memcached服务的许多状态信息.使用方法如下:先在命令行直接输入telnet 主机名端口号,连接到memcached服务器,然后再连接成功后, ...