2016-08-12 2 views
3

J'utilise des conteneurs Docker basés sur la balise "ubuntu" et je ne peux pas obtenir l'outil de perfusion linux pour afficher les symboles de débogage.Comment obtenez-vous les symboles de débogage qui travaillent dans l'outil de perfusion linux dans les conteneurs Docker?

Voici ce que je fais pour démontrer le problème.

D'abord, je démarre un conteneur, ici avec un shell interactif. Puis, à partir de l'invite de conteneur, j'installe l'outil de perfusion linux. Je peux maintenant utiliser l'outil perf. Mon noyau est 3.16.0-77-generic.

Maintenant, je vais installer gcc, compiler un programme de test, et essayer de l'exécuter sous perf record.

apt-get install -y gcc 

Je coller dans le programme de test en 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); 
     } 
    } 
} 

compilez Ensuite, exécutez et signaler: gcc -g -O0 test.c && perf record ./a.out && perf report

La sortie ressemble à ceci: 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

Cela n'a pas de symboles, même si l'exécutable a symbo l information.

Faire les mêmes étapes générales à l'extérieur du récipient fonctionne très bien, et montre quelque chose comme ceci: 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

Dans le système hôte, je l'ai déjà tourné sur les symboles du noyau en devenant racine et faire: echo 0 > /proc/sys/kernel/kptr_restrict

Comment faire pour que la version conteneurisée fonctionne correctement et affiche les symboles de débogage?

Répondre

5

Exécution du conteneur avec -v /:/host drapeau et en cours d'exécution perf report dans le conteneur avec --symfs /host drapeau résout le problème:

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

Pour pourquoi il ne fonctionne pas tel quel, la sortie de perf script sorte de jette une certaine lumière sur :

... 
      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) 
... 

Notez le chemin /var/lib/docker/aufs. C'est à partir de l'hôte de sorte qu'il n'existe pas dans le conteneur et vous devez aider perf report pour le localiser. Cela se produit probablement parce que les événements mmap sont suivis par perf en dehors de tout groupe de contrôle et perf ne tente pas de remapper les chemins.

Une autre option consiste à exécuter perf-côté hôte, comme sudo perf record -a docker run -ti <container name>. Mais la collection doit être à l'échelle du système ici (le drapeau -a) car les conteneurs sont générés par le processus démon docker qui n'est pas dans la hiérarchie de processus de l'outil client docker que nous exécutons ici.

+0

Merci, c'était exactement cela. Pour ajouter à la solution, afin d'obtenir les symboles du noyau, vous devez également ajouter: '--kallsyms =/proc/kallsyms'. –

+1

Au cas où cela aiderait quelqu'un d'autre: un moyen encore plus simple est d'appeler 'docker run' avec' -v/var/lib/docker /:/var/lib/docker', ce qui fait que 'perf' ne nécessite aucune arguments spéciaux pour résoudre correctement les symboles. –

+0

Ah, c'est un bon. –

1

Une autre façon qui ne nécessite pas de modifier la façon dont vous exécutez le conteneur (vous pouvez profiler un déjà processus en cours d'exécution) est de monter la racine du conteneur sur l'hôte en utilisant bindfs:

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

Lancez ensuite le rapport perf comme perf report --symfs /foo

vous devez exécuter perf record l'ensemble du système, mais vous pouvez restreindre à ne recueillir que des événements pour le conteneur spécifique:

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