1tnfctl_pid_open(3TNF) TNF Library Functions tnfctl_pid_open(3TNF)
2
3
4
6 tnfctl_pid_open, tnfctl_exec_open, tnfctl_continue - interfaces for
7 direct probe and process control for another process
8
10 cc [ flag ... ] file ... -ltnfctl [ library ... ]
11 #include <tnf/tnfctl.h>
12
13 tnfctl_errcode_t tnfctl_pid_open(pid_t pid, tnfctl_handle_t **ret_val);
14
15
16 tnfctl_errcode_t tnfctl_exec_open(const char *pgm_name,
17 char * const *argv, char * const *envp,
18 const char *libnfprobe_path, const char *ld_preload,
19 tnfctl_handle_t **ret_val);
20
21
22 tnfctl_errcode_t tnfctl_continue(tnfctl_handle_t *hndl,
23 tnfctl_event_t *evt, tnfctl_handle_t **child_hndl);
24
25
27 The tnfctl_pid_open(), tnfctl_exec_open(), and tnfctl_continue() func‐
28 tions create handles to control probes in another process (direct
29 process probe control). Either tnfctl_pid_open() or tnfctl_exec_open()
30 will return a handle in ret_val that can be used for probe control. On
31 return of these calls, the process is stopped. tnfctl_continue() allows
32 the process specified by hndl to continue execution.
33
34
35 The tnfctl_pid_open() function attaches to a running process with
36 process id of pid. The process is stopped on return of this call. The
37 tnfctl_pid_open() function returns an error message if pid is the same
38 as the calling process. See tnfctl_internal_open(3TNF) for information
39 on internal process probe control. A pointer to an opaque handle is
40 returned in ret_val, which can be used to control the process and the
41 probes in the process. The target process must have libtnfprobe.so.1
42 (defined in <tnf/tnfctl.h> as macro TNFCTL_LIBTNFPROBE) linked in for
43 probe control to work.
44
45
46 The tnfctl_exec_open() function is used to exec(2) a program and obtain
47 a probe control handle. For probe control to work, the process image to
48 be exec'd must load libtnfprobe.so.1. The tnfctl_exec_open() function
49 makes it simple for the library to be loaded at process start up time.
50 The pgm_name argument is the command to exec. If pgm_name is not an
51 absolute path, then the $PATH environment variable is used to find the
52 pgm_name. argv is a null-terminated argument pointer, that is, it is a
53 null-terminated array of pointers to null-terminated strings. These
54 strings constitute the argument list available to the new process
55 image. The argv argument must have at least one member, and it should
56 point to a string that is the same as pgm_name. See execve(2). The lib‐
57 nfprobe_path argument is an optional argument, and if set, it should be
58 the path to the directory that contains libtnfprobe.so.1. There is no
59 need for a trailing "/" in this argument. This argument is useful if
60 libtnfprobe.so.1 is not installed in /usr/lib. ld_preload is a space-
61 separated list of libraries to preload into the target program. This
62 string should follow the syntax guidelines of the LD_PRELOAD environ‐
63 ment variable. See ld.so.1(1). The following illustrates how strings
64 are concatenated to form the LD_PRELOAD environment variable in the new
65 process image:
66
67 <current value of $LD_PRELOAD> + <space> +
68 libtnfprobe_path + "/libtnfprobe.so.1" +<space> +
69 ld_preload
70
71
72
73 This option is useful for preloading interposition libraries that have
74 probes in them.
75
76
77 envp is an optional argument, and if set, it is used for the environ‐
78 ment of the target program. It is a null-terminated array of pointers
79 to null-terminated strings. These strings constitute the environment
80 of the new process image. See execve(2). If envp is set, it overrides
81 ld_preload. In this case, it is the caller's responsibility to ensure
82 that libtnfprobe.so.1 is loaded into the target program. If envp is
83 not set, the new process image inherits the environment of the calling
84 process, except for LD_PRELOAD.
85
86
87 The ret_val argument is the handle that can be used to control the
88 process and the probes within the process. Upon return, the process is
89 stopped before any user code, including .init sections, has been exe‐
90 cuted.
91
92
93 The tnfctl_continue() function is a blocking call and lets the target
94 process referenced by hndl continue running. It can only be used on
95 handles returned by tnfctl_pid_open() and tnfctl_exec_open() (direct
96 process probe control). It returns when the target stops; the reason
97 that the process stopped is returned in evt. This call is interrupt‐
98 ible by signals. If it is interrupted, the process is stopped, and
99 TNFCTL_EVENT_EINTR is returned in evt. The client of this library will
100 have to decide which signal implies a stop to the target and catch
101 that signal. Since a signal interrupts tnfctl_continue(), it will
102 return, and the caller can decide whether or not to call tnfctl_con‐
103 tinue() again.
104
105
106 tnfctl_continue() returns with an event of TNFCTL_EVENT_DLOPEN,
107 TNFCTL_EVENT_DLCLOSE, TNFCTL_EVENT_EXEC, TNFCTL_EVENT_FORK,
108 TNFCTL_EVENT_EXIT, or TNFCTL_EVENT_TARGGONE, respectively, when the
109 target program calls dlopen(3C), dlclose(3C), any flavor of exec(2),
110 fork(2) (or fork1(2)), exit(2), or terminates unexpectedly. If the tar‐
111 get program called exec(2), the client then needs to call
112 tnfctl_close(3TNF) on the current handle leaving the target resumed,
113 suspended, or killed (second argument to tnfctl_close(3TNF)). No other
114 libtnfctl interface call can be used on the existing handle. If the
115 client wants to control the exec'ed image, it should leave the old han‐
116 dle suspended, and use tnfctl_pid_open() to reattach to the same
117 process. This new handle can then be used to control the exec'ed
118 image. See EXAMPLES below for sample code. If the target process did
119 a fork(2) or fork1(2), and if control of the child process is not
120 needed, then child_hndl should be NULL. If control of the child
121 process is needed, then child_hndl should be set. If it is set, a
122 pointer to a handle that can be used to control the child process is
123 returned in child_hndl. The child process is stopped at the end of the
124 fork() system call. See EXAMPLES for an example of this event.
125
127 The tnfctl_pid_open(), tnfctl_exec_open(), and tnfctl_continue() func‐
128 tions return TNFCTL_ERR_NONE upon success.
129
131 The following error codes apply to tnfctl_pid_open():
132
133 TNFCTL_ERR_BADARG The pid specified is the same process.
134 Use tnfctl_internal_open(3TNF) instead.
135
136
137 TNFCTL_ERR_ACCES Permission denied. No privilege to connect
138 to a setuid process.
139
140
141 TNFCTL_ERR_ALLOCFAIL A memory allocation failure occurred.
142
143
144 TNFCTL_ERR_BUSY Another client is already using /proc to
145 control this process or internal tracing is
146 being used.
147
148
149 TNFCTL_ERR_NOTDYNAMIC The process is not a dynamic executable.
150
151
152 TNFCTL_ERR_NOPROCESS No such target process exists.
153
154
155 TNFCTL_ERR_NOLIBTNFPROBE libtnfprobe.so.1 is not linked in the tar‐
156 get process.
157
158
159 TNFCTL_ERR_INTERNAL An internal error occurred.
160
161
162
163 The following error codes apply to tnfctl_exec_open():
164
165 TNFCTL_ERR_ACCES Permission denied.
166
167
168 TNFCTL_ERR_ALLOCFAIL A memory allocation failure occurred.
169
170
171 TNFCTL_ERR_NOTDYNAMIC The target is not a dynamic executable.
172
173
174 TNFCTL_ERR_NOLIBTNFPROBE libtnfprobe.so.1 is not linked in the tar‐
175 get process.
176
177
178 TNFCTL_ERR_FILENOTFOUND The program is not found.
179
180
181 TNFCTL_ERR_INTERNAL An internal error occurred.
182
183
184
185 The following error codes apply to tnfctl_continue():
186
187 TNFCTL_ERR_BADARG Bad input argument. hndl is not a direct
188 process probe control handle.
189
190
191 TNFCTL_ERR_INTERNAL An internal error occurred.
192
193
194 TNFCTL_ERR_NOPROCESS No such target process exists.
195
196
198 Example 1 Using tnfctl_pid_open()
199
200
201 These examples do not include any error-handling code. Only the ini‐
202 tial example includes the declaration of the variables that are used
203 in all of the examples.
204
205
206
207 The following example shows how to preload libtnfprobe.so.1 from the
208 normal location and inherit the parent's environment.
209
210
211 const char *pgm;
212 char * const *argv;
213 tnfctl_handle_t *hndl, *new_hndl, *child_hndl;
214 tnfctl_errcode_t err;
215 char * const *envptr;
216 extern char **environ;
217 tnfctl_event_t evt;
218 int pid;
219
220 /* assuming argv has been allocated */
221 argv[0] = pgm;
222 /* set up rest of argument vector here */
223 err = tnfctl_exec_open(pgm, argv, NULL, NULL, NULL, &hndl);
224
225
226
227 This example shows how to preload two user-supplied libraries
228 libc_probe.so.1 and libthread_probe.so.1. They interpose on the corre‐
229 sponding libc.so and libthread.so interfaces and have probes for func‐
230 tion entry and exit. libtnfprobe.so.1 is preloaded from the normal
231 location and the parent's environment is inherited.
232
233
234 /* assuming argv has been allocated */
235 argv[0] = pgm;
236 /* set up rest of argument vector here */
237 err = tnfctl_exec_open(pgm, argv, NULL, NULL,
238 "libc_probe.so.1 libthread_probe.so.1", &hndl);
239
240
241
242 This example preloads an interposition library libc_probe.so.1, and
243 specifies a different location from which to preload libtnfprobe.so.1.
244
245
246 /* assuming argv has been allocated */
247 argv[0] = pgm;
248 /* set up rest of argument vector here */
249 err = tnfctl_exec_open(pgm, argv, NULL, "/opt/SUNWXXX/lib",
250 "libc_probe.so.1", &hndl);
251
252
253
254 To set up the environment explicitly for probe control to work, the
255 target process must link libtnfprobe.so.1. If using envp, it is the
256 caller's responsibility to do so.
257
258
259 /* assuming argv has been allocated */
260 argv[0] = pgm;
261 /* set up rest of argument vector here */
262 /* envptr set up to caller's needs */
263 err = tnfctl_exec_open(pgm, argv, envptr, NULL, NULL, &hndl);
264
265
266
267 Use this example to resume a process that does an exec(2) without con‐
268 trolling it.
269
270
271 err = tnfctl_continue(hndl, &evt, NULL);
272 switch (evt) {
273 case TNFCTL_EVENT_EXEC:
274 /* let target process continue without control */
275 err = tnfctl_close(hndl, TNFCTL_TARG_RESUME);
276 ...
277 break;
278 }
279
280
281
282 Alternatively, use the next example to control a process that does an
283 exec(2).
284
285
286 /*
287 * assume the pid variable has been set by calling
288 * tnfctl_trace_attrs_get()
289 */
290 err = tnfctl_continue(hndl, &evt, NULL);
291 switch (evt) {
292 case TNFCTL_EVENT_EXEC:
293 /* suspend the target process */
294 err = tnfctl_close(hndl, TNFCTL_TARG_SUSPEND);
295 /* re-open the exec'ed image */
296 err = tnfctl_pid_open(pid, &new_hndl);
297 /* new_hndl now controls the exec'ed image */
298 ...
299 break;
300 }
301
302
303
304 To let fork'ed children continue without control, use NULL as the last
305 argument to tnfctl_continue().
306
307
308 err = tnfctl_continue(hndl, &evt, NULL);
309
310
311
312 The next example is how to control child processes that fork(2) or
313 fork1(2) create.
314
315
316 err = tnfctl_continue(hndl, &evt, &child_hndl);
317 switch (evt) {
318 case TNFCTL_EVENT_FORK:
319 /* spawn a new thread or process to control child_hndl */
320 ...
321 break;
322 }
323
324
326 See attributes(5) for descriptions of the following attributes:
327
328
329
330
331 ┌─────────────────────────────┬─────────────────────────────┐
332 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
333 ├─────────────────────────────┼─────────────────────────────┤
334 │Availability │SUNWtnfc │
335 ├─────────────────────────────┼─────────────────────────────┤
336 │MT Level │MT-Safe │
337 └─────────────────────────────┴─────────────────────────────┘
338
340 ld(1), prex(1), proc(1), exec(2), execve(2), exit(2), fork(2),
341 TNF_PROBE(3TNF), dlclose(3C), dlopen(3C), libtnfctl(3TNF),
342 tnfctl_close(3TNF), tnfctl_internal_open(3TNF), tracing(3TNF)
343 attributes(5)
344
345
346 Linker and Libraries Guide
347
349 After a call to tnfctl_continue() returns, a client should use
350 tnfctl_trace_attrs_get(3TNF) to check the trace_buf_state member of the
351 trace attributes and make sure that there is no internal error in the
352 target.
353
354
355
356SunOS 5.11 1 Mar 2004 tnfctl_pid_open(3TNF)