addr2line 命令可以在程序core时,提供一种辅助手段定位程序问题。
下面演示除零错误:
#include <stdio.h> int main(int argc, char **argv) { int x = 10; int y = 0; printf("%d/%d=%d\n", x, y, x/y); return 0; }
程序执行后立即退出,可查看系统dmesg日志:
$ ./test Floating point exception (core dumped) $ dmesg [15222401.075980] traps: test[26231] trap divide error ip:400611 sp:7ffcdb1f0290 error:0 in test[400000+1000] $ addr2line -e test 400611 /data/home/kanesun/test/test.c:7
addr2line显示第7行除零错误。程序需要加-g编译debug版本才行,否则命令无法显示行:??:?,因为addr2line是通过查找调试信息定位到行的。
DWARF(Debugging With Attributed Record Formats)调试格式记录了程序调试信息,其中.debug_line记录了程序地址与源代码行对应关系。
$ readelf -w test Line Number Statements: Extended opcode 2: set Address to 0x4005f0 Special opcode 8: advance Address by 0 to 0x4005f0 and Line by 3 to 4 Special opcode 216: advance Address by 15 to 0x4005ff and Line by 1 to 5 Special opcode 104: advance Address by 7 to 0x400606 and Line by 1 to 6 Special opcode 104: advance Address by 7 to 0x40060d and Line by 1 to 7 Advance PC by constant 17 to 0x40061e Special opcode 216: advance Address by 15 to 0x40062d and Line by 1 to 8 Special opcode 76: advance Address by 5 to 0x400632 and Line by 1 to 9
二进制编码从0x4005ff开始,0x40062d对应第8行,则0x400611对应第7行。
线上监控发现程序有重启,但是没有开启coredump,查看dmesg,发现有打印:
[2157427.236306] traps: flowmonitor[158426] general protection ip:409445 sp:7f519cb3d450 error:0 in flowmonitor[400000+be000]\ addr2line -e flowmonitor 409445 /usr/include/c++/4.8.2/bits/stl_list.h:235
查看stl源码:
_List_const_iterator(const iterator& __x) : _M_node(__x._M_node) { } _Self& operator++() { _M_node = _M_node->_M_next; // 出错行 return *this; }
获取list const迭代器下一个节点时出错,可能是该迭代器被清除了,直接访问下一个node会出错。 可是flowmonitor 程序中没有操作std::list 的常量迭代器,发现依赖的rdkafka 接口有std::list 使用,此时通过lsof查看程序的网络连接,发现只有一个连接,与运营同学沟通发现果然是kafka集群出问题了。 addr2line 提供了线上排障提供更多的一个选择。
相关推荐
`addr2line`是Linux系统下一款非常实用的调试工具,它属于GNU Binutils的一部分,主要用于帮助开发者在遇到程序崩溃或者错误时,根据二进制文件(如动态链接库`.so`)中的内存地址,反向查找对应的源代码行号。...
Qualcomm865_3/android-ndk-r21e/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-addr2line -f -C -e workplace/Qualcomm865_3/native-agent/Agent/bin/AC_card_agent ...
如果错误发生在静态库或不在动态库中的代码,我们可以直接使用`addr2line`命令,结合可执行文件名和偏移地址,来确定出错的源代码行。例如,如果`addr2line -e 可执行文件名 偏移地址`,它将打印出对应的源代码行。 ...
Linux Binutils 是一组用于处理各种程序文件的工具集合,它包含了一系列用于开发和调试的实用程序,如 addr2line、ar、nm等。这些工具在Linux操作系统和类似环境中的软件开发过程中扮演着重要角色。 首先,`addr2...
2. **NDK集成**:此工具链可能与Android Native Development Kit (NDK)相关联,NDK是一套用于在Android平台上开发原生应用和库的工具。 3. **目标API级别**:根据目标设备的Android版本,选择合适的API级别进行编译...
### Linux下Socket编程的端口问题 (Bind(): Address already in use) #### 一、问题背景与常见场景 在进行Linux下的网络编程时,经常会遇到端口绑定失败的问题,尤其是在使用`bind()`函数尝试绑定端口时,可能会...
2. `arm-linux-gnueabihf-addr2line`:此工具可以将二进制代码地址转换为源代码行号,帮助开发者定位程序中的错误。 3. `arm-linux-gnueabihf-ar`:这是一个归档工具,用于创建、修改和提取库文件。 4. `arm-linux-...
本文将重点介绍如何在Linux环境下加载vmlinux进行调试,以及如何利用gdb和addr2line工具来定位和分析内核代码中的问题。 首先,我们需要明白vmlinux是Linux内核的未压缩二进制形式,包含了所有编译后的内核模块和...
2. `addr2line`:将内存地址转换为源代码行号,便于定位问题。 3. `objdump`:用于查看二进制文件的结构信息,辅助分析。 四、core dump的定位流程 1. 检查core dump文件:确认文件是否生成,大小是否正常,是否有...
6. 下列二进制工具哪个是用来把程序地址转换为文件名和行号的(D)addr2line 答案:正确,addr2line 是将程序地址转换为文件名和行号的二进制工具。 7. FS4412 开发平台上,uImage 被解压到什么地址(B)0x40008000...
例如,使用 addr2line 工具可以将虚拟地址转换为物理地址,从而快速定位问题所在。 Linux 内核或应用程序异常终止调试方法是一门复杂的技术,需要开发者和管理员具备一定的知识和经验。但是,通过本文的介绍,...
2. 解压:将下载的zip文件解压缩到本地目录。 3. 配置环境变量:为了在命令行中方便地使用这些工具,需要将解压后的路径添加到系统的PATH环境变量中。这通常涉及修改`~/.bashrc`(对于Linux或macOS)或`Environment ...
通过`ulimit -c unlimited`命令开启核心转储,并使用`gdb`或`addr2line`工具分析。 总结来说,定位Linux C段错误的关键步骤包括:注册信号处理器、收集堆栈信息、反汇编代码、使用GDB调试和分析核心转储。这些方法...
3. **addr2line**:这个工具可以将内存地址转换为源代码的行号,对于定位代码执行路径非常有用。 4. **gdb调试器**:虽然不是专门分析map文件的工具,但GDB能提供丰富的内存和代码执行信息,可以和map文件一起使用来...
- 每个工具如addr2line、nm、objdump等都有其特定功能,如addr2line用于从地址查找代码行,ld用于连接编译后的对象文件形成可执行程序,nm列出目标文件的符号信息等。 - 环境变量的正确设置是确保交叉编译顺利进行的...
- `arm-linux-addr2line`用于根据程序地址查找对应的源文件和行号。 - `arm-linux-ar`管理归档文件,如创建、修改和提取档案成员。 - `arm-linux-c++filt`过滤C++和Java符号,防止重载函数冲突。 - `arm-linux-gprof...
例如,在上面的示例代码中,我们可以使用 addr2line 工具来查看 804888c 的调用堆栈,并定位到具体的行号和文件名。 backtrace 函数和 backtrace_symbols 函数是 Linux 平台上 C 语言编写的程序中非常有用的调试...
在C语言编程中,控制I2C设备需要使用特定的库,例如Linux环境下的i2c-dev或 wiringPi 库。编写程序时,首先需要打开I2C设备文件,然后通过write函数发送命令到设备地址,读取数据则使用read函数。对于NCA9555,可能...
s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) > $@ ``` 在这个过程中,`TEXTADDR`变量定义了内核代码段的起始地址,例如`0xC0008000`。链接脚本文件`vmlinux-armv.lds.in`会被预处理,其中的占位符(如`TEXTADDR`)会被...