Monitorare le chiamate di sistema CPU / sistema in Linux


9

Ho un paio di processi che stanno consumando molto tempo di CPU del sistema (come determinato guardando vmstat). C'è un modo semplice per scoprire che tipo di chiamate di sistema vengono effettuate?

So che c'è straccia, ma c'è un modo più rapido e semplice? Esiste qualcosa come un "top" per le chiamate di sistema?


1
strace è la soluzione.
Warner,

Risposte:


15

Penso che il passo con la -cbandiera sia probabilmente il più vicino che io conosca. Se non hai usato la -cbandiera, prova questo:

$  sudo strace -c -p 12345

Dove 12345 è l'ID processo (PID) del processo in questione. Si noti che la traccia di un processo aggiunge un sovraccarico aggiuntivo, quindi mentre lo si traccia, il processo verrà eseguito più lentamente.

Dopo averlo eseguito per tutto il tempo che desideri raccogliere dati, premi Ctrl-Cper interrompere la raccolta dei dati e produrre i risultati. Produrrà qualcosa del genere:

% 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

Come puoi vedere, si tratta di una suddivisione di tutte le chiamate di sistema effettuate dall'applicazione, ordinate in base al tempo totale e comprendente il tempo medio per chiamata e il numero di chiamate per ogni syscall. Se vuoi ordinarli diversamente, vedi la pagina man per strace, in quanto ci sono un paio di opzioni.


2
Accidenti a te, inutile mutex! stringe il pugno
Gaius,

2

Forse provare uno dei profiler di campionamento, come oprofile, o per i kernel più recenti, perf. Se sei fortunato, "perf top" potrebbe dirti esattamente quello che vuoi. Vedi qui per alcuni esempi


2

Il tipo di switch di strace che tendo a usare è questo.

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

Un esempio di questo sarebbe simile,

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>

Si vede la differenza di orario sul lato destro della chiamata di sistema che mostra quanto tempo è passato da una chiamata di sistema a un'altra.

Ti colpirà la differenza di tempo tra le chiamate di sistema. Quindi, quando vedi che una chiamata di sistema ha un intervallo di alcuni secondi rispetto alla successiva chiamata di sistema, allora c'è un po 'di rumore.

Un altro metodo è coredump con gcore. Tuttavia, ciò richiede una piccola esperienza nella navigazione attraverso gdb.

Ma, se il thread è un thread del kernel, non è possibile rintracciarlo o coredump. In tal caso, dobbiamo usare qualcosa di più complesso. Nel kernel RHEL5, usiamo oprofile. In RHEL6, usiamo perf. Preferisco perf rispetto a oprofile. I dati perf possono essere raccolti con un grafico come il formato che mostra la chiamata di sistema in cui viene utilizzata la percentuale massima di CPU.

Con un test perf, vedo questo.

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   

Mostra la funzione del kernel in cui viene impiegato il 38% del tempo CPU. Ora, possiamo controllare la funzione e vedere cosa sta facendo e cosa dovrebbe fare.

Con alcuni esempi, non è poi così difficile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.