首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Perf中确定库装入地址的机制

Perf中确定库装入地址的机制
EN

Stack Overflow用户
提问于 2020-01-13 20:03:07
回答 2查看 447关注 0票数 2

在后处理期间,perf如何确定每个已加载映像(例如,共享库)的加载地址。例如,perf report使用此信息使每个符号地址相对于每个已加载图像的开头。如下图所示(unwind: _int_malloc...):

它是否存储在elf二进制文件或分析输出(例如,perf.data)中的某个位置?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-15 07:02:40

共享库加载地址存储在perf record命令期间记录的perf.data文件中。您可以使用perf script -D命令以部分解码的格式转储来自perf.data的数据。当你的程序被ld-linux*.so.2加载时(或者当需要使用dlopen时),加载器将使用mmap syscall搜索库并加载其段。这些mmap事件由内核记录,并在perf.data文件中具有PERF_RECORD_MMAP或PERF_RECORD_MMAP2类型。perf report (和perf script)将重建内存偏移量来解码符号名称。

代码语言:javascript
运行
复制
$ perf record  echo 1
$ perf script -D|grep MMAP -c
7
$ perf script -D|less
PERF_RECORD_MMAP2 ... r-xp /bin/echo
...
PERF_RECORD_MMAP2 ... r-xp /lib/x86_64-linux-gnu/libc-2.27.so

https://github.com/torvalds/linux/blob/master/tools/perf/design.txt文件中描述了perf的基本思想。要开始分析,有一个带有perf_event_attr *attr参数的perf_event_open syscallMan page描述了attr的mmap相关字段:

代码语言:javascript
运行
复制
   The perf_event_attr structure provides detailed configuration
   information for the event being created.

                 mmap           : 1,   /* include mmap data */
                 mmap_data      : 1,   /* non-exec mmap data */
                 mmap2          :  1,  /* include mmap with inode data */

Linux内核在其内核子系统( perf_events / events )中将记录所分析进程所需的事件,并使用fd和mmap将数据导出到探查器。perf record通常在不进行繁重处理的情况下将这些数据从内核转储到perf.data文件中(检查perf record输出的“唤醒1次以写入数据”打印)。内核中的Mmap事件由从perf_event_mmap_event中调用的perf_event_mmap_output记录,该事件从perf_event_mmap中调用。mm/mmap.c中的mmap syscall实现有一些对perf_event_mmap的无条件调用。

perf的design.txt提到了munmap,但当前实现没有munmap字段或事件,事件代码2被重用为PERF_RECORD_LOST。有一些想法认为,通过链接到https://lkml.org/lkml/2016/12/10/1https://lkml.org/lkml/2017/1/27/452,munmap可以对https://www.spinics.net/lists/netdev/msg524414.html很有帮助

perf工具是linux内核源代码的一部分,可以通过LXR/elixir网站在线查看: mmap/mmap2事件的https://elixir.bootlin.com/linux/v5.4/source/tools/perf/处理代码在perf/util/machine.c machine__process_mmap_eventmachine__process_mmap2_event中;记录的mmap参数、返回地址、偏移量和文件名在进程(pid/tid)的map__newthread__insert_map的帮助下记录,并在以后用于将样本事件地址转换为符号名称。

PS:你的perf.data有300+ MB的大小,这是巨大的,并且处理可能会很慢。对于长时间运行的程序,您可能希望使用perf recordperf record -F40-F freq选项或使用-c选项来降低性能记录事件采样频率。

票数 4
EN

Stack Overflow用户

发布于 2020-01-14 04:12:24

您不能仅仅通过查看ELF可执行文件和库来找到它。每次运行都会有所不同;即使像GDB那样被perf禁用了ASLR,程序也可能在使用某些后来加载可选库的dlopen之前使用dlopen,因此dlopen必须选择与通常不同的地址来映射库。(正常的动态链接发生在main运行之前,而不是通过dlopen,但perf可能希望能够为任何文件备份映射记录地址->文件映射。)

可能perf将每个ELF对象的运行时基址保存在perf.data

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59716303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档