在幽兰上用ELF-Dissector观察ELF文件

幽兰预装的小工具ELF-Dissector是一款用于可视化ELF文件中各部分体积比的小工具,与Krusader都来自KDE社区。(Krusader是支持Linux的文件管理器,类似于Windows上的Total Commander。)当需要分析加载瓶颈和总结式浏览符号的时候,是一个不错的图形化工具。

官网的介绍如下:

ELF 解析器对于以下任务很有用:

在库和符号级别检查前向和后向依赖。
查明加载时的性能瓶颈,例如昂贵的静态构造器或者过量的重定位。
ELF 文件的大小分析
主要功能:

ELF 结构浏览器。
ELF 文件各个部分大小的树形映射可视化。
重定位热图。
内置的 x86 和 AArch64 反汇编器。
从 DWARF 调试信息中提取的数据类型内存布局浏览器。
前向和后向依赖查看器。

使用ELF-Dissector简单分析KernelShark

具体的效果如何呢?我们尝试用ELF-Dissector来试着分析一下KernelShark。先通过grep找到main函数所在位置。

这里选择分析kernelshark对应的ELF文件。

测试加载性能

在Performance页,通过Action选单里的Run Benchmark可以得到不同文件在加载时的速度情况,稍微再排一下序,就可以立马找到加载慢的部分。从例子可以看到,窗口以及GUI相关的部分加载时间显著大于其他部分。

借助gnuplot,还可以把积累时间画成曲线图(需要先Run Benchmark才会有图)

直观查看各部分大小占比

可以再选中.text段,可以直观地看到不同的部分所占比例。destroy()占了大头。

除此之外,还可以选择不同的着色方式方案以及隐藏规则。

查看ELF结构信息的更多细节

直接选择ELF Structure,选择想要观察的信息即可。可以看到机器相关的信息,以及入口点。还有各个Segment的信息,包括类型信息、标志位、偏移量、虚址、物理地址、占文件大小、读到内存后占的大小、对齐字节数。

查看符号依赖关系

如果要快速地从整体上浏览模块、找出重要函数间的依赖情况、知道不同模块间使用符号的依赖关系,也可以通过Dependencies查看,而且也支持搜索。如果要找反向依赖关系也行。

查看数据类型

(在点击的时候会警告可能会占用过高的内存,但是实际上小文件不会占用很多内存。)里面可以看到很多数据类型的结构体定义。如果对于某个结构体感兴趣,可以直接搜索。如果有源码,还可以通过source location定位到源码。

某些使用场景,比如,通过调试的方式学习完某个源码之后,想要总结数据结构,就可以用它配合搜索进行快速浏览。

假设现在要学习KernelShark源码,这里搜索shark,选最大的数据结构kshark_data_stream,它可能就是需要重点理解的最复杂数据结构。很快我们就可以定位到源码位置/home/geduer/Download/kernel-shark/src/libkshark.h的第282行。

值得一提的是,它还帮你算好了每个字段的偏移量,注明了大小和对齐方式。更贴心的是,把中间的padding也明确地标了出来,而针对bool值还提示你只需要1bit的空间。当然,最后还给出整个结构体的大小以及对齐字节数。

诊断

最后,如果你想让它帮你做一些简单的诊断也是可以的,如图:

附:其他aarch64机器上的简要安装指导

如果想在非幽兰的ubuntu机器上使用,可能会比较麻烦,因为官方的链接暂时无法直接安装,需要从源码进行安装,同时也没有给出具体的安装说明。

经过测试,需要安装extra-cmake-modules、libiberty-dev、libdw-dev、texinfo、libdwarf-dev,如果没有安装libdwarf-dev会提示无法链接。再从官网下载libdwarf源码进行安装,从官网下载binutils安装并且版本应小于2.39

binutils的版本要求小于2.39,是因为2.39之后的版本修改了INIT_DISASSEMBLE_INFO的定义,不兼容。

最后在项目cmake之前,需要把elf-dissector的FindDwarf.cmake文件要针对aarch64改一下,修改find_library(Dwarf_LIBRARY NAMES dwarf)为find_library(Dwarf_LIBRARY NAMES dwarf HINTS /usr/lib/aarch64-linux-gnu/)

安装成功之后,如果需要使用Performance页的内容,还需要再安装gnuplot

如果最后运行.py提示找不到bcc,需要检查python命令默认使用的python版本,bcc需要是python3(sudo ln -s /usr/bin/python3 /usr/bin/python)

作者:沈根成  创建时间:2023-04-17 09:50
最后编辑:王璐蓉  更新时间:2024-05-06 17:42