最近在一块新的板子下作开发, 有些变量发生异常(就是我们不想到的值),可以加上backtrace,知道是哪个函数调用它,导致出现异常, 就像死机了,你可以gdb和core文件用bt 命令,查看死机在哪里(有一种 情况 不能看见, 就是发生信号异常不在本文范围 ), 本人感觉还有用, 关说不炼、假把式,下面是实现代码:

首先实现核心代码backtrace函数:

[html] view plaincopyprint
  1. extern void * __libc_stack_end;
  2. # define BOUNDED_N(PTR, N) (PTR)
  3. #define BOUNDED_1(PTR) BOUNDED_N (PTR, 1)
  4. /* Get some notion of the current stack. Need not be exactly the top
  5. of the stack, just something somewhere in the current frame. */
  6. #ifndef CURRENT_STACK_FRAME
  7. # define CURRENT_STACK_FRAME ({ char __csf; &__csf; })
  8. #endif
  9. /* By default we assume that the stack grows downward. */
  10. #ifndef INNER_THAN
  11. # define INNER_THAN <
  12. #endif
  13. /* By default assume the `next' pointer in struct layout points to the
  14. next struct layout. */
  15. #ifndef ADVANCE_STACK_FRAME
  16. # define ADVANCE_STACK_FRAME(next) BOUNDED_1 ((struct layout *) (((int)next) - 4))
  17. #endif
  18. /* By default, the frame pointer is just what we get from gcc. */
  19. #ifndef FIRST_FRAME_POINTER
  20. # define FIRST_FRAME_POINTER (__builtin_frame_address (0) - 4)
  21. #endif
  22. int backtrace (void **array, int size)
  23. {
  24. struct layout *current;
  25. void *top_frame;
  26. void *top_stack;
  27. int cnt = 0;
  28. top_frame = FIRST_FRAME_POINTER;
  29. top_stack = CURRENT_STACK_FRAME;
  30. /* We skip the call to this function, it makes no sense to record it. */
  31. current = BOUNDED_1 ((struct layout *) top_frame);
  32. while (cnt <size)
  33. {
  34. if ((void *) current->fp INNER_THAN top_stack
  35. || !((void *) current->fp INNER_THAN __libc_stack_end))
  36. {
  37. /* This means the address is out of range. Note that for the
  38. toplevel we see a frame pointer with value NULL which clearly is
  39. out of range. */
  40. break;
  41. }
  42. array[cnt] = current->lr;
  43. cnt++;
  44. current = ADVANCE_STACK_FRAME (current->fp);
  45. }
  46. /*
  47. * In leaf function
  48. * gcc not push lr when call it
  49. */
  50. printf(" ");
  51. return cnt;
  52. }
extern void * __libc_stack_end;# define BOUNDED_N(PTR, N) (PTR)
#define BOUNDED_1(PTR) BOUNDED_N (PTR, 1)
/* Get some notion of the current stack.  Need not be exactly the topof the stack, just something somewhere in the current frame.  */
#ifndef CURRENT_STACK_FRAME
# define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
#endif/* By default we assume that the stack grows downward.  */
#ifndef INNER_THAN
# define INNER_THAN <
#endif/* By default assume the `next' pointer in struct layout points to thenext struct layout.  */
#ifndef ADVANCE_STACK_FRAME
# define ADVANCE_STACK_FRAME(next) BOUNDED_1 ((struct layout *) (((int)next) - 4))
#endif/* By default, the frame pointer is just what we get from gcc.  */
#ifndef FIRST_FRAME_POINTER
# define FIRST_FRAME_POINTER  (__builtin_frame_address (0) - 4)
#endifint backtrace (void **array, int size)
{struct layout *current;void *top_frame;void *top_stack;int cnt = 0;top_frame = FIRST_FRAME_POINTER;top_stack = CURRENT_STACK_FRAME;/* We skip the call to this function, it makes no sense to record it.  */current = BOUNDED_1 ((struct layout *) top_frame);while (cnt < size){if ((void *) current->fp INNER_THAN top_stack|| !((void *) current->fp INNER_THAN __libc_stack_end)){/* This means the address is out of range.  Note that for thetoplevel we see a frame pointer with value NULL which clearly isout of range.  */break;}array[cnt] = current->lr;cnt++;current = ADVANCE_STACK_FRAME (current->fp);}/** In leaf function* gcc not push lr when call it*/printf(" ");return cnt;
}

下面就是将她加入一个文件中了

[cpp] view plaincopyprint?
  1. /**
  2. * @fn writeToFile
  3. * @brief backtrace写入文件
  4. * @param[in] *pIndex: 目录
  5. * *pAppend: 附加信息
  6. * @param[out]
  7. * @return BSTAR_OK BSTAR_FAIL
  8. */
  9. int writeToFile(constchar *pIndex, constchar* pAppend)
  10. {
  11. int j, nptrs = 0;
  12. void *buffer[100];
  13. char str[1024] = {0};
  14. int fd = 0;
  15. if(NULL == pIndex)
  16. {
  17. fprintf(stderr, "the Index is NULL!\n");
  18. return -1;
  19. }
  20. if((fd = open(pIndex, O_RDWR|O_APPEND, 0644)) < 0)
  21. {
  22. fd = open(pIndex, O_RDWR|O_CREAT|O_APPEND, 0644);
  23. }
  24. nptrs = backtrace(buffer, 100);
  25. if(NULL != pAppend)
  26. {
  27. write(fd, pAppend, strlen(pAppend));
  28. memset(str, 0, 1024);
  29. }
  30. for (j = 0; j < nptrs; j++)
  31. {
  32. sprintf(str, "%p\n", buffer[j]);
  33. write(fd, str, strlen(str));
  34. memset(str, 0, 1024);
  35. }
  36. write(fd, "================\n", strlen("================\n"));
  37. close(fd);
  38. return 0;
  39. }
