2016-08-12 9 views
3

私は「Ubuntuの」タグに基づいてドッカーコンテナを使用していますし、デバッグシンボルを表示するツールPERFのlinuxを取得することはできません。ここではどのようにドッカーコンテナ内部のLinuxのPERFツールで作業デバッグシンボルを得るのですか?

は、私は、問題を示すためにやっているものです。

まず私はここで対話型シェルと、コンテナを起動します。

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

その後、コンテナのプロンプトからlinux perfツールをインストールします。私は今perfツールを使用することができます

apt-get update 
apt-get install -y linux-tools-common linux-tools-generic linux-tools-`uname -r` 

。私のカーネルは3.16.0-77-genericです。

今私は、gccをインストールするテストプログラムをコンパイルし、そしてperf recordの下でそれを実行しようとするでしょう。

私は test.cにテストプログラムに貼り付ける
apt-get install -y gcc 

:次に

#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

を実行可能ファイルにはシンボルが含まれていても、シンボルはありませんl情報。ルートになることと行うことによって 96.96% a.out a.out [.] function 0.35% a.out libc-2.19.so [.] [email protected]@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

私はすでにカーネルシンボルをオンにしているホストシステムで:コンテナが正常に動作し、このようなものを示して外に同じ一般的な手順を行う

echo 0 > /proc/sys/kernel/kptr_restrict

コンテナ化されたバージョンを正しく動作させ、デバッグシンボルを表示するにはどうすればよいですか?

答えて

5

-v /:/hostフラグを使用してコンテナを実行し、--symfs /hostフラグの修正をした容器内perf reportを実行している:それはそのまま動作しない理由については

Samples: 4K of event 'cycles', Event count (approx.): 3420992473 96.59% a.out a.out [.] function 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 [.] write

、小屋のperf script一種からの出力にいくつかの光:

... 
      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に注意してください。それがコンテナ内に存在しないだろう、あなたはそれを見つけるためにperf reportを支援する必要があるので、それはホストからです。これは、mmapイベントがcgroupの外部のperfによって追跡され、perfがパスを再マップしようとしないために発生する可能性があります。

もう1つの選択肢は、sudo perf record -a docker run -ti <container name>のようにperfホスト側を実行することです。しかし、ここで実行するドッカークライアントツールのプロセス階層にないドッカーデーモンプロセスによってコンテナが生成されるので、コレクションはここでシステム全体(-aフラグ)にする必要があります。

+0

ありがとう、それはまさにそれでした。 解決策に追加するには、カーネルシンボルを取得するために、さらに: '--kallsyms =/proc/kallsyms'を追加する必要があります。 –

+1

他の誰かを助ける場合には、より簡単な方法は '-v/var/lib/docker /:/ var/lib/docker'で' docker run'を呼び出すことです。シンボルを正しく解決するための特別な引数。 –

+0

ああ、それは良いものです。 –

1

あなたは(あなたがすでに実行中のプロセスをプロファイリングすることができます)コンテナを実行する方法を変更する必要はありませんもう一つの方法は、bindfsを使用して、ホスト上のコンテナのルートをマウントすることです:

bindfs /proc/$(docker inspect --format {{.State.Pid}} $CONTAINER_ID)/root /foo

次にレポートPERF実行perf report --symfs /foo

としてあなたはperf recordシステム全体を実行する必要がありますが、あなたは、特定のコンテナのイベントを収集することを制限することができます。

perf record -g -a -F 100 -e cpu-clock -G docker/$(docker inspect --format {{.Id}} $CONTAINER_ID) sleep 90

関連する問題