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

posted on 2014-06-22 17:52 secularbird 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/zelos/p/3802792.html

pthread中如何追踪stack over flow相关推荐

  1. 在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-> ...

  2. 在onelogin中使用OpenId Connect Implicit Flow

    文章目录 简介 OpenId Implicit Flow 创建onelogin的配置 页面的运行和请求流程 关键代码 总结 简介 onelogin支持多种OpenId Connect的连接模式,上一篇 ...

  3. linux C语言多线程库pthread中条件变量的正确用法逐步详解

    linux C语言多线程库pthread中条件变量的正确用法: 了解pthread常用多线程API和pthread互斥锁,但是对条件变量完全不知道或者不完全了解的人群. 关于条件变量的典型应用,可以参 ...

  4. s:property=a value=/取的s:debug/s:debug中的value stack中的属性值

    <s:property="a"  value=""/>取的<s:debug></s:debug>中的value stack中 ...

  5. 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. ...

  6. java中的exception stack有时候不输出的原因

    有时候,我们在看java错误日志时,只看到一个java.lang.NullPointerException,却没有看到错误的栈,原因是启动时候有一项参数可以选择配置:OmitStackTraceInF ...

  7. java利用栈求复杂表达式_java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式...

    利用栈Stack计算合法的算术表达式 限定的算术表达式求值问题:包含 "+"."-"."*"."/" .正整数和圆括号的 ...

  8. 刷题upupup【Java中Queue、Stack、Heap用法总结】

    [Queue] 先进先出(First-In-First-Out),LinkedList实现了Queue接口.它只允许在表的前端进行删除操作,而在表的后端进行插入操作. add()       增加一个 ...

  9. 编程中的心流模式flow

    周末看电影,接触到了心流这个概念,挺有意思.了解心流理论,可以指导我们进入一个更为高效愉悦的工作状态. 电影<社交网络>里程序员写代码出现了两次"wired in", ...

最新文章

  1. 智能零售来了!Amazon Go无人商店周一正式对公众开放
  2. 2015#183;Fool#39;s Day#183;NND
  3. MySQL索引面试题:优化 索引分类
  4. 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug
  5. linux mariadb 乱码,配置mariadb远程访问权限,解决数据库乱码问题
  6. 台达b2伺服说明书_三菱Q系列定位模块及伺服参数不会设置?看这一篇就够了!...
  7. c语言define定义全局变量,webpack中使用DefinePlugin定义全局变量
  8. linux如何增加一个进程,linux – 如何增加新生成进程的CPU频率
  9. 洛谷 P4300 BZOJ 1266 [AHOI2006]上学路线route
  10. java函数void返回值是,Java中main()函数的返回值是什么( )。A、StringB、intC、c......
  11. 安装jdk和oracle要注意的知识点
  12. 浙大 PAT a1027
  13. python爬虫知识点总结(三)urllib库详解
  14. 公司招聘asp.net 工程师
  15. 【转】如何防止softmax函数上溢出(overflow)和下溢出(underflow)
  16. 微软的补丁服务器,Microsoft 安全公告 MS17-010 - 严重
  17. C语言版数据结构计算顺序表中X的个数,设计算法。数据结构课后习题,定义顺序表,查找顺序表中X元素的个数。
  18. 华为设备SEP配置命令
  19. python实现合并多个excel中同名的sheet
  20. 【优化理论与方法】线性规划的基本定理

热门文章

  1. docker基本入门
  2. Windows Server 2008 之 终端服务TS WEB ACCESS
  3. Silverlight+WCF 新手实例 象棋 主界面-事件区-求和认输(三十二)
  4. ObjC block入门
  5. 最短路径问题-Dijkstra算法的python实现
  6. [BZOJ 5093]图的价值
  7. Win10如何显示系统托盘所有图标
  8. JS识别不同浏览器信息
  9. linux 信号处理
  10. 发布方配模板引擎V2.1及开发教程和案例