Monitoree las llamadas de sistema / CPU del sistema en Linux

9

Tengo un par de procesos que están consumiendo mucho tiempo de CPU del sistema (según lo determinado al mirar vmstat). ¿Hay una manera fácil de averiguar qué tipo de llamadas al sistema se están realizando?

Sé que hay strace, pero ¿hay una manera más rápida y fácil? ¿Existe algo así como un "top" para las llamadas al sistema?

bajafresh4life
fuente
1
Strace es la solución.
Warner

Respuestas:

15

Creo que estar cerca de la -cbandera es probablemente lo más cercano que conozco. Si no ha usado la -cbandera, intente esto:

$  sudo strace -c -p 12345

Donde 12345 es el ID de proceso (PID) del proceso en cuestión. Tenga en cuenta que dividir un proceso agrega una sobrecarga adicional, por lo que mientras lo rastrea, el proceso se ejecutará más lentamente.

Después de ejecutar eso durante el tiempo que desee recopilar datos, presione Ctrl-Cpara detener la recopilación de datos y generar los resultados. Producirá algo como esto:

% 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 puede ver, este es un desglose de todas las llamadas al sistema realizadas por la aplicación, ordenadas por tiempo total e incluyendo el tiempo promedio por llamada y el número de llamadas para cada llamada al sistema. Si desea ordenarlos de manera diferente, consulte la página de manual de strace, ya que hay un par de opciones.

Christopher Cashell
fuente
2
¡Maldita sea, mutex inútil! sacude el puño
Gaius
2

Quizás pruebe uno de los perfiladores de muestreo, como oprofile, o para núcleos más nuevos, perf. Si tienes suerte, "perf top" podría decirte exactamente lo que quieres. Vea aquí algunos ejemplos.

janneb
fuente
2

El tipo de interruptores strace que tiendo a usar es este.

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

Un ejemplo de esto sería,

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>

Verá la diferencia horaria en el lado derecho de la llamada del sistema que muestra cuánto tiempo ha llevado pasar de una llamada del sistema a otra.

Le detectará la diferencia horaria entre las llamadas del sistema. Entonces, cuando ve que una llamada del sistema tiene un intervalo de unos segundos con la siguiente llamada del sistema, entonces está haciendo algo de ruido.

Otro método es coredumplo con gcore. Sin embargo, eso requiere un poco de experiencia para navegar a través de gdb.

Pero, si el subproceso es un subproceso del núcleo, entonces no se puede dividir o coredump. En ese caso, tenemos que usar algo más complejo. En el kernel RHEL5, utilizamos oprofile. En RHEL6, utilizamos perf. Prefiero perf sobre oprofile. Los datos de rendimiento se pueden recopilar con un formato similar al gráfico que muestra la llamada al sistema donde se utiliza el porcentaje máximo de CPU.

Con una prueba de rendimiento, veo esto.

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   

Muestra la función del núcleo donde se está gastando el 38% del tiempo de CPU. Ahora, podemos verificar la función y ver qué está haciendo y qué se supone que debe hacer.

Con algunos ejemplos, no es tan difícil.

Soham Chakraborty
fuente