1 <?xml version=
"1.0" encoding=
"ISO-8859-1"?>
2 <!DOCTYPE article PUBLIC
"-//OASIS//DTD DocBook XML V4.3//EN"
3 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4 <!ENTITY % defs SYSTEM
"/xserver/doc/xml/xserver.ent"> %defs;
7 <article id=
"Xserver-DTrace">
9 <title>Xserver Provider for DTrace
</title>
11 <firstname>Alan
</firstname><surname>Coopersmith
</surname>
13 <orgname>Oracle Corporation
</orgname>
14 <orgdiv>Solaris Engineering
</orgdiv>
17 <releaseinfo>X Server Version &xserver.version;
</releaseinfo>
18 <copyright><year>2005</year><year>2006</year><year>2007</year><year>2010</year>
19 <holder>Oracle and/or its affiliates. All rights reserved.
</holder>
21 <legalnotice id=
"copyright">
23 Permission is hereby granted, free of charge, to any person obtaining a
24 copy of this software and associated documentation files (the
"Software"),
25 to deal in the Software without restriction, including without limitation
26 the rights to use, copy, modify, merge, publish, distribute, sublicense,
27 and/or sell copies of the Software, and to permit persons to whom the
28 Software is furnished to do so, subject to the following conditions:
30 The above copyright notice and this permission notice (including the next
31 paragraph) shall be included in all copies or substantial portions of the
34 THE SOFTWARE IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
37 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
40 DEALINGS IN THE SOFTWARE.
45 <sect1 id=
"introduction">
46 <title>Introduction
</title>
48 This page provides details on a
49 <ulink url=
"http://wikis.sun.com/display/DTrace/Statically+Defined+Tracing+for+User+Applications">statically defined user application tracing provider
</ulink>
51 <ulink url=
"http://hub.opensolaris.org/bin/view/Community+Group+dtrace/">DTrace
</ulink>
52 facility in
<productname>Solaris
</productname> 10,
53 <productname>MacOS X
</productname> 10.5, and later releases. This
54 provider instruments various points in the X server, to allow
55 tracing what client applications are up to. DTrace probes may be used
56 with
<ulink url=
"http://sourceware.org/systemtap/">SystemTap
</ulink>
61 The provider was integrated into the X.Org git master repository
62 with Solaris
10 & OpenSolaris support for the Xserver
1.4 release,
63 released in
2007 with X11R7.3. Support for DTrace on MacOS X
64 was added in Xserver
1.7.
68 These probes expose the request and reply structure of the X protocol
69 between clients and the X server, so an understanding of that basic
70 nature will aid in learning how to use these probes.
75 <title>Available probes
</title>
78 Due to the way User-Defined DTrace probes work, arguments to
79 these probes all bear undistinguished names of
80 <parameter>arg0
</parameter>,
<parameter>arg1
</parameter>,
81 <parameter>arg2
</parameter>, etc. These tables should help you
82 determine what the real data is for each of the probe arguments.
84 <table id=
"Probes_and_their_arguments">
85 <title>Probes and their arguments
</title>
87 <colspec colname=
"probe" colwidth=
"2*"/>
88 <colspec colname=
"desc" colwidth=
"3*"/>
89 <colspec colname=
"arg0" colwidth=
"1*"/>
90 <colspec colname=
"arg1" colwidth=
"1*"/>
91 <colspec colname=
"arg2" colwidth=
"1*"/>
92 <colspec colname=
"arg3" colwidth=
"1*"/>
93 <colspec colname=
"arg4" colwidth=
"1*"/>
94 <colspec colname=
"arg5" colwidth=
"1*"/>
95 <colspec colname=
"arg6" colwidth=
"1*"/>
96 <spanspec spanname=
"all" namest=
"probe" nameend=
"arg4"/>
99 <entry>Probe name
</entry>
100 <entry>Description
</entry>
112 <entry spanname=
"all" class=
"grouphead">Request Probes
</entry>
115 <entry>request-start
</entry>
116 <entry>Called just before processing each client request.
</entry>
117 <entry><parameter>requestName
</parameter></entry>
118 <entry><parameter>requestCode
</parameter></entry>
119 <entry><parameter>requestLength
</parameter></entry>
120 <entry><parameter>clientId
</parameter></entry>
121 <entry><parameter>requestBuffer
</parameter></entry>
122 <entry nameend=
"arg5" class=
"unused"/>
123 <entry nameend=
"arg6" class=
"unused"/>
126 <entry>request-done
</entry>
127 <entry>Called just after processing each client request.
</entry>
128 <entry><parameter>requestName
</parameter></entry>
129 <entry><parameter>requestCode
</parameter></entry>
130 <entry><parameter>sequenceNumber
</parameter></entry>
131 <entry><parameter>clientId
</parameter></entry>
132 <entry><parameter>resultCode
</parameter></entry>
133 <entry nameend=
"arg5" class=
"unused"/>
134 <entry nameend=
"arg6" class=
"unused"/>
137 <entry spanname=
"all" class=
"grouphead">Event Probes
</entry>
140 <entry>send-event
</entry>
141 <entry>Called just before send each event to a client.
</entry>
142 <entry><parameter>clientId
</parameter></entry>
143 <entry><parameter>eventCode
</parameter></entry>
144 <entry><parameter>eventBuffer
</parameter></entry>
145 <entry nameend=
"arg3" class=
"unused"/>
146 <entry nameend=
"arg4" class=
"unused"/>
147 <entry nameend=
"arg5" class=
"unused"/>
148 <entry nameend=
"arg6" class=
"unused"/>
151 <entry spanname=
"all" class=
"grouphead">Client Connection Probes
</entry>
154 <entry>client-connect
</entry>
155 <entry>Called when a new connection is opened from a client
</entry>
156 <entry><parameter>clientId
</parameter></entry>
157 <entry><parameter>clientFD
</parameter></entry>
158 <entry nameend=
"arg2" class=
"unused"/>
159 <entry nameend=
"arg3" class=
"unused"/>
160 <entry nameend=
"arg4" class=
"unused"/>
161 <entry nameend=
"arg5" class=
"unused"/>
162 <entry nameend=
"arg6" class=
"unused"/>
165 <entry>client-auth
</entry>
166 <entry>Called when client authenticates (normally just after connection opened)
</entry>
167 <entry><parameter>clientId
</parameter></entry>
168 <entry><parameter>clientAddr
</parameter></entry>
169 <entry><parameter>clientPid
</parameter></entry>
170 <entry><parameter>clientZoneId
</parameter></entry>
171 <entry nameend=
"arg4" class=
"unused"/>
172 <entry nameend=
"arg5" class=
"unused"/>
173 <entry nameend=
"arg6" class=
"unused"/>
176 <entry>client-disconnect
</entry>
177 <entry>Called when a client connection is closed
</entry>
178 <entry><parameter>clientId
</parameter></entry>
179 <entry nameend=
"arg1" class=
"unused"/>
180 <entry nameend=
"arg2" class=
"unused"/>
181 <entry nameend=
"arg3" class=
"unused"/>
182 <entry nameend=
"arg4" class=
"unused"/>
183 <entry nameend=
"arg5" class=
"unused"/>
184 <entry nameend=
"arg6" class=
"unused"/>
187 <entry spanname=
"all" class=
"grouphead">Resource Allocation Probes
</entry>
190 <entry>resource-alloc
</entry>
191 <entry>Called when a new resource (pixmap, gc, colormap, etc.) is allocated
</entry>
192 <entry><parameter>resourceId
</parameter></entry>
193 <entry><parameter>resourceTypeId
</parameter></entry>
194 <entry><parameter>resourceValue
</parameter></entry>
195 <entry><parameter>resourceTypeName
</parameter></entry>
196 <entry nameend=
"arg4" class=
"unused"/>
197 <entry nameend=
"arg5" class=
"unused"/>
198 <entry nameend=
"arg6" class=
"unused"/>
201 <entry>resource-free
</entry>
202 <entry>Called when a resource is freed
</entry>
203 <entry><parameter>resourceId
</parameter></entry>
204 <entry><parameter>resourceTypeId
</parameter></entry>
205 <entry><parameter>resourceValue
</parameter></entry>
206 <entry><parameter>resourceTypeName
</parameter></entry>
207 <entry nameend=
"arg4" class=
"unused"/>
208 <entry nameend=
"arg5" class=
"unused"/>
209 <entry nameend=
"arg6" class=
"unused"/>
212 <entry spanname=
"all" class=
"grouphead">Input API probes
</entry>
215 <entry>input-event
</entry>
216 <entry>Called when an input event was submitted for processing
</entry>
217 <entry><parameter>deviceid
</parameter></entry>
218 <entry><parameter>eventtype
</parameter></entry>
219 <entry><parameter>button
</parameter> or
220 <parameter>keycode
</parameter> or
221 <parameter>touchid
</parameter></entry>
222 <entry><parameter>flags
</parameter></entry>
223 <entry><parameter>nvalues
</parameter></entry>
224 <entry><parameter>mask
</parameter></entry>
225 <entry><parameter>values
</parameter></entry>
233 <sect1 id=
"arguments">
234 <title>Data Available in Probe Arguments
</title>
237 To access data in arguments of type
<type>string
</type>, you will need
238 to use
<ulink url=
"http://wikis.sun.com/display/DTrace/Actions+and+Subroutines#ActionsandSubroutines-{{copyinstr}}"><function>copyinstr()
</function></ulink>.
239 To access data buffers referenced via
<type>uintptr_t
</type>'s, you will
240 need to use
<ulink url=
"http://wikis.sun.com/display/DTrace/Actions+and+Subroutines#ActionsandSubroutines-{{copyin}}"><function>copyin()
</function></ulink>.
242 <table id=
"Probe_Arguments">
243 <title>Probe Arguments
</title>
245 <colspec colname=
"arg" colwidth=
"2*"/>
246 <colspec colname=
"type" colwidth=
"1*"/>
247 <colspec colname=
"desc" colwidth=
"7*"/>
250 <entry>Argument name
</entry>
252 <entry>Description
</entry>
257 <entry><parameter>clientAddr
</parameter></entry>
258 <entry><type>string
</type></entry>
259 <entry>String representing address client connected from
</entry>
262 <entry><parameter>clientFD
</parameter></entry>
263 <entry><type>int
</type></entry>
264 <entry>X server's file descriptor for server side of each connection
</entry>
267 <entry><parameter>clientId
</parameter></entry>
268 <entry><type>int
</type></entry>
269 <entry>Unique integer identifier for each connection to the
273 <entry><parameter>clientPid
</parameter></entry>
274 <entry><type>pid_t
</type></entry>
275 <entry>Process id of client, if connection is local
276 (from
<function>getpeerucred()
</function>)
</entry>
279 <entry><parameter>clientZoneId
</parameter></entry>
280 <entry><type>zoneid_t
</type></entry>
281 <entry>Solaris: Zone id of client, if connection is local
282 (from
<function>getpeerucred()
</function>)
</entry>
285 <entry><parameter>eventBuffer
</parameter></entry>
286 <entry><type>uintptr_t
</type></entry>
287 <entry>Pointer to buffer containing X event - decode using
289 <<ulink url=
"http://cgit.freedesktop.org/xorg/proto/xproto/tree/Xproto.h"><filename class=
"headerfile">X11/Xproto.h
</filename></ulink>>
290 and similar headers for each extension
</entry>
293 <entry><parameter>eventCode
</parameter></entry>
294 <entry><type>uint8_t
</type></entry>
295 <entry>Event number of X event
</entry>
298 <entry><parameter>resourceId
</parameter></entry>
299 <entry><type>uint32_t
</type></entry>
300 <entry>X resource id (XID)
</entry>
303 <entry><parameter>resourceTypeId
</parameter></entry>
304 <entry><type>uint32_t
</type></entry>
305 <entry>Resource type id
</entry>
308 <entry><parameter>resourceTypeName
</parameter></entry>
309 <entry><type>string
</type></entry>
310 <entry>String representing X resource type
311 (
<literal>"PIXMAP"</literal>, etc.)
</entry>
314 <entry><parameter>resourceValue
</parameter></entry>
315 <entry><type>uintptr_t
</type></entry>
316 <entry>Pointer to data for X resource
</entry>
319 <entry><parameter>resultCode
</parameter></entry>
320 <entry><type>int
</type></entry>
321 <entry>Integer code representing result status of request
</entry>
324 <entry><parameter>requestBuffer
</parameter></entry>
325 <entry><type>uintptr_t
</type></entry>
326 <entry>Pointer to buffer containing X request - decode using
328 <<ulink url=
"http://cgit.freedesktop.org/xorg/proto/xproto/tree/Xproto.h"><filename class=
"headerfile">X11/Xproto.h
</filename></ulink>>
329 and similar headers for each extension
</entry>
332 <entry><parameter>requestCode
</parameter></entry>
333 <entry><type>uint8_t
</type></entry>
334 <entry>Request number of X request or Extension
</entry>
337 <entry><parameter>requestName
</parameter></entry>
338 <entry><type>string
</type></entry>
339 <entry>Name of X request or Extension
</entry>
342 <entry><parameter>requestLength
</parameter></entry>
343 <entry><type>uint16_t
</type></entry>
344 <entry>Length of X request
</entry>
347 <entry><parameter>sequenceNumber
</parameter></entry>
348 <entry><type>uint32_t
</type></entry>
349 <entry>Number of X request in in this connection
</entry>
352 <entry><parameter>deviceid
</parameter></entry>
353 <entry><type>int
</type></entry>
354 <entry>The device's numerical ID
</entry>
357 <entry><parameter>eventtype
</parameter></entry>
358 <entry><type>int
</type></entry>
359 <entry>Protocol event type
</entry>
362 <entry><parameter>button, keycode, touchid
</parameter></entry>
363 <entry><type>uint32_t
</type></entry>
364 <entry>The button number, keycode or touch ID
</entry>
367 <entry><parameter>flags
</parameter></entry>
368 <entry><type>uint32_t
</type></entry>
369 <entry>Miscellaneous event-specific server flags
</entry>
372 <entry><parameter>nvalues
</parameter></entry>
373 <entry><type>int8_t
</type></entry>
374 <entry>Number of bits in
<parameter>mask
</parameter> and number of elements
375 in
<parameter>values
</parameter></entry>
378 <entry><parameter>mask
</parameter></entry>
379 <entry><type>uint8_t*
</type></entry>
380 <entry>Binary mask indicating which indices in
<parameter>values
</parameter> contain
384 <entry><parameter>values
</parameter></entry>
385 <entry><type>double*
</type></entry>
386 <entry>Valuator values. Values for indices for which the
387 <parameter>mask
</parameter> is not set are undefined
</entry>
395 <sect1 id=
"examples">
396 <title>Examples
</title>
398 <example id=
"Counting_requests_by_request_name">
399 <title>Counting requests by request name
</title>
402 This script simply increments a counter for each different request
403 made, and when you exit the script (such as by hitting
404 <keycombo action='simul'
><keycap>Control
</keycap><keycap>C
</keycap>
405 </keycombo>) prints the counts.
408 #!/usr/sbin/dtrace -s
410 Xserver*:::request-start
412 @counts[copyinstr(arg0)] = count();
416 The output from a short run may appear as:
432 This can be rewritten slightly to cache the string containing the name
433 of the request since it will be reused many times, instead of copying
434 it over and over from the kernel:
437 #!/usr/sbin/dtrace -s
439 string Xrequest[uintptr_t];
441 Xserver*:::request-start
442 /Xrequest[arg0] ==
""/
444 Xrequest[arg0] = copyinstr(arg0);
447 Xserver*:::request-start
449 @counts[Xrequest[arg0]] = count();
455 <example id=
"Get_average_CPU_time_per_request">
456 <title>Get average CPU time per request
</title>
458 <para>This script records the CPU time used between the probes at
459 the start and end of each request and aggregates it per request type.
462 #!/usr/sbin/dtrace -s
464 Xserver*:::request-start
466 reqstart = vtimestamp;
469 Xserver*:::request-done
471 @times[copyinstr(arg0)] = avg(vtimestamp - reqstart);
475 The output from a sample run might look like:
480 SetClipRectangles
1319
495 MIT-SCREEN-SAVER
16747
496 ConfigureWindow
22917
504 <example id=
"Monitoring_clients_that_connect_and_disconnect">
505 <title>Monitoring clients that connect and disconnect
</title>
508 This script simply prints information about each client that
509 connects or disconnects from the server while it is running.
510 Since the provider is specified as
<code>Xserver$
1</code> instead
511 of
<code>Xserver*
</code> like previous examples, it won't monitor
512 all Xserver processes running on the machine, but instead expects
513 the process id of the X server to monitor to be specified as the
514 argument to the script.
517 #!/usr/sbin/dtrace -s
519 Xserver$
1:::client-connect
521 printf(
"** Client Connect: id %d\n", arg0);
524 Xserver$
1:::client-auth
526 printf(
"** Client auth'ed: id %d => %s pid %d\n",
527 arg0, copyinstr(arg1), arg2);
530 Xserver$
1:::client-disconnect
532 printf(
"** Client Disconnect: id %d\n", arg0);
539 <prompt>#
</prompt> <userinput>./foo.d
5790</userinput>
540 <computeroutput>dtrace: script './foo.d' matched
4 probes
542 0 15774 CloseDownClient:client-disconnect ** Client Disconnect: id
65
544 2 15774 CloseDownClient:client-disconnect ** Client Disconnect: id
64
546 0 15773 EstablishNewConnections:client-connect ** Client Connect: id
64
548 0 15772 AuthAudit:client-auth ** Client auth'ed: id
64 =
> local host pid
2034
550 0 15773 EstablishNewConnections:client-connect ** Client Connect: id
65
552 0 15772 AuthAudit:client-auth ** Client auth'ed: id
65 =
> local host pid
2034
554 0 15774 CloseDownClient:client-disconnect ** Client Disconnect: id
64
561 <example id=
"Monitoring_clients_creating_Pixmaps">
562 <title>Monitoring clients creating Pixmaps
</title>
565 This script can be used to determine which clients are creating
566 pixmaps in the X server, printing information about each client
567 as it connects to help trace it back to the program on the other
568 end of the X connection.
571 #!/usr/sbin/dtrace -qs
573 string Xrequest[uintptr_t];
574 string Xrestype[uintptr_t];
576 Xserver$
1:::request-start
577 /Xrequest[arg0] ==
""/
579 Xrequest[arg0] = copyinstr(arg0);
582 Xserver$
1:::resource-alloc
583 /arg3 !=
0 && Xrestype[arg3] ==
""/
585 Xrestype[arg3] = copyinstr(arg3);
589 Xserver$
1:::request-start
590 /Xrequest[arg0] ==
"X_CreatePixmap"/
592 printf(
"-> %s: client %d\n", Xrequest[arg0], arg3);
595 Xserver$
1:::request-done
596 /Xrequest[arg0] ==
"X_CreatePixmap"/
598 printf(
"<- %s: client %d\n", Xrequest[arg0], arg3);
601 Xserver$
1:::resource-alloc
602 /Xrestype[arg3] ==
"PIXMAP"/
604 printf(
"** Pixmap alloc: %08x\n", arg0);
608 Xserver$
1:::resource-free
609 /Xrestype[arg3] ==
"PIXMAP"/
611 printf(
"** Pixmap free: %08x\n", arg0);
614 Xserver$
1:::client-connect
616 printf(
"** Client Connect: id %d\n", arg0);
619 Xserver$
1:::client-auth
621 printf(
"** Client auth'ed: id %d => %s pid %d\n",
622 arg0, copyinstr(arg1), arg2);
625 Xserver$
1:::client-disconnect
627 printf(
"** Client Disconnect: id %d\n", arg0);
631 Sample output from a run of this script:
632 <screen><computeroutput>
633 ** Client Connect: id
17
634 ** Client auth'ed: id
17 =
> local host pid
20273
635 -
> X_CreatePixmap: client
17
636 ** Pixmap alloc:
02200009
637 <- X_CreatePixmap: client
17
638 -
> X_CreatePixmap: client
15
639 ** Pixmap alloc:
01e00180
640 <- X_CreatePixmap: client
15
641 -
> X_CreatePixmap: client
15
642 ** Pixmap alloc:
01e00181
643 <- X_CreatePixmap: client
15
644 -
> X_CreatePixmap: client
14
645 ** Pixmap alloc:
01c004c8
646 <- X_CreatePixmap: client
14
647 ** Pixmap free:
02200009
648 ** Client Disconnect: id
17
649 ** Pixmap free:
01e00180
650 ** Pixmap free:
01e00181
651 </computeroutput></screen>
657 <example id=
"Input_API_monitoring_with_systemtap">
658 <title>Input API monitoring with SystemTap
</title>
661 This script can be used to monitor events submitted by drivers to
662 the server for enqueuing. Due to the integration of the input API
663 probes, some server-enqueued events will show up too.
666 # stap -g xorg.stp /usr/bin/Xorg
670 function print_valuators:string(nvaluators:long, mask_in:long, valuators_in:long) %{
672 unsigned char *mask = (unsigned char*)THIS-
>mask_in;
673 double *valuators = (double*)THIS-
>valuators_in;
677 #define BitIsSet(ptr, bit) (((unsigned char*)(ptr))[(bit)
>>3]
& (
1 << ((bit)
& 7)))
679 s += sprintf(s,
"nval: %d ::", (int)THIS-
>nvaluators);
680 for (i =
0; i
< THIS-
>nvaluators; i++)
682 s += sprintf(s,
" %d: ", i);
683 if (BitIsSet(mask, i))
684 s += sprintf(s,
"%d", (int)valuators[i]);
687 sprintf(THIS-
>__retvalue,
"%s", str);
690 probe process(@
1).mark(
"input__event")
698 str = print_valuators(nvaluators, $arg6, $arg7)
699 printf(
"Event: device %d type %d detail %d flags %#x %s\n",
700 deviceid, type, detail, flags, str);
704 Sample output from a run of this script:
705 <screen><computeroutput>
706 Event: device
13 type
4 detail
1 flags
0x0 nval:
0 ::
707 Event: device
13 type
6 detail
0 flags
0xa nval:
1 ::
0:
1
708 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
2 1: -
1
709 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
2 1: -
1
710 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
4 1: -
3
711 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
3 1: -
3
712 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
3 1: -
2
713 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
2 1: -
2
714 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
2 1: -
2
715 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
2 1: -
2
716 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
1: -
1
717 Event: device
13 type
6 detail
0 flags
0xa nval:
2 ::
0:
1: -
1
718 Event: device
13 type
5 detail
1 flags
0x0 nval:
0 ::
719 </computeroutput></screen>