/*** @fn          writeToFile* @brief       backtrace写入文件* @param[in]   *pIndex: 目录*              *pAppend: 附加信息* @param[out]* @return      BSTAR_OK    BSTAR_FAIL*/
int writeToFile(const char *pIndex, const char* pAppend)
{int j, nptrs = 0;void *buffer[100];char str[1024] = {0};int fd = 0;if(NULL == pIndex){fprintf(stderr, "the Index is NULL!\n");return -1;}if((fd = open(pIndex, O_RDWR|O_APPEND, 0644)) < 0){fd = open(pIndex, O_RDWR|O_CREAT|O_APPEND, 0644);}nptrs = backtrace(buffer, 100);if(NULL != pAppend){write(fd, pAppend, strlen(pAppend));memset(str, 0, 1024);}for (j = 0; j < nptrs; j++){sprintf(str, "%p\n", buffer[j]);write(fd, str, strlen(str));memset(str, 0, 1024);}write(fd, "================\n", strlen("================\n"));close(fd);return 0;
}

好了,就是这些了, 你可以将她编写成so库, 那样就方便调用了

转载于:https://www.cnblogs.com/zhangyoushugz/archive/2012/11/07/2758298.html

gcc4.4下实现backtrace代码相关推荐

  1. 嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误

    嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误 2015-05-27 14:19 184人阅读 评论(0) 收藏 举报  分类: 嵌入式(928)  一般察看函数运行时堆栈的 ...

  2. windows下 Source Monitor代码度量工具的使用

    windows下 Source Monitor代码度量工具的使用 引用链接: https://www.cnblogs.com/xuehanyu/p/4520965.html 1.总体介绍 Source ...

  3. 如何在vs 下敲linux代码且具有提示功能

    本文使用的是vs2010 如何在windows 下敲linux代码时具有提示功能那? 1 先安装vs2010 2 安装西红柿插件VA_X_Setup.官网现在地址https://www.wholeto ...

  4. 灰色简约三级CSS下拉菜单代码

    代码简介: 又一款CSS Menu,银灰色下拉菜单,老外网站扒下来的,兼容性还不错.它最多可以支持三级,如果你的菜单项目很多,你可以自己扩展,一般都是成对出现的标签,分清楚就可以了. 代码内容: &l ...

  5. java 委托机制_通过反射实现Java下的委托机制代码详解

    简述 一直对Java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块API public Class Delegater()//空参构造,该类管理委托实例并 ...

  6. php图片自动分页,WordPress点击图片自动进入下一分页代码【图片站福利】

    前一段时间做了一个图片站,由于每篇文章都有十几张图片,所以对文章进行了分页.关于如何对wordpress的长文章进行分页,百度一下相关教程多如牛毛,这里不再进行阐述. 由于分了页,用户每次都只能点击下 ...

  7. java委托机制教程_通过反射实现Java下的委托机制代码详解

    简述 一直对java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块api public class delegater()//空参构造,该类管理委托实例并 ...

  8. 在python3.x下使用如下代码: import cPickle as pk 报错

    在python3.x下使用如下代码: import cPickle as pk 会报如下错误: ImportError: No module named 'cPickle' 原因:python2有cP ...

  9. php里的%是什么意思,大家帮小弟我看下这段代码中的“%”是什么意思

    大家帮我看下这段代码中的"%"是什么意思 $col = 4; $index = 0; $share_display = array(); foreach($share_list a ...

最新文章

  1. IE浏览器里无法运行脚本(script)常见的解决方法!
  2. CodeForces - 451A - Game With Sticks(博弈论)
  3. 嫦娥五号完美落月,背后黑科技令人惊叹
  4. python意外缩进引发逻辑错误_如何编写 Python 程序
  5. SQL 查询数据库中包含指定字符串的相关表和相关记录
  6. leetcode - 5. 最长回文子串
  7. Evaluate that you caught up with the price cut
  8. ArcGIS API for JavaScript 加载水经注离线地图
  9. 开源生态研究与实践| ChinaOSC
  10. ERROR - org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:158)] Unable to deliver event.
  11. Android 5.1.1 源码目录结构
  12. 开展922绿色出行活动 加强城市绿色交通安全管理
  13. 解决Apache提示“You don‘t have permission to access...“错误
  14. 手机验证码接收注册新账户
  15. 被带走的机密文件WP
  16. 银行业务模拟系统的设计与实现
  17. Installing Oracle11g R2 RAC on RedHat Linux AS 5.5
  18. 华硕启动修复无法自动修复此计算机怎么办,华硕电脑无法启动,自动也修复不了怎么办...
  19. WiFi(Wireless Fidelity)基础(八)
  20. 基于ALIENTEK MINISTM32开发板 ADC+DMA 8通道显示

热门文章

  1. 如何在EDUIS中导出ETL字幕模板_给视频加字幕?这8个工具助力你的短视频创作!...
  2. jQuery keyup事件
  3. jsf如何与数据库连接_JSF数据库示例– MySQL JDBC
  4. jsf集成spring_Spring JSF集成
  5. scala面试问题_Scala高级面试问答
  6. zookeeper入门学习《一》
  7. [msi]Cannot open database file. System error -2147287035
  8. 全栈工程师的价值是什么?
  9. [zz]linux之sed用法
  10. 第二单元总结——多线程设计