Essensielle verktøy: strace

strace er et av de aller mest anvendelige verktøyene for en systemadministrator. Av og til sitter du og lurer på hva en prosess gjør for noe. Hvis en prosess kræsjer eller henger er det ofte veldig hjelpsomt å få greie på hva den siste fila prosessen tok i før den døde er. strace kan gjøre akkurat dette. strace kan koble seg på eksisterende prosesser og fortelle deg hvilke systemkall prosessen gjør.

Dette vises kanskje best ved et eksempel. Sett at vi har en prosess som står og tar opp skrekkelig mye CPU. Du lurer på hva den driver med. strace -p $PID kan gi deg svaret. Se her:

: [perbu@nfsd ~/tmp/foo]; strace -p 12717
Process 12717 attached – interrupt to quit
stat64(“/tmp/baz”, 0x814c0c8) = -1 ENOENT (No such file or directory)
stat64(“/tmp/baz”, 0x814c0c8) = -1 ENOENT (No such file or directory)
stat64(“/tmp/baz”, 0x814c0c8) = -1 ENOENT (No such file or directory)
^C avslutter strace. Hva ser vi? Jo – pid 12717 står og poller /tmp/baz hele tiden. Den venter tydeligvis på at noe skal dukke opp der og forfatteren av programmet forventet tydeligvis ikke at det ikke skulle være noe der og går i en altfor tett løkk rundt sjekken sin.

Et eksempel til. Sett at noen har tøyset noe til og mysql-klienten kræsjer når du forsøker å starte den. En sannsynlig årsak vil være at mysql-klienten er lenket mot feil versjon av biblioteket – libmysql. Hvis vi later som om vi ikke vet hva ldd er til så kan vi bruke strace. Faktisk kan strace avsløre lenking som ldd ikke vet om – fordi programmet laster so-filene på egen hånd – senere i programmets kjøring. Vel – uansett – slik ser det ut:

[perbu@nfsd ~/tmp/foo]; strace -e open mysql

open(“/etc/ld.so.preload”, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/usr/lib/mysql/tls/i686/mmx/cmov/libreadline.so.4″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/usr/lib/mysql/tls/i686/mmx/libreadline.so.4″, O_RDONLY) = -1 ENOENT (No such file or directory)
open(“/usr/lib/mysql/tls/i686/cmov/libreadline.so.4″, O_RDONLY) = -1 ENOENT (No such file or directory)
(..)

Okey – her viser strace at programmet forsøkes lenket mot biblioteker vi ikke har installert. Dette er er helt normalt. Litt lenger ned ser vi følgende:

open(“/etc/ld.so.cache”, O_RDONLY) = 3
open(“/lib/libreadline.so.4″, O_RDONLY) = 3
open(“/lib/libncurses.so.5″, O_RDONLY) = 3
open(“/usr/lib/libstdc++.so.5″, O_RDONLY) = 3
open(“/usr/local/lib/libmysqlclient.so.6″, O_RDONLY) = 3

Her ser vi libmysql bli åpnet og lenket inn.

(..)

— SIGSEGV (Segmentation fault) @ 0 (0) —
+++ killed by SIGSEGV +++

Og her kræsjer mysql-klienten. Sett at vi har versjon 5 av mysql-klienten og strace forteller oss at den forsøker å bruke libmysql.so.6 – ikke bra. Fint, hva?

Comments are closed.