Mercurial > hg > nginx-site
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> |