运维开发网

如何在Docker容器中的linux perf工具中获得调试符号?

运维开发网 https://www.qedev.com 2020-06-13 15:42 出处:网络 作者:运维开发网整理
我正在使用基于“ubuntu”标签的Docker容器,并且无法获得 linux perf工具来显示调试符号. 这是我正在做的来证明这个问题. 首先,我启动一个容器,这里有一个交互式shell. docker run -t -i ubuntu:14.04 /bin/bash 然后从容器提示我安装linux perf工具. apt-get update apt-get install -y linux
我正在使用基于“ubuntu”标签的Docker容器,并且无法获得 Linux perf工具来显示调试符号.

这是我正在做的来证明这个问题.

首先,我启动一个容器,这里有一个交互式shell.

docker run -t -i ubuntu:14.04 /bin/bash

然后从容器提示我安装Linux perf工具.

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记录下运行它.

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记录./a.out&& perf报告

输出看起来像这样:

  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

即使可执行文件具有符号信息,也没有符号.

在容器外执行相同的一般步骤可以正常工作,并显示如下内容:

a.out [.]函数的96.96%

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 /内核/ kptr_restrict

如何使容器化版本正常工作并显示调试符号?

使用-v /:/ host标志运行容器并使用–symfs / host标志在容器中运行perf report修复它:

样本:4K事件’周期’,事件计数(约):3420992473

 a.out [.]函数的96.59%

  2.93%a.out [kernel.kallsyms] [k] 0xffffffff8105144a

  0.13%a.out [nvidia] [k] 0x00000000002eda57

  0.11%a.out libc-2.19.so [.] vfprintf

  0.11%a.out libc-2.19.so [.] 0x0000000000049980

  0.09%a.out a.out [.] main

  0.02%a.out libc-2.19.so [.] _IO_file_write

  0.02%a.out libc-2.19.so [.]写

为什么它不能正常工作,perf脚本的输出有点说明:

...
           a.out    24 3374818.880960: cycles:  ffffffff81141140 __perf_event__output_id_sample ([kernel.kallsyms])
           a.out    24 3374818.881012: cycles:  ffffffff817319fd _raw_spin_lock_irqsave ([kernel.kallsyms])
           a.out    24 3374818.882217: cycles:  ffffffff8109aba3 ttwu_do_activate.constprop.75 ([kernel.kallsyms])
           a.out    24 3374818.884071: cycles:            40053d [unknown] (/var/lib/docker/aufs/diff/9bd2d4389cf7ad185405245b1f5c7d24d461bd565757880bfb4f970d3f4f7915/a.out)
           a.out    24 3374818.885329: cycles:            400544 [unknown] (/var/lib/docker/aufs/diff/9bd2d4389cf7ad185405245b1f5c7d24d461bd565757880bfb4f970d3f4f7915/a.out)
...

注意/ var / lib / docker / aufs路径.这是来自主机,因此它不会存在于容器中,您需要帮助执行报告以找到它.这可能是因为mmap事件由任何cgroup外部的perf跟踪,并且perf不会尝试重新映射路径.

另一种选择是运行perf主机端,如sudo perf record -a docker run -ti< container name>.但是集合必须在这里是系统范围的(-a标志),因为容器是由docker守护程序进程生成的,该进程不在我们在这里运行的docker客户端工具的进程层次结构中.

0

精彩评论

暂无评论...
验证码 换一张
取 消