我正在使用基于“ubuntu”标签的Docker容器,并且无法使Linux Perf工具显示调试符号。
以下是我演示问题的步骤。
首先,我启动一个容器,这里使用交互式shell。
$ docker run -t -i ubuntu:14.04 /bin/bash
然后从容器提示符处安装Linux性能工具。
$ apt-get update
$ apt-get install -y linux-tools-common linux-tools-generic linux-tools-`uname -r`
我现在可以使用perf
工具了。我的内核版本是3.16.0-77-generic
。
现在,我将安装gcc
,编译一个测试程序,并尝试在perf record
下运行它。
$ apt-get install -y gcc
我将测试程序粘贴到
test.c
文件中:#include <stdio.h>
int function(int i) {
int j;
for(j = 2; j <= i / 2; j++) {
if (i % j == 0) {
return 0;
}
}
return 1;
}
int main() {
int i;
for(i = 2; i < 100000; i++) {
if(function(i)) {
printf("%d\n", i);
}
}
}
然后进行编译,运行并报告:
$ gcc -g -O0 test.c && perf record ./a.out && perf report
输出结果大致如下:
72.38% a.out a.out [.] 0x0000000000000544
8.37% a.out a.out [.] 0x000000000000055a
8.30% a.out a.out [.] 0x000000000000053d
7.81% a.out a.out [.] 0x0000000000000551
0.40% a.out a.out [.] 0x0000000000000540
这段代码没有符号,即使可执行文件有符号信息。
在容器外进行相同的一般步骤可以正常工作,并显示类似于以下内容:
96.96% a.out a.out [.] function
0.35% a.out libc-2.19.so [.] _IO_file_xsputn@@GLIBC_2.2.5
0.14% a.out [kernel.kallsyms] [k] update_curr
0.12% a.out [kernel.kallsyms] [k] update_cfs_shares
0.11% a.out [kernel.kallsyms] [k] _raw_spin_lock_irqsave
在主机系统中,我已经通过切换为root用户并执行以下命令打开了内核符号:
$ echo 0 > /proc/sys/kernel/kptr_restrict
如何使容器化版本正常工作并显示调试符号?
--kallsyms=/proc/kallsyms
。 - Nathan Whiteheaddocker run
命令并加上参数-v /var/lib/docker/:/var/lib/docker
,这样perf
就不需要任何特殊参数来正确解析符号。 - Nathan Whitehead