GNU Binutils 剖析
创始人
2025-05-30 11:33:26
0

GNU Binutils简介

  1. GNU为GCC编译器提供了配套的辅助工具集(Binutils),具体参考:https://www.gnu.org/software/binutils/

  1. GCC大写表示一整套工具集,小写gcc只代表编译器。

常见工具简介

工具名

功能简介

add2line

将代码地址转化为对应的行号

strip

剔除可执行程序中 的调试信息

ar

将目标文件打包成为静态库

nm

列出目标文件中的符号以及对应地址

objdump

查看程序段信息以及反汇编

size

查看目标文件中的段大小

strings

查看目标文件中的字符串

add2line

  1. 将指定地址转换为对应的文件名和行号。

  1. 经常用于分析和定位内存访问错误的问题。

void func()
{*g_pointer = (int)"SoftWare";return;
}
//比如,第三行代码,如果g_pointer为空的话,就肯定会造成程序崩溃。

使用步骤

addr2line 示例:定位0地址访问

  1. 开启core dump 选项,ulimit -c unlimited

  1. 运行程序,并生成崩溃时core文件,执行导致程序崩溃的测试用例

  1. 读取core文件,获取IP寄存器的值(0x08048000),dmesg core

  1. 使用addrline 定位代码行,addr2line 0x08048000 -f -e test.out

看一下如下demo:

//func.c
#include int* g_pointer;void func()
{*g_pointer = (int)"SoftWare";return;
}
//test.c
#include int g_global = 0;
int g_test = 1;extern int* g_pointer;
extern void func();int main(int argc,char* argv[])
{printf("&g_global = %p\n",&g_global);printf("&g_test = %p\n",&g_test);printf("&g_pointer = %p\n",&g_pointer);printf("g_pointer = %p\n",g_pointer);printf("&func = %p\n",&func);printf("&main = %p\n",&main);func();return 0;
}

编译运行:

delphi@delphi-vm:~/DT_SiFang$ gcc -g func.c test.c -o test.out
delphi@delphi-vm:~/DT_SiFang$ ./test.out 
&g_global = 0x804a020
&g_test = 0x804a014
&g_pointer = 0x804a024
g_pointer = (nil)
&func = 0x80483c4
&main = 0x80483d8
段错误
delphi@delphi-vm:~/DT_SiFang$ 

使用add2line 进行定位:

delphi@delphi-vm:~/DT_SiFang$ ulimit -c unlimited
delphi@delphi-vm:~/DT_SiFang$ ./test.out 
&g_global = 0x804a020
&g_test = 0x804a014
&g_pointer = 0x804a024
g_pointer = (nil)
&func = 0x80483c4
&main = 0x80483d8
段错误 (核心已转储)
delphi@delphi-vm:~/DT_SiFang$ ls
core  func.c  test.c  test.out
delphi@delphi-vm:~/DT_SiFang$ dmesg core

这样就可以定位出来func.c文件第7行,func函数出问题了。

strip

  1. 剔除程序文件中的调试信息,减少目标程序的大小

  1. 一般在程序发布前都需要将调试信息剔除

  1. 过多的调试信息可能影响程序的执行效率

  1. 用法:strip test.out

注意事项

  1. 几乎所有的调试辅助工具都依赖于目标文件中调试信息。

  1. 调试信息的运用能够快速定位问题。

  1. 使用gcc编译程序时使用-g选项生成调试信息。

  1. 发布程序时再考虑是否使用strip剔除调试信息。

ar

  1. 打包目标文件

ar crs libname.a x.o y.o

  1. 解压目标文件

ar x libname.a

nm

  1. 列出目标文件中的标识符(变量名,函数名)

  1. 输出结果由三部分组成:{地址,段,标识符}

示例:

08048430(标识符对应的地址) T(标识符位于代码段) func(标识符的名字)

段标识说明

段标识

说明

A

地址值在链接过程中不会发生改变

B或b

标识符位于未初始化数据段(.bss)

C

未定义存储段的标识符,链接时决定段位置

D或d

标识符位于数据段(.data)

N

调试专用标识符

R或r

标识符位于只读存储区(.rdata)

T 或 t

标识符位于代码段(.text)

U

未定义的标识符

objdump

  1. 反汇编目标文件,查看汇编到源码的映射

objdump -d func.o

objdump -S func.o

  1. 查看目标文件中的详细段信息

objdump -h test.out

objdump -h的输出说明

说明

Idx

段下标

Name

段标识符(名字)

Size

段所占空间的大小

VMA

段起始位置的虚存地址

LMA

段在存储空间中的加载地址

File off

段在目标文件中的相对位置

Algn

段的边界对齐字节数

size

获取目标文件中的所有段大小 size test.out

strings

获取目标文件中的所有字符串常量 strings test.out

相关内容

热门资讯

【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
ChatGPT 怎么用最新详细... ChatGPT 以其强大的信息整合和对话能力惊艳了全球,在自然语言处理上面表现出了惊人...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...