pthread中如何追踪stack over flow
通常在程序挂掉的时候我们会catch 他们挂掉的signal,然后在signal中打印出当时的一个stack,来方便问题调查, 但是在stack overflow的情况发生时,会没有拿到stack。signal的stack也是建立在thread的调用栈上的,在overflow的情况下,stack没有足够的空间来执行signal处理函数,signal处理函数就会被忽略。
示例代码:
main 主程序
#include <signal.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include "mybacktrace.h"void recursiondeath() {char buffer[1024];recursiondeath();memset(buffer, 0xeb, sizeof(buffer));printf("%d", buffer[0]); }void* threadloop(void* args) {// using sginal stackchar altstack[SIGSTKSZ];addsignalstack(altstack, SIGSTKSZ);recursiondeath();return NULL; }int main(int argc, char const *argv[]) {char altstack[SIGSTKSZ];registersignal();addsignalstack(altstack, SIGSTKSZ);pthread_t t;pthread_create(&t, NULL, threadloop, NULL);pthread_join(t, NULL);return 0; }
mybacktrace.h 头文件
#include <execinfo.h> #include <signal.h> #include <assert.h>void signalhandler(int sig) {printf("signal revived [%d]\n", sig);// get the back traceenum {MAX_STACK = 32,};void *stack[MAX_STACK];int size = backtrace(stack, MAX_STACK);if(size == 0) {printf("fail to get backtrace\n");} char** strs = backtrace_symbols(stack, size);int i = 0;for (i = 0; i < size; ++i) {printf("%s\n", strs[i]);}free(strs);signal(sig, SIG_DFL); }void addsignalstack(char *stack, int size) {assert(stack!=NULL);// using sginal stack stack_t sigstack;sigstack.ss_sp = stack;sigstack.ss_size = SIGSTKSZ;sigstack.ss_flags = 0;if (sigaltstack(&sigstack, 0) < 0) {perror("sig stack setting failed");} }void registersignal() {struct sigaction act;act.sa_handler = signalhandler;act.sa_flags = SA_ONSTACK|SA_RESTART;int ret = sigaction(SIGSEGV, &act, NULL);if (ret < 0) {perror("sigaction failed\n");}ret = sigaction(SIGBUS, &act, NULL);if (ret < 0) {perror("sigaction failed\n");}ret = sigaction(SIGILL, &act, NULL);if (ret < 0) {perror("sigaction failed\n");}}
说明:
添加signal alt stack
void addsignalstack(char *stack, int size) {assert(stack!=NULL);// using sginal stack stack_t sigstack;sigstack.ss_sp = stack;sigstack.ss_size = SIGSTKSZ;sigstack.ss_flags = 0;if (sigaltstack(&sigstack, 0) < 0) {perror("sig stack setting failed");} }
这边由外部传进来的数组作为signal 处理函数执行用的stack
注册signal函数:
```
void registersignal() {struct sigaction act;act.sa_handler = signalhandler;act.sa_flags = SA_ONSTACK|SA_RESTART;int ret = sigaction(SIGSEGV, &act, NULL);if (ret < 0) {perror("sigaction failed\n");}ret = sigaction(SIGBUS, &act, NULL);if (ret < 0) {perror("sigaction failed\n");}ret = sigaction(SIGILL, &act, NULL);if (ret < 0) {perror("sigaction failed\n");} }
注册了signal
SIGSEGV
SIGBUS
SIGILL
另外sigaction flag添加了SA_ONSTACK,确保当signal发生的时候,
signal处理函数会将sig atl stack作为函数frame
主函数:
int main(int argc, char const *argv[]) {char altstack[SIGSTKSZ];registersignal();addsignalstack(altstack, SIGSTKSZ);pthread_t t;pthread_create(&t, NULL, threadloop, NULL);pthread_join(t, NULL);return 0; }
执行前添加下signal的altstak,这里使用栈上的数组来作为signal处理函数的函数栈,可以通过malloc或者mmap分配.
线程的主函数
void* threadloop(void* args) {// using sginal stackchar altstack[SIGSTKSZ];addsignalstack(altstack, SIGSTKSZ);recursiondeath();return NULL; }
执行前再添加下sig alt stack
注意:sig alt stack时每个线程自己单独的属性,所以每个线程都需要添加自己的sig alt stack
转载于:https://www.cnblogs.com/zelos/p/3802792.html
pthread中如何追踪stack over flow相关推荐
- 在IAR 中出现the stack plug-in failed to set a breakpoint on main
在IAR AVR中出现the stack plug-in failed to set a breakpoint on "main" Project->Options-> ...
- 在onelogin中使用OpenId Connect Implicit Flow
文章目录 简介 OpenId Implicit Flow 创建onelogin的配置 页面的运行和请求流程 关键代码 总结 简介 onelogin支持多种OpenId Connect的连接模式,上一篇 ...
- linux C语言多线程库pthread中条件变量的正确用法逐步详解
linux C语言多线程库pthread中条件变量的正确用法: 了解pthread常用多线程API和pthread互斥锁,但是对条件变量完全不知道或者不完全了解的人群. 关于条件变量的典型应用,可以参 ...
- s:property=a value=/取的s:debug/s:debug中的value stack中的属性值
<s:property="a" value=""/>取的<s:debug></s:debug>中的value stack中 ...
- mac中使用Sourcetree的git flow
mac中使用Sourcetree的git flow 前言 1.git flow工作流 1.1 什么是git flow 1.2 git flow上的分支 1.2.1 长期分支 1.2.2 短期分支 1. ...
- java中的exception stack有时候不输出的原因
有时候,我们在看java错误日志时,只看到一个java.lang.NullPointerException,却没有看到错误的栈,原因是启动时候有一项参数可以选择配置:OmitStackTraceInF ...
- java利用栈求复杂表达式_java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式...
利用栈Stack计算合法的算术表达式 限定的算术表达式求值问题:包含 "+"."-"."*"."/" .正整数和圆括号的 ...
- 刷题upupup【Java中Queue、Stack、Heap用法总结】
[Queue] 先进先出(First-In-First-Out),LinkedList实现了Queue接口.它只允许在表的前端进行删除操作,而在表的后端进行插入操作. add() 增加一个 ...
- 编程中的心流模式flow
周末看电影,接触到了心流这个概念,挺有意思.了解心流理论,可以指导我们进入一个更为高效愉悦的工作状态. 电影<社交网络>里程序员写代码出现了两次"wired in", ...
最新文章
- 智能零售来了!Amazon Go无人商店周一正式对公众开放
- 2015#183;Fool#39;s Day#183;NND
- MySQL索引面试题:优化 索引分类
- 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug
- linux mariadb 乱码,配置mariadb远程访问权限,解决数据库乱码问题
- 台达b2伺服说明书_三菱Q系列定位模块及伺服参数不会设置?看这一篇就够了!...
- c语言define定义全局变量,webpack中使用DefinePlugin定义全局变量
- linux如何增加一个进程,linux – 如何增加新生成进程的CPU频率
- 洛谷 P4300 BZOJ 1266 [AHOI2006]上学路线route
- java函数void返回值是,Java中main()函数的返回值是什么( )。A、StringB、intC、c......
- 安装jdk和oracle要注意的知识点
- 浙大 PAT a1027
- python爬虫知识点总结(三)urllib库详解
- 公司招聘asp.net 工程师
- 【转】如何防止softmax函数上溢出(overflow)和下溢出(underflow)
- 微软的补丁服务器,Microsoft 安全公告 MS17-010 - 严重
- C语言版数据结构计算顺序表中X的个数,设计算法。数据结构课后习题,定义顺序表,查找顺序表中X元素的个数。
- 华为设备SEP配置命令
- python实现合并多个excel中同名的sheet
- 【优化理论与方法】线性规划的基本定理