文档章节

编程基础-----c语言打印调用栈

傻呆
 傻呆
发布于 2016/06/22 10:05
字数 783
阅读 111
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

官方介绍:


SYNOPSIS         top

#include <execinfo.h>

       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);

DESCRIPTION         top

backtrace() returns a backtrace for the calling program, in the array
       pointed to by buffer.  A backtrace is the series of currently active
       function calls for the program.  Each item in the array pointed to by
       buffer is of type void *, and is the return address from the
       corresponding stack frame.  The size argument specifies the maximum
       number of addresses that can be stored in buffer.  If the backtrace
       is larger than size, then the addresses corresponding to the size
       most recent function calls are returned; to obtain the complete
       backtrace, make sure that buffer and size are large enough.

       Given the set of addresses returned by backtrace() in buffer,
       backtrace_symbols() translates the addresses into an array of strings
       that describe the addresses symbolically.  The size argument
       specifies the number of addresses in buffer.  The symbolic
       representation of each address consists of the function name (if this
       can be determined), a hexadecimal offset into the function, and the
       actual return address (in hexadecimal).  The address of the array of
       string pointers is returned as the function result of
       backtrace_symbols().  This array is malloc(3)ed by
       backtrace_symbols(), and must be freed by the caller.  (The strings
       pointed to by the array of pointers need not and should not be
       freed.)

       backtrace_symbols_fd() takes the same buffer and size arguments as
       backtrace_symbols(), but instead of returning an array of strings to
       the caller, it writes the strings, one per line, to the file
       descriptor fd.  backtrace_symbols_fd() does not call malloc(3), and
       so can be employed in situations where the latter function might
       fail.

RETURN VALUE         top

backtrace() returns the number of addresses returned in buffer, which
       is not greater than size.  If the return value is less than size,
       then the full backtrace was stored; if it is equal to size, then it
       may have been truncated, in which case the addresses of the oldest
       stack frames are not returned.

       On success, backtrace_symbols() returns a pointer to the array
       malloc(3)ed by the call; on error, NULL is returned.

VERSIONS         top

backtrace(), backtrace_symbols(), and backtrace_symbols_fd() are
       provided in glibc since version 2.1.

CONFORMING TO         top

These functions are GNU extensions.

NOTES         top

These functions make some assumptions about how a function's return
       address is stored on the stack.  Note the following:

       *  Omission of the frame pointers (as implied by any of gcc(1)'s
          nonzero optimization levels) may cause these assumptions to be
          violated.

       *  Inlined functions do not have stack frames.

       *  Tail-call optimization causes one stack frame to replace another.

       The symbol names may be unavailable without the use of special linker
       options.  For systems using the GNU linker, it is necessary to use
       the -rdynamic linker option.  Note that names of "static" functions
       are not exposed, and won't be available in the backtrace.

EXAMPLE         top

The program below demonstrates the use of backtrace() and
       backtrace_symbols().  The following shell session shows what we might
       see when running the program:

           $ cc -rdynamic prog.c -o prog
           $ ./prog 3
           backtrace() returned 8 addresses
           ./prog(myfunc3+0x5c) [0x80487f0]
           ./prog [0x8048871]
           ./prog(myfunc+0x21) [0x8048894]
           ./prog(myfunc+0x1a) [0x804888d]
           ./prog(myfunc+0x1a) [0x804888d]
           ./prog(main+0x65) [0x80488fb]
           /lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c]
           ./prog [0x8048711]

Program source

