Überwachen Sie die CPU- / Systemaufrufe des Systems unter Linux

9

Ich habe ein paar Prozesse, die viel System-CPU-Zeit verbrauchen (wie durch Betrachten von vmstat bestimmt). Gibt es eine einfache Möglichkeit herauszufinden, welche Systemaufrufe getätigt werden?

Ich weiß, dass es Strace gibt, aber gibt es einen schnelleren und einfacheren Weg? Gibt es so etwas wie ein "Top" für Systemaufrufe?

bajafresh4life
quelle
1
strace ist die lösung.
Warner

Antworten:

15

Ich denke, die Strace mit der -cFlagge ist wahrscheinlich die nächste, die ich kenne. Wenn Sie die -cFlagge nicht verwendet haben , versuchen Sie Folgendes:

$  sudo strace -c -p 12345

Dabei ist 12345 die Prozess-ID (PID) des betreffenden Prozesses. Beachten Sie, dass das Stracing eines Prozesses zusätzlichen Overhead verursacht. Während Sie ihn verfolgen, wird der Prozess langsamer ausgeführt.

Nachdem Sie das so lange ausgeführt haben, wie Sie Daten erfassen möchten, drücken Sie, um die Datenerfassung Ctrl-Czu beenden und die Ergebnisse auszugeben. Es wird so etwas produzieren:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 31.88    0.001738         145        12           futex
 16.79    0.000915          11        80           tgkill
 12.36    0.000674          34        20           read
  9.76    0.000532         266         2           statfs
  8.42    0.000459          13        35           time
  4.38    0.000239           6        40           gettimeofday
  3.65    0.000199           4        48           sigprocmask
  2.94    0.000160          18         9           open
  2.88    0.000157          12        13           stat64
  1.32    0.000072           9         8           munmap
  0.90    0.000049           6         8           mmap2
  0.88    0.000048           3        14         7 sigreturn
  0.79    0.000043           5         9           close
  0.77    0.000042           4        10           rt_sigprocmask
  0.64    0.000035           3        12           setitimer
  0.55    0.000030           5         6         6 rt_sigsuspend
  0.53    0.000029           4         8           fstat64
  0.29    0.000016           8         2           setresuid32
  0.13    0.000007           4         2           _llseek
  0.09    0.000005           3         2           prctl
  0.04    0.000002           2         1           geteuid32
------ ----------- ----------- --------- --------- ----------------
100.00    0.005451                   341        13 total

Wie Sie sehen, ist dies eine Aufschlüsselung aller von der Anwendung getätigten Systemaufrufe, sortiert nach der Gesamtzeit, einschließlich der durchschnittlichen Zeit pro Anruf und der Anzahl der Anrufe für jeden Systemaufruf. Wenn Sie sie anders sortieren möchten, lesen Sie die Manpage für strace, da es einige Optionen gibt.

Christopher Cashell
quelle
2
Verdammt, vergeblicher Mutex! schüttelt die Faust
Gaius
2

Probieren Sie vielleicht einen der Sampling-Profiler aus, z. B. oprofile, oder für neuere Kernel perf. Wenn Sie Glück haben, sagt Ihnen "perf top" vielleicht genau, was Sie wollen. Sehen Sie hier einige Beispiele

janneb
quelle
2

Die Art von Strace-Schaltern, die ich normalerweise benutze, ist diese.

strace -ffttT -p pid -o /tmp/strace.out

Ein Beispiel dafür würde aussehen wie:

19:35:57.485493 mprotect(0x7f35e7472000, 16384, PROT_READ) = 0 <0.000037>
19:35:57.485599 mprotect(0x7f35e7692000, 4096, PROT_READ) = 0 <0.000030>
19:35:57.485697 mprotect(0x7f35e78b7000, 4096, PROT_READ) = 0 <0.000030>
19:35:57.485782 munmap(0x7f35e7896000, 129588) = 0 <0.000037>
19:35:57.485875 set_tid_address(0x7f35e78949d0) = 10730 <0.000029>
19:35:57.485960 set_robust_list(0x7f35e78949e0, 0x18) = 0 <0.000024>
19:35:57.486048 futex(0x7fff8f58628c, FUTEX_WAKE_PRIVATE, 1) = 0 <0.000025>
19:35:57.486131 futex(0x7fff8f58628c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1,       NULL, 7f35e7894700) = -1 EAGAIN (Resource temporarily unavailable) <0.000024>

Der Zeitunterschied auf der rechten Seite des Systemaufrufs zeigt an, wie lange es gedauert hat, von einem Systemaufruf zum nächsten zu wechseln.

Sie erkennen den Zeitunterschied zwischen den Systemaufrufen. Wenn Sie also sehen, dass ein Systemaufruf einige Sekunden Abstand zum nächsten Systemaufruf hat, macht er dort ein gewisses Rauschen.

Eine andere Methode besteht darin, es mit gcore zu entleeren. Dies erfordert jedoch ein wenig Erfahrung in der Navigation durch GDB.

Wenn es sich bei dem Thread jedoch um einen Kernel-Thread handelt, können Sie ihn nicht straffen oder entleeren. In diesem Fall müssen wir etwas Komplexeres verwenden. Im RHEL5-Kernel verwenden wir oprofile. In RHEL6 verwenden wir perf. Ich bevorzuge Perf gegenüber Oprofile. Perf-Daten können mit einem grafischen Format erfasst werden, das den Systemaufruf zeigt, bei dem der maximale Prozentsatz der CPU verwendet wird.

Mit einer Testleistung sehe ich das.

38.06%  swapper  [kernel.kallsyms]  [k] mwait_idle_with_hints                                                                                                               ↑

29.45%  swapper  [kernel.kallsyms]  [k] read_hpet 
4.90%  swapper  [kernel.kallsyms]  [k] acpi_os_read_port                                                                                                                   ▒
4.74%  swapper  [kernel.kallsyms]  [k] hpet_next_event   

Es zeigt die Kernelfunktion, in der 38% der CPU-Zeit verbracht werden. Jetzt können wir die Funktion überprüfen und sehen, was sie tut und was sie tun soll.

Mit ein paar Beispielen ist es nicht so schwer.

Soham Chakraborty
quelle