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

异常信息转储预研笔记-捕获指定进程的异常信号

信号中断中存储堆栈信息

目的

捕获指定进程的信号,当信号为core中止信号时,则对指定进程的异常堆栈信息转储至指定文件。

demo

demo代码如下:由于环境隔离,以下代码为手敲且未编译,谨慎使用,领会思路即可。

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <libunwind-ptrace.h>static pid_t pid;static void unwind_pid()
{unw_addr_space_r as = unw_create_addr_space(&_UPT_accessors, 0);long errnum = ptrace(PTRACE_ATTACH, pid, 0 ,0);if (errnum != 0){printf("error: xxx \n");}void *context = _UPT_create(pid);unw_cursor_t cursor;if (unw_init_remote(&cursor, as, context) != 0){printf("error: cannot initialize cursor for remote unwinding\n");}FILE *fp;fp = fopen("ap.core", "w");if (fp == null){printf("error: open file failed!\n");return;}do {unw_word_t offset, pc;char sym[10240];if (unw_get_reg(&cursor, UNW_REG_IP, &pc))printf("error: xxx\n");fprintf(fp, "0x%lx: ", pc);if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0){fprintf(fp, "(%s+0x%lx)\n", sym, offset);}else{    printf("no symbol name found.\n");}} while (unw_step(&cursor) > 0);_UPT_destroy(conteext);(void)ptrace(PTRACE_DETACH, pid, 0, 0);fclose(fp);
}static void signal_cb(int32_t signo)
{unwind_pid();signal(signo, SIG_DFL);
}int main(int argc, char** argv)
{if (argc != 2){printf("USAGE: unwind-pid <pid>\n");}pid = atoi(argv[1]);signal(SIGINT, signal_cb);while(1){sleep(1);}return 0;
}

大致思路是注册一个信号处理回调,demo中是对SIGINT信号做出事件处理,可根据需求替换或增加(这里有个小坑,下面讲),具体信号说明依然查看这篇文章《异常信息转储预研笔记》,里面有具体说明。当内核发送信号给指定进程,demo进程就会捕获到并进入信号回调处理函数,后面就是通过libunwind开源库将指定进程收到信号前一刻的堆栈信息输出至指定文件

小坑

在测试demo中,一开始使用的是SIGKILL信号,这个信号是最了解最方便模拟的,我想当然的使用kill -9 来结束指定进程,内核当然就会发送SIGKILL信号给指定进程。

但是多次测试发现,demo进程无法捕获到任何信号,不知道哪里有问题,只能来回研究代码。

反复测试无果,只能求助谷歌,终于明白!原来!SIGKILL和SIGSTOP这两个信号!既不能被忽略!也不能被捕捉!:)

换了SIGINT信号,终于行了!SIGINT信号通过键盘键入ctrl c即可模拟。

最后

目前使用的方式都非常粗糙,仅仅输出最基本的堆栈信息,边学习边记录,有不对的地方欢迎提出来共同进步。

后续

下一步计划:输出更丰富可读性更强的异常转储core文件,可能通过dladdr转换地址为函数名称和行号。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python 微服务实战:Dapr 基础入门指南
  • HashMap的数据结构是怎样的?为什么JDK8中要将其转换为红黑树?
  • uvm(7)factory
  • sql 优化,提高查询速度
  • java-idea如何配置plugins的Repositoies和proxy
  • DETR论文,基于transformer的目标检测网络 DETR:End-to-End Object Detection with Transformers
  • 面向对象编程-继承
  • 谷歌发布会现场尴尬瞬间:AI助手Gemini展示挑战苹果
  • 图数据库在社交网络分析中的应用
  • X-Recon:一款针对Web安全的XSS安全扫描检测工具
  • opencv基础的图像操作
  • 再见Figma!!新的设计,代码协作神器!【送源码】
  • C#单例模式
  • HTML5+JavaScript绘制彩虹和云朵
  • GNU/Linux - copy_{to,from}_user: 用户和内核空间的内存互拷贝
  • @jsonView过滤属性
  • “大数据应用场景”之隔壁老王(连载四)
  • CentOS 7 防火墙操作
  • eclipse(luna)创建web工程
  • Elasticsearch 参考指南(升级前重新索引)
  • ES6语法详解(一)
  • JavaScript服务器推送技术之 WebSocket
  • mysql innodb 索引使用指南
  • nginx 配置多 域名 + 多 https
  • php面试题 汇集2
  • Python 基础起步 (十) 什么叫函数?
  • Python学习笔记 字符串拼接
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • scala基础语法(二)
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 服务器从安装到部署全过程(二)
  • 基于Android乐音识别(2)
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 昨天1024程序员节,我故意写了个死循环~
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​ArcGIS Pro 如何批量删除字段
  • ​Java并发新构件之Exchanger
  • ![CDATA[ ]] 是什么东东
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • $.ajax()
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (C#)获取字符编码的类
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (第27天)Oracle 数据泵转换分区表
  • (二)十分简易快速 自己训练样本 opencv级联lbp分类器 车牌识别
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)Linux整合apache和tomcat构建Web服务器