gcc4.4下实现backtrace代码
最近在一块新的板子下作开发, 有些变量发生异常(就是我们不想到的值),可以加上backtrace,知道是哪个函数调用它,导致出现异常, 就像死机了,你可以gdb和core文件用bt 命令,查看死机在哪里(有一种 情况 不能看见, 就是发生信号异常不在本文范围 ), 本人感觉还有用, 关说不炼、假把式,下面是实现代码:
首先实现核心代码backtrace函数:
- 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 top
- of 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 the
- next 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)
- #endif
- int 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 the
- toplevel we see a frame pointer with value NULL which clearly is
- out 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;
- }
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;
}
下面就是将她加入一个文件中了
- /**
- * @fn writeToFile
- * @brief backtrace写入文件
- * @param[in] *pIndex: 目录
- * *pAppend: 附加信息
- * @param[out]
- * @return BSTAR_OK BSTAR_FAIL
- */
- int writeToFile(constchar *pIndex, constchar* 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;
- }
/*** @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代码相关推荐
- 嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误
嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误 2015-05-27 14:19 184人阅读 评论(0) 收藏 举报 分类: 嵌入式(928) 一般察看函数运行时堆栈的 ...
- windows下 Source Monitor代码度量工具的使用
windows下 Source Monitor代码度量工具的使用 引用链接: https://www.cnblogs.com/xuehanyu/p/4520965.html 1.总体介绍 Source ...
- 如何在vs 下敲linux代码且具有提示功能
本文使用的是vs2010 如何在windows 下敲linux代码时具有提示功能那? 1 先安装vs2010 2 安装西红柿插件VA_X_Setup.官网现在地址https://www.wholeto ...
- 灰色简约三级CSS下拉菜单代码
代码简介: 又一款CSS Menu,银灰色下拉菜单,老外网站扒下来的,兼容性还不错.它最多可以支持三级,如果你的菜单项目很多,你可以自己扩展,一般都是成对出现的标签,分清楚就可以了. 代码内容: &l ...
- java 委托机制_通过反射实现Java下的委托机制代码详解
简述 一直对Java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块API public Class Delegater()//空参构造,该类管理委托实例并 ...
- php图片自动分页,WordPress点击图片自动进入下一分页代码【图片站福利】
前一段时间做了一个图片站,由于每篇文章都有十几张图片,所以对文章进行了分页.关于如何对wordpress的长文章进行分页,百度一下相关教程多如牛毛,这里不再进行阐述. 由于分了页,用户每次都只能点击下 ...
- java委托机制教程_通过反射实现Java下的委托机制代码详解
简述 一直对java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块api public class delegater()//空参构造,该类管理委托实例并 ...
- 在python3.x下使用如下代码: import cPickle as pk 报错
在python3.x下使用如下代码: import cPickle as pk 会报如下错误: ImportError: No module named 'cPickle' 原因:python2有cP ...
- php里的%是什么意思,大家帮小弟我看下这段代码中的“%”是什么意思
大家帮我看下这段代码中的"%"是什么意思 $col = 4; $index = 0; $share_display = array(); foreach($share_list a ...
最新文章
- IE浏览器里无法运行脚本(script)常见的解决方法!
- CodeForces - 451A - Game With Sticks(博弈论)
- 嫦娥五号完美落月,背后黑科技令人惊叹
- python意外缩进引发逻辑错误_如何编写 Python 程序
- SQL 查询数据库中包含指定字符串的相关表和相关记录
- leetcode - 5. 最长回文子串
- Evaluate that you caught up with the price cut
- ArcGIS API for JavaScript 加载水经注离线地图
- 开源生态研究与实践| ChinaOSC
- ERROR - org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:158)] Unable to deliver event.
- Android 5.1.1 源码目录结构
- 开展922绿色出行活动 加强城市绿色交通安全管理
- 解决Apache提示“You don‘t have permission to access...“错误
- 手机验证码接收注册新账户
- 被带走的机密文件WP
- 银行业务模拟系统的设计与实现
- Installing Oracle11g R2 RAC on RedHat Linux AS 5.5
- 华硕启动修复无法自动修复此计算机怎么办,华硕电脑无法启动,自动也修复不了怎么办...
- WiFi(Wireless Fidelity)基础(八)
- 基于ALIENTEK MINISTM32开发板 ADC+DMA 8通道显示
热门文章
- 如何在EDUIS中导出ETL字幕模板_给视频加字幕?这8个工具助力你的短视频创作!...
- jQuery keyup事件
- jsf如何与数据库连接_JSF数据库示例– MySQL JDBC
- jsf集成spring_Spring JSF集成
- scala面试问题_Scala高级面试问答
- zookeeper入门学习《一》
- [msi]Cannot open database file. System error -2147287035
- 全栈工程师的价值是什么?
- [zz]linux之sed用法
- 第二单元总结——多线程设计