2016-08-12 3 views
3

Я использую контейнеры Docker на основе тега «ubuntu» и не могу получить инструмент linux perf для отображения отладочных символов.Как вы получаете отладочные символы, работающие в linux perf tool внутри контейнеров Docker?

Вот что я делаю, чтобы продемонстрировать проблему.

Сначала я запускаю контейнер, здесь с интерактивной оболочкой.

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

Тогда из подсказки контейнера я устанавливаю linux perf tool.

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 [.] [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 флагом и работает perf report в контейнере с --symfs /host флагом фиксирует это:

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 отслеживаются с помощью perf вне любой группы, и perf не пытается переназначить пути.

Другой вариант - запустить первичную хост-сторону, например sudo perf record -a docker run -ti <container name>. Но коллекция должна быть общесистемной здесь (флаг -a), так как контейнеры создаются процессом демона-докера, который не находится в иерархии процессов инструмента-клиента докера, который мы запускаем здесь.

+0

Спасибо, это было именно так. Чтобы добавить решение, чтобы получить символы ядра, вам также необходимо добавить: '--kallsyms =/proc/kallsyms'. –

+1

В случае, если это помогает кому-либо еще: еще более простой способ - вызвать 'docker run' с' -v/var/lib/docker /:/var/lib/docker', что делает так, что 'perf' не требует никаких специальные аргументы для правильного разрешения символов. –

+0

А, это хороший. –

1

Другой способ, который не требует изменения, как вы запустите контейнер (так что вы можете профилировать процесс уже запущен), чтобы смонтировать корневой контейнер на хост с помощью bindfs:

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

Затем запустите перфорация отчет в 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

Смежные вопросы