Ausführen des Containers mit -v /:/host
Flag und Ausführen von perf report
im Container mit --symfs /host
Flag behebt es:
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
Ein Teil des Grundes, warum es nicht so funktioniert wie es ist? Die Ausgabe von perf script
bringt etwas Licht ins Dunkel:
...
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)
...
Beachten Sie die /var/lib/docker/aufs
Weg. Das kommt vom Host, also existiert es nicht im Container und Sie müssen perf report
helfen um es zu lokalisieren. Dies geschieht wahrscheinlich, weil die mmap-Ereignisse von perf außerhalb einer Kontrollgruppe verfolgt werden und perf nicht versucht, die Pfade neu zuzuordnen.
Eine andere Option ist, perf hostseitig auszuführen, wie sudo perf record -a docker run -ti <container name>
. Aber die Sammlung muss hier systemweit sein (die -a
-Flag), da Container vom Docker-Daemon-Prozess erzeugt werden, der sich nicht in der Prozesshierarchie des Docker-Client-Tools befindet, das wir hier ausführen.
Eine andere Möglichkeit, bei der Sie die Art und Weise, wie Sie den Container ausführen, nicht ändern müssen (damit Sie einen bereits laufenden Prozess profilieren können), besteht darin, das Root-Verzeichnis des Containers auf dem Host mit bindfs zu mounten:
bindfs /proc/$(docker inspect --format {{.State.Pid}} $CONTAINER_ID)/root /foo
Führen Sie dann den Leistungsbericht als perf report --symfs /foo
aus
Sie müssen perf record
ausführen systemweit, aber Sie können es darauf beschränken, nur Ereignisse für den spezifischen Container zu sammeln:
perf record -g -a -F 100 -e cpu-clock -G docker/$(docker inspect --format {{.Id}} $CONTAINER_ID) sleep 90