DWARF常见section总结

2023-12-22 19:12
文章标签 总结 常见 section dwarf

本文主要是介绍DWARF常见section总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、使用工具查看ELF中DWARF相关信息

使用objdump可以查看ELF中DWARF相关的所有section,具体操作说明如下:

objdump <option(s)> <file(s)>-W, --dwarf[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,U/=trace_info]

如想查看可执行文件variable中的.debug_abbrev节的内容,可使用命令:

objdump -Wa variable
objdump --dwarf=abbrev variable

二、DWARF各个section详解

.debug_info 	#包含DWARF调试信息项(DIE)的核心DWARF数据,其类型的定义在debug_abbrev中
.debug_abbrev	#debug_info节中的所有对象的类型
.debug_aranges	#代码段的内存地址和debug_info编译单元之间的映射
.debug_frame	#调用帧信息
.debug_line		#行号程序
.debug_loc		#DW_AT_location属性中使用的位置列表
.debug_macinfo	#宏描述
.debug_pubnames	#全局对象和函数到编译单元的映射表
.debug_pubtypes	#全局类型名字到编译单元的映射表
.debug_ranges	#DW_AT_ranges属性中使用的地址范围
.debug_str		#debug_info使用的字符串表
.debug_types	#类型说明

2.1 debug_info 和 debug_abbrev

这两个节是天生在一起的两个节,它们是一个“实例和类型”的关系,也就是info节中的内容是abbrev节中的一个结构的实例。在abbrev节中声明了很多中不同的Dwarf类型组合(我们可以想象为C语言中的结构声明,而这些类型都是DWARF格式约定好的类型),然后在info节的每一项都声明自己使用的是abbrev节中的那个类型,也就是说明自己是那个结构的实例。这样两者结合就可以得到系统中的所有类型声明信息。

 # debug_info中的部分内容# <0>表示这是根DIE,<1>是<0>的一个子DIE,将其理解成树形结构# <b>表示这个这个DIE在debug_info节中的起始偏移,其他<b>也是字段或DIE的偏移# Abbrev Number: 1 表示这是abbrev节中第1个类型的一个实例,我们可以交叉到abbrev节的第1个类型声明看一下其中关于这个结构类型的声明<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)     # DW_TAG_compile_unit表示一个编译单元,一个源文件对应一个DW_TAG_compile_unit<c>   DW_AT_producer    : (indirect string, offset: 0x92): GNU C++14 12.2.0 -mtune=generic -march=x86-64 -gdwarf-2 -g -O0 -O0 -std=gnu++14 -fasynchronous-unwind-tables<10>   DW_AT_language    : 4    (C++)<11>   DW_AT_name        : (indirect string, offset: 0x50): /home/data/huangqiqi/workfile/myGDB/minidbg/examples/variable.cpp<15>   DW_AT_comp_dir    : (indirect string, offset: 0): /home/data/huangqiqi/workfile/myGDB/minidbg/build<19>   DW_AT_low_pc      : 0x1139   # variable.cpp编译程序的开始位置<21>   DW_AT_high_pc     : 0x118a   # variable.cpp编译程序的结束位置<29>   DW_AT_stmt_list   : 0<1><b4>: Abbrev Number: 9 (DW_TAG_subprogram)  # variable.cpp文件中的main函数<b5>   DW_AT_external    : 1 <b6>   DW_AT_name        : (indirect string, offset: 0x10d): main<ba>   DW_AT_decl_file   : 1    # 下面三个分别对应源文件、行、列<bb>   DW_AT_decl_line   : 3 <bc>   DW_AT_decl_column : 5 <bd>   DW_AT_type        : <0x57>   # 函数返回类型,与debug_info节<0x57>偏移处的类型一样<c1>   DW_AT_low_pc      : 0x1139   # low和high是函数编译后的开始和结束位置<c9>   DW_AT_high_pc     : 0x118a<d1>   DW_AT_frame_base  : 0 (location list)<d5>   DW_AT_GNU_all_tail_call_sites: 1<2><d6>: Abbrev Number: 10 (DW_TAG_variable)   # main函数中的变量a<d7>   DW_AT_name        : a <d9>   DW_AT_decl_file   : 1 <da>   DW_AT_decl_line   : 4 <db>   DW_AT_decl_column : 10<dc>   DW_AT_type        : <0x5e><e0>   DW_AT_location    : 2 byte block: 91 68  (DW_OP_fbreg: -24)

2.2 debug_aranges

debug_aranges段是编译单元(CU)与代码段地址之间的一个映射。借助工具理解这个段的方法:

  • objdump -d ./a.out > disass_log,反汇编代码
  • objdump -Wri ./a.out > dwarf_log,输出调试信息

dwarf_log文件中找到debug_aranges段,就可以看到如下的信息,Compilation Unit @ offsetdebug_info段中的内容。

Contents of the .debug_aranges section:Length:                   764    Version:                  2      Offset into .debug_info:  0   // debug_info中偏移0处的CU(Compilation Unit @ offset 0)地址映射Pointer Size:             8      Segment Size:             0      Address            Length 0000000000024909 000000000000033a   // 在disass_log中就可以找到地址24909处的指令,范围长度是33a
...Length:                   44     Version:                  2      Offset into .debug_info:  0x115f4 // debug_info中偏移0x115f4处的CU(Compilation Unit @ offset 0x115f4)地址映射Pointer Size:             8 Segment Size:             0Address            Length0000000000025496 000000000000017b0000000000000000 0000000000000000

2.3 debug_ranges

DW_AT_ranges属性中使用的地址范围。

2.4 debug_line

debug_line段包含了程序中的行号信息,通过读取、解析该段的内容,我们就能知道源代码行号与机器码指令地址之间的映射关系。如下是解析debug_line所得(objdump -WL ./a.out):

File name       Line number   Starting address
dwarf_test.c            8           0x1179
dwarf_test.c            12          0x1189
dwarf_test.c            13          0x11a5
dwarf_test.c            15          0x11ab

如果按照上面这种看上去很直观的方式来存储行号调试信息,那debug_line段所占用的空间将会非常大。设计者就设计了一种更节省空间的规则和方法,这样可以将调试信息中的debug_line内容压缩减少。对于调试器开发人员,他们如果想得到debug_line中源代码行号与机器码指令地址之间的映射关系,要先读取其中的内容,再按照规则和方法解析读取到的内容,最终就可以得到如上面代码段所示的内容。

至于规则和方法是如何设计的,可以查阅dwarf 4中的 6.2 Line Number Information章节。

也发现了一个关于这块的中文介绍:https://zhuanlan.zhihu.com/p/642441074,介绍的虽不太全,参考意义却挺大。

解析dwarf信息的开源项目挺多的,我比较熟悉的有delve调试器中所用的方法:delve/pkg/dwarf,还用过libelfin,但是没有阅读过其源码。

这篇关于DWARF常见section总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/525139

相关文章

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