当前位置: 首页 > news >正文

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

为什么80%的码农都做不了架构师?>>>   hot3.png

官方介绍:


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

转载于:https://my.oschina.net/shadai/blog/698970

相关文章:

  • xcache为php加速
  • 倒立三角打印
  • TCP协议简介
  • 程序图标,几十万个随你选
  • JAVA的双色球 小程序
  • 写出好的 commit message
  • 微软开发团队的DevOps实践启示
  • centos6.5环境下svn服务器和客户端配置实用详解
  • python 字典(dict)按键和值排序
  • url获取数据
  • 如何绘制caffe网络训练曲线
  • 日志分析系统——Hangout源码学习
  • spring boot 调试 - 热部署
  • 阿里云服务器Linux CentOS安装配置(零)目录
  • 数据结构 树 相关面试试题
  • .pyc 想到的一些问题
  • 2018一半小结一波
  • 345-反转字符串中的元音字母
  • angular2开源库收集
  • CentOS从零开始部署Nodejs项目
  • CSS实用技巧
  • emacs初体验
  • express如何解决request entity too large问题
  • REST架构的思考
  • vue学习系列(二)vue-cli
  • Vue组件定义
  • 反思总结然后整装待发
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 十年未变!安全,谁之责?(下)
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 通过npm或yarn自动生成vue组件
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • #AngularJS#$sce.trustAsResourceUrl
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (3)STL算法之搜索
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (附源码)springboot教学评价 毕业设计 641310
  • (六)vue-router+UI组件库
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (未解决)macOS matplotlib 中文是方框
  • (一)为什么要选择C++
  • (转)Oracle存储过程编写经验和优化措施
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .describe() python_Python-Win32com-Excel
  • .NET Core WebAPI中封装Swagger配置
  • .NET Core 成都线下面基会拉开序幕
  • .NET 中让 Task 支持带超时的异步等待
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET简谈设计模式之(单件模式)
  • @angular/cli项目构建--Dynamic.Form