在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+程序里打印调用栈。转
在C/C++程序里打印调用栈信息 我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如 ...
- 利用backtrace和backtrace_symbols函数打印调用栈信息
在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include <execinfo.h> int backtrace(void * ...
- android打印调用栈
在某些机器上,不能下断点,出现了某个诡异的问题,想到唯一的解决方式,就是打印调用栈了,google发现这个,记录下,以后备用 Log.d(",Log.getStackTraceString( ...
- kernel中,dump_stack打印调用栈,print_hex_dump打印一片内存,记录一下
kernel中,dump_stack打印调用栈,print_hex_dump打印一片内存,记录一下
- perf打印调用栈的过程
perf_prepare_sample-->perf_callchain-->get_perf_callchain 上面的调用栈会使用 perf_event_output--> 0x ...
- Android 中调试手段 打印函数调用栈信息
下面来简单介绍下 android 中的一种调试方法. 在 android 的 app 开发与调试中,经常需要用到打 Log 的方式来查看函数调用点. 这里介绍一种方法来打印当前栈中的函数调用关系 St ...
- 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().
- Python错误 -- try/except/finally 、调用栈、记录错误、抛出错误
Bug:程序编写有问题造成的错误,称之为Bug. debug:调试 注意:bug是程序本身有问题.有缺陷.系统漏洞 异常:完全无法在程序运行中预测的错误,例如写入文件的时候,磁盘满了,写不进去了 ...
随机推荐
- Unity3D独立游戏开发日记(一):动态生成树木
目前写的独立游戏是一个沙盒类型的游戏.游戏DEMO视频如下: 提到沙盒类型的游戏,就有人给出了这样的定义: 游戏世界离现实世界越近,自由度.随机度越高才叫沙盒游戏.所谓自由度,就是你在游戏里想干啥就干 ...
- [转]DBA,SYSDBA,SYSOPER三者的区别
原文地址:http://www.oracleonlinux.cn/2010/02/dba_sysdba_sysoper/ 什么是DBA?什么是SYSDBA,什么又是SYSOPER?三者究竟有何联系呢? ...
- keep_on _coding——js_good_parts
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Spring 使用中的设计模式
1. 简单工厂 又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一. 简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类. ...
- [转]window.opener用法
window.opener 实际上就是通过window.open打开的窗体的父窗体. 比如在父窗体parentForm里面 通过 window.open("subForm.html" ...
- json2.js的初步学习与了解
json2.js的初步学习与了解,想要学习json的朋友可以参考下. json2.js的初步学习与了解 1.)该js的下载地址是:http://www.json.org/json2.js 2.)在页面 ...
- Java编程思想学习(十五) 注解
注解Annotation又叫元数据,是JDK5中引入的一种以通用格式为程序提供配置信息的方式.使用注解Annotation可以使元数据写在程序源码中,使得代码看起来简洁,同时编译器也提供了对注解Ann ...
- Web 测试经验总结
Web功能测试常用方法 1.页面链接检查每一个链接是否都有对应的页面,并且页面之间切换正确: 2.相关性检查删除/增加一项会不会对其他项产生影响,如果产生影响,这些影响是否都正确. 3.检查按钮的功能 ...
- Linux内核之内存管理完全剖析
linux虚拟内存管理功能 ? 大地址空间:? 进程保护:? 内存映射:? 公平的物理内存分配:? 共享虚拟内存.实现结构剖析 (1)内存映射模块(mmap):负责把磁盘文件的逻辑地址映射到虚拟地 ...
- POJ2531Network Saboteur(DFS+剪枝)
Network Saboteur Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10391 Accepted: 4990 ...