我所做的是:
1. sudo rm -rf /root/.debug/
2. compile program with -g -O2 -fno-omit-frame-pointer
3. run the program and get the pid
4. sudo perf record -F 2000 -a -s -g -p $pid sleep 15
5. sudo perf report
然后我得到了“未知”的一小部分,例如
- 2.50% 0.00% postgres [unknown] [k] 0000000000000000
- 0
1.12% _int_malloc ▒
0.79% _IO_vsnprintf
看起来这是由于libc'malloc'调用引起的。然后我在同一台计算机上编写了一个程序进行测试。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
while(1) {
printf("perf record -g -p %d -- sleep 5; perf report\n", getpid());
sleep(1);
void *p = malloc(10);
memset(p, 0, 10);
free(p);
}
return 0;
}
然后我做与上述相同的事情,没有“未知”部分。
如何解释/解决这个问题?
答案 0 :(得分:1)
[unknown]
输出中的perf report
块引用动态共享库的名称( DSO )。 perf report
无法解析 DSO 路径,因此它会打印[unknown]
。根据最新的内核源代码树(在撰写本文时为5.3.9),您可以看到此here。
重要的是要知道,DSO符号的确定是在采样的事件地址的帮助下发生的。函数thread__resolve负责执行此操作。在较早的内核中,thread__resolve
方法有另一个名称-perf_event__preprocess_sample_addr
。
给出输出快照,看起来perf record
期间采样的事件的地址为0。这意味着该地址根本无法解析。它是内核空间中的地址(看符号[k] 0000000000000000
),根据您的情况,perf
无法解析。
注释会突出显示将perf_event_paranoid
设置为适当的值,以便您可以成功探测内核和用户空间事件。将perf_event_paranoid
的值设置为允许您正确探测内核空间中的事件,应该“一步”来正确解析地址。