comparison xml/en/docs/nginx_dtrace_pid_provider.xml @ 698:5182e655d055

DTrace article added
author Sergey Budnevitch <sb@waeme.net>
date Tue, 02 Oct 2012 15:04:30 +0000
parents
children 8205c2fcde2f
comparison
equal deleted inserted replaced
697:5d939bef335c 698:5182e655d055
1 <?xml version="1.0"?>
2
3 <!--
4 Copyright (C) Nginx, Inc.
5 -->
6
7 <!DOCTYPE article SYSTEM "../../../dtd/article.dtd">
8
9
10 <article name="Debugging nginx with DTrace pid provider"
11 link="/en/docs/nginx_dtrace_pid_provider.html"
12 lang="en"
13 rev="1"
14 toc="no">
15
16 <section>
17
18 <para>
19 This article assumes the reader has a general knowledge of nginx internals and
20 <link id="see_also">DTrace</link>.
21 </para>
22
23 <para>
24 Although nginx build with <link doc="debugging_log.xml">--with-debug</link> option
25 already provides a lot of information about request processing, it is sometimes desirable
26 to trace particular parts of code path more thoroughly and at the same time
27 omit the rest of debug output. DTrace pid provider (available on Solaris, OS X) is a useful
28 tool to explore userland programs internals, since it doesn't require any code changes and
29 it can help with the task. E.g. a simple DTrace script to trace and print nginx
30 functions calls may look like:
31
32 <programlisting>
33 #pragma D option flowindent
34
35 pid$target:nginx::entry {
36 }
37
38 pid$target:nginx::return {
39 }
40 </programlisting>
41
42 </para>
43
44 <para>
45 DTrace capabilities for function calls tracing provide only a limited amount
46 of useful information, though. Real-time inspection of function arguments
47 is typically more interesting, but also a bit more complicated. Examples below
48 are intended to help the reader become more familiar with DTrace and the
49 process of analyzing nginx behavior using DTrace.
50 </para>
51
52 <para>
53 One of the common scenarios for using DTrace with nginx is the following:
54 attach to the nginx worker to log request lines and request start times.
55 The corresponding function to attach is
56 <literal>ngx_http_process_request</literal>, and the argument in question
57 is a pointer to <literal>ngx_http_request_t</literal> structure.
58 DTrace script for such request logging can be as simple as:
59
60 <programlisting>
61
62 pid$target::*ngx_http_process_request:entry
63 {
64 this->request = (ngx_http_request_t *)copyin(arg0, sizeof(ngx_http_request_t));
65 this->request_line = stringof(copyin((uintptr_t)this->request->request_line.data,
66 this->request->request_line.len));
67 printf("request line = %s\n", this->request_line);
68 printf("request start sec = %d\n", this->request->start_sec);
69 }
70
71 </programlisting>
72 </para>
73
74 <para>
75 It should be noted that in the example above DTrace requires some knowledge about
76 <literal>ngx_http_process_request</literal> structure.
77 Unfortunately while it is possible to use a specific <literal>#include</literal>
78 directive in the DTrace script and then pass it to a C preprocessor
79 (with -C flag), that doesn't really work. Due to a lot of cross dependencies almost
80 all nginx header files have to be included. In turn, based on configure script
81 settings, nginx headers will include PCRE, OpenSSL and a variety of system header
82 files. While in theory all those header files related to a specific nginx build
83 might be included in DTrace script preprocessing and compilation, in reality
84 DTrace script most probably will fail to compile because of unknown syntax in
85 some header files.
86 </para>
87
88 <para>
89 The problem above can be solved by including only the relevant and
90 necessary structures and types definitions in the DTrace script. DTrace has to know
91 sizes of structures, types, and fields offsets. Thus dependencies can be further
92 reduced by manually optimizing structure definitions for use with DTrace.
93 </para>
94
95 <para>
96 Let's use DTrace script example above and see what structure definitions it needs
97 to work properly.
98 </para>
99
100 <para>
101 First of all <literal>objs/ngx_auto_config.h</literal> file generated by configure
102 should be included, because it defines a number of constants affecting various
103 <literal>#ifdef's</literal>. After that there's some basic types and definitions
104 like <literal>ngx_str_t</literal>, <literal>ngx_table_elt_t</literal>,
105 <literal>ngx_uint_t</literal> etc. should be put at the beginning of DTrace script.
106 These definitions are compact, commonly used and unlikely to be frequently changed.
107 </para>
108
109 <para>
110 Then there's the <literal>ngx_http_process_request_t</literal> structure which
111 contains a lot of pointers to other structures. Because these pointers are
112 really irrelevant to this script, and because they have the same size,
113 it is possible to just replace them with void pointers. Instead of changing
114 definitions, it is better to add appropriate typedefs, though:
115
116 <programlisting>
117 typedef ngx_http_upstream_t void;
118 typedef ngx_http_request_body_t void;
119 </programlisting>
120
121 Last but not least it is necessary to add definitions of two member structures:
122 <literal>ngx_http_headers_in_t</literal> and
123 <literal>ngx_http_headers_out_t</literal>, callback functions
124 declarations and constants definitions.
125 </para>
126
127 <para>
128 Final DTrace script can be downloaded
129 <link url="http://nginx.org/download/trace_process_request.d">here</link>.
130 </para>
131
132 <para>
133 The example below shows the output of the DTrace script:
134
135 <programlisting>
136 # dtrace -C -I ./objs -s trace_process_request.d -p 4848
137 dtrace: script 'trace_process_request.d' matched 1 probe
138 CPU ID FUNCTION:NAME
139 1 4 .XAbmO.ngx_http_process_request:entry request line = GET / HTTP/1.1
140 request start sec = 1349162898
141
142 0 4 .XAbmO.ngx_http_process_request:entry request line = GET /en/docs/nginx_dtrace_pid_provider.html HTTP/1.1
143 request start sec = 1349162899
144 </programlisting>
145
146 </para>
147
148 <para>Using similar techniques the reader should be able to trace other
149 nginx functions calls.
150 </para>
151
152 </section>
153
154 <section id="see_also"
155 name="See also">
156
157 <para>
158 <list type="bullet">
159
160 <listitem>
161 <link url="http://docs.oracle.com/cd/E19253-01/817-6223/index.html">
162 Solaris Dynamic Tracing Guide</link>
163 </listitem>
164
165 <listitem>
166 <link url="http://dtrace.org/blogs/brendan/2011/02/09/dtrace-pid-provider/">
167 Introduction article on DTrace pid provider</link>
168 </listitem>
169
170 </list>
171 </para>
172
173 </section>
174
175 </article>