Default style (Cherry Eve). Switch styles (Capricorn). XML Feed Calendar
All | General
20041209 Thursday December 09, 2004

DTrace & Mozilla

I gave a brief talk about how to use dtrace to debug mozilla on Wed. Here are the examples I used for the talk.

Examples

Ex1. How many files opend by mozilla and what they are?

dtrace -n syscall::open:entry'/execname=="mozilla-bin"/{trace(copyinstr(arg0))}'

Another form:

#!/usr/sbin/dtrace -s

syscall::open:entry
/execname=="mozilla-bin"/
{
  trace(copyinstr(arg0));
}
(# ./open.d)

Highlights:

  • syscall provider - lets you trace every system call entry and return
  • predicate - / ... /
  • copyinstr - copy user process data into the address space of kernel

Ex2. The .mozill bug - which convertor is mozilla using?

#!/usr/sbin/dtrace -s

BEGIN
{
  self->start = 0;
}

/* nsLocalFile::GetPath */
pid$1::__1cLnsLocalFileHGetPath6MrnJnsAString__I_:entry
{
  self->start = 1;
}

pid$1::__1cLnsLocalFileHGetPath6MrnJnsAString__I_:return
{
  self->start = 0;
}

/* http://aggregate.eng/ws/on10_nightly/source/usr/src/lib/libc/port/gen/iconv.c */
pid$1::_icv_iconv:entry
/self->start/
{
  trace(probemod);
}
(# ./iconv.d `pgrep mozilla-bin` (1.4))
(# ./iconv.d `pgrep mozilla-bin` (1.7))

Highlights:

  • pid provider - allows you to trace any instruction in a process
  • D language variable type
    • associative array
    • thread-local variable - self
    • clause-local variable - this
    • built-in variables - execname, probemod, probefunc, pid, etc.

Ex3. Constructor & Destructor

#!/usr/sbin/dtrace -s

BEGIN
{
  self->div = 0;
}

pid$1:libgklayout:__1cQnsHTMLDivElement2t*6M_v_:entry
{
  self->div++;
  printf("Div++: %d", self->div);
}

pid$1:libgklayout:__1cQnsHTMLDivElement2T*6M_v_:entry
{
  self->div--;
  printf("Div--: %d", self->div);
}
(# ./ctordtor.d `pgrep mozilla-bin`)

Highlights:

  • some utilities: nm - symbol lookup; c++filt - C++ symbol demangler
  • no optimized build

Ex4. What's leaked?

#!/usr/sbin/dtrace -s

BEGIN
{
 self->div = 0;
}

pid$1:libgklayout:__1cQnsHTMLDivElement2t*6M_v_:entry
{
 @t[arg0] = count();
 self->div++;
 printf("Div++: %d", self->div);
}

pid$1:libgklayout:__1cQnsHTMLDivElement2T*6M_v_:entry
{
 @t[arg0] = count();
 self->div--;
 printf("Div--: %d", self->div);
}
(# ./count.d `pgrep mozilla-bin`)

Highlights:

  • arg0 - arg9: for entry probe - first ten arguments, int64 (in C++ program, the last argument is always "this".); for return prob - arg1 - return value;
  • aggregating functions
    • count - the number of times called.
    • sum - the total value of specified expressions.
    • quantize - see Ex 6.

Ex5. More aggregations 1 - How many system calls did mozilla make?

dtrace -n syscall:::entry'/execname=="mozilla-bin"/{@t[probefunc] = count()}'

Ex6. More aggregations 2 - How many bytes write to disk for every "write" system call?

dtrace -n syscall::write:entry'/execname=="mozilla-bin"/{@t[execname] = quantize(arg2);}'

Ex7. Timing & aggregations - How many time do js* functions consume?

#!/usr/sbin/dtrace -s

pid$1:libmozjs:js*:entry
{
  time[probefunc] = vtimestamp;
}

pid$1:libmozjs:js*:return
/time[probefunc]/
{
  @t[probefunc] =  sum(vtimestamp - time[probefunc]);
  time[probefunc] = 0;
}
(# ./time.d `pgrep mozilla-bin`)

Ex8. Which gtk functions have been called by gtk_window_new?

#!/usr/sbin/dtrace -Fs

pid$1::$2:entry
{
  self->trace = 1;
}

pid$1::$2:return
/self->trace/
{
  self->trace = 0;
}

pid$1:libgtk-x11-2.0::entry,
pid$1:libgtk-x11-2.0::return
/self->trace/
{
}
(# ./userfunc.d `pgrep mozilla-bin` gtk_window_new)

Ex9. Tracing arbitrary instruction

dtrace -n pid29967:libmozjs:JS_MaybeGC:

Highlights:

  • pid provider can trace any instruction in any user function;
  • useful to determine the code path;

Ex10. Watch the stack - Which files failed to open?

#!/usr/sbin/dtrace -s

syscall::open:entry
/pid == $1/
{
  self->path = copyinstr(arg0);
}

syscall::open:return
/self->path != NULL && arg1 == -1/
{
  printf("open for %s failed!", self->path);
  ustack(30);
}
(# ./badopen.d `pgrep mozilla-bin`)

Highlights:

  • ustack() - records a user stack trace (stack() is for kernel stack);

Ex11. $target - Tracing from the beginning

#!/usr/sbin/dtrace -s

pid$target:libc::entry
{
  @[probefunc] = count();
}
(# dtrace -s libc.d -c date)

Highlights:

  • pid provider can only be used on processes that are already running;

Resources

  • Home page: http://dtrace.eng
  • Mail alias: dtrace-interest
  • Solaris Dynamic Tracing Guide: http://docs.sun.com/app/docs/doc/817-6223?q=dtrace
  • Examples: /usr/demo/dtrace
December 09, 2004 07:26 PM PST Permalink

Calendar

« December 2004 »
SunMonTueWedThuFriSat
   
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
       
Today

Links


Navigation


Referers

Today's Page Hits: 17