如何摆脱性能中的“未知”部分

时间:2019-11-05 10:54:01

标签: c linux perf

我所做的是:

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;
}

然后我做与​​上述相同的事情,没有“未知”部分。

如何解释/解决这个问题?

1 个答案:

答案 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的值设置为允许您正确探测内核空间中的事件,应该“一步”来正确解析地址。