Luigi Catuogno
Dipartimento di Informatica ed Applicazioni
Università degli Studi di Salerno
[email protected]
Cos’è DTrace
•  Un sofisticato sistema di debugging
•  Integrato nel sistema operativo
•  Tracciamento dinamico a run-time
dell’esecuzione
–  Applicazioni
–  Sistema operativo
Dtrace: cenni storici
•  Sviluppato dalla Sun Microsystem nel novembre 2003
•  Distribuito nel 2005 come componente di Solaris 10
•  Codice sorgente distribuito, come componente di
Open Solaris
–  licenza Common Development Distribution License
(CDDL)
–  Disponibile su:
•  NetBSD, FreeBSD, Mac OS X 10.5 “Leopard”
–  Porting in corso:
•  Linux, QNX 6
DTrace: cenni storici
•  Creato da:
–  Bryan Cantrill, Mike Shapiro, Adam Leventhal
•  Premi e riconoscimenti:
–  InfoWorld and Technology Review(2005)
–  Technical Innovation Awards Competition Wall Street Journal (2006)
–  USENIX (2008)
Cosa fa Dtrace/1
•  Attivazione dinamica, a run-time di
“sonde” (probes) per la rilevazione di
eventi di interesse nell’esecuzione del
sistema operativo e nelle applicazioni
•  Tracing di variabili e strutture dati
Cosa fa Dtrace/2
•  Definizione di sequenze di “azioni”
associate agli eventi di interesse
–  Linguaggio D, per la definizione delle azioni
•  Esecuzione, a run time, delle azioni
associate agli eventi rilevati dalle sonde
attivate
Cosa permette DTrace
•  Può tracciare l’esecuzione di codice
–  Compilato da terze parti
–  Senza supporto per il debugging
–  Sorgenti non disponibili
–  Senza bisogno di ri-compilare
•  Già in esecuzione
–  Senza bisogno di ri-lanciare il processo
–  Senza alterare significativamente
•  Comportamento
•  Prestazioni
Linguaggio D
•  Linguaggio di scripting utilizzato per
–  identificare la/le probes da attivare
•  eventi di interesse
–  Definizione di predicati per ulteriore filtraggio
degli eventi
–  Definizione delle azioni associate all’evento
Linguaggio D: clausola
probe description
/predicate/
{
actions
}
Esempio 1
syscall::write:entry
/execname == “bash”/
{
printf (“bash (%d) writes something!\n”,
pid);
}
Linguaggio D:
•  Probe description
–  nella forma
provider:module:function:name
pid1234:libc:malloc:entry
syscall::read*:
sysinfo:::pswitch
–  module, function e name sono opzionali
–  sono ammesse wildcards ‘*’ e ‘?’
•  Quando un evento si verifica si dice che la
sonda corrispondente “spari” (the probe fires)
I Provider
•  Indicano il “livello” al quale viene effettuato
il tracing:
–  syscall: livello interfaccia system calls
–  io: disk I/O
–  pid: chiamate a funzioni in un processo
–  sysinfo: statistiche a livello kernel
–  proc: informazioni sul ciclo di vita dei processi
–  sched: informazioni sugli eventi di scheduling
Moduli e funzioni
•  Moduli
–  componenti (ove presenti) dell’eseguibile
tracciato
•  pid135:libc::entry
•  pid334:a.out:foo:
•  Funzioni
–  funzioni da tracciare:
•  syscall::open:
•  pid334::printf:entry
Funzioni ed Eventi
•  La sonda
syscall::open:entry
–  attiva una sonda “sulla system call open” e
spara quando la system call viene invocata
syscall::open:return
–  spara quando la system cal restituisce il
controllo al chiamante
sysinfo:::pswitch
–  spara ogni volta che un processo viene
eseguito dalla CPU
Predicati
•  Valutati se la sonda cui sono associati
spara
•  Restituiscono vero o falso
•  Le azioni della clausola vengono eseguite
se il predicato restituisce vero
/execname == “bash”/
/ppid != 0/
/probemod == “sendmail”/
Predicati e variabili built-in
pid, ppid
process id, parent process id
uid, gid
execname
user id, group id
arg0,arg1,…
probemod, probefunc
argomenti della funzione/system call
nome dell’eseguibile
nomi del modulo/funzione su cui la sonda è
attivata
Dtrace: Azioni
•  descritte in un sottoinsieme del C
•  utilizzano funzioni e variabili built-in
{
printf(“Il processo %s(%d) è stato lanciato da %d”,
execname, pid, uid);
}
esempio: primo.c
int main(void) {
int fd;
char cmd[3];
int i=0, r;
bzero(cmd,4);
while(!i) {
fd=open("cmd",O_RDONLY);
if(fd<0) {
fprintf(stderr,"Impossibile aprire il file");
exit(0);
}
r=read(fd,cmd,3);
if(!strncmp(cmd,"END",3))
i=1;
close(fd);
}
}
esempio: primo.d
syscall::read:entry
/execname == "primo"/
{
printf("L'eseguibile %s(%d), ha invocato read\n",
execname,pid);
}
primo.d: ouput
>sudo dtrace -s primo.d
Password:
dtrace: script 'primo-1.d' matched 5 probes
CPU ID
FUNCTION:NAME
0 13940 read_nocancel:entry L'eseguibile primo(325) ha invocato read
0 13940 read_nocancel:entry L'eseguibile primo(325) ha invocato read
…..
Esempio: secondo.c
int main(void)
{
int fd, i=0,r;
char cmd[3];
…
while(!i) {
fd=open("cmd",O_RDONLY);
if(fd<0) { …. }
r=read(fd,cmd,3);
if(!check(cmd))
i=1;
close(fd);
}
}
int check(char *cmd) {
return strncmp(cmd,"END",3);
}
Esempio: secondo.d
pid392:::entry
{
printf("L'eseguibile %s(%d) ha invocato %s--%s\n",
execname,
pid,
probemod,
probefunc);
}
secondo.d: output
dtrace: script 'secondo-2.d' matched 5739 probes
CPU ID
FUNCTION:NAME
0 17067 open$UNIX2003:entry L'eseguibile secondo(392)
ha invocato libSystem.B.dylib--open$UNIX2003
0 16938 read:entry L'eseguibile secondo(392)
ha invocato libSystem.B.dylib--read
0 16778 check:entry L'eseguibile secondo(392)
ha invocato secondo--check
0 16993 strncmp:entry L'eseguibile secondo(392)
ha invocato libSystem.B.dylib--strncmp
0 16939 close$NOCANCEL$UNIX2003:entry L'eseguibile secondo(392)
ha invocato libSystem.B.dylib--close$NOCANCEL$UNIX2003
Alcune domande..
•  C’è un browser in esecuzione:
–  Quali file apre?
–  A quali server si connette?
Esempio: si vuole tracciare il processo
execname = firefox-bin
pid = 158
esempio: firefox.d
pid158::open*:entry
{
printf("Aperto il file: %s, mode=%o\n", copyinstr(arg0),arg1);
}
firefox.d: ouput
CPU ID
FUNCTION:NAME
0 16776
opendir$UNIX2003:entry Aperto il file:
/System/Library/PrivateFrameworks/Shortcut.framework, mode=0
0 16774 open$NOCANCEL$UNIX2003:entry Aperto il file:
/System/Library/PrivateFrameworks/Shortcut.framework, mode=4000004
0 16776
opendir$UNIX2003:entry Aperto il file:
/System/Library/PrivateFrameworks/Shortcut.framework/Resources, mode=0
0 16774 open$NOCANCEL$UNIX2003:entry Aperto il file:
/System/Library/PrivateFrameworks/Shortcut.framework/Resources,
mode=4000004
0 16775
open$UNIX2003:entry Aperto il file:
/dev/autofs_nowait, mode=0
…
esempio: firefox-2.d
syscall::socket*:entry
/execname=="firefox-bin"/
{
printf("creato un socket famiglia %d\n",arg0);
}
syscall::connect*:entry
/execname=="firefox-bin"/
{
this->sa=(struct sockaddr_in *) copyin(arg1,arg2);
printf("Connect: \n");
printf("\t: socket_fd=%d\n",arg0);
printf("\t: sa.sin_addr=%x\n",
(this->sa->sin_addr.s_addr));
}
firefox-2.d: output
0 13342
socket:entry creato un socket famiglia 2
0 13966
connect_nocancel:entry Connect: : socket_f6
: sa.sin_addr=d55c10bf
0 13342
socket:entry creato un socket famiglia 2
0 13966
connect_nocancel:entry Connect: : socket_fd=35
: sa.sin_addr=d55c10bf
Esempio: firefox-3.d
pid158::malloc:entry
{
@total=sum(arg0)
}
firefox-3.d: output
>sudo dtrace -s firefox-3.d Password:
dtrace: script 'firefox-1.d' matched 2 probes
^C
79749177
Aggregazione dati
count()
Contatore monotono
sum()
avg()
sommatore
min()/max()
media aritmetica
esempio: firefox-4.d
syscall:::entry
/execname=="firefox-bin"/
{
@[probefunc]=count();
}
firefox-4.d: output
dtrace: script 'firefox-4.d' matched 427 probes
^C
fsync_nocancel
2
ftruncate
2
rename
2
pread
5
access
8
__disable_threadsignal
10
bsdthread_create
10
bsdthread_terminate
10
getdirentriesattr
10
stat
10
close
17
fstat
17
open
17
mprotect
31
Questa presentazione
•  Luigi Catuogno
–  [email protected]
–  (oppure venite a trovarmi…)
•  Tutti gli esempi sono stati realizzati e
testati (per questioni di tempo) su
–  Mac PowerBook G4
•  Mac OS X 10.5.8
FONTI
RISORSE WEB
http://dtrace.org
http://hub.opensolaris.org/bin/view/Community+Group+dtrace/dtracetoolkit
http://www.opensource.apple.com/source/dtrace/
http://www.crisp.demon.co.uk/blog/index.html
http://sourceware.org/systemtap/
http://video.google.com/videoplay?docid=-8002801113289007228#
Scarica

DTrace - HCSSLUG