summaryrefslogtreecommitdiffstats
path: root/doc/Tapset_Reference_Guide/en-US/Tapset_Dev_Guide.xml
blob: d497eae661798acbe3c1d6464fb3fea005b9faa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
<?xml version='1.0'?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>

<chapter id="Tapset_Dev_Guide">
	<title>Tapset Development Guidelines</title>

<para>
	This chapter describes the upstream guidelines on proper tapset documentation. It also contains
	information on how to properly document your tapsets, to ensure that they are properly 
	defined in this guide.
</para>
	
	<section id="Tapsetcontents">
		<title>Writing Good Tapsets</title>
		
<para>
	The first step to writing good tapsets is  to create a simple model of your subject area.  For
	example, a model of the process subsystem might include the following:
</para>

<formalpara>
	<title>Key Data</title>
	<para>
		<itemizedlist>
			<listitem><para>process ID</para></listitem>
			<listitem><para>parent process ID</para></listitem>
			<listitem><para>process group ID</para></listitem>
		</itemizedlist>
	</para>
</formalpara>

<formalpara>
	<title>State Transitions</title>
	<para>
		<itemizedlist>
			<listitem><para>forked</para></listitem>
			<listitem><para>exec'd</para></listitem>
			<listitem><para>running</para></listitem>
			<listitem><para>stopped</para></listitem>
			<listitem><para>terminated</para></listitem>
		</itemizedlist>
	</para>
</formalpara>
			
<note>
	<title>Note</title>
	<para>Both lists are examples, and are not meant to represent a complete list.</para>
</note>

<para>
	Use your subsystem expertise to find probe points (function entries and
	exits) that expose the elements of the model, then define probe aliases
	for those points.  Be aware that some state transitions can occur in more
	than one place. In those cases, an alias can place a probe in multiple
	locations.
</para>

<para>
	For example, process execs can occur in either the <command>do_execve()</command> or the
	<command>compat_do_execve()</command> functions. The following alias inserts probes at the
	beginning of those functions:
</para>

<para>
<programlisting>
probe process.exec = kernel.function("do_execve"),
kernel.function("compat_do_execve") 
{<replaceable>probe body</replaceable>}
</programlisting>		
</para>

<para>
	Try to place probes on stable interfaces (i.e., functions
	that are unlikely to change at the interface level) whenever possible.  This will
	make the tapset less likely to break due to kernel changes. Where
	kernel version or architecture dependencies are unavoidable, use
	preprocessor conditionals (see the <command>stap(1)</command> man page for details).
</para>


<para>
	Fill in the probe bodies with the key data available at the probe points.
	Function entry probes can access the entry parameters specified to
	the function, while exit probes can access the entry parameters and the
	return value.  Convert the data into meaningful forms where appropriate
	(e.g., bytes to kilobytes, state values to strings, etc).
</para>

<para>
	You may need to use auxiliary functions to access or convert some of the data. Auxiliary
	functions often use embedded C to do things that cannot be done in the
	SystemTap language, like access structure fields in some contexts, follow
	linked lists, etc. You can use auxiliary functions defined in other tapsets
	or write your own.
</para>

<para>
	In the following example, <command>copy_process()</command> returns a 
	pointer to the <command>task_struct</command> for the new process.  Note 
	that the process ID of the new process is retrieved by calling 
	<command>task_pid()</command> and passing it the <command>task_struct</command>
	pointer. In this case, the auxiliary function is an embedded C function
	defined in <filename>task.stp</filename>.
</para>

<para>
<programlisting>
probe process.create = kernel.function("copy_process").return 
{
   task = $return
   new_pid = task_pid(task)
}
</programlisting>
</para>

<para>
	It is not advisable to write probes for every function. Most SystemTap users
	will not need or understand them. Keep your tapsets simple and high-level.
</para>

<remark>info from here:http://sources.redhat.com/git/?p=systemtap.git;a=blob_plain;f=tapset/DEVGUIDE</remark>

	</section>
	
<section id="Tapsetelements">
	<title>Elements of a Tapset</title>
		
	<para>
		The following sections describe the most important aspects of writing a tapset. Most of
		the content herein is suitable for developers who wish to contribute to 
		SystemTap's upstream library of tapsets.
	</para>
	
