Monitorar as chamadas CPU / sistema do sistema no Linux

9

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

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

    
por bajafresh4life 15.07.2010 / 16:16

3 respostas

14

Eu acho que strace com o sinal -c é provavelmente o mais próximo que eu sei. Se você não usou o sinalizador -c , tente o seguinte:

$  sudo strace -c -p 12345

Em que 12345 é o ID do processo (PID) do processo em questão. Observe que o stracing de um processo adiciona uma sobrecarga adicional, portanto, enquanto você estiver rastreando, o processo será executado mais lentamente.

Depois de executar isso por quanto tempo você quiser coletar dados, pressione Ctrl-C para interromper a coleta de dados e gerar os resultados. Isso produzirá algo assim:

% 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, este é um detalhamento de todas as chamadas do sistema feitas pelo aplicativo, classificadas pelo tempo total e incluindo o tempo médio por chamada e número de chamadas para cada syscall. Se você quiser classificá-los de forma diferente, veja a man page para strace, pois há algumas opções.

    
por 15.07.2010 / 18:55
2

Talvez experimente um dos profiladores de amostragem, como oprofile, ou para novos kernels, perf. Se você tiver sorte, o "perf top" pode dizer exatamente o que você quer. Veja aqui para alguns exemplos

    
por 15.07.2010 / 17:15
2

O tipo de interruptores de strace que eu costumo usar é isso.

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 de horário no lado direito da chamada do sistema mostrando quanto tempo levou para ir de uma chamada de sistema para outra.

Ele vai pegar a diferença de tempo entre as chamadas do sistema. Então, quando você vê que uma chamada de sistema tem uma lacuna de alguns segundos com a próxima chamada de sistema, então está fazendo algum ruído.

Outro método é recolocá-lo no gcore. No entanto, isso requer uma pequena experiência navegando pelo gdb.

Mas, se o encadeamento for um encadeamento de kernel, você não poderá aplicar strings ou decodificá-lo. Nesse caso, temos que usar algo mais complexo. No kernel RHEL5, usamos o oprofile. No RHEL6, usamos perf. Eu prefiro perf em oprofile. Os dados de desempenho podem ser coletados com o formato de gráfico, mostrando a chamada do sistema em que a porcentagem máxima de CPU está sendo usada.

Com um teste de perf, 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 onde 38% do tempo da CPU está sendo gasto. Agora, podemos verificar a função e ver o que ela está fazendo e o que deve fazer.

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

    
por 02.10.2012 / 10:28