addr2line查看死机代码的位置

本文详细介绍了Addr2line工具的功能及使用方法,该工具能够帮助开发者将程序崩溃时的地址转换为源代码的位置,便于快速定位问题。文章还解释了epc和ra的概念,并提供了具体的使用案例。
Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。这种功能对于追踪死机地址转换成源码位置很有意义。
      在调用 Addr2line 工具时,要使用  -e  选项来指定可执行映像是  test, 通过使用  -f  选项,可以告诉工具输出函数名。
例如:addr2line -e test   0x1234654(死机地址)  -f 

      这个工具在我们日常开发中非常有用。他可以快速的定位到程序死机的位置。注意,这里说的死机是指程序因为非法地址访问,除数为0,地址未对其访问(部分平台有此限制),bus error等错误造成的程序崩溃。不包含死锁、程序死循环等造成的死机现象。

在说明该工具的用法之前,先了解两个概念:
     1. epc:在学校我们学习汇编的时候知道pc是CPU保存当前运行指令地址的寄存器,那么这个 epc就是error pc。保存的是当程序崩溃时,造成指令异常的那条指令的地址。也就是问题的第一现场。比如,程序因为非法地址访问造成了死机,那么epc保存的就是直接造成非法地址访问的那条指令的地址。
     2. ra:当前程序返回地址。当程序进行函数调用时更新该寄存器。当程序死机时,该地址就是第二现场。
        一般程序崩溃时都有epc、ra的地址打印出来。

addr2line实例
命令:addr2line -e integration/product/a.out 802f07a8 –f
其中integration/product/a.out为造成死机对应的程序。 802f07a8 为地址。比如上面一张所说的epc地址或者是ra地址。

待查地址的确定?
有时出现的是fault add 地址,有时出现的是epc地址( exception地址)或者pc地址(通常是指向函数的地址),针对fault add地址,此处假设该为 0x00250465,而有没有堆栈,则可以先通过查看进程的内存映射信息,定位到地址所在的映像文件(动态库or可执行文件)所在的位置。

cat /proc/PID/maps 查看内存信息,例如:
[root@rhel5 ~]# cat /proc/2674/maps 
00110000-00239000 r-xp 00000000 08:02 130647     /lib/libcrypto.so.0.9.8e
00239000-0024c000 rwxp 00129000 08:02 130647     /lib/libcrypto.so.0.9.8e
0024c000-00250000 rwxp 0024c000 00:00 0 
00250000-00252000 r-xp 00000000 08:02 130462     /lib/mylib-2.5.so
00252000-00253000 r-xp 00001000 08:02 130462     /lib/mylib.so
找到对应的地址区间和映像(库)之后,然后利用fault addr地址和该库地址区间计算出,该死机地址在该库中的偏移地址。接着使用addr2line 来定位该地址的所在的代码位置。

使用此命令时有几个条件:
(1)test 可执行文件在gcc编译时必须包含-g选项;
(2)(死机)地址的确定;

相关示例:


http://blog.youkuaiyun.com/whz_zb/article/details/7604760


转自:http://blog.youkuaiyun.com/kehyuanyu/article/details/37668195

