Jeremy Uejio's BlogJeremy Uejio's Weblog |
|
Wednesday Nov 14, 2007
DTrace Tutorial for X Window Programmers
Here's some notes on a DTrace presentation I gave to our desktop sustaining group. It's geared towards application debugging esp. for X Window System programmers and not for kernel debugging. DTrace is usually thought of as a tool for kernel debugging. However, I
have found it very useful for user level debugging, too. It's especially
useful when first debugging an issue that you don't know where to begin
and for issues involving applications that are already running.
Useful One-liners:
Here are some one-liners for client debugging. There are a number
of useful ones from Brendan Gregg's website at:
dtrace -qn 'syscall::exec*:return { printf("%Y %s\n",walltimestamp,curpsinfo->pr_psargs); }'
If I run gnome-terminal, I see the following output: 2007 Nov 14 16:56:17 gnome-terminal 2007 Nov 14 16:56:18 gnome-pty-helper 2007 Nov 14 16:56:18 pt_chmod 4 2007 Nov 14 16:56:18 /usr/lib/utmp_update testuser /5 pts/5 19917 7 0 0 1195088178 373248 0 000000000 2007 Nov 14 16:56:18 bash Here's one for looking at files opened by processes:
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'
If I run gnome-terminal again, I get a lot of output: ... 0 43837 open64:entry gnome-terminal /usr/share/themes/blueprint/gtk-2.0/vertStepDwnButton.png 0 43837 open64:entry gnome-terminal /usr/share/themes/blueprint/gtk-2.0/menuBorderButton.png 0 43453 open:entry nscd /etc/user_attr 0 43453 open:entry utmpd /proc/19924/psinfo 0 43453 open:entry gconfd-2 /export/home/testuser/.gconf/apps/panel/profiles/default/applets/... 0 43453 open:entry gconfd-2 /export/home/testuser/.gconfd/saved_state.tmp ... Try doing this with dbx or truss or any other tool, especially the first example!
# dtrace -n 'syscall::XOpenDisplay:entry' You will get the error: dtrace: invalid probe specifier syscall::XOpenDisplay:entry: probe description syscall::XOpenDisplay:entry does not match any probes DTrace only knows about system calls, but you can use the pid provider to look at all the calls in a particular process. For example "dtrace -l" will list out the probes. You can limit that also with -n. Let's look at the probes for metacity for an Xlib call XMoveWindow:
dtrace -l -n "pid`pgrep metacity`::XMove*:" ID PROVIDER MODULE FUNCTION NAME 44083 pid19834 libX11.so.4 XMoveWindow return 44084 pid19834 libX11.so.4 XMoveWindow entry 44085 pid19834 libX11.so.4 XMoveWindow 0 44086 pid19834 libX11.so.4 XMoveWindow 1 ... # ./libX11.d `pgrep gnome-terminal` dtrace: script './libX11.d' matched 1629 probes CPU ID FUNCTION:NAME 0 44400 XPending:entry 0 44401 _XEventsQueued:entry 0 44326 _XFlush:entry 0 44309 _XFlushInt:entry 0 44402 _X11TransBytesReadable:entry 0 44403 _X11TransSocketBytesReadable:entry ... Wow, lots of calls to
XPending() and other functions. We probably don't want to debug those,
so before we remove them, we can format the output nicer by adding to the libX11.d script:
#pragma D option flowindent Now we can see that XPending is calling these functions and that's probably not a very interesting function to look at, so, we can get rid of them by setting a flag in the entry probe to XPending(). Then
in the return probe of XPending unset the flag. When the flag is set, don't print out
the function calls and when it is not set, then print out calls.
# ./libX11_pending.d `pgrep gnome-terminal` XNextEvent called _XDeq called XFilterEvent called XNextEvent called _XDeq called ... XChangeGC called _XUpdateGCCache called XChangeGC called XChangeGC called XSetClipRectangles called _XSetClipRectangles called XSetTSOrigin called XFillRectangle called ... So, we see lots and lots of libX11 functions being called. Well, this also is too much information and probably not useful. Suppose, we wanted to instead limit the calls to a specific
type of call. So, let's look at the next example. libX11_grab.d. This
example prints out all the calls to any Xlib grab functions. It also
prints out the stack trace of the user process (gnome-terminal in this
case) whenever the grab or ungrab function is called. Printing out
stack traces for grabs can be a problem when running in dbx since you
probably can't type in the dbx window if client has a keyboard or
pointer grab. So, DTrace is definitely the better tool here. In this example, I press the mouse button on the Edit menu item and get a popdown menu. # ./libX11_grab.d `pgrep gnome-terminal`
XGrabPointer called
libX11.so.4`XGrabPointer
libgdk-x11-2.0.so.0.400.9`gdk_pointer_grab+0x180
XGrabKeyboard called
libX11.so.4`XGrabKeyboard
libgdk-x11-2.0.so.0.400.9`gdk_keyboard_grab+0x6c
...
More Complex Examples:
Now let's look at a complex example involving two processes. Suppose,
we want to know what happens in one processs when another process calls
some function.
The script trace2processes.d takes 3 arguments--the process id of the two processes and the function to key off of. For example, if I want to know what the Xserver is doing when metacity calls XMoveWindow(), I would execute: # ./trace2processes.d `pgrep Xnest` `pgrep metacity` XMoveWindow metacity: XMoveWindow: enters metacity: XMoveWindow: returns Xnest: xnestGetImage: return = 1 Xnest: WriteToClient: entering Xnest: WriteToClient: return = 2400 Xnest: DoGetImage: return = 0 Xnest: ProcGetImage: return = 0 Xnest: FlushAllOutput: entering ... In my example, I am using the Xnest server since I was demo'ing this via a VNC session to engineers in Ireland and India and had Xnest running in VNC. xscope.d
This shows how to use some of the Xserver probes to implement a simple DTrace version of the X debugging tool called xscope. Xscope is a tool
for viewing the X protocol between client and server.
Handy DTrace scripts from the DTrace Toolkit at:
http://www.brendangregg.com/dtrace.html#DTraceToolkit Posted at 09:59PM Nov 14, 2007 by uejio in Sun | Comments:
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||