<section id="Tapsetelements-tapsetfiles">
	<title>Tapset Files</title>
	
	<para>
		Tapset files are stored in <filename><replaceable>src</replaceable>/tapset/</filename> 
		of the SystemTap GIT directory. Most tapset files are kept at that level. If you have
		code that only works with a specific architecture or kernel version, you may 
		choose to put your tapset in the appropriate subdirectory.
	</para>
	
	<para>
		Installed tapsets are located in <filename>/usr/share/systemtap/tapset/</filename>
		or <filename>/usr/local/share/systemtap/tapset</filename>.
	</para>
	
	<para>
		Personal tapsets can be stored anywhere. However, to ensure that SystemTap
		can use them, use <command>-I <replaceable>tapset_directory</replaceable></command> 
		to specify their location when invoking <command>stap</command>.
	</para>
</section>	
	
<section id="Tapsetelements-namespace">
	<title>Namespace</title>
	
	
	<para>
		Probe alias names should take the form
		<command><replaceable>tapset_name.probe_name</replaceable></command>.
		For example, the probe for sending a signal could be named 
		<command>signal.send</command>.
	</para>
	
	<para>
		Global symbol names (probes, functions, and variables) should be unique
		accross all tapsets. This helps avoid namespace collisions in scripts
		that use multiple tapsets. To ensure this, use tapset-specific 
		prefixes in your global symbols.
	</para>
	
	<para>
		Internal symbol names should be prefixed with an underscore 
		(<command>_</command>).
	</para>
</section>	

<section id="Tapsetelements-docscomments">
	<title>Comments and Documentation</title>
	
	<para>
		All probes and functions should include comment blocks that describe
		their purpose, the data they provide, and the context in which they run 
		(e.g. interrupt, process, etc). Use comments in areas where your intent may not
		be clear from reading the code. 
	</para>
	
	<para>
		Note that specially-formatted comments are automatically extracted from most 
		tapsets and included in this guide. This helps ensure that tapset contributors
		can write their tapset <emphasis>and</emphasis> document it in the same place.
		The specified format for documenting tapsets is as follows:
	</para>
	
<para>
<programlisting>
/**
 * probe tapset.name - Short summary of what the tapset does.
 * @argument: Explanation of argument.
 * @argument2: Explanation of argument2. Probes can have multiple arguments.
 *
 * Context:
 * A brief explanation of the tapset context. 
 * Note that the context should only be 1 paragraph short.
 *
 * Text that will appear under "Description."
 *
 * A new paragraph that will also appear under the heading "Description".
 *
 * Header:
 * A paragraph that will appear under the heading "Header".
 **/
</programlisting>
</para>

<para>For example:</para>

<para>
<programlisting>
/**
 * probe vm.write_shared_copy- Page copy for shared page write.
 * @address: The address of the shared write.
 * @zero: Boolean indicating whether it is a zero page
 *         (can do a clear instead of a copy).
 *
 * Context:
 *  The process attempting the write.
 *
 *  Fires when a write to a shared page requires a page copy.  This is
 *  always preceded by a <command>vm.shared_write</command>.
 **/
</programlisting>
</para>

<para>To override the automatically-generated <command>Synopsis</command> content, use:</para>
	
<para>
<programlisting>
 * Synopsis:
 * <replaceable>New Synopsis string</replaceable>
 *
</programlisting>
</para>

<para>For example:</para>

<para>
<programlisting>
/**
 * probe signal.handle - Fires when the signal handler is invoked
 * @sig: The signal number that invoked the signal handler
 *
 * Synopsis:
 * &lt;programlisting>static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 * sigset_t *oldset, struct pt_regs * regs)&lt;/programlisting>
 */
</programlisting>
</para>

<para>
	It is recommended that you use the <command>&lt;programlisting&gt;</command> tag in 
	this instance, since overriding the <command>Synopsis</command> content of an entry
	does not automatically form the necessary tags.
</para>

<para>
	For the purposes of improving the DocBook XML output of your comments, you can also
	use the following XML tags in your comments:
</para>

<itemizedlist>
	<listitem><para><command>command</command></para></listitem>
	<listitem><para><command>emphasis</command></para></listitem>
	<listitem><para><command>programlisting</command></para></listitem>
	<listitem><para><command>remark</command> (tagged strings will appear in Publican beta
			builds of the document)</para></listitem>
</itemizedlist>


</section>
	
</section>	
	
<!--	
<section id="Tapset_Reference_Guide-Test-Section_2_Test">
	<title>Section 2 Test</title>
	<para>
		Test of a section
	</para>
</section>
-->
</chapter>