initial commit
[profile/ivi/xorg-x11-server.git] / doc / xml / dtrace / Xserver-DTrace.xml
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;
5 ]>
6
7 <article id="Xserver-DTrace">
8   <articleinfo>
9     <title>Xserver provider for DTrace</title>
10     <author>
11       <firstname>Alan</firstname><surname>Coopersmith</surname>
12       <affiliation>
13         <orgname>Oracle Corporation</orgname>
14         <orgdiv>Solaris Engineering</orgdiv>
15       </affiliation>
16     </author>
17     <releaseinfo>X.Org Xserver version &xserver.version;</releaseinfo>
18     <legalnotice>
19       <para>
20 Copyright (c) 2005, 2006, 2007, 2010, Oracle and/or its affiliates.
21 All rights reserved.
22       </para><para>
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:
29       </para><para>
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
32 Software.
33       </para><para>
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.
41       </para>
42     </legalnotice>
43   </articleinfo>
44
45   <sect1 id="introduction">
46     <title>Introduction</title>
47     <para>
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>
50       for the
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.
56     </para>
57
58     <para>
59       The provider was integrated into the X.Org git master repository
60       with Solaris 10 &amp; OpenSolaris support for the Xserver 1.4 release,
61       released in 2007 with X11R7.3.   Support for DTrace on MacOS X
62       was added in Xserver 1.7.
63     </para>
64
65     <para>
66       These probes expose the request and reply structure of the X protocol
67       between clients and the X server, so an understanding of that basic
68       nature will aid in learning how to use these probes.
69     </para>
70   </sect1>
71
72   <sect1 id="probes">
73     <title>Available probes</title>
74
75     <para>
76       Due to the way User-Defined DTrace probes work, arguments to
77       these probes all bear undistinguished names of
78       <parameter>arg0</parameter>, <parameter>arg1</parameter>,
79       <parameter>arg2</parameter>, etc.  These tables should help you
80       determine what the real data is for each of the probe arguments.
81
82     <table>
83       <title>Probes and their arguments</title>
84       <tgroup cols='7'>
85         <colspec colname="probe" colwidth="2*"/>
86         <colspec colname="desc" colwidth="3*"/>
87         <colspec colname="arg0" colwidth="1*"/>
88         <colspec colname="arg1" colwidth="1*"/>
89         <colspec colname="arg2" colwidth="1*"/>
90         <colspec colname="arg3" colwidth="1*"/>
91         <colspec colname="arg4" colwidth="1*"/>
92         <spanspec spanname="all" namest="probe" nameend="arg4"/>
93         <thead>
94           <row>
95             <entry>Probe name</entry>
96             <entry>Description</entry>
97             <entry>arg0</entry>
98             <entry>arg1</entry>
99             <entry>arg2</entry>
100             <entry>arg3</entry>
101             <entry>arg4</entry>
102           </row>
103         </thead>
104         <tbody>
105           <row>
106             <entry spanname="all" class="grouphead">Request Probes</entry>
107           </row>
108           <row>
109             <entry>request-start</entry>
110             <entry>Called just before processing each client request.</entry>
111             <entry><parameter>requestName</parameter></entry>
112             <entry><parameter>requestCode</parameter></entry>
113             <entry><parameter>requestLength</parameter></entry>
114             <entry><parameter>clientId</parameter></entry>
115             <entry><parameter>requestBuffer</parameter></entry>
116           </row>
117           <row>
118             <entry>request-done</entry>
119             <entry>Called just after processing each client request.</entry>
120             <entry><parameter>requestName</parameter></entry>
121             <entry><parameter>requestCode</parameter></entry>
122             <entry><parameter>sequenceNumber</parameter></entry>
123             <entry><parameter>clientId</parameter></entry>
124             <entry><parameter>resultCode</parameter></entry>
125           </row>
126           <row>
127             <entry spanname="all" class="grouphead">Event Probes</entry>
128           </row>
129           <row>
130             <entry>send-event</entry>
131             <entry>Called just before send each event to a client.</entry>
132             <entry><parameter>clientId</parameter></entry>
133             <entry><parameter>eventCode</parameter></entry>
134             <entry><parameter>eventBuffer</parameter></entry>
135             <entry nameend="arg4" class="unused"/>
136           </row>
137           <row>
138             <entry spanname="all" class="grouphead">Client Connection Probes</entry>
139           </row>
140           <row>
141             <entry>client-connect</entry>
142             <entry>Called when a new connection is opened from a client</entry>
143             <entry><parameter>clientId</parameter></entry>
144             <entry><parameter>clientFD</parameter></entry>
145             <entry nameend="arg4" class="unused"/>
146           </row>
147           <row>
148             <entry>client-auth</entry>
149             <entry>Called when client authenticates (normally just after connection opened)</entry>
150             <entry><parameter>clientId</parameter></entry>
151             <entry><parameter>clientAddr</parameter></entry>
152             <entry><parameter>clientPid</parameter></entry>
153             <entry><parameter>clientZoneId</parameter></entry>
154             <entry nameend="arg4" class="unused"/>
155           </row>
156           <row>
157             <entry>client-disconnect</entry>
158             <entry>Called when a client connection is closed</entry>
159             <entry><parameter>clientId</parameter></entry>
160             <entry nameend="arg4" class="unused"/>
161           </row>
162           <row>
163             <entry spanname="all" class="grouphead">Resource Allocation Probes</entry>
164           </row>
165           <row>
166             <entry>resource-alloc</entry>
167             <entry>Called when a new resource (pixmap, gc, colormap, etc.) is allocated</entry>
168             <entry><parameter>resourceId</parameter></entry>
169             <entry><parameter>resourceTypeId</parameter></entry>
170             <entry><parameter>resourceValue</parameter></entry>
171             <entry><parameter>resourceTypeName</parameter></entry>
172             <entry nameend="arg4" class="unused"/>
173           </row>
174           <row>
175             <entry>resource-free</entry>
176             <entry>Called when a resource is freed</entry>
177             <entry><parameter>resourceId</parameter></entry>
178             <entry><parameter>resourceTypeId</parameter></entry>
179             <entry><parameter>resourceValue</parameter></entry>
180             <entry><parameter>resourceTypeName</parameter></entry>
181             <entry nameend="arg4" class="unused"/>
182           </row>
183         </tbody>
184       </tgroup>
185     </table>
186     </para>
187   </sect1>
188
189   <sect1 id="arguments">
190     <title>Data Available in Probe Arguments</title>
191
192     <para>
193       To access data in arguments of type <type>string</type>, you will need
194       to use <ulink url="http://wikis.sun.com/display/DTrace/Actions+and+Subroutines#ActionsandSubroutines-{{copyinstr}}"><function>copyinstr()</function></ulink>.
195       To access data buffers referenced via <type>uintptr_t</type>'s, you will
196       need to use <ulink url="http://wikis.sun.com/display/DTrace/Actions+and+Subroutines#ActionsandSubroutines-{{copyin}}"><function>copyin()</function></ulink>.
197
198     <table>
199       <title>Probe Arguments</title>
200       <tgroup cols='3'>
201         <colspec colname="arg" colwidth="2*"/>
202         <colspec colname="type" colwidth="1*"/>
203         <colspec colname="desc" colwidth="7*"/>
204         <thead>
205           <row>
206             <entry>Argument name</entry>
207             <entry>Type</entry>
208             <entry>Description</entry>
209           </row>
210         </thead>
211         <tbody>
212           <row>
213             <entry><parameter>clientAddr</parameter></entry>
214             <entry><type>string</type></entry>
215             <entry>String representing address client connected from</entry>
216           </row>
217           <row>
218             <entry><parameter>clientFD</parameter></entry>
219             <entry><type>int</type></entry>
220             <entry>X server's file descriptor for server side of each connection</entry>
221           </row>
222           <row>
223             <entry><parameter>clientId</parameter></entry>
224             <entry><type>int</type></entry>
225             <entry>Unique integer identifier for each connection to the
226               X server</entry>
227           </row>
228           <row>
229             <entry><parameter>clientPid</parameter></entry>
230             <entry><type>pid_t</type></entry>
231             <entry>Process id of client, if connection is local
232               (from <function>getpeerucred()</function>)</entry>
233           </row>
234           <row>
235             <entry><parameter>clientZoneId</parameter></entry>
236             <entry><type>zoneid_t</type></entry>
237             <entry>Solaris: Zone id of client, if connection is local
238               (from <function>getpeerucred()</function>)</entry>
239           </row>
240           <row>
241             <entry><parameter>eventBuffer</parameter></entry>
242             <entry><type>uintptr_t</type></entry>
243             <entry>Pointer to buffer containing X event - decode using
244               structures in
245               &lt;<ulink url="http://cgit.freedesktop.org/xorg/proto/xproto/tree/Xproto.h"><filename class="headerfile">X11/Xproto.h</filename></ulink>&gt;
246               and similar headers for each extension</entry>
247           </row>
248           <row>
249             <entry><parameter>eventCode</parameter></entry>
250             <entry><type>uint8_t</type></entry>
251             <entry>Event number of X event</entry>
252           </row>
253           <row>
254             <entry><parameter>resourceId</parameter></entry>
255             <entry><type>uint32_t</type></entry>
256             <entry>X resource id (XID)</entry>
257           </row>
258           <row>
259             <entry><parameter>resourceTypeId</parameter></entry>
260             <entry><type>uint32_t</type></entry>
261             <entry>Resource type id</entry>
262           </row>
263           <row>
264             <entry><parameter>resourceTypeName</parameter></entry>
265             <entry><type>string</type></entry>
266             <entry>String representing X resource type
267                 (<literal>"PIXMAP"</literal>, etc.)</entry>
268           </row>
269           <row>
270             <entry><parameter>resourceValue</parameter></entry>
271             <entry><type>uintptr_t</type></entry>
272             <entry>Pointer to data for X resource</entry>
273           </row>
274           <row>
275             <entry><parameter>resultCode</parameter></entry>
276             <entry><type>int</type></entry>
277             <entry>Integer code representing result status of request</entry>
278           </row>
279           <row>
280             <entry><parameter>requestBuffer</parameter></entry>
281             <entry><type>uintptr_t</type></entry>
282             <entry>Pointer to buffer containing X request - decode using
283               structures in
284               &lt;<ulink url="http://cgit.freedesktop.org/xorg/proto/xproto/tree/Xproto.h"><filename class="headerfile">X11/Xproto.h</filename></ulink>&gt;
285               and similar headers for each extension</entry>
286           </row>
287           <row>
288             <entry><parameter>requestCode</parameter></entry>
289             <entry><type>uint8_t</type></entry>
290             <entry>Request number of X request or Extension</entry>
291           </row>
292           <row>
293             <entry><parameter>requestName</parameter></entry>
294             <entry><type>string</type></entry>
295             <entry>Name of X request or Extension</entry>
296           </row>
297           <row>
298             <entry><parameter>requestLength</parameter></entry>
299             <entry><type>uint16_t</type></entry>
300             <entry>Length of X request</entry>
301           </row>
302           <row>
303             <entry><parameter>sequenceNumber</parameter></entry>
304             <entry><type>uint32_t</type></entry>
305             <entry>Number of X request in in this connection</entry>
306           </row>
307         </tbody>
308       </tgroup>
309     </table>
310     </para>
311   </sect1>
312
313   <sect1 id="examples">
314     <title>Examples</title>
315
316     <example>
317       <title>Counting requests by request name</title>
318
319       <para>
320         This script simply increments a counter for each different request
321         made, and when you exit the script (such as by hitting
322         <keycombo action='simul'><keycap>Control</keycap><keycap>C</keycap>
323         </keycombo>) prints the counts.
324
325         <programlisting>
326 #!/usr/sbin/dtrace -s
327
328 Xserver*:::request-start
329 {
330     @counts[copyinstr(arg0)] = count();
331 }
332         </programlisting>
333
334         The output from a short run may appear as:
335         <screen>
336   QueryPointer                                                      1
337   CreatePixmap                                                      2
338   FreePixmap                                                        2
339   PutImage                                                          2
340   ChangeGC                                                         10
341   CopyArea                                                         10
342   CreateGC                                                         14
343   FreeGC                                                           14
344   RENDER                                                           28
345   SetClipRectangles                                                40
346         </screen>
347       </para>
348
349       <para>
350         This can be rewritten slightly to cache the string containing the name
351         of the request since it will be reused many times, instead of copying
352         it over and over from the kernel:
353
354         <programlisting>
355 #!/usr/sbin/dtrace -s
356
357 string Xrequest[uintptr_t];
358
359 Xserver*:::request-start
360 /Xrequest[arg0] == ""/
361 {
362     Xrequest[arg0] = copyinstr(arg0);
363 }
364
365 Xserver*:::request-start
366 {
367     @counts[Xrequest[arg0]] = count();
368 }
369         </programlisting>
370       </para>
371     </example>
372
373     <example>
374       <title>Get average CPU time per request</title>
375
376       <para>This script records the CPU time used between the probes at
377         the start and end of each request and aggregates it per request type.
378
379         <programlisting>
380 #!/usr/sbin/dtrace -s
381
382 Xserver*:::request-start
383 {
384     reqstart = vtimestamp;
385 }
386
387 Xserver*:::request-done
388 {
389     @times[copyinstr(arg0)] = avg(vtimestamp - reqstart);
390 }
391         </programlisting>
392
393         The output from a sample run might look like:
394
395         <screen>
396   ChangeGC                                                        889
397   MapWindow                                                       907
398   SetClipRectangles                                              1319
399   PolyPoint                                                      1413
400   PolySegment                                                    1434
401   PolyRectangle                                                  1828
402   FreeCursor                                                     1895
403   FreeGC                                                         1950
404   CreateGC                                                       2244
405   FreePixmap                                                     2246
406   GetInputFocus                                                  2249
407   TranslateCoords                                                8508
408   QueryTree                                                      8846
409   GetGeometry                                                    9948
410   CreatePixmap                                                  12111
411   AllowEvents                                                   14090
412   GrabServer                                                    14791
413   MIT-SCREEN-SAVER                                              16747
414   ConfigureWindow                                               22917
415   SetInputFocus                                                 28521
416   PutImage                                                     240841
417
418         </screen>
419       </para>
420     </example>
421
422     <example>
423       <title>Monitoring clients that connect and disconnect</title>
424
425       <para>
426         This script simply prints information about each client that
427         connects or disconnects from the server while it is running.
428         Since the provider is specified as <code>Xserver$1</code> instead
429         of <code>Xserver*</code> like previous examples, it won't monitor
430         all Xserver processes running on the machine, but instead expects
431         the process id of the X server to monitor to be specified as the
432         argument to the script.
433
434         <programlisting>
435 #!/usr/sbin/dtrace -s
436
437 Xserver$1:::client-connect
438 {
439         printf("** Client Connect: id %d\n", arg0);
440 }
441
442 Xserver$1:::client-auth
443 {
444         printf("** Client auth'ed: id %d =&gt; %s pid %d\n",
445                 arg0, copyinstr(arg1), arg2);
446 }
447
448 Xserver$1:::client-disconnect
449 {
450         printf("** Client Disconnect: id %d\n", arg0);
451 }
452         </programlisting>
453
454         A sample run:
455
456         <screen>
457 <prompt>#</prompt> <userinput>./foo.d 5790</userinput>
458 <computeroutput>dtrace: script './foo.d' matched 4 probes
459 CPU     ID                    FUNCTION:NAME
460   0  15774 CloseDownClient:client-disconnect ** Client Disconnect: id 65
461
462   2  15774 CloseDownClient:client-disconnect ** Client Disconnect: id 64
463
464   0  15773 EstablishNewConnections:client-connect ** Client Connect: id 64
465
466   0  15772            AuthAudit:client-auth ** Client auth'ed: id 64 =&gt; local host pid 2034
467
468   0  15773 EstablishNewConnections:client-connect ** Client Connect: id 65
469
470   0  15772            AuthAudit:client-auth ** Client auth'ed: id 65 =&gt; local host pid 2034
471
472   0  15774 CloseDownClient:client-disconnect ** Client Disconnect: id 64
473           </computeroutput>
474         </screen>
475
476       </para>
477     </example>
478
479     <example>
480       <title>Monitoring clients creating Pixmaps</title>
481
482       <para>
483         This script can be used to determine which clients are creating
484         pixmaps in the X server, printing information about each client
485         as it connects to help trace it back to the program on the other
486         end of the X connection.
487
488         <programlisting>
489 #!/usr/sbin/dtrace -qs
490
491 string Xrequest[uintptr_t];
492 string Xrestype[uintptr_t];
493
494 Xserver$1:::request-start
495 /Xrequest[arg0] == ""/
496 {
497         Xrequest[arg0] = copyinstr(arg0);
498 }
499
500 Xserver$1:::resource-alloc
501 /arg3 != 0 &amp;&amp; Xrestype[arg3] == ""/
502 {
503         Xrestype[arg3] = copyinstr(arg3);
504 }
505
506
507 Xserver$1:::request-start
508 /Xrequest[arg0] == "X_CreatePixmap"/
509 {
510         printf("-&gt; %s: client %d\n", Xrequest[arg0], arg3);
511 }
512
513 Xserver$1:::request-done
514 /Xrequest[arg0] == "X_CreatePixmap"/
515 {
516         printf("&lt;- %s: client %d\n", Xrequest[arg0], arg3);
517 }
518
519 Xserver$1:::resource-alloc
520 /Xrestype[arg3] == "PIXMAP"/
521 {
522         printf("** Pixmap alloc: %08x\n", arg0);
523 }
524
525
526 Xserver$1:::resource-free
527 /Xrestype[arg3] == "PIXMAP"/
528 {
529         printf("** Pixmap free:  %08x\n", arg0);
530 }
531
532 Xserver$1:::client-connect
533 {
534         printf("** Client Connect: id %d\n", arg0);
535 }
536
537 Xserver$1:::client-auth
538 {
539         printf("** Client auth'ed: id %d =&gt; %s pid %d\n",
540                 arg0, copyinstr(arg1), arg2);
541 }
542
543 Xserver$1:::client-disconnect
544 {
545         printf("** Client Disconnect: id %d\n", arg0);
546 }
547         </programlisting>
548
549         Sample output from a run of this script:
550         <screen><computeroutput>
551 ** Client Connect: id 17
552 ** Client auth'ed: id 17 =&gt; local host pid 20273
553 -&gt; X_CreatePixmap: client 17
554 ** Pixmap alloc: 02200009
555 &lt;- X_CreatePixmap: client 17
556 -&gt; X_CreatePixmap: client 15
557 ** Pixmap alloc: 01e00180
558 &lt;- X_CreatePixmap: client 15
559 -&gt; X_CreatePixmap: client 15
560 ** Pixmap alloc: 01e00181
561 &lt;- X_CreatePixmap: client 15
562 -&gt; X_CreatePixmap: client 14
563 ** Pixmap alloc: 01c004c8
564 &lt;- X_CreatePixmap: client 14
565 ** Pixmap free:  02200009
566 ** Client Disconnect: id 17
567 ** Pixmap free:  01e00180
568 ** Pixmap free:  01e00181
569           </computeroutput></screen>
570
571       </para>
572
573     </example>
574
575
576   </sect1>
577
578 </article>
579