#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);
       }

       static void   /* "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);
       }


自己示例:

[cpp]  view plain  copy
 print ?
  1. #include <stdio.h>  
  2. #include <execinfo.h>  
  3. #include <stdlib.h>  
  4.   
  5. void fun1();  
  6. void fun2();  
  7. void fun3();  
  8. void print_stack();  
  9.   
  10. int main()  
  11. {  
  12.     fun3();  
  13.     return 0;  
  14. }  
  15.   
  16. void fun1()  
  17. {  
  18.     printf("print_stack begin\n");    
  19.     print_stack();  
  20. }  
  21.   
  22. void fun2()  
  23. {  
  24.     fun1();  
  25. }  
  26.   
  27. void fun3()  
  28. {  
  29.     fun2();  
  30. }  
  31.   
  32. void print_stack()  
  33. {  
  34.     int size = 16;  
  35.     int i;    
  36.     void *array[16];  
  37.     int stack_num = backtrace(array, size);  
  38.     char **stacktrace = NULL;  
  39.           
  40.     stacktrace = (char**)backtrace_symbols(array, stack_num);  
  41.       
  42.     for(i = 0; i < stack_num; i++)  
  43.     {  
  44.         printf("%s\n", stacktrace[i]);  
  45.     }  
  46.     free(stacktrace);  
  47. }  

编译:


原博文地址   http://blog.csdn.net/yf210yf/article/details/14642837

© 著作权归作者所有

傻呆
粉丝 1
博文 143
码字总数 138424
作品 0
成都
私信 提问
C语言实现数据结构之栈的详解

在函数调用的过程中,需要的就是先进后出的特点,因此,栈就出现了。 栈是一种数据结构,是计算机怎么处理程序运行的一种方式。具有先进后出的特点,下面看的就是这些抽象的数据结构怎么用C...

ningcaichen66
2017/09/21
0
0
一直没有搞懂的C语言参数传递,今天终于明白了

本讲我们和大家一起来聊一聊C语言中有关参数传递的一些知识。 1. 问题引入 请写出以下程序的打印结果。 #include <stdio.h> // 将某整数加10 void addby10(int a){ a = a + 10; } int main(...

算法与编程之美
2017/04/08
32
0
修饰符static extern const的注意点

static 1>修饰全局变量 *全局变量的作用域仅限于当前文件内部,防止重命名,其他文件无法访问 2>修饰局部变量 ***局部变量的生命周期,与全局变量类似 *但是不能改变作用域 *能保证局部变量永...

Ethan-GOGO
2015/07/18
165
0
跟涛哥一起学嵌入式 第05集:一道程序改错题,测出你的嵌入式功底

大家好,欢迎阅读《跟涛哥一起学嵌入式》第05集,我们今天讨论一下中断的基本概念。 中断,是嵌入式开发中经常使用的一个功能,也是嵌入式工程师必须要掌握的一个概念:CPU和外设通信时,一般...

宅学部落
2018/07/06
0
0
宣传一下我的C语言库

简介 cfan是开源的ANSI C实现的基础库。讲究代码整洁,性能和跨平台。 包括内存检测,内存分配池,日志记录,堆栈跟踪,字符串处理, 动态数组,哈希表,队列,单元测试,线程池,文件,流等...

chunquedong
2013/04/11
2.2K
17

没有更多内容

加载失败,请刷新页面

加载更多

在C语言中“静态”是什么意思?

我已经在C代码的不同地方看到了static一词。 这就像C#中的静态函数/类(实现在对象之间共享)吗? #1楼 多文件变量作用域示例 在这里,我说明了静态如何影响多个文件中函数定义的范围。 交流...

javail
21分钟前
13
0
利用 FC + OSS 快速搭建 Serverless 实时按需图像处理服务

作者:泽尘 简介 随着具有不同屏幕尺寸和分辨率设备的爆炸式增长,开发人员经常需要提供各种尺寸的图像,从而确保良好的用户体验。目前比较常见的做法是预先为一份图像存放多份具有不同尺寸的...

阿里巴巴云原生
23分钟前
7
0
前端架构最佳实践

Folders-by-Feature Structure 胜过 Folders-by-Type Structure

lilugirl
34分钟前
9
0
Seata AT 模式启动源码分析

从上一篇文章「分布式事务中间件Seata的设计原理」讲了下 Seata AT 模式的一些设计原理,从中也知道了 AT 模式的三个角色(RM、TM、TC),接下来我会更新 Seata 源码分析系列文章。今天就来分...

后端进阶
35分钟前
9
0
Python中“自我”一词的目的是什么?

Python中self词的目的是什么? 我知道它是指从该类创建的特定对象,但是我看不到为什么要将它显式地作为参数添加到每个函数中。 为了说明这一点,在Ruby中,我可以这样做: class myClass ...

技术盛宴
37分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部