gdb/
[deliverable/binutils-gdb.git] / gdb / proc-api.c
CommitLineData
0fda6bd2 1/* Machine independent support for SVR4 /proc (process file system) for GDB.
2555fe1a 2
0b302171
JB
3 Copyright (C) 1999-2001, 2003, 2005, 2007-2012 Free Software
4 Foundation, Inc.
2555fe1a 5
0fda6bd2
JM
6 Written by Michael Snyder at Cygnus Solutions.
7 Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
8
a9762ec7
JB
9 This file is part of GDB.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0fda6bd2
JM
23
24/*
25 * Pretty-print trace of api calls to the /proc api
26 * (ioctl or read/write calls).
27 *
28 */
29
30#include "defs.h"
31#include "gdbcmd.h"
8e40d292 32#include "completer.h"
0fda6bd2
JM
33
34#if defined (NEW_PROC_API)
35#define _STRUCTURED_PROC 1
36#endif
37
38#include <stdio.h>
39#include <sys/types.h>
40#include <sys/procfs.h>
8dd72958 41#ifdef HAVE_SYS_PROC_H
0fda6bd2 42#include <sys/proc.h> /* for struct proc */
8dd72958 43#endif
6e8cb14a 44#ifdef HAVE_SYS_USER_H
0fda6bd2 45#include <sys/user.h> /* for struct user */
6e8cb14a 46#endif
0df8b418 47#include <fcntl.h> /* for O_RDWR etc. */
2555fe1a 48#include "gdb_wait.h"
0fda6bd2
JM
49
50#include "proc-utils.h"
51
52/* Much of the information used in the /proc interface, particularly for
53 printing status information, is kept as tables of structures of the
54 following form. These tables can be used to map numeric values to
0df8b418 55 their symbolic names and to a string that describes their specific use. */
0fda6bd2
JM
56
57struct trans {
58 long value; /* The numeric value */
59 char *name; /* The equivalent symbolic value */
60 char *desc; /* Short description of value */
61};
62
103b3ef5 63static int procfs_trace = 0;
0fda6bd2
JM
64static FILE *procfs_file = NULL;
65static char *procfs_filename = "procfs_trace";
66
103b3ef5
MS
67static void
68prepare_to_trace (void)
69{
70 if (procfs_trace) /* if procfs tracing turned on */
71 if (procfs_file == NULL) /* if output file not yet open */
72 if (procfs_filename != NULL) /* if output filename known */
73 procfs_file = fopen (procfs_filename, "a"); /* open output file */
74}
75
0fda6bd2 76static void
fba45db2 77set_procfs_trace_cmd (char *args, int from_tty, struct cmd_list_element *c)
0fda6bd2
JM
78{
79#if 0 /* not sure what I might actually need to do here, if anything */
80 if (procfs_file)
81 fflush (procfs_file);
82#endif
83}
84
85static void
fba45db2 86set_procfs_file_cmd (char *args, int from_tty, struct cmd_list_element *c)
0fda6bd2
JM
87{
88 /* Just changed the filename for procfs tracing.
89 If a file was already open, close it. */
90 if (procfs_file)
91 fclose (procfs_file);
92 procfs_file = NULL;
93}
94
95
96#ifndef NEW_PROC_API
97
98static struct trans ioctl_table[] = {
99#ifdef PIOCACINFO /* irix */
100 { PIOCACINFO, "PIOCACINFO", "get process account info" },
101#endif
102 { PIOCACTION, "PIOCACTION", "get signal action structs" },
103#ifdef PIOCARGUMENTS /* osf */
104 { PIOCARGUMENTS, "PIOCARGUMENTS", "command line args" },
105#endif
106#ifdef PIOCAUXV /* solaris aux vectors */
107 { PIOCAUXV, "PIOCAUXV", "get aux vector" },
108 { PIOCNAUXV, "PIOCNAUXV", "get number of aux vector entries" },
109#endif /* AUXV */
110 { PIOCCFAULT, "PIOCCFAULT", "clear current fault" },
111 { PIOCCRED, "PIOCCRED", "get process credentials" },
112#ifdef PIOCENEVCTRS /* irix event counters */
113 { PIOCENEVCTRS, "PIOCENEVCTRS", "acquire and start event counters" },
114 { PIOCGETEVCTRL, "PIOCGETEVCTRL", "get control info of event counters" },
115 { PIOCGETEVCTRS, "PIOCGETEVCTRS", "dump event counters" },
116 { PIOCGETPREVCTRS, "PIOCGETPREVCTRS", "dump event counters & prusage info" },
117 { PIOCRELEVCTRS, "PIOCRELEVCTRS", "release/stop event counters" },
118 { PIOCSETEVCTRL, "PIOCSETEVCTRL", "set control info of event counters" },
119 { PIOCGETPTIMER, "PIOCGETPTIMER", "get process timers" },
120#endif /* irix event counters */
121 { PIOCGENTRY, "PIOCGENTRY", "get traced syscall entry set" },
6e8cb14a 122#if defined (PIOCGETPR)
0fda6bd2 123 { PIOCGETPR, "PIOCGETPR", "read struct proc" },
6e8cb14a
AC
124#endif
125#if defined (PIOCGETU)
0fda6bd2 126 { PIOCGETU, "PIOCGETU", "read user area" },
6e8cb14a 127#endif
0fda6bd2
JM
128#if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
129 { PIOCGETUTK, "PIOCGETUTK", "get the utask struct" },
130#endif
131 { PIOCGEXIT, "PIOCGEXIT", "get traced syscall exit set" },
132 { PIOCGFAULT, "PIOCGFAULT", "get traced fault set" },
133#ifdef PIOCGFPCR /* osf */
134 { PIOCGFPCR, "PIOCGFPCR", "get FP control register" },
135 { PIOCSFPCR, "PIOCSFPCR", "set FP conrtol register" },
136#endif
137 { PIOCGFPREG, "PIOCGFPREG", "get floating point registers" },
138 { PIOCGHOLD, "PIOCGHOLD", "get held signal set" },
139 { PIOCGREG, "PIOCGREG", "get general registers" },
140 { PIOCGROUPS, "PIOCGROUPS", "get supplementary groups" },
141#ifdef PIOCGSPCACT /* osf */
142 { PIOCGSPCACT, "PIOCGSPCACT", "get special action" },
143 { PIOCSSPCACT, "PIOCSSPCACT", "set special action" },
144#endif
145 { PIOCGTRACE, "PIOCGTRACE", "get traced signal set" },
146#ifdef PIOCGWATCH /* irix watchpoints */
147 { PIOCGWATCH, "PIOCGWATCH", "get watchpoint" },
148 { PIOCSWATCH, "PIOCSWATCH", "set watchpoint" },
149 { PIOCNWATCH, "PIOCNWATCH", "get number of watchpoints" },
150#endif /* irix watchpoints */
151#ifdef PIOCGWIN /* solaris sparc */
152 { PIOCGWIN, "PIOCGWIN", "get gwindows_t" },
153#endif
154#ifdef PIOCGXREG /* solaris sparc extra regs */
155 { PIOCGXREGSIZE, "PIOCXREGSIZE", "get extra register state size" },
156 { PIOCGXREG, "PIOCGXREG", "get extra register state" },
157 { PIOCSXREG, "PIOCSXREG", "set extra register state" },
158#endif /* XREG */
159 { PIOCKILL, "PIOCKILL", "send signal" },
160#ifdef PIOCLDT /* solaris i386 */
161 { PIOCLDT, "PIOCLDT", "get LDT" },
162 { PIOCNLDT, "PIOCNLDT", "get number of LDT entries" },
163#endif
05b4bd79 164#ifdef PIOCLSTATUS /* solaris */
0fda6bd2
JM
165 { PIOCLSTATUS, "PIOCLSTATUS", "get status of all lwps" },
166 { PIOCLUSAGE, "PIOCLUSAGE", "get resource usage of all lwps" },
167 { PIOCOPENLWP, "PIOCOPENLWP", "get lwp file descriptor" },
168 { PIOCLWPIDS, "PIOCLWPIDS", "get lwp identifiers" },
169#endif /* LWP */
170 { PIOCMAP, "PIOCMAP", "get memory map information" },
171 { PIOCMAXSIG, "PIOCMAXSIG", "get max signal number" },
172 { PIOCNICE, "PIOCNICE", "set nice priority" },
173 { PIOCNMAP, "PIOCNMAP", "get number of memory mappings" },
174 { PIOCOPENM, "PIOCOPENM", "open mapped object for reading" },
175#ifdef PIOCOPENMOBS /* osf */
176 { PIOCOPENMOBS, "PIOCOPENMOBS", "open mapped object" },
177#endif
178#ifdef PIOCOPENPD /* solaris */
179 { PIOCOPENPD, "PIOCOPENPD", "get page data file descriptor" },
180#endif
181 { PIOCPSINFO, "PIOCPSINFO", "get ps(1) information" },
182 { PIOCRESET, "PIOCRESET", "reset process flags" },
183 { PIOCRFORK, "PIOCRFORK", "reset inherit-on-fork flag" },
184 { PIOCRRLC, "PIOCRRLC", "reset run-on-last-close flag" },
185 { PIOCRUN, "PIOCRUN", "make process runnable" },
186#ifdef PIOCSAVECCNTRS /* irix */
187 { PIOCSAVECCNTRS, "PIOCSAVECCNTRS", "parent gets child cntrs" },
188#endif
189 { PIOCSENTRY, "PIOCSENTRY", "set traced syscall entry set" },
190 { PIOCSET, "PIOCSET", "set process flags" },
191 { PIOCSEXIT, "PIOCSEXIT", "set traced syscall exit set" },
192 { PIOCSFAULT, "PIOCSFAULT", "set traced fault set" },
193 { PIOCSFORK, "PIOCSFORK", "set inherit-on-fork flag" },
194 { PIOCSFPREG, "PIOCSFPREG", "set floating point registers" },
195 { PIOCSHOLD, "PIOCSHOLD", "set held signal set" },
196 { PIOCSREG, "PIOCSREG", "set general registers" },
197 { PIOCSRLC, "PIOCSRLC", "set run-on-last-close flag" },
198 { PIOCSSIG, "PIOCSSIG", "set current signal" },
199 { PIOCSTATUS, "PIOCSTATUS", "get process status" },
200 { PIOCSTOP, "PIOCSTOP", "post stop request" },
201 { PIOCSTRACE, "PIOCSTRACE", "set traced signal set" },
202 { PIOCUNKILL, "PIOCUNKILL", "delete a signal" },
203#ifdef PIOCUSAGE /* solaris */
204 { PIOCUSAGE, "PIOCUSAGE", "get resource usage" },
205#endif
206 { PIOCWSTOP, "PIOCWSTOP", "wait for process to stop" },
207
208#ifdef PIOCNTHR /* osf threads */
209 { PIOCNTHR, "PIOCNTHR", "get thread count" },
210 { PIOCRTINH, "PIOCRTINH", "reset inherit-on-thread-creation" },
211 { PIOCSTINH, "PIOCSTINH", "set inherit-on-thread-creation" },
212 { PIOCTLIST, "PIOCTLIST", "get thread ids" },
213 { PIOCXPTH, "PIOCXPTH", "translate port to thread handle" },
214 { PIOCTRUN, "PIOCTRUN", "make thread runnable" },
215 { PIOCTSTATUS, "PIOCTSTATUS", "get thread status" },
216 { PIOCTSTOP, "PIOCTSTOP", "stop a thread" },
217 /* ... TGTRACE TSTRACE TSSIG TKILL TUNKILL TCFAULT TGFAULT TSFAULT
218 TGFPREG TSFPREG TGREG TSREG TACTION TTERM TABRUN TGENTRY TSENTRY
219 TGEXIT TSEXIT TSHOLD ... thread functions */
220#endif /* osf threads */
221 { -1, NULL, NULL }
222};
223
224int
fba45db2 225ioctl_with_trace (int fd, long opcode, void *ptr, char *file, int line)
0fda6bd2 226{
8e40d292
EZ
227 int i = 0;
228 int ret;
229 int arg1;
0fda6bd2 230
103b3ef5
MS
231 prepare_to_trace ();
232
0fda6bd2
JM
233 if (procfs_trace)
234 {
0fda6bd2
JM
235 for (i = 0; ioctl_table[i].name != NULL; i++)
236 if (ioctl_table[i].value == opcode)
237 break;
238
239 if (info_verbose)
240 fprintf (procfs_file ? procfs_file : stdout,
241 "%s:%d -- ", file, line);
242 switch (opcode) {
243 case PIOCSET:
244 arg1 = ptr ? *(long *) ptr : 0;
245 fprintf (procfs_file ? procfs_file : stdout,
246 "ioctl (PIOCSET, %s) %s\n",
247 arg1 == PR_FORK ? "PR_FORK" :
248 arg1 == PR_RLC ? "PR_RLC" :
249#ifdef PR_ASYNC
250 arg1 == PR_ASYNC ? "PR_ASYNC" :
251#endif
252 "<unknown flag>",
253 info_verbose ? ioctl_table[i].desc : "");
254 break;
255 case PIOCRESET:
256 arg1 = ptr ? *(long *) ptr : 0;
257 fprintf (procfs_file ? procfs_file : stdout,
258 "ioctl (PIOCRESET, %s) %s\n",
259 arg1 == PR_FORK ? "PR_FORK" :
260 arg1 == PR_RLC ? "PR_RLC" :
261#ifdef PR_ASYNC
262 arg1 == PR_ASYNC ? "PR_ASYNC" :
263#endif
264 "<unknown flag>",
265 info_verbose ? ioctl_table[i].desc : "");
266 break;
267 case PIOCSTRACE:
268 fprintf (procfs_file ? procfs_file : stdout,
269 "ioctl (PIOCSTRACE) ");
270 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
271 (sigset_t *) ptr, 0);
272 break;
273 case PIOCSFAULT:
274 fprintf (procfs_file ? procfs_file : stdout,
275 "ioctl (%s) ",
276 opcode == PIOCSFAULT ? "PIOCSFAULT" : "PIOCGFAULT");
277 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
278 (fltset_t *) ptr, 0);
279 break;
280 case PIOCSENTRY:
281 fprintf (procfs_file ? procfs_file : stdout,
282 "ioctl (%s) ",
283 opcode == PIOCSENTRY ? "PIOCSENTRY" : "PIOCGENTRY");
284 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
285 (sysset_t *) ptr, 0);
286 break;
287 case PIOCSEXIT:
288 fprintf (procfs_file ? procfs_file : stdout,
289 "ioctl (%s) ",
290 opcode == PIOCSEXIT ? "PIOCSEXIT" : "PIOCGEXIT");
291 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
292 (sysset_t *) ptr, 0);
293 break;
294 case PIOCSHOLD:
295 fprintf (procfs_file ? procfs_file : stdout,
296 "ioctl (%s) ",
297 opcode == PIOCSHOLD ? "PIOCSHOLD" : "PIOCGHOLD");
298 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
299 (sigset_t *) ptr, 0);
300 break;
301 case PIOCSSIG:
302 fprintf (procfs_file ? procfs_file : stdout,
303 "ioctl (PIOCSSIG) ");
304 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
305 ptr ? ((siginfo_t *) ptr)->si_signo : 0,
306 0);
307 fprintf (procfs_file ? procfs_file : stdout, "\n");
308 break;
309 case PIOCRUN:
310 fprintf (procfs_file ? procfs_file : stdout,
311 "ioctl (PIOCRUN) ");
312
313 arg1 = ptr ? *(long *) ptr : 0;
314 if (arg1 & PRCSIG)
315 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
316 if (arg1 & PRCFAULT)
317 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
318 if (arg1 & PRSTRACE)
319 fprintf (procfs_file ? procfs_file : stdout, "setTrace ");
320 if (arg1 & PRSHOLD)
321 fprintf (procfs_file ? procfs_file : stdout, "setHold ");
322 if (arg1 & PRSFAULT)
323 fprintf (procfs_file ? procfs_file : stdout, "setFlt ");
324 if (arg1 & PRSVADDR)
325 fprintf (procfs_file ? procfs_file : stdout, "setVaddr ");
326 if (arg1 & PRSTEP)
327 fprintf (procfs_file ? procfs_file : stdout, "step ");
328 if (arg1 & PRSABORT)
329 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
330 if (arg1 & PRSTOP)
331 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
332
333 fprintf (procfs_file ? procfs_file : stdout, "\n");
334 break;
335 case PIOCKILL:
336 fprintf (procfs_file ? procfs_file : stdout,
337 "ioctl (PIOCKILL) ");
338 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
339 ptr ? *(long *) ptr : 0, 0);
340 fprintf (procfs_file ? procfs_file : stdout, "\n");
341 break;
342#ifdef PIOCSSPCACT
343 case PIOCSSPCACT:
344 fprintf (procfs_file ? procfs_file : stdout,
345 "ioctl (PIOCSSPCACT) ");
346 arg1 = ptr ? *(long *) ptr : 0;
347 if (arg1 & PRFS_STOPFORK)
348 fprintf (procfs_file ? procfs_file : stdout, "stopFork ");
349 if (arg1 & PRFS_STOPEXEC)
350 fprintf (procfs_file ? procfs_file : stdout, "stopExec ");
351 if (arg1 & PRFS_STOPTERM)
352 fprintf (procfs_file ? procfs_file : stdout, "stopTerm ");
353 if (arg1 & PRFS_STOPTCR)
354 fprintf (procfs_file ? procfs_file : stdout, "stopThreadCreate ");
355 if (arg1 & PRFS_STOPTTERM)
356 fprintf (procfs_file ? procfs_file : stdout, "stopThreadTerm ");
357 if (arg1 & PRFS_KOLC)
358 fprintf (procfs_file ? procfs_file : stdout, "killOnLastClose ");
359 fprintf (procfs_file ? procfs_file : stdout, "\n");
360 break;
361#endif /* PIOCSSPCACT */
362 default:
363 if (ioctl_table[i].name)
364 fprintf (procfs_file ? procfs_file : stdout,
365 "ioctl (%s) %s\n",
366 ioctl_table[i].name,
367 info_verbose ? ioctl_table[i].desc : "");
368 else
369 fprintf (procfs_file ? procfs_file : stdout,
370 "ioctl (<unknown %ld (0x%lx)) \n", opcode, opcode);
371 break;
372 }
373 if (procfs_file)
374 fflush (procfs_file);
375 }
103b3ef5 376 errno = 0;
0fda6bd2
JM
377 ret = ioctl (fd, opcode, ptr);
378 if (procfs_trace && ret < 0)
379 {
380 fprintf (procfs_file ? procfs_file : stdout,
103b3ef5 381 "[ioctl (%s) FAILED! (%s)]\n",
0fda6bd2 382 ioctl_table[i].name != NULL ?
103b3ef5
MS
383 ioctl_table[i].name : "<unknown>",
384 safe_strerror (errno));
0fda6bd2
JM
385 if (procfs_file)
386 fflush (procfs_file);
387 }
388
389 return ret;
390}
391
392#else /* NEW_PROC_API */
393
394static struct trans rw_table[] = {
395#ifdef PCAGENT /* solaris */
396 { PCAGENT, "PCAGENT", "create agent lwp with regs from argument" },
397#endif
398 { PCCFAULT, "PCCFAULT", "clear current fault" },
399#ifdef PCCSIG /* solaris */
400 { PCCSIG, "PCCSIG", "clear current signal" },
401#endif
640b227f 402#ifdef PCDSTOP /* solaris */
0fda6bd2 403 { PCDSTOP, "PCDSTOP", "post stop request" },
640b227f 404#endif
0fda6bd2 405 { PCKILL, "PCKILL", "post a signal" },
640b227f 406#ifdef PCNICE /* solaris */
0fda6bd2 407 { PCNICE, "PCNICE", "set nice priority" },
640b227f 408#endif
0fda6bd2
JM
409#ifdef PCREAD /* solaris */
410 { PCREAD, "PCREAD", "read from the address space" },
411 { PCWRITE, "PCWRITE", "write to the address space" },
0fda6bd2
JM
412#endif
413 { PCRUN, "PCRUN", "make process/lwp runnable" },
414#ifdef PCSASRS /* solaris 2.7 only */
415 { PCSASRS, "PCSASRS", "set ancillary state registers" },
416#endif
417#ifdef PCSCRED /* solaris */
418 { PCSCRED, "PCSCRED", "set process credentials" },
419#endif
420 { PCSENTRY, "PCSENTRY", "set traced syscall entry set" },
421 { PCSET, "PCSET", "set modes" },
422 { PCSEXIT, "PCSEXIT", "set traced syscall exit set" },
423 { PCSFAULT, "PCSFAULT", "set traced fault set" },
424 { PCSFPREG, "PCSFPREG", "set floating point registers" },
151fefe2 425#ifdef PCSHOLD /* solaris */
0fda6bd2 426 { PCSHOLD, "PCSHOLD", "set signal mask" },
640b227f 427#endif
0fda6bd2
JM
428 { PCSREG, "PCSREG", "set general registers" },
429 { PCSSIG, "PCSSIG", "set current signal" },
430 { PCSTOP, "PCSTOP", "post stop request and wait" },
431 { PCSTRACE, "PCSTRACE", "set traced signal set" },
432#ifdef PCSVADDR /* solaris */
433 { PCSVADDR, "PCSVADDR", "set pc virtual address" },
434#endif
435#ifdef PCSXREG /* solaris sparc only */
436 { PCSXREG, "PCSXREG", "set extra registers" },
437#endif
438#ifdef PCTWSTOP /* solaris */
439 { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
440#endif
640b227f 441#ifdef PCUNKILL /* solaris */
0fda6bd2 442 { PCUNKILL, "PCUNKILL", "delete a pending signal" },
640b227f 443#endif
0fda6bd2
JM
444#ifdef PCUNSET /* solaris */
445 { PCUNSET, "PCUNSET", "unset modes" },
446#endif
447#ifdef PCWATCH /* solaris */
448 { PCWATCH, "PCWATCH", "set/unset watched memory area" },
449#endif
450 { PCWSTOP, "PCWSTOP", "wait for process/lwp to stop, no timeout" },
451 { 0, NULL, NULL }
452};
453
454static off_t lseek_offset;
455
456int
fba45db2 457write_with_trace (int fd, void *varg, size_t len, char *file, int line)
0fda6bd2 458{
1e52e2eb 459 int i = ARRAY_SIZE (rw_table) - 1;
0fda6bd2 460 int ret;
37de36c6 461 procfs_ctl_t *arg = (procfs_ctl_t *) varg;
0fda6bd2 462
103b3ef5 463 prepare_to_trace ();
0fda6bd2
JM
464 if (procfs_trace)
465 {
37de36c6 466 procfs_ctl_t opcode = arg[0];
0fda6bd2
JM
467 for (i = 0; rw_table[i].name != NULL; i++)
468 if (rw_table[i].value == opcode)
469 break;
470
471 if (info_verbose)
472 fprintf (procfs_file ? procfs_file : stdout,
473 "%s:%d -- ", file, line);
474 switch (opcode) {
475 case PCSET:
476 fprintf (procfs_file ? procfs_file : stdout,
477 "write (PCSET, %s) %s\n",
478 arg[1] == PR_FORK ? "PR_FORK" :
479 arg[1] == PR_RLC ? "PR_RLC" :
480#ifdef PR_ASYNC
481 arg[1] == PR_ASYNC ? "PR_ASYNC" :
482#endif
483 "<unknown flag>",
484 info_verbose ? rw_table[i].desc : "");
485 break;
486#ifdef PCUNSET
487 case PCUNSET:
488#endif
489#ifdef PCRESET
37de36c6 490#if PCRESET != PCUNSET
0fda6bd2 491 case PCRESET:
37de36c6 492#endif
0fda6bd2
JM
493#endif
494 fprintf (procfs_file ? procfs_file : stdout,
495 "write (PCRESET, %s) %s\n",
496 arg[1] == PR_FORK ? "PR_FORK" :
497 arg[1] == PR_RLC ? "PR_RLC" :
498#ifdef PR_ASYNC
499 arg[1] == PR_ASYNC ? "PR_ASYNC" :
500#endif
501 "<unknown flag>",
502 info_verbose ? rw_table[i].desc : "");
503 break;
504 case PCSTRACE:
505 fprintf (procfs_file ? procfs_file : stdout,
506 "write (PCSTRACE) ");
507 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
508 (sigset_t *) &arg[1], 0);
509 break;
510 case PCSFAULT:
511 fprintf (procfs_file ? procfs_file : stdout,
512 "write (PCSFAULT) ");
513 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
514 (fltset_t *) &arg[1], 0);
515 break;
516 case PCSENTRY:
517 fprintf (procfs_file ? procfs_file : stdout,
518 "write (PCSENTRY) ");
519 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
520 (sysset_t *) &arg[1], 0);
521 break;
522 case PCSEXIT:
523 fprintf (procfs_file ? procfs_file : stdout,
524 "write (PCSEXIT) ");
525 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
526 (sysset_t *) &arg[1], 0);
527 break;
640b227f 528#ifdef PCSHOLD
0fda6bd2
JM
529 case PCSHOLD:
530 fprintf (procfs_file ? procfs_file : stdout,
531 "write (PCSHOLD) ");
532 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
533 (sigset_t *) &arg[1], 0);
534 break;
640b227f 535#endif
0fda6bd2
JM
536 case PCSSIG:
537 fprintf (procfs_file ? procfs_file : stdout,
538 "write (PCSSIG) ");
539 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
540 arg[1] ? ((siginfo_t *) &arg[1])->si_signo
541 : 0,
542 0);
543 fprintf (procfs_file ? procfs_file : stdout, "\n");
544 break;
545 case PCRUN:
546 fprintf (procfs_file ? procfs_file : stdout,
547 "write (PCRUN) ");
548 if (arg[1] & PRCSIG)
549 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
550 if (arg[1] & PRCFAULT)
551 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
552 if (arg[1] & PRSTEP)
553 fprintf (procfs_file ? procfs_file : stdout, "step ");
640b227f 554#ifdef PRSABORT
0fda6bd2
JM
555 if (arg[1] & PRSABORT)
556 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
640b227f
JB
557#endif
558#ifdef PRSTOP
0fda6bd2
JM
559 if (arg[1] & PRSTOP)
560 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
640b227f 561#endif
0fda6bd2
JM
562
563 fprintf (procfs_file ? procfs_file : stdout, "\n");
564 break;
565 case PCKILL:
566 fprintf (procfs_file ? procfs_file : stdout,
567 "write (PCKILL) ");
568 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
569 arg[1], 0);
570 fprintf (procfs_file ? procfs_file : stdout, "\n");
571 break;
572 default:
573 {
37de36c6 574 if (rw_table[i].name)
0fda6bd2
JM
575 fprintf (procfs_file ? procfs_file : stdout,
576 "write (%s) %s\n",
577 rw_table[i].name,
578 info_verbose ? rw_table[i].desc : "");
579 else
580 {
581 if (lseek_offset != -1)
582 fprintf (procfs_file ? procfs_file : stdout,
b943d152
MS
583 "write (<unknown>, %lud bytes at 0x%08lx) \n",
584 (unsigned long) len, (unsigned long) lseek_offset);
0fda6bd2
JM
585 else
586 fprintf (procfs_file ? procfs_file : stdout,
b943d152
MS
587 "write (<unknown>, %lud bytes) \n",
588 (unsigned long) len);
0fda6bd2
JM
589 }
590 break;
591 }
592 }
593 if (procfs_file)
594 fflush (procfs_file);
595 }
103b3ef5 596 errno = 0;
b943d152 597 ret = write (fd, (void *) arg, len);
0fda6bd2
JM
598 if (procfs_trace && ret != len)
599 {
600 fprintf (procfs_file ? procfs_file : stdout,
103b3ef5 601 "[write (%s) FAILED! (%s)]\n",
0fda6bd2 602 rw_table[i].name != NULL ?
103b3ef5
MS
603 rw_table[i].name : "<unknown>",
604 safe_strerror (errno));
0fda6bd2
JM
605 if (procfs_file)
606 fflush (procfs_file);
607 }
608
609 lseek_offset = -1;
610 return ret;
611}
612
613off_t
fba45db2 614lseek_with_trace (int fd, off_t offset, int whence, char *file, int line)
0fda6bd2
JM
615{
616 off_t ret;
617
103b3ef5
MS
618 prepare_to_trace ();
619 errno = 0;
0fda6bd2
JM
620 ret = lseek (fd, offset, whence);
621 lseek_offset = ret;
103b3ef5 622 if (procfs_trace && (ret == -1 || errno != 0))
0fda6bd2 623 {
0fda6bd2 624 fprintf (procfs_file ? procfs_file : stdout,
103b3ef5
MS
625 "[lseek (0x%08lx) FAILED! (%s)]\n",
626 (unsigned long) offset, safe_strerror (errno));
0fda6bd2
JM
627 if (procfs_file)
628 fflush (procfs_file);
629 }
630
631 return ret;
632}
633
634#endif /* NEW_PROC_API */
635
636int
fba45db2 637open_with_trace (char *filename, int mode, char *file, int line)
0fda6bd2 638{
103b3ef5 639 int ret;
0fda6bd2 640
103b3ef5
MS
641 prepare_to_trace ();
642 errno = 0;
643 ret = open (filename, mode);
0fda6bd2
JM
644 if (procfs_trace)
645 {
0fda6bd2
JM
646 if (info_verbose)
647 fprintf (procfs_file ? procfs_file : stdout,
648 "%s:%d -- ", file, line);
103b3ef5
MS
649
650 if (errno)
651 {
652 fprintf (procfs_file ? procfs_file : stdout,
653 "[open FAILED! (%s) line %d]\\n",
654 safe_strerror (errno), line);
655 }
656 else
657 {
658 fprintf (procfs_file ? procfs_file : stdout,
659 "%d = open (%s, ", ret, filename);
660 if (mode == O_RDONLY)
661 fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
662 line);
663 else if (mode == O_WRONLY)
664 fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
665 line);
666 else if (mode == O_RDWR)
667 fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n",
668 line);
669 }
0fda6bd2
JM
670 if (procfs_file)
671 fflush (procfs_file);
672 }
673
674 return ret;
675}
676
677int
fba45db2 678close_with_trace (int fd, char *file, int line)
0fda6bd2 679{
103b3ef5 680 int ret;
0fda6bd2 681
103b3ef5
MS
682 prepare_to_trace ();
683 errno = 0;
684 ret = close (fd);
0fda6bd2
JM
685 if (procfs_trace)
686 {
0fda6bd2
JM
687 if (info_verbose)
688 fprintf (procfs_file ? procfs_file : stdout,
689 "%s:%d -- ", file, line);
103b3ef5
MS
690 if (errno)
691 fprintf (procfs_file ? procfs_file : stdout,
692 "[close FAILED! (%s)]\n", safe_strerror (errno));
693 else
694 fprintf (procfs_file ? procfs_file : stdout,
695 "%d = close (%d)\n", ret, fd);
0fda6bd2
JM
696 if (procfs_file)
697 fflush (procfs_file);
698 }
699
700 return ret;
701}
702
103b3ef5 703pid_t
fba45db2 704wait_with_trace (int *wstat, char *file, int line)
0fda6bd2
JM
705{
706 int ret, lstat = 0;
707
103b3ef5 708 prepare_to_trace ();
0fda6bd2
JM
709 if (procfs_trace)
710 {
0fda6bd2
JM
711 if (info_verbose)
712 fprintf (procfs_file ? procfs_file : stdout,
713 "%s:%d -- ", file, line);
714 fprintf (procfs_file ? procfs_file : stdout,
715 "wait (line %d) ", line);
716 if (procfs_file)
717 fflush (procfs_file);
718 }
103b3ef5 719 errno = 0;
0fda6bd2
JM
720 ret = wait (&lstat);
721 if (procfs_trace)
722 {
103b3ef5
MS
723 if (errno)
724 fprintf (procfs_file ? procfs_file : stdout,
725 "[wait FAILED! (%s)]\n", safe_strerror (errno));
726 else
727 fprintf (procfs_file ? procfs_file : stdout,
728 "returned pid %d, status 0x%x\n", ret, lstat);
0fda6bd2
JM
729 if (procfs_file)
730 fflush (procfs_file);
731 }
732 if (wstat)
733 *wstat = lstat;
734
735 return ret;
736}
737
738void
fba45db2 739procfs_note (char *msg, char *file, int line)
0fda6bd2 740{
103b3ef5 741 prepare_to_trace ();
0fda6bd2
JM
742 if (procfs_trace)
743 {
0fda6bd2
JM
744 if (info_verbose)
745 fprintf (procfs_file ? procfs_file : stdout,
746 "%s:%d -- ", file, line);
e34e1a85 747 fprintf (procfs_file ? procfs_file : stdout, "%s", msg);
0fda6bd2
JM
748 if (procfs_file)
749 fflush (procfs_file);
750 }
751}
752
753void
fba45db2 754proc_prettyfprint_status (long flags, int why, int what, int thread)
0fda6bd2 755{
103b3ef5 756 prepare_to_trace ();
0fda6bd2
JM
757 if (procfs_trace)
758 {
0fda6bd2
JM
759 if (thread)
760 fprintf (procfs_file ? procfs_file : stdout,
761 "Thread %d: ", thread);
762
763 proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
764 flags, 0);
765
766 if (flags & (PR_STOPPED | PR_ISTOP))
767 proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
768 why, what, 0);
769 if (procfs_file)
770 fflush (procfs_file);
771 }
772}
773
774
a0911fd0
MR
775/* Provide a prototype to silence -Wmissing-prototypes. */
776extern void _initialize_proc_api (void);
777
0fda6bd2 778void
fba45db2 779_initialize_proc_api (void)
0fda6bd2
JM
780{
781 struct cmd_list_element *c;
782
54433e38
MK
783 add_setshow_boolean_cmd ("procfs-trace", no_class, &procfs_trace, _("\
784Set tracing for /proc api calls."), _("\
785Show tracing for /proc api calls."), NULL,
5bf193a2
AC
786 set_procfs_trace_cmd,
787 NULL, /* FIXME: i18n: */
788 &setlist, &showlist);
0fda6bd2 789
54433e38
MK
790 add_setshow_filename_cmd ("procfs-file", no_class, &procfs_filename, _("\
791Set filename for /proc tracefile."), _("\
792Show filename for /proc tracefile."), NULL,
f397e303
AC
793 set_procfs_file_cmd,
794 NULL, /* FIXME: i18n: */
795 &setlist, &showlist);
0fda6bd2 796}
This page took 1.17429 seconds and 4 git commands to generate.