Linux下进程崩溃时定位源代码位置

简介:
前几天领导安排一个小项目,大意是解决这样一个问题:
在Linux系统下,进程可能由于各种原因崩溃,此时我们要找到出问题的源代码在某一个文 件的具体行号,这样调试起来就会方便,高效很多,可能是公司项目要用到,想想挺有意思的,加上自己本身是个Linux狂热者,最终花了两三天解决了这个问 题,当然我的领导我们称之为专家指点了我很多,废话少说,下面是解决问题的思路和步骤以及自己的一些想法  

解 决该问题的大体思路是这样的:在Linux下,进程崩溃时内核(也就是我们所谓的操作系统)会向进程发送信号,比如我们程序运行崩溃时经常会看到 segmentation falt这样的信息,这是进程非法操作内存,内核会向进程发送SIGENV信号,那么我们凭什么可以找到进程崩溃的原因对应的源代码的位置呢,我们知道, 每个进程都有自己的堆栈,当某个进程崩溃时,堆栈里保存了一些关键信息,通过这些信息我们可以定位到出错的源代码位置,那么我们怎么来获得进程崩溃时堆栈 的信息呢,请记住,Linux是当今世界上最为强大的操作系统(不管你信不信,反正我是信了,^_^),在Linux系统里有个backtrace这些个 函数可以获得当前堆栈信息,好了,到这里问题已经解决了一半,backtrace信息中的有一个地址包含了出错代码在文件中的偏移量

需要注意的是编译时一定要加上 -g和-rdynamic参数

如果我们使用的是静态库或者出错的代码不在动态库中,那么我们可以直接用命令"addr2line -e 可执行文件名 偏移地址"打印出出错的代码行,下面是具体步骤
在测试程序的29行非法操作了内存

我们把addr2line命令放在程序里面做了,在代码中也可以看得到,下面这幅图片是程序的输出,可以看到
打印出源代码出错的行数为29

如果crash在一个动态库so里面,比较麻烦一点,此时addr2line不能直接给出代码行。因为我们都知道,so里面的地址在可执行文件装载的时候, 是可以被 reallocate的。所以,如果只有一个so的地址,要找出对应代码行的话,送给 addr2line的参数地址就是一个偏移地址,这里的偏移地址就是backtrace中的地址减去动态库加载的时候的基地址,这个基地址我们可以通过 /proc/pid/maps这个文件找到,pid是当前进程号,下面是具体步骤,跟之前的步骤类似,只不过我们为了测试,将func函数编译进了一个动 态库里面
这里我们只给出测试文件,具体怎么实现动态库,这个很容易,不在此多提,下面是测试程序的一部分

我们在/proc/pid/maps文件中找出出错动态库加载的基地址,用backtrace中的地址与基地址相减得到偏移地址就可以了,下面是程序输出
可以看到,我们用hello.c做的动态库,定位到代码出错在hello.c的第五行

下面是定位动态库错误的源代码:

 test.zip   

目录
相关文章
|
5天前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
28 4
linux进程管理万字详解!!!
|
5天前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
28 4
|
6天前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
7天前
|
消息中间件 存储 Linux
|
14天前
|
运维 Linux
Linux查找占用的端口,并杀死进程的简单方法
通过上述步骤和命令,您能够迅速识别并根据实际情况管理Linux系统中占用特定端口的进程。为了获得更全面的服务器管理技巧和解决方案,提供了丰富的资源和专业服务,是您提升运维技能的理想选择。
15 1
|
25天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
【10月更文挑战第9天】本文将深入浅出地介绍Linux系统中的进程管理机制,包括进程的概念、状态、调度以及如何在Linux环境下进行进程控制。我们将通过直观的语言和生动的比喻,让读者轻松掌握这一核心概念。文章不仅适合初学者构建基础,也能帮助有经验的用户加深对进程管理的理解。
18 1
|
30天前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
26 0
Linux c/c++之IPC进程间通信
|
30天前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
20 0
Linux c/c++进程间通信(1)
|
30天前
|
Linux C++
Linux c/c++之进程的创建
这篇文章介绍了在Linux环境下使用C/C++创建进程的三种方式:system函数、fork函数以及exec族函数,并展示了它们的代码示例和运行结果。
30 0
Linux c/c++之进程的创建
|
30天前
|
Linux C++
Linux c/c++进程之僵尸进程和守护进程
这篇文章介绍了Linux系统中僵尸进程和守护进程的概念、产生原因、解决方法以及如何创建守护进程。
17 0