1 /* Machine independent support for SVR4 /proc (process file system) for GDB.
2 Copyright 1999 Free Software Foundation, Inc.
3 Written by Michael Snyder at Cygnus Solutions.
4 Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software Foundation,
20 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * Pretty-print trace of api calls to the /proc api
24 * (ioctl or read/write calls).
31 #if defined (NEW_PROC_API)
32 #define _STRUCTURED_PROC 1
36 #include <sys/types.h>
37 #include <sys/procfs.h>
38 #include <sys/proc.h> /* for struct proc */
39 #ifdef HAVE_SYS_USER_H
40 #include <sys/user.h> /* for struct user */
42 #include <fcntl.h> /* for O_RDWR etc. */
45 #include "proc-utils.h"
47 /* Much of the information used in the /proc interface, particularly for
48 printing status information, is kept as tables of structures of the
49 following form. These tables can be used to map numeric values to
50 their symbolic names and to a string that describes their specific use. */
53 long value; /* The numeric value */
54 char *name; /* The equivalent symbolic value */
55 char *desc; /* Short description of value */
58 static int procfs_trace = 0;
59 static FILE *procfs_file = NULL;
60 static char *procfs_filename = "procfs_trace";
63 prepare_to_trace (void)
65 if (procfs_trace) /* if procfs tracing turned on */
66 if (procfs_file == NULL) /* if output file not yet open */
67 if (procfs_filename != NULL) /* if output filename known */
68 procfs_file = fopen (procfs_filename, "a"); /* open output file */
72 set_procfs_trace_cmd (args, from_tty, c)
75 struct cmd_list_element *c;
77 #if 0 /* not sure what I might actually need to do here, if anything */
84 set_procfs_file_cmd (args, from_tty, c)
87 struct cmd_list_element *c;
89 /* Just changed the filename for procfs tracing.
90 If a file was already open, close it. */
99 static struct trans ioctl_table[] = {
100 #ifdef PIOCACINFO /* irix */
101 { PIOCACINFO, "PIOCACINFO", "get process account info" },
103 { PIOCACTION, "PIOCACTION", "get signal action structs" },
104 #ifdef PIOCARGUMENTS /* osf */
105 { PIOCARGUMENTS, "PIOCARGUMENTS", "command line args" },
107 #ifdef PIOCAUXV /* solaris aux vectors */
108 { PIOCAUXV, "PIOCAUXV", "get aux vector" },
109 { PIOCNAUXV, "PIOCNAUXV", "get number of aux vector entries" },
111 { PIOCCFAULT, "PIOCCFAULT", "clear current fault" },
112 { PIOCCRED, "PIOCCRED", "get process credentials" },
113 #ifdef PIOCENEVCTRS /* irix event counters */
114 { PIOCENEVCTRS, "PIOCENEVCTRS", "acquire and start event counters" },
115 { PIOCGETEVCTRL, "PIOCGETEVCTRL", "get control info of event counters" },
116 { PIOCGETEVCTRS, "PIOCGETEVCTRS", "dump event counters" },
117 { PIOCGETPREVCTRS, "PIOCGETPREVCTRS", "dump event counters & prusage info" },
118 { PIOCRELEVCTRS, "PIOCRELEVCTRS", "release/stop event counters" },
119 { PIOCSETEVCTRL, "PIOCSETEVCTRL", "set control info of event counters" },
120 { PIOCGETPTIMER, "PIOCGETPTIMER", "get process timers" },
121 #endif /* irix event counters */
122 { PIOCGENTRY, "PIOCGENTRY", "get traced syscall entry set" },
123 #if defined (PIOCGETPR)
124 { PIOCGETPR, "PIOCGETPR", "read struct proc" },
126 #if defined (PIOCGETU)
127 { PIOCGETU, "PIOCGETU", "read user area" },
129 #if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
130 { PIOCGETUTK, "PIOCGETUTK", "get the utask struct" },
132 { PIOCGEXIT, "PIOCGEXIT", "get traced syscall exit set" },
133 { PIOCGFAULT, "PIOCGFAULT", "get traced fault set" },
134 #ifdef PIOCGFPCR /* osf */
135 { PIOCGFPCR, "PIOCGFPCR", "get FP control register" },
136 { PIOCSFPCR, "PIOCSFPCR", "set FP conrtol register" },
138 { PIOCGFPREG, "PIOCGFPREG", "get floating point registers" },
139 { PIOCGHOLD, "PIOCGHOLD", "get held signal set" },
140 { PIOCGREG, "PIOCGREG", "get general registers" },
141 { PIOCGROUPS, "PIOCGROUPS", "get supplementary groups" },
142 #ifdef PIOCGSPCACT /* osf */
143 { PIOCGSPCACT, "PIOCGSPCACT", "get special action" },
144 { PIOCSSPCACT, "PIOCSSPCACT", "set special action" },
146 { PIOCGTRACE, "PIOCGTRACE", "get traced signal set" },
147 #ifdef PIOCGWATCH /* irix watchpoints */
148 { PIOCGWATCH, "PIOCGWATCH", "get watchpoint" },
149 { PIOCSWATCH, "PIOCSWATCH", "set watchpoint" },
150 { PIOCNWATCH, "PIOCNWATCH", "get number of watchpoints" },
151 #endif /* irix watchpoints */
152 #ifdef PIOCGWIN /* solaris sparc */
153 { PIOCGWIN, "PIOCGWIN", "get gwindows_t" },
155 #ifdef PIOCGXREG /* solaris sparc extra regs */
156 { PIOCGXREGSIZE, "PIOCXREGSIZE", "get extra register state size" },
157 { PIOCGXREG, "PIOCGXREG", "get extra register state" },
158 { PIOCSXREG, "PIOCSXREG", "set extra register state" },
160 { PIOCKILL, "PIOCKILL", "send signal" },
161 #ifdef PIOCLDT /* solaris i386 */
162 { PIOCLDT, "PIOCLDT", "get LDT" },
163 { PIOCNLDT, "PIOCNLDT", "get number of LDT entries" },
165 #ifdef PIOCLSTATUS /* solaris and unixware */
166 { PIOCLSTATUS, "PIOCLSTATUS", "get status of all lwps" },
167 { PIOCLUSAGE, "PIOCLUSAGE", "get resource usage of all lwps" },
168 { PIOCOPENLWP, "PIOCOPENLWP", "get lwp file descriptor" },
169 { PIOCLWPIDS, "PIOCLWPIDS", "get lwp identifiers" },
171 { PIOCMAP, "PIOCMAP", "get memory map information" },
172 { PIOCMAXSIG, "PIOCMAXSIG", "get max signal number" },
173 { PIOCNICE, "PIOCNICE", "set nice priority" },
174 { PIOCNMAP, "PIOCNMAP", "get number of memory mappings" },
175 { PIOCOPENM, "PIOCOPENM", "open mapped object for reading" },
176 #ifdef PIOCOPENMOBS /* osf */
177 { PIOCOPENMOBS, "PIOCOPENMOBS", "open mapped object" },
179 #ifdef PIOCOPENPD /* solaris */
180 { PIOCOPENPD, "PIOCOPENPD", "get page data file descriptor" },
182 { PIOCPSINFO, "PIOCPSINFO", "get ps(1) information" },
183 { PIOCRESET, "PIOCRESET", "reset process flags" },
184 { PIOCRFORK, "PIOCRFORK", "reset inherit-on-fork flag" },
185 { PIOCRRLC, "PIOCRRLC", "reset run-on-last-close flag" },
186 { PIOCRUN, "PIOCRUN", "make process runnable" },
187 #ifdef PIOCSAVECCNTRS /* irix */
188 { PIOCSAVECCNTRS, "PIOCSAVECCNTRS", "parent gets child cntrs" },
190 { PIOCSENTRY, "PIOCSENTRY", "set traced syscall entry set" },
191 { PIOCSET, "PIOCSET", "set process flags" },
192 { PIOCSEXIT, "PIOCSEXIT", "set traced syscall exit set" },
193 { PIOCSFAULT, "PIOCSFAULT", "set traced fault set" },
194 { PIOCSFORK, "PIOCSFORK", "set inherit-on-fork flag" },
195 { PIOCSFPREG, "PIOCSFPREG", "set floating point registers" },
196 { PIOCSHOLD, "PIOCSHOLD", "set held signal set" },
197 { PIOCSREG, "PIOCSREG", "set general registers" },
198 { PIOCSRLC, "PIOCSRLC", "set run-on-last-close flag" },
199 { PIOCSSIG, "PIOCSSIG", "set current signal" },
200 { PIOCSTATUS, "PIOCSTATUS", "get process status" },
201 { PIOCSTOP, "PIOCSTOP", "post stop request" },
202 { PIOCSTRACE, "PIOCSTRACE", "set traced signal set" },
203 { PIOCUNKILL, "PIOCUNKILL", "delete a signal" },
204 #ifdef PIOCUSAGE /* solaris */
205 { PIOCUSAGE, "PIOCUSAGE", "get resource usage" },
207 { PIOCWSTOP, "PIOCWSTOP", "wait for process to stop" },
209 #ifdef PIOCNTHR /* osf threads */
210 { PIOCNTHR, "PIOCNTHR", "get thread count" },
211 { PIOCRTINH, "PIOCRTINH", "reset inherit-on-thread-creation" },
212 { PIOCSTINH, "PIOCSTINH", "set inherit-on-thread-creation" },
213 { PIOCTLIST, "PIOCTLIST", "get thread ids" },
214 { PIOCXPTH, "PIOCXPTH", "translate port to thread handle" },
215 { PIOCTRUN, "PIOCTRUN", "make thread runnable" },
216 { PIOCTSTATUS, "PIOCTSTATUS", "get thread status" },
217 { PIOCTSTOP, "PIOCTSTOP", "stop a thread" },
218 /* ... TGTRACE TSTRACE TSSIG TKILL TUNKILL TCFAULT TGFAULT TSFAULT
219 TGFPREG TSFPREG TGREG TSREG TACTION TTERM TABRUN TGENTRY TSENTRY
220 TGEXIT TSEXIT TSHOLD ... thread functions */
221 #endif /* osf threads */
226 ioctl_with_trace (fd, opcode, ptr, file, line)
239 for (i = 0; ioctl_table[i].name != NULL; i++)
240 if (ioctl_table[i].value == opcode)
244 fprintf (procfs_file ? procfs_file : stdout,
245 "%s:%d -- ", file, line);
248 arg1 = ptr ? *(long *) ptr : 0;
249 fprintf (procfs_file ? procfs_file : stdout,
250 "ioctl (PIOCSET, %s) %s\n",
251 arg1 == PR_FORK ? "PR_FORK" :
252 arg1 == PR_RLC ? "PR_RLC" :
254 arg1 == PR_ASYNC ? "PR_ASYNC" :
257 info_verbose ? ioctl_table[i].desc : "");
260 arg1 = ptr ? *(long *) ptr : 0;
261 fprintf (procfs_file ? procfs_file : stdout,
262 "ioctl (PIOCRESET, %s) %s\n",
263 arg1 == PR_FORK ? "PR_FORK" :
264 arg1 == PR_RLC ? "PR_RLC" :
266 arg1 == PR_ASYNC ? "PR_ASYNC" :
269 info_verbose ? ioctl_table[i].desc : "");
272 fprintf (procfs_file ? procfs_file : stdout,
273 "ioctl (PIOCSTRACE) ");
274 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
275 (sigset_t *) ptr, 0);
278 fprintf (procfs_file ? procfs_file : stdout,
280 opcode == PIOCSFAULT ? "PIOCSFAULT" : "PIOCGFAULT");
281 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
282 (fltset_t *) ptr, 0);
285 fprintf (procfs_file ? procfs_file : stdout,
287 opcode == PIOCSENTRY ? "PIOCSENTRY" : "PIOCGENTRY");
288 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
289 (sysset_t *) ptr, 0);
292 fprintf (procfs_file ? procfs_file : stdout,
294 opcode == PIOCSEXIT ? "PIOCSEXIT" : "PIOCGEXIT");
295 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
296 (sysset_t *) ptr, 0);
299 fprintf (procfs_file ? procfs_file : stdout,
301 opcode == PIOCSHOLD ? "PIOCSHOLD" : "PIOCGHOLD");
302 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
303 (sigset_t *) ptr, 0);
306 fprintf (procfs_file ? procfs_file : stdout,
307 "ioctl (PIOCSSIG) ");
308 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
309 ptr ? ((siginfo_t *) ptr)->si_signo : 0,
311 fprintf (procfs_file ? procfs_file : stdout, "\n");
314 fprintf (procfs_file ? procfs_file : stdout,
317 arg1 = ptr ? *(long *) ptr : 0;
319 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
321 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
323 fprintf (procfs_file ? procfs_file : stdout, "setTrace ");
325 fprintf (procfs_file ? procfs_file : stdout, "setHold ");
327 fprintf (procfs_file ? procfs_file : stdout, "setFlt ");
329 fprintf (procfs_file ? procfs_file : stdout, "setVaddr ");
331 fprintf (procfs_file ? procfs_file : stdout, "step ");
333 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
335 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
337 fprintf (procfs_file ? procfs_file : stdout, "\n");
340 fprintf (procfs_file ? procfs_file : stdout,
341 "ioctl (PIOCKILL) ");
342 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
343 ptr ? *(long *) ptr : 0, 0);
344 fprintf (procfs_file ? procfs_file : stdout, "\n");
348 fprintf (procfs_file ? procfs_file : stdout,
349 "ioctl (PIOCSSPCACT) ");
350 arg1 = ptr ? *(long *) ptr : 0;
351 if (arg1 & PRFS_STOPFORK)
352 fprintf (procfs_file ? procfs_file : stdout, "stopFork ");
353 if (arg1 & PRFS_STOPEXEC)
354 fprintf (procfs_file ? procfs_file : stdout, "stopExec ");
355 if (arg1 & PRFS_STOPTERM)
356 fprintf (procfs_file ? procfs_file : stdout, "stopTerm ");
357 if (arg1 & PRFS_STOPTCR)
358 fprintf (procfs_file ? procfs_file : stdout, "stopThreadCreate ");
359 if (arg1 & PRFS_STOPTTERM)
360 fprintf (procfs_file ? procfs_file : stdout, "stopThreadTerm ");
361 if (arg1 & PRFS_KOLC)
362 fprintf (procfs_file ? procfs_file : stdout, "killOnLastClose ");
363 fprintf (procfs_file ? procfs_file : stdout, "\n");
365 #endif /* PIOCSSPCACT */
367 if (ioctl_table[i].name)
368 fprintf (procfs_file ? procfs_file : stdout,
371 info_verbose ? ioctl_table[i].desc : "");
373 fprintf (procfs_file ? procfs_file : stdout,
374 "ioctl (<unknown %ld (0x%lx)) \n", opcode, opcode);
378 fflush (procfs_file);
381 ret = ioctl (fd, opcode, ptr);
382 if (procfs_trace && ret < 0)
384 fprintf (procfs_file ? procfs_file : stdout,
385 "[ioctl (%s) FAILED! (%s)]\n",
386 ioctl_table[i].name != NULL ?
387 ioctl_table[i].name : "<unknown>",
388 safe_strerror (errno));
390 fflush (procfs_file);
396 #else /* NEW_PROC_API */
398 static struct trans rw_table[] = {
399 #ifdef PCAGENT /* solaris */
400 { PCAGENT, "PCAGENT", "create agent lwp with regs from argument" },
402 { PCCFAULT, "PCCFAULT", "clear current fault" },
403 #ifdef PCCSIG /* solaris */
404 { PCCSIG, "PCCSIG", "clear current signal" },
406 { PCDSTOP, "PCDSTOP", "post stop request" },
407 { PCKILL, "PCKILL", "post a signal" },
408 { PCNICE, "PCNICE", "set nice priority" },
409 #ifdef PCREAD /* solaris */
410 { PCREAD, "PCREAD", "read from the address space" },
411 { PCWRITE, "PCWRITE", "write to the address space" },
413 #ifdef PCRESET /* unixware */
414 { PCRESET, "PCRESET", "unset modes" },
416 { PCRUN, "PCRUN", "make process/lwp runnable" },
417 #ifdef PCSASRS /* solaris 2.7 only */
418 { PCSASRS, "PCSASRS", "set ancillary state registers" },
420 #ifdef PCSCRED /* solaris */
421 { PCSCRED, "PCSCRED", "set process credentials" },
423 { PCSENTRY, "PCSENTRY", "set traced syscall entry set" },
424 { PCSET, "PCSET", "set modes" },
425 { PCSEXIT, "PCSEXIT", "set traced syscall exit set" },
426 { PCSFAULT, "PCSFAULT", "set traced fault set" },
427 { PCSFPREG, "PCSFPREG", "set floating point registers" },
428 { PCSHOLD, "PCSHOLD", "set signal mask" },
429 { PCSREG, "PCSREG", "set general registers" },
430 { PCSSIG, "PCSSIG", "set current signal" },
431 { PCSTOP, "PCSTOP", "post stop request and wait" },
432 { PCSTRACE, "PCSTRACE", "set traced signal set" },
433 #ifdef PCSVADDR /* solaris */
434 { PCSVADDR, "PCSVADDR", "set pc virtual address" },
436 #ifdef PCSXREG /* solaris sparc only */
437 { PCSXREG, "PCSXREG", "set extra registers" },
439 #ifdef PCTWSTOP /* solaris */
440 { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
442 { PCUNKILL, "PCUNKILL", "delete a pending signal" },
443 #ifdef PCUNSET /* solaris */
444 { PCUNSET, "PCUNSET", "unset modes" },
446 #ifdef PCWATCH /* solaris */
447 { PCWATCH, "PCWATCH", "set/unset watched memory area" },
449 { PCWSTOP, "PCWSTOP", "wait for process/lwp to stop, no timeout" },
453 static off_t lseek_offset;
456 write_with_trace (fd, varg, len, file, line)
465 long *arg = (long *) varg;
470 long opcode = arg[0];
471 for (i = 0; rw_table[i].name != NULL; i++)
472 if (rw_table[i].value == opcode)
476 fprintf (procfs_file ? procfs_file : stdout,
477 "%s:%d -- ", file, line);
480 fprintf (procfs_file ? procfs_file : stdout,
481 "write (PCSET, %s) %s\n",
482 arg[1] == PR_FORK ? "PR_FORK" :
483 arg[1] == PR_RLC ? "PR_RLC" :
485 arg[1] == PR_ASYNC ? "PR_ASYNC" :
488 info_verbose ? rw_table[i].desc : "");
496 fprintf (procfs_file ? procfs_file : stdout,
497 "write (PCRESET, %s) %s\n",
498 arg[1] == PR_FORK ? "PR_FORK" :
499 arg[1] == PR_RLC ? "PR_RLC" :
501 arg[1] == PR_ASYNC ? "PR_ASYNC" :
504 info_verbose ? rw_table[i].desc : "");
507 fprintf (procfs_file ? procfs_file : stdout,
508 "write (PCSTRACE) ");
509 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
510 (sigset_t *) &arg[1], 0);
513 fprintf (procfs_file ? procfs_file : stdout,
514 "write (PCSFAULT) ");
515 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
516 (fltset_t *) &arg[1], 0);
519 fprintf (procfs_file ? procfs_file : stdout,
520 "write (PCSENTRY) ");
521 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
522 (sysset_t *) &arg[1], 0);
525 fprintf (procfs_file ? procfs_file : stdout,
527 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
528 (sysset_t *) &arg[1], 0);
531 fprintf (procfs_file ? procfs_file : stdout,
533 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
534 (sigset_t *) &arg[1], 0);
537 fprintf (procfs_file ? procfs_file : stdout,
539 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
540 arg[1] ? ((siginfo_t *) &arg[1])->si_signo
543 fprintf (procfs_file ? procfs_file : stdout, "\n");
546 fprintf (procfs_file ? procfs_file : stdout,
549 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
550 if (arg[1] & PRCFAULT)
551 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
553 fprintf (procfs_file ? procfs_file : stdout, "step ");
554 if (arg[1] & PRSABORT)
555 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
557 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
559 fprintf (procfs_file ? procfs_file : stdout, "\n");
562 fprintf (procfs_file ? procfs_file : stdout,
564 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
566 fprintf (procfs_file ? procfs_file : stdout, "\n");
570 static unsigned char break_insn[] = BREAKPOINT;
572 if (len == sizeof (break_insn) &&
573 memcmp (arg, &break_insn, len) == 0)
574 fprintf (procfs_file ? procfs_file : stdout,
575 "write (<breakpoint at 0x%08lx>) \n",
576 (unsigned long) lseek_offset);
577 else if (rw_table[i].name)
578 fprintf (procfs_file ? procfs_file : stdout,
581 info_verbose ? rw_table[i].desc : "");
584 if (lseek_offset != -1)
585 fprintf (procfs_file ? procfs_file : stdout,
586 "write (<unknown>, %lud bytes at 0x%08lx) \n",
587 (unsigned long) len, (unsigned long) lseek_offset);
589 fprintf (procfs_file ? procfs_file : stdout,
590 "write (<unknown>, %lud bytes) \n",
591 (unsigned long) len);
597 fflush (procfs_file);
600 ret = write (fd, (void *) arg, len);
601 if (procfs_trace && ret != len)
603 fprintf (procfs_file ? procfs_file : stdout,
604 "[write (%s) FAILED! (%s)]\n",
605 rw_table[i].name != NULL ?
606 rw_table[i].name : "<unknown>",
607 safe_strerror (errno));
609 fflush (procfs_file);
617 lseek_with_trace (fd, offset, whence, file, line)
628 ret = lseek (fd, offset, whence);
630 if (procfs_trace && (ret == -1 || errno != 0))
632 fprintf (procfs_file ? procfs_file : stdout,
633 "[lseek (0x%08lx) FAILED! (%s)]\n",
634 (unsigned long) offset, safe_strerror (errno));
636 fflush (procfs_file);
642 #endif /* NEW_PROC_API */
645 open_with_trace (filename, mode, file, line)
655 ret = open (filename, mode);
659 fprintf (procfs_file ? procfs_file : stdout,
660 "%s:%d -- ", file, line);
664 fprintf (procfs_file ? procfs_file : stdout,
665 "[open FAILED! (%s) line %d]\\n",
666 safe_strerror (errno), line);
670 fprintf (procfs_file ? procfs_file : stdout,
671 "%d = open (%s, ", ret, filename);
672 if (mode == O_RDONLY)
673 fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
675 else if (mode == O_WRONLY)
676 fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
678 else if (mode == O_RDWR)
679 fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n",
683 fflush (procfs_file);
690 close_with_trace (fd, file, line)
703 fprintf (procfs_file ? procfs_file : stdout,
704 "%s:%d -- ", file, line);
706 fprintf (procfs_file ? procfs_file : stdout,
707 "[close FAILED! (%s)]\n", safe_strerror (errno));
709 fprintf (procfs_file ? procfs_file : stdout,
710 "%d = close (%d)\n", ret, fd);
712 fflush (procfs_file);
719 wait_with_trace (wstat, file, line)
730 fprintf (procfs_file ? procfs_file : stdout,
731 "%s:%d -- ", file, line);
732 fprintf (procfs_file ? procfs_file : stdout,
733 "wait (line %d) ", line);
735 fflush (procfs_file);
742 fprintf (procfs_file ? procfs_file : stdout,
743 "[wait FAILED! (%s)]\n", safe_strerror (errno));
745 fprintf (procfs_file ? procfs_file : stdout,
746 "returned pid %d, status 0x%x\n", ret, lstat);
748 fflush (procfs_file);
757 procfs_note (msg, file, line)
766 fprintf (procfs_file ? procfs_file : stdout,
767 "%s:%d -- ", file, line);
768 fprintf (procfs_file ? procfs_file : stdout, msg);
770 fflush (procfs_file);
775 proc_prettyfprint_status (flags, why, what, thread)
785 fprintf (procfs_file ? procfs_file : stdout,
786 "Thread %d: ", thread);
788 proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
791 if (flags & (PR_STOPPED | PR_ISTOP))
792 proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
795 fflush (procfs_file);
801 _initialize_proc_api ()
803 struct cmd_list_element *c;
805 c = add_set_cmd ("procfs-trace", no_class,
806 var_boolean, (char *) &procfs_trace,
807 "Set tracing for /proc api calls.\n", &setlist);
809 add_show_from_set (c, &showlist);
810 c->function.sfunc = set_procfs_trace_cmd;
812 c = add_set_cmd ("procfs-file", no_class, var_filename,
813 (char *) &procfs_filename,
814 "Set filename for /proc tracefile.\n", &setlist);
816 add_show_from_set (c, &showlist);
817 c->function.sfunc = set_procfs_file_cmd;