<think>我们正在讨论Linux内核中的WARN_ON()宏。用户之前已经了解了WARN_ON()的基本用法和最佳实践,现在用户提出了一个更深入的问题:WARN_ON()触发死机的原因和解决方法。 注意:根据Linux内核的设计,WARN_ON()本身不应该导致系统死机(panic)。它的设计目的是在条件为真时打印警告信息(包括堆栈跟踪)并继续运行。然而,在某些特殊情况下,用户可能会观察到WARN_ON()后系统崩溃,这通常是由其他因素引起的。 我们需要分析可能的原因并提供解决方法。 步骤: 1. 明确WARN_ON()的预期行为:它不会导致内核panic,除非有额外的配置或伴随的严重错误。 2. 分析可能导致系统崩溃的原因: a. 配置了panic_on_warn b. WARN_ON()触发的条件本身已经导致系统处于不稳定状态(例如内存损坏) c. 在中断上下文或原子上下文中,WARN_ON()产生的输出可能导致死锁 d. 硬件问题(如内存故障)在WARN_ON()触发时暴露 3. 针对每个原因提供解决方法。 参考引用: 用户提供的引用中,引用[1]和[2]与AR游戏和前端开发相关,与当前问题无关。引用[3]是Spark Structured Streaming的代码片段,与内核无关。引用[4]是关于C++的auto_ptr,也不相关。因此,我们主要依据内核知识和经验。 回答结构: 1. 解释WARN_ON()的预期行为(不导致panic) 2. 详细说明导致死机的可能原因 3. 针对每个原因的解决方法 4. 总结如何避免 注意:使用中文,并按照要求使用LaTeX格式的数学表达式(如果有数学表达的话,但这里可能较少),并在适当位置添加引用标记(由于没有直接引用,但为了遵循格式,我们可以在参考内核文档的地方添加一个引用标记,但实际用户没有提供相关引用,所以我们可以不添加,或者假设我们参考了内核文档[^5]) 由于用户之前的问题中我们有一个引用[^5](假设是内核文档),这里我们可以沿用。 生成相关问题。 开始回答:</think>### WARN_ON() 触发死机的原因与解决方法 在 Linux 内核中,**WARN_ON() 本身不会直接导致系统死机**,其设计初衷是打印警告并继续运行。但当系统出现死机时,通常由以下原因引起: --- #### 一、死机根本原因分析 1. **配置触发 panic 模式** - 若启用 `panic_on_warn=1` 参数,所有 `WARN_ON()` 会升级为致命错误 - 数学表达:当 $ \text{panic\_on\_warn} = 1 \land \text{WARN\_ON}(condition) = \text{true} $ 时,系统立即 panic - 特征:`dmesg` 日志中出现 **"Kernel panic - not syncing: panic_on_warn set..."**[^5] 2. **伴随内存损坏** - `WARN_ON()` 检测到条件时,系统可能已处于不稳定状态(如内存越界、野指针) - 示例场景: ```c void *buf = kmalloc(size, GFP_KERNEL); WARN_ON(!buf); // 内存分配失败警告 memcpy(buf, src, size); // 若buf=NULL,此处触发oops死机 ``` 3. **原子上下文中的调用** - 在中断处理/原子上下文中调用 `WARN_ON()` 可能引发死锁 - 原因:警告输出需要调度,但原子上下文禁止调度 - 特征:`dmesg` 显示 **"BUG: scheduling while atomic"** 4. **硬件故障连锁反应** - 硬件错误(如ECC内存故障)被 `WARN_ON()` 捕获后,后续操作暴露更多问题 --- #### 二、解决方法 1. **禁用 panic 升级** ```bash # 启动参数添加(永久生效) echo "kernel.panic_on_warn=0" >> /etc/sysctl.conf # 临时禁用 sysctl -w kernel.panic_on_warn=0 ``` 2. **增强错误处理逻辑** ```c if (WARN_ON(condition)) { pr_err("Error details: param=%d\n", debug_param); // 记录关键信息 return -EINVAL; // 立即终止操作 } ``` 3. **避免原子上下文使用** - 在中断处理函数中替换为原子安全检查: ```c if (unlikely(condition)) { pr_crit("Atomic context error!"); return IRQ_NONE; } ``` 4. **内存损坏排查** - 启用内核内存检测工具: ```bash # 编译内核时启用 CONFIG_DEBUG_KMEMLEAK=y CONFIG_KASAN=y ``` 5. **硬件诊断** - 运行 `memtester` 检测内存故障 - 检查 `dmesg | grep MCE` 获取硬件错误记录 --- #### 三、调试流程 1. **收集崩溃信息** ```bash dmesg -T | grep "WARN" # 定位警告位置 cp /proc/vmcore /root/crash # 保存崩溃内存(需kdump) ``` 2. **分析堆栈轨迹** - 使用 `addr2line -e vmlinux <address>` 转换地址到代码- 检查警告附近的变量值:`drgn` 或 `crash` 工具动态分析 3. **复现与监控** ```bash echo 1 > /proc/sys/kernel/softlockup_panic # 检测死锁 perf record -g -a & stress -c 4 # 压力测试 ``` > **最佳实践**:生产环境通过 `CONFIG_BUG_ON_DATA_CORRUPTION=n` 禁用警告升级[^5],开发阶段保留完整调试符号(`CONFIG_DEBUG_INFO=y`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值