Monitoruj wywołania systemowe CPU / systemowe w systemie Linux

9

Mam kilka procesów, które pochłaniają dużo czasu procesora systemowego (ustalonego na podstawie vmstat). Czy istnieje prosty sposób, aby dowiedzieć się, jakie są wywołania systemowe?

Wiem, że jest strace, ale czy istnieje szybszy i łatwiejszy sposób? Czy istnieje coś w rodzaju „góry” dla wywołań systemowych?

bajafresh4life
źródło
1
strace jest rozwiązaniem.
Warner

Odpowiedzi:

15

Myślę, że strace z -cflagą są prawdopodobnie najbliższe, jakie znam. Jeśli -cflaga nie była używana , spróbuj tego:

$  sudo strace -c -p 12345

Gdzie 12345 jest identyfikatorem procesu (PID) danego procesu. Pamiętaj, że obrysowywanie procesu powoduje dodatkowe obciążenie, więc podczas śledzenia proces będzie działał wolniej.

Po uruchomieniu tego, niezależnie od tego, jak długo chcesz zbierać dane, naciśnij, Ctrl-Caby zatrzymać gromadzenie danych i wygenerować wyniki. Wyprodukuje coś takiego:

% 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

Jak widać, jest to podział wszystkich wywołań systemowych wykonanych przez aplikację, posortowanych według całkowitego czasu, w tym średniego czasu na połączenie i liczby połączeń dla każdego połączenia systemowego. Jeśli chcesz posortować je inaczej, zajrzyj na stronę man strace, ponieważ jest kilka opcji.

Christopher Cashell
źródło
2
Cholera, bezowocny muteksie! potrząsa pięścią
Gajusz
2

Może wypróbuj jeden z profilerów próbkujących, taki jak oprofile lub dla nowszych jąder, perf. Jeśli masz szczęście, „perf top” może powiedzieć ci dokładnie, czego chcesz. Zobacz tutaj kilka przykładów

janneb
źródło
2

Oto typ przełączników strace, których zwykle używam.

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

Przykładem może być:

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>

Różnica czasu widoczna jest po prawej stronie wywołania systemowego, pokazując ile czasu zajęło przejście z jednego wywołania systemowego do drugiego.

Złapie różnicę czasu między wywołaniami systemowymi. Tak więc, gdy zobaczysz, że wywołanie systemowe ma kilka sekund przerwy w stosunku do następnego wywołania systemowego, wtedy robi hałas.

Inną metodą jest poradzenie sobie z gcore. Jednak wymaga to trochę doświadczenia w poruszaniu się po gdb.

Ale jeśli wątek jest wątkiem jądra, nie można go śledzić ani zrzucać. W takim przypadku musimy użyć czegoś bardziej złożonego. W jądrze RHEL5 używamy oprofile. W RHEL6 używamy perf. Wolę perf niż oprofile. Dane Perf mogą być gromadzone w formacie wykresu pokazującym wywołanie systemowe, w którym wykorzystywany jest maksymalny procent procesora.

Widzę to z testową wydajnością.

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   

Pokazuje funkcję jądra, w której spędza się 38% czasu procesora. Teraz możemy sprawdzić funkcję i zobaczyć, co robi i co ma robić.

Z kilkoma przykładami nie jest to takie trudne.

Soham Chakraborty
źródło