1 /* Machine independent support for SVR4 /proc (process file system) for GDB.
3 Copyright 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
5 Written by Michael Snyder at Cygnus Solutions.
6 Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation,
22 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 * Pretty-print trace of api calls to the /proc api
26 * (ioctl or read/write calls).
32 #include "completer.h"
34 #if defined (NEW_PROC_API)
35 #define _STRUCTURED_PROC 1
39 #include <sys/types.h>
40 #include <sys/procfs.h>
41 #ifdef HAVE_SYS_PROC_H
42 #include <sys/proc.h> /* for struct proc */
44 #ifdef HAVE_SYS_USER_H
45 #include <sys/user.h> /* for struct user */
47 #include <fcntl.h> /* for O_RDWR etc. */
50 #include "proc-utils.h"
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
55 their symbolic names and to a string that describes their specific use. */
58 long value; /* The numeric value */
59 char *name; /* The equivalent symbolic value */
60 char *desc; /* Short description of value */
63 static int procfs_trace = 0;
64 static FILE *procfs_file = NULL;
65 static char *procfs_filename = "procfs_trace";
68 prepare_to_trace (void)
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 */
77 set_procfs_trace_cmd (char *args, int from_tty, struct cmd_list_element *c)
79 #if 0 /* not sure what I might actually need to do here, if anything */
86 set_procfs_file_cmd (char *args, int from_tty, struct cmd_list_element *c)
88 /* Just changed the filename for procfs tracing.
89 If a file was already open, close it. */
98 static struct trans ioctl_table[] = {
99 #ifdef PIOCACINFO /* irix */
100 { PIOCACINFO, "PIOCACINFO", "get process account info" },
102 { PIOCACTION, "PIOCACTION", "get signal action structs" },
103 #ifdef PIOCARGUMENTS /* osf */
104 { PIOCARGUMENTS, "PIOCARGUMENTS", "command line args" },
106 #ifdef PIOCAUXV /* solaris aux vectors */
107 { PIOCAUXV, "PIOCAUXV", "get aux vector" },
108 { PIOCNAUXV, "PIOCNAUXV", "get number of aux vector entries" },
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" },
122 #if defined (PIOCGETPR)
123 { PIOCGETPR, "PIOCGETPR", "read struct proc" },
125 #if defined (PIOCGETU)
126 { PIOCGETU, "PIOCGETU", "read user area" },
128 #if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
129 { PIOCGETUTK, "PIOCGETUTK", "get the utask struct" },
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" },
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" },
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" },
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" },
159 { PIOCKILL, "PIOCKILL", "send signal" },
160 #ifdef PIOCLDT /* solaris i386 */
161 { PIOCLDT, "PIOCLDT", "get LDT" },
162 { PIOCNLDT, "PIOCNLDT", "get number of LDT entries" },
164 #ifdef PIOCLSTATUS /* solaris and unixware */
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" },
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" },
178 #ifdef PIOCOPENPD /* solaris */
179 { PIOCOPENPD, "PIOCOPENPD", "get page data file descriptor" },
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" },
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" },
206 { PIOCWSTOP, "PIOCWSTOP", "wait for process to stop" },
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 */
225 ioctl_with_trace (int fd, long opcode, void *ptr, char *file, int line)
235 for (i = 0; ioctl_table[i].name != NULL; i++)
236 if (ioctl_table[i].value == opcode)
240 fprintf (procfs_file ? procfs_file : stdout,
241 "%s:%d -- ", file, line);
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" :
250 arg1 == PR_ASYNC ? "PR_ASYNC" :
253 info_verbose ? ioctl_table[i].desc : "");
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" :
262 arg1 == PR_ASYNC ? "PR_ASYNC" :
265 info_verbose ? ioctl_table[i].desc : "");
268 fprintf (procfs_file ? procfs_file : stdout,
269 "ioctl (PIOCSTRACE) ");
270 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
271 (sigset_t *) ptr, 0);
274 fprintf (procfs_file ? procfs_file : stdout,
276 opcode == PIOCSFAULT ? "PIOCSFAULT" : "PIOCGFAULT");
277 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
278 (fltset_t *) ptr, 0);
281 fprintf (procfs_file ? procfs_file : stdout,
283 opcode == PIOCSENTRY ? "PIOCSENTRY" : "PIOCGENTRY");
284 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
285 (sysset_t *) ptr, 0);
288 fprintf (procfs_file ? procfs_file : stdout,
290 opcode == PIOCSEXIT ? "PIOCSEXIT" : "PIOCGEXIT");
291 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
292 (sysset_t *) ptr, 0);
295 fprintf (procfs_file ? procfs_file : stdout,
297 opcode == PIOCSHOLD ? "PIOCSHOLD" : "PIOCGHOLD");
298 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
299 (sigset_t *) ptr, 0);
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,
307 fprintf (procfs_file ? procfs_file : stdout, "\n");
310 fprintf (procfs_file ? procfs_file : stdout,
313 arg1 = ptr ? *(long *) ptr : 0;
315 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
317 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
319 fprintf (procfs_file ? procfs_file : stdout, "setTrace ");
321 fprintf (procfs_file ? procfs_file : stdout, "setHold ");
323 fprintf (procfs_file ? procfs_file : stdout, "setFlt ");
325 fprintf (procfs_file ? procfs_file : stdout, "setVaddr ");
327 fprintf (procfs_file ? procfs_file : stdout, "step ");
329 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
331 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
333 fprintf (procfs_file ? procfs_file : stdout, "\n");
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");
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");
361 #endif /* PIOCSSPCACT */
363 if (ioctl_table[i].name)
364 fprintf (procfs_file ? procfs_file : stdout,
367 info_verbose ? ioctl_table[i].desc : "");
369 fprintf (procfs_file ? procfs_file : stdout,
370 "ioctl (<unknown %ld (0x%lx)) \n", opcode, opcode);
374 fflush (procfs_file);
377 ret = ioctl (fd, opcode, ptr);
378 if (procfs_trace && ret < 0)
380 fprintf (procfs_file ? procfs_file : stdout,
381 "[ioctl (%s) FAILED! (%s)]\n",
382 ioctl_table[i].name != NULL ?
383 ioctl_table[i].name : "<unknown>",
384 safe_strerror (errno));
386 fflush (procfs_file);
392 #else /* NEW_PROC_API */
394 static struct trans rw_table[] = {
395 #ifdef PCAGENT /* solaris */
396 { PCAGENT, "PCAGENT", "create agent lwp with regs from argument" },
398 { PCCFAULT, "PCCFAULT", "clear current fault" },
399 #ifdef PCCSIG /* solaris */
400 { PCCSIG, "PCCSIG", "clear current signal" },
402 #ifdef PCDSTOP /* solaris */
403 { PCDSTOP, "PCDSTOP", "post stop request" },
405 { PCKILL, "PCKILL", "post a signal" },
406 #ifdef PCNICE /* solaris */
407 { 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 #ifdef PCSHOLD /* solaris */
429 { PCSHOLD, "PCSHOLD", "set signal mask" },
431 { PCSREG, "PCSREG", "set general registers" },
432 { PCSSIG, "PCSSIG", "set current signal" },
433 { PCSTOP, "PCSTOP", "post stop request and wait" },
434 { PCSTRACE, "PCSTRACE", "set traced signal set" },
435 #ifdef PCSVADDR /* solaris */
436 { PCSVADDR, "PCSVADDR", "set pc virtual address" },
438 #ifdef PCSXREG /* solaris sparc only */
439 { PCSXREG, "PCSXREG", "set extra registers" },
441 #ifdef PCTWSTOP /* solaris */
442 { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
444 #ifdef PCUNKILL /* solaris */
445 { PCUNKILL, "PCUNKILL", "delete a pending signal" },
447 #ifdef PCUNSET /* solaris */
448 { PCUNSET, "PCUNSET", "unset modes" },
450 #ifdef PCWATCH /* solaris */
451 { PCWATCH, "PCWATCH", "set/unset watched memory area" },
453 { PCWSTOP, "PCWSTOP", "wait for process/lwp to stop, no timeout" },
457 static off_t lseek_offset;
460 write_with_trace (int fd, void *varg, size_t len, char *file, int line)
462 int i = ARRAY_SIZE (rw_table) - 1;
464 procfs_ctl_t *arg = (procfs_ctl_t *) varg;
469 procfs_ctl_t opcode = arg[0];
470 for (i = 0; rw_table[i].name != NULL; i++)
471 if (rw_table[i].value == opcode)
475 fprintf (procfs_file ? procfs_file : stdout,
476 "%s:%d -- ", file, line);
479 fprintf (procfs_file ? procfs_file : stdout,
480 "write (PCSET, %s) %s\n",
481 arg[1] == PR_FORK ? "PR_FORK" :
482 arg[1] == PR_RLC ? "PR_RLC" :
484 arg[1] == PR_ASYNC ? "PR_ASYNC" :
487 info_verbose ? rw_table[i].desc : "");
493 #if PCRESET != PCUNSET
497 fprintf (procfs_file ? procfs_file : stdout,
498 "write (PCRESET, %s) %s\n",
499 arg[1] == PR_FORK ? "PR_FORK" :
500 arg[1] == PR_RLC ? "PR_RLC" :
502 arg[1] == PR_ASYNC ? "PR_ASYNC" :
505 info_verbose ? rw_table[i].desc : "");
508 fprintf (procfs_file ? procfs_file : stdout,
509 "write (PCSTRACE) ");
510 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
511 (sigset_t *) &arg[1], 0);
514 fprintf (procfs_file ? procfs_file : stdout,
515 "write (PCSFAULT) ");
516 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
517 (fltset_t *) &arg[1], 0);
520 fprintf (procfs_file ? procfs_file : stdout,
521 "write (PCSENTRY) ");
522 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
523 (sysset_t *) &arg[1], 0);
526 fprintf (procfs_file ? procfs_file : stdout,
528 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
529 (sysset_t *) &arg[1], 0);
533 fprintf (procfs_file ? procfs_file : stdout,
535 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
536 (sigset_t *) &arg[1], 0);
540 fprintf (procfs_file ? procfs_file : stdout,
542 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
543 arg[1] ? ((siginfo_t *) &arg[1])->si_signo
546 fprintf (procfs_file ? procfs_file : stdout, "\n");
549 fprintf (procfs_file ? procfs_file : stdout,
552 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
553 if (arg[1] & PRCFAULT)
554 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
556 fprintf (procfs_file ? procfs_file : stdout, "step ");
558 if (arg[1] & PRSABORT)
559 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
563 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
566 fprintf (procfs_file ? procfs_file : stdout, "\n");
569 fprintf (procfs_file ? procfs_file : stdout,
571 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
573 fprintf (procfs_file ? procfs_file : stdout, "\n");
577 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 (int fd, off_t offset, int whence, char *file, int line)
623 ret = lseek (fd, offset, whence);
625 if (procfs_trace && (ret == -1 || errno != 0))
627 fprintf (procfs_file ? procfs_file : stdout,
628 "[lseek (0x%08lx) FAILED! (%s)]\n",
629 (unsigned long) offset, safe_strerror (errno));
631 fflush (procfs_file);
637 #endif /* NEW_PROC_API */
640 open_with_trace (char *filename, int mode, char *file, int line)
646 ret = open (filename, mode);
650 fprintf (procfs_file ? procfs_file : stdout,
651 "%s:%d -- ", file, line);
655 fprintf (procfs_file ? procfs_file : stdout,
656 "[open FAILED! (%s) line %d]\\n",
657 safe_strerror (errno), line);
661 fprintf (procfs_file ? procfs_file : stdout,
662 "%d = open (%s, ", ret, filename);
663 if (mode == O_RDONLY)
664 fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
666 else if (mode == O_WRONLY)
667 fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
669 else if (mode == O_RDWR)
670 fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n",
674 fflush (procfs_file);
681 close_with_trace (int fd, char *file, int line)
691 fprintf (procfs_file ? procfs_file : stdout,
692 "%s:%d -- ", file, line);
694 fprintf (procfs_file ? procfs_file : stdout,
695 "[close FAILED! (%s)]\n", safe_strerror (errno));
697 fprintf (procfs_file ? procfs_file : stdout,
698 "%d = close (%d)\n", ret, fd);
700 fflush (procfs_file);
707 wait_with_trace (int *wstat, char *file, int line)
715 fprintf (procfs_file ? procfs_file : stdout,
716 "%s:%d -- ", file, line);
717 fprintf (procfs_file ? procfs_file : stdout,
718 "wait (line %d) ", line);
720 fflush (procfs_file);
727 fprintf (procfs_file ? procfs_file : stdout,
728 "[wait FAILED! (%s)]\n", safe_strerror (errno));
730 fprintf (procfs_file ? procfs_file : stdout,
731 "returned pid %d, status 0x%x\n", ret, lstat);
733 fflush (procfs_file);
742 procfs_note (char *msg, char *file, int line)
748 fprintf (procfs_file ? procfs_file : stdout,
749 "%s:%d -- ", file, line);
750 fprintf (procfs_file ? procfs_file : stdout, "%s", msg);
752 fflush (procfs_file);
757 proc_prettyfprint_status (long flags, int why, int what, int thread)
763 fprintf (procfs_file ? procfs_file : stdout,
764 "Thread %d: ", thread);
766 proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
769 if (flags & (PR_STOPPED | PR_ISTOP))
770 proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
773 fflush (procfs_file);
779 _initialize_proc_api (void)
781 struct cmd_list_element *c;
783 c = add_set_cmd ("procfs-trace", no_class,
784 var_boolean, (char *) &procfs_trace,
785 "Set tracing for /proc api calls.\n", &setlist);
787 deprecated_add_show_from_set (c, &showlist);
788 set_cmd_sfunc (c, set_procfs_trace_cmd);
789 set_cmd_completer (c, filename_completer);
791 add_setshow_filename_cmd ("procfs-file", no_class, &procfs_filename, _("\
792 Set filename for /proc tracefile."), _("\
793 Show filename for /proc tracefile."), NULL,
795 NULL, /* FIXME: i18n: */
796 &setlist, &showlist);