Monitorar chamadas de CPU / sistema do sistema no Linux

9

Eu tenho alguns processos que estão consumindo muito tempo de CPU do sistema (conforme determinado olhando para vmstat). Existe uma maneira fácil de descobrir que tipo de chamadas do sistema estão sendo feitas?

Eu sei que há traços, mas existe uma maneira mais rápida e fácil? Existe algo como um "top" para chamadas do sistema?

bajafresh4life
fonte
1
Strace é a solução.
21410 Warner

Respostas:

15

Acho que strace com a -cbandeira é provavelmente o mais próximo que eu conheço. Se você não usou o -csinalizador, tente o seguinte:

$  sudo strace -c -p 12345

Onde 12345 é o ID do processo (PID) do processo em questão. Observe que rastrear um processo adiciona sobrecarga adicional; portanto, enquanto você o rastreia, o processo será mais lento.

Depois de executar isso por quanto tempo você desejar coletar dados, pressione Ctrl-Cpara interromper a coleta de dados e gerar os resultados. Produzirá algo como isto:

% 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

Como você pode ver, trata-se de um detalhamento de todas as chamadas do sistema feitas pelo aplicativo, classificadas pelo tempo total e incluindo o tempo médio por chamada e o número de chamadas para cada syscall. Se você deseja classificá-los de maneira diferente, consulte a página de manual para strace, pois há algumas opções.

Christopher Cashell
fonte
2
Maldito seja, mutex fútil! sacode o punho
Gaius
2

Talvez tente um dos criadores de perfil de amostragem, como oprofile, ou para kernels mais recentes, perf. Se você tiver sorte, o "perf top" poderá dizer exatamente o que você deseja. Veja aqui alguns exemplos

janneb
fonte
2

O tipo de switch strace que eu costumo usar é esse.

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

Um exemplo disso seria,

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>

Você vê a diferença horária no lado direito da chamada do sistema, mostrando quanto tempo levou para passar de uma chamada do sistema para outra.

Você perceberá a diferença de horário entre as chamadas do sistema. Portanto, quando você vê que uma chamada do sistema tem alguns segundos de diferença com a próxima chamada do sistema, então está fazendo barulho.

Outro método é despejá-lo com o gcore. No entanto, isso requer um pouco de experiência na navegação pelo gdb.

Mas, se o thread for um thread do kernel, não será possível rastreá-lo ou despejá-lo. Nesse caso, temos que usar algo mais complexo. No kernel RHEL5, usamos oprofile. No RHEL6, usamos perf. Eu prefiro perf sobre oprofile. Os dados do Perf podem ser coletados com formato gráfico, mostrando a chamada do sistema em que a porcentagem máxima de CPU está sendo usada.

Com um teste perf, eu vejo isso.

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   

Ele mostra a função do kernel em que 38% do tempo da CPU está sendo gasto. Agora, podemos verificar a função e ver o que está fazendo e o que deve fazer.

Com alguns exemplos, não é tão difícil.

Soham Chakraborty
fonte