gpt4 book ai didi

linux - 用perf记录缺页的指令地址

转载 作者:太空狗 更新时间:2023-10-29 12:22:24 26 4
gpt4 key购买 nike

我想使用 perf 获取导致主要页面错误的指令的地址。我有一个简单的程序:

#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>


int main(int argc, char* argv[]) {
int fd = open("path to large file several Gb", O_RDONLY);
struct stat st;
fstat(fd, &st);
void* ptr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
const uint8_t* data = (const uint8_t*) ptr;

srand(time(NULL));
size_t i1 = ((double) rand() / RAND_MAX) * st.st_size;
size_t i2 = ((double) rand() / RAND_MAX) * st.st_size;
size_t i3 = ((double) rand() / RAND_MAX) * st.st_size;

printf("%x[%lu], %x[%lu], %x[%lu]\n", data[i1], i1, data[i2], i2, data[i3], i3);

munmap(ptr, st.st_size);
close(fd);
return 0;
}

我使用 gcc -g -O0 main.c 编译它并运行 perf record -e major-faults -g -d ./a.out

接下来,我使用 perf report -g 打开生成的报告报告说有 3 个主要页面错误(这是正确的),但我无法理解导致页面错误的指令地址。报告如下:

# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 3 of event 'major-faults'
# Event count (approx.): 3
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................ ......................
#
100.00% 0.00% a.out libc-2.23.so [.] __libc_start_main
|
---__libc_start_main
main

100.00% 100.00% a.out a.out [.] main
|
---0x33e258d4c544155
__libc_start_main
main

100.00% 0.00% a.out [unknown] [.] 0x033e258d4c544155
|
---0x33e258d4c544155
__libc_start_main
main

a.out 不包含地址 0x33e258d4c544155 或以 155 结尾的内容。

问题是如何获取导致页面错误的指令地址?

最佳答案

出于某种原因,我无法重现您的示例,即我没有获得任何有关 major-faults 事件的样本。但我可以用一个不同的例子来解释。

pref report 输出具有误导性,它没有显示三个事件,它显示了三个堆栈级别。使用 perf script 更容易理解 - 它显示了实际事件(包括它们的堆栈)。条目看起来像这样(对每个样本重复):

a.out 22107 14721.378764:   10000000 cycles:u: 
5653c1afb134 main+0x1b (/tmp/a.out)
7f58bb1eeee3 __libc_start_main+0xf3 (/usr/lib/libc-2.29.so)
49564100002cdb3d [unknown] ([unknown])

现在您可以看到带有虚拟指令地址、最近的符号和与符号的偏移量的函数堆栈。如果您想自己修改地址,可以运行 perf script --show-mmap-events,它会告诉您:

a.out 22107 14721.372233: PERF_RECORD_MMAP2 22107/22107: [0x5653c1afb000(0x1000) @ 0x1000 00:2b 463469 624179165]: r-xp /tmp/a.out
^ Base ^ size ^ offset ^ file

然后您可以对 0x5653c1afb134 进行数学运算,方法是减去基数 0x5653c1afb000 并加上偏移量 0x1000 - 您会得到指令的地址或文件中的返回地址。

您还看到 0x49564100002cdb3d 未映射,无法解析 - 它只是来自基于帧指针的堆栈展开的垃圾。你可以忽略它。您还可以使用 --call-graph dwarf--call-graph lbr 这似乎显示了更合理的堆栈来源。

关于linux - 用perf记录缺页的指令地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56985686/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com