1 /* Machine independent support for SVR4 /proc (process file system) for GDB.
3 Copyright (C) 1999-2013 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 3 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, see <http://www.gnu.org/licenses/>. */
24 * Pretty-print trace of api calls to the /proc api
25 * (ioctl or read/write calls).
31 #include "completer.h"
33 #if defined (NEW_PROC_API)
34 #define _STRUCTURED_PROC 1
38 #include <sys/types.h>
39 #include <sys/procfs.h>
40 #ifdef HAVE_SYS_PROC_H
41 #include <sys/proc.h> /* for struct proc */
43 #ifdef HAVE_SYS_USER_H
44 #include <sys/user.h> /* for struct user */
46 #include <fcntl.h> /* for O_RDWR etc. */
49 #include "proc-utils.h"
51 /* Much of the information used in the /proc interface, particularly for
52 printing status information, is kept as tables of structures of the
53 following form. These tables can be used to map numeric values to
54 their symbolic names and to a string that describes their specific use. */
57 long value
; /* The numeric value */
58 char *name
; /* The equivalent symbolic value */
59 char *desc
; /* Short description of value */
62 static int procfs_trace
= 0;
63 static FILE *procfs_file
= NULL
;
64 static char *procfs_filename
= "procfs_trace";
67 prepare_to_trace (void)
69 if (procfs_trace
) /* if procfs tracing turned on */
70 if (procfs_file
== NULL
) /* if output file not yet open */
71 if (procfs_filename
!= NULL
) /* if output filename known */
72 procfs_file
= fopen (procfs_filename
, "a"); /* open output file */
76 set_procfs_trace_cmd (char *args
, int from_tty
, struct cmd_list_element
*c
)
78 #if 0 /* not sure what I might actually need to do here, if anything */
85 set_procfs_file_cmd (char *args
, int from_tty
, struct cmd_list_element
*c
)
87 /* Just changed the filename for procfs tracing.
88 If a file was already open, close it. */
97 static struct trans ioctl_table
[] = {
98 #ifdef PIOCACINFO /* irix */
99 { PIOCACINFO
, "PIOCACINFO", "get process account info" },
101 { PIOCACTION
, "PIOCACTION", "get signal action structs" },
102 #ifdef PIOCARGUMENTS /* osf */
103 { PIOCARGUMENTS
, "PIOCARGUMENTS", "command line args" },
105 #ifdef PIOCAUXV /* solaris aux vectors */
106 { PIOCAUXV
, "PIOCAUXV", "get aux vector" },
107 { PIOCNAUXV
, "PIOCNAUXV", "get number of aux vector entries" },
109 { PIOCCFAULT
, "PIOCCFAULT", "clear current fault" },
110 { PIOCCRED
, "PIOCCRED", "get process credentials" },
111 #ifdef PIOCENEVCTRS /* irix event counters */
112 { PIOCENEVCTRS
, "PIOCENEVCTRS", "acquire and start event counters" },
113 { PIOCGETEVCTRL
, "PIOCGETEVCTRL", "get control info of event counters" },
114 { PIOCGETEVCTRS
, "PIOCGETEVCTRS", "dump event counters" },
115 { PIOCGETPREVCTRS
, "PIOCGETPREVCTRS", "dump event counters & prusage info" },
116 { PIOCRELEVCTRS
, "PIOCRELEVCTRS", "release/stop event counters" },
117 { PIOCSETEVCTRL
, "PIOCSETEVCTRL", "set control info of event counters" },
118 { PIOCGETPTIMER
, "PIOCGETPTIMER", "get process timers" },
119 #endif /* irix event counters */
120 { PIOCGENTRY
, "PIOCGENTRY", "get traced syscall entry set" },
121 #if defined (PIOCGETPR)
122 { PIOCGETPR
, "PIOCGETPR", "read struct proc" },
124 #if defined (PIOCGETU)
125 { PIOCGETU
, "PIOCGETU", "read user area" },
127 #if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
128 { PIOCGETUTK
, "PIOCGETUTK", "get the utask struct" },
130 { PIOCGEXIT
, "PIOCGEXIT", "get traced syscall exit set" },
131 { PIOCGFAULT
, "PIOCGFAULT", "get traced fault set" },
132 #ifdef PIOCGFPCR /* osf */
133 { PIOCGFPCR
, "PIOCGFPCR", "get FP control register" },
134 { PIOCSFPCR
, "PIOCSFPCR", "set FP conrtol register" },
136 { PIOCGFPREG
, "PIOCGFPREG", "get floating point registers" },
137 { PIOCGHOLD
, "PIOCGHOLD", "get held signal set" },
138 { PIOCGREG
, "PIOCGREG", "get general registers" },
139 { PIOCGROUPS
, "PIOCGROUPS", "get supplementary groups" },
140 #ifdef PIOCGSPCACT /* osf */
141 { PIOCGSPCACT
, "PIOCGSPCACT", "get special action" },
142 { PIOCSSPCACT
, "PIOCSSPCACT", "set special action" },
144 { PIOCGTRACE
, "PIOCGTRACE", "get traced signal set" },
145 #ifdef PIOCGWATCH /* irix watchpoints */
146 { PIOCGWATCH
, "PIOCGWATCH", "get watchpoint" },
147 { PIOCSWATCH
, "PIOCSWATCH", "set watchpoint" },
148 { PIOCNWATCH
, "PIOCNWATCH", "get number of watchpoints" },
149 #endif /* irix watchpoints */
150 #ifdef PIOCGWIN /* solaris sparc */
151 { PIOCGWIN
, "PIOCGWIN", "get gwindows_t" },
153 #ifdef PIOCGXREG /* solaris sparc extra regs */
154 { PIOCGXREGSIZE
, "PIOCXREGSIZE", "get extra register state size" },
155 { PIOCGXREG
, "PIOCGXREG", "get extra register state" },
156 { PIOCSXREG
, "PIOCSXREG", "set extra register state" },
158 { PIOCKILL
, "PIOCKILL", "send signal" },
159 #ifdef PIOCLDT /* solaris i386 */
160 { PIOCLDT
, "PIOCLDT", "get LDT" },
161 { PIOCNLDT
, "PIOCNLDT", "get number of LDT entries" },
163 #ifdef PIOCLSTATUS /* solaris */
164 { PIOCLSTATUS
, "PIOCLSTATUS", "get status of all lwps" },
165 { PIOCLUSAGE
, "PIOCLUSAGE", "get resource usage of all lwps" },
166 { PIOCOPENLWP
, "PIOCOPENLWP", "get lwp file descriptor" },
167 { PIOCLWPIDS
, "PIOCLWPIDS", "get lwp identifiers" },
169 { PIOCMAP
, "PIOCMAP", "get memory map information" },
170 { PIOCMAXSIG
, "PIOCMAXSIG", "get max signal number" },
171 { PIOCNICE
, "PIOCNICE", "set nice priority" },
172 { PIOCNMAP
, "PIOCNMAP", "get number of memory mappings" },
173 { PIOCOPENM
, "PIOCOPENM", "open mapped object for reading" },
174 #ifdef PIOCOPENMOBS /* osf */
175 { PIOCOPENMOBS
, "PIOCOPENMOBS", "open mapped object" },
177 #ifdef PIOCOPENPD /* solaris */
178 { PIOCOPENPD
, "PIOCOPENPD", "get page data file descriptor" },
180 { PIOCPSINFO
, "PIOCPSINFO", "get ps(1) information" },
181 { PIOCRESET
, "PIOCRESET", "reset process flags" },
182 { PIOCRFORK
, "PIOCRFORK", "reset inherit-on-fork flag" },
183 { PIOCRRLC
, "PIOCRRLC", "reset run-on-last-close flag" },
184 { PIOCRUN
, "PIOCRUN", "make process runnable" },
185 #ifdef PIOCSAVECCNTRS /* irix */
186 { PIOCSAVECCNTRS
, "PIOCSAVECCNTRS", "parent gets child cntrs" },
188 { PIOCSENTRY
, "PIOCSENTRY", "set traced syscall entry set" },
189 { PIOCSET
, "PIOCSET", "set process flags" },
190 { PIOCSEXIT
, "PIOCSEXIT", "set traced syscall exit set" },
191 { PIOCSFAULT
, "PIOCSFAULT", "set traced fault set" },
192 { PIOCSFORK
, "PIOCSFORK", "set inherit-on-fork flag" },
193 { PIOCSFPREG
, "PIOCSFPREG", "set floating point registers" },
194 { PIOCSHOLD
, "PIOCSHOLD", "set held signal set" },
195 { PIOCSREG
, "PIOCSREG", "set general registers" },
196 { PIOCSRLC
, "PIOCSRLC", "set run-on-last-close flag" },
197 { PIOCSSIG
, "PIOCSSIG", "set current signal" },
198 { PIOCSTATUS
, "PIOCSTATUS", "get process status" },
199 { PIOCSTOP
, "PIOCSTOP", "post stop request" },
200 { PIOCSTRACE
, "PIOCSTRACE", "set traced signal set" },
201 { PIOCUNKILL
, "PIOCUNKILL", "delete a signal" },
202 #ifdef PIOCUSAGE /* solaris */
203 { PIOCUSAGE
, "PIOCUSAGE", "get resource usage" },
205 { PIOCWSTOP
, "PIOCWSTOP", "wait for process to stop" },
207 #ifdef PIOCNTHR /* osf threads */
208 { PIOCNTHR
, "PIOCNTHR", "get thread count" },
209 { PIOCRTINH
, "PIOCRTINH", "reset inherit-on-thread-creation" },
210 { PIOCSTINH
, "PIOCSTINH", "set inherit-on-thread-creation" },
211 { PIOCTLIST
, "PIOCTLIST", "get thread ids" },
212 { PIOCXPTH
, "PIOCXPTH", "translate port to thread handle" },
213 { PIOCTRUN
, "PIOCTRUN", "make thread runnable" },
214 { PIOCTSTATUS
, "PIOCTSTATUS", "get thread status" },
215 { PIOCTSTOP
, "PIOCTSTOP", "stop a thread" },
216 /* ... TGTRACE TSTRACE TSSIG TKILL TUNKILL TCFAULT TGFAULT TSFAULT
217 TGFPREG TSFPREG TGREG TSREG TACTION TTERM TABRUN TGENTRY TSENTRY
218 TGEXIT TSEXIT TSHOLD ... thread functions */
219 #endif /* osf threads */
224 ioctl_with_trace (int fd
, long opcode
, void *ptr
, char *file
, int line
)
234 for (i
= 0; ioctl_table
[i
].name
!= NULL
; i
++)
235 if (ioctl_table
[i
].value
== opcode
)
239 fprintf (procfs_file
? procfs_file
: stdout
,
240 "%s:%d -- ", file
, line
);
243 arg1
= ptr
? *(long *) ptr
: 0;
244 fprintf (procfs_file
? procfs_file
: stdout
,
245 "ioctl (PIOCSET, %s) %s\n",
246 arg1
== PR_FORK
? "PR_FORK" :
247 arg1
== PR_RLC
? "PR_RLC" :
249 arg1
== PR_ASYNC
? "PR_ASYNC" :
252 info_verbose
? ioctl_table
[i
].desc
: "");
255 arg1
= ptr
? *(long *) ptr
: 0;
256 fprintf (procfs_file
? procfs_file
: stdout
,
257 "ioctl (PIOCRESET, %s) %s\n",
258 arg1
== PR_FORK
? "PR_FORK" :
259 arg1
== PR_RLC
? "PR_RLC" :
261 arg1
== PR_ASYNC
? "PR_ASYNC" :
264 info_verbose
? ioctl_table
[i
].desc
: "");
267 fprintf (procfs_file
? procfs_file
: stdout
,
268 "ioctl (PIOCSTRACE) ");
269 proc_prettyfprint_signalset (procfs_file
? procfs_file
: stdout
,
270 (sigset_t
*) ptr
, 0);
273 fprintf (procfs_file
? procfs_file
: stdout
,
275 opcode
== PIOCSFAULT
? "PIOCSFAULT" : "PIOCGFAULT");
276 proc_prettyfprint_faultset (procfs_file
? procfs_file
: stdout
,
277 (fltset_t
*) ptr
, 0);
280 fprintf (procfs_file
? procfs_file
: stdout
,
282 opcode
== PIOCSENTRY
? "PIOCSENTRY" : "PIOCGENTRY");
283 proc_prettyfprint_syscalls (procfs_file
? procfs_file
: stdout
,
284 (sysset_t
*) ptr
, 0);
287 fprintf (procfs_file
? procfs_file
: stdout
,
289 opcode
== PIOCSEXIT
? "PIOCSEXIT" : "PIOCGEXIT");
290 proc_prettyfprint_syscalls (procfs_file
? procfs_file
: stdout
,
291 (sysset_t
*) ptr
, 0);
294 fprintf (procfs_file
? procfs_file
: stdout
,
296 opcode
== PIOCSHOLD
? "PIOCSHOLD" : "PIOCGHOLD");
297 proc_prettyfprint_signalset (procfs_file
? procfs_file
: stdout
,
298 (sigset_t
*) ptr
, 0);
301 fprintf (procfs_file
? procfs_file
: stdout
,
302 "ioctl (PIOCSSIG) ");
303 proc_prettyfprint_signal (procfs_file
? procfs_file
: stdout
,
304 ptr
? ((siginfo_t
*) ptr
)->si_signo
: 0,
306 fprintf (procfs_file
? procfs_file
: stdout
, "\n");
309 fprintf (procfs_file
? procfs_file
: stdout
,
312 arg1
= ptr
? *(long *) ptr
: 0;
314 fprintf (procfs_file
? procfs_file
: stdout
, "clearSig ");
316 fprintf (procfs_file
? procfs_file
: stdout
, "clearFlt ");
318 fprintf (procfs_file
? procfs_file
: stdout
, "setTrace ");
320 fprintf (procfs_file
? procfs_file
: stdout
, "setHold ");
322 fprintf (procfs_file
? procfs_file
: stdout
, "setFlt ");
324 fprintf (procfs_file
? procfs_file
: stdout
, "setVaddr ");
326 fprintf (procfs_file
? procfs_file
: stdout
, "step ");
328 fprintf (procfs_file
? procfs_file
: stdout
, "syscallAbort ");
330 fprintf (procfs_file
? procfs_file
: stdout
, "stopReq ");
332 fprintf (procfs_file
? procfs_file
: stdout
, "\n");
335 fprintf (procfs_file
? procfs_file
: stdout
,
336 "ioctl (PIOCKILL) ");
337 proc_prettyfprint_signal (procfs_file
? procfs_file
: stdout
,
338 ptr
? *(long *) ptr
: 0, 0);
339 fprintf (procfs_file
? procfs_file
: stdout
, "\n");
343 fprintf (procfs_file
? procfs_file
: stdout
,
344 "ioctl (PIOCSSPCACT) ");
345 arg1
= ptr
? *(long *) ptr
: 0;
346 if (arg1
& PRFS_STOPFORK
)
347 fprintf (procfs_file
? procfs_file
: stdout
, "stopFork ");
348 if (arg1
& PRFS_STOPEXEC
)
349 fprintf (procfs_file
? procfs_file
: stdout
, "stopExec ");
350 if (arg1
& PRFS_STOPTERM
)
351 fprintf (procfs_file
? procfs_file
: stdout
, "stopTerm ");
352 if (arg1
& PRFS_STOPTCR
)
353 fprintf (procfs_file
? procfs_file
: stdout
, "stopThreadCreate ");
354 if (arg1
& PRFS_STOPTTERM
)
355 fprintf (procfs_file
? procfs_file
: stdout
, "stopThreadTerm ");
356 if (arg1
& PRFS_KOLC
)
357 fprintf (procfs_file
? procfs_file
: stdout
, "killOnLastClose ");
358 fprintf (procfs_file
? procfs_file
: stdout
, "\n");
360 #endif /* PIOCSSPCACT */
362 if (ioctl_table
[i
].name
)
363 fprintf (procfs_file
? procfs_file
: stdout
,
366 info_verbose
? ioctl_table
[i
].desc
: "");
368 fprintf (procfs_file
? procfs_file
: stdout
,
369 "ioctl (<unknown %ld (0x%lx)) \n", opcode
, opcode
);
373 fflush (procfs_file
);
376 ret
= ioctl (fd
, opcode
, ptr
);
377 if (procfs_trace
&& ret
< 0)
379 fprintf (procfs_file
? procfs_file
: stdout
,
380 "[ioctl (%s) FAILED! (%s)]\n",
381 ioctl_table
[i
].name
!= NULL
?
382 ioctl_table
[i
].name
: "<unknown>",
383 safe_strerror (errno
));
385 fflush (procfs_file
);
391 #else /* NEW_PROC_API */
393 static struct trans rw_table
[] = {
394 #ifdef PCAGENT /* solaris */
395 { PCAGENT
, "PCAGENT", "create agent lwp with regs from argument" },
397 { PCCFAULT
, "PCCFAULT", "clear current fault" },
398 #ifdef PCCSIG /* solaris */
399 { PCCSIG
, "PCCSIG", "clear current signal" },
401 #ifdef PCDSTOP /* solaris */
402 { PCDSTOP
, "PCDSTOP", "post stop request" },
404 { PCKILL
, "PCKILL", "post a signal" },
405 #ifdef PCNICE /* solaris */
406 { PCNICE
, "PCNICE", "set nice priority" },
408 #ifdef PCREAD /* solaris */
409 { PCREAD
, "PCREAD", "read from the address space" },
410 { PCWRITE
, "PCWRITE", "write to the address space" },
412 { PCRUN
, "PCRUN", "make process/lwp runnable" },
413 #ifdef PCSASRS /* solaris 2.7 only */
414 { PCSASRS
, "PCSASRS", "set ancillary state registers" },
416 #ifdef PCSCRED /* solaris */
417 { PCSCRED
, "PCSCRED", "set process credentials" },
419 { PCSENTRY
, "PCSENTRY", "set traced syscall entry set" },
420 { PCSET
, "PCSET", "set modes" },
421 { PCSEXIT
, "PCSEXIT", "set traced syscall exit set" },
422 { PCSFAULT
, "PCSFAULT", "set traced fault set" },
423 { PCSFPREG
, "PCSFPREG", "set floating point registers" },
424 #ifdef PCSHOLD /* solaris */
425 { PCSHOLD
, "PCSHOLD", "set signal mask" },
427 { PCSREG
, "PCSREG", "set general registers" },
428 { PCSSIG
, "PCSSIG", "set current signal" },
429 { PCSTOP
, "PCSTOP", "post stop request and wait" },
430 { PCSTRACE
, "PCSTRACE", "set traced signal set" },
431 #ifdef PCSVADDR /* solaris */
432 { PCSVADDR
, "PCSVADDR", "set pc virtual address" },
434 #ifdef PCSXREG /* solaris sparc only */
435 { PCSXREG
, "PCSXREG", "set extra registers" },
437 #ifdef PCTWSTOP /* solaris */
438 { PCTWSTOP
, "PCTWSTOP", "wait for stop, with timeout arg" },
440 #ifdef PCUNKILL /* solaris */
441 { 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 (int fd
, void *varg
, size_t len
, char *file
, int line
)
458 int i
= ARRAY_SIZE (rw_table
) - 1;
460 procfs_ctl_t
*arg
= (procfs_ctl_t
*) varg
;
465 procfs_ctl_t opcode
= arg
[0];
466 for (i
= 0; rw_table
[i
].name
!= NULL
; i
++)
467 if (rw_table
[i
].value
== opcode
)
471 fprintf (procfs_file
? procfs_file
: stdout
,
472 "%s:%d -- ", file
, line
);
475 fprintf (procfs_file
? procfs_file
: stdout
,
476 "write (PCSET, %s) %s\n",
477 arg
[1] == PR_FORK
? "PR_FORK" :
478 arg
[1] == PR_RLC
? "PR_RLC" :
480 arg
[1] == PR_ASYNC
? "PR_ASYNC" :
483 info_verbose
? rw_table
[i
].desc
: "");
489 #if PCRESET != PCUNSET
493 fprintf (procfs_file
? procfs_file
: stdout
,
494 "write (PCRESET, %s) %s\n",
495 arg
[1] == PR_FORK
? "PR_FORK" :
496 arg
[1] == PR_RLC
? "PR_RLC" :
498 arg
[1] == PR_ASYNC
? "PR_ASYNC" :
501 info_verbose
? rw_table
[i
].desc
: "");
504 fprintf (procfs_file
? procfs_file
: stdout
,
505 "write (PCSTRACE) ");
506 proc_prettyfprint_signalset (procfs_file
? procfs_file
: stdout
,
507 (sigset_t
*) &arg
[1], 0);
510 fprintf (procfs_file
? procfs_file
: stdout
,
511 "write (PCSFAULT) ");
512 proc_prettyfprint_faultset (procfs_file
? procfs_file
: stdout
,
513 (fltset_t
*) &arg
[1], 0);
516 fprintf (procfs_file
? procfs_file
: stdout
,
517 "write (PCSENTRY) ");
518 proc_prettyfprint_syscalls (procfs_file
? procfs_file
: stdout
,
519 (sysset_t
*) &arg
[1], 0);
522 fprintf (procfs_file
? procfs_file
: stdout
,
524 proc_prettyfprint_syscalls (procfs_file
? procfs_file
: stdout
,
525 (sysset_t
*) &arg
[1], 0);
529 fprintf (procfs_file
? procfs_file
: stdout
,
531 proc_prettyfprint_signalset (procfs_file
? procfs_file
: stdout
,
532 (sigset_t
*) &arg
[1], 0);
536 fprintf (procfs_file
? procfs_file
: stdout
,
538 proc_prettyfprint_signal (procfs_file
? procfs_file
: stdout
,
539 arg
[1] ? ((siginfo_t
*) &arg
[1])->si_signo
542 fprintf (procfs_file
? procfs_file
: stdout
, "\n");
545 fprintf (procfs_file
? procfs_file
: stdout
,
548 fprintf (procfs_file
? procfs_file
: stdout
, "clearSig ");
549 if (arg
[1] & PRCFAULT
)
550 fprintf (procfs_file
? procfs_file
: stdout
, "clearFlt ");
552 fprintf (procfs_file
? procfs_file
: stdout
, "step ");
554 if (arg
[1] & PRSABORT
)
555 fprintf (procfs_file
? procfs_file
: stdout
, "syscallAbort ");
559 fprintf (procfs_file
? procfs_file
: stdout
, "stopReq ");
562 fprintf (procfs_file
? procfs_file
: stdout
, "\n");
565 fprintf (procfs_file
? procfs_file
: stdout
,
567 proc_prettyfprint_signal (procfs_file
? procfs_file
: stdout
,
569 fprintf (procfs_file
? procfs_file
: stdout
, "\n");
573 if (rw_table
[i
].name
)
574 fprintf (procfs_file
? procfs_file
: stdout
,
577 info_verbose
? rw_table
[i
].desc
: "");
580 if (lseek_offset
!= -1)
581 fprintf (procfs_file
? procfs_file
: stdout
,
582 "write (<unknown>, %lud bytes at 0x%08lx) \n",
583 (unsigned long) len
, (unsigned long) lseek_offset
);
585 fprintf (procfs_file
? procfs_file
: stdout
,
586 "write (<unknown>, %lud bytes) \n",
587 (unsigned long) len
);
593 fflush (procfs_file
);
596 ret
= write (fd
, (void *) arg
, len
);
597 if (procfs_trace
&& ret
!= len
)
599 fprintf (procfs_file
? procfs_file
: stdout
,
600 "[write (%s) FAILED! (%s)]\n",
601 rw_table
[i
].name
!= NULL
?
602 rw_table
[i
].name
: "<unknown>",
603 safe_strerror (errno
));
605 fflush (procfs_file
);
613 lseek_with_trace (int fd
, off_t offset
, int whence
, char *file
, int line
)
619 ret
= lseek (fd
, offset
, whence
);
621 if (procfs_trace
&& (ret
== -1 || errno
!= 0))
623 fprintf (procfs_file
? procfs_file
: stdout
,
624 "[lseek (0x%08lx) FAILED! (%s)]\n",
625 (unsigned long) offset
, safe_strerror (errno
));
627 fflush (procfs_file
);
633 #endif /* NEW_PROC_API */
636 open_with_trace (char *filename
, int mode
, char *file
, int line
)
642 ret
= open (filename
, mode
);
646 fprintf (procfs_file
? procfs_file
: stdout
,
647 "%s:%d -- ", file
, line
);
651 fprintf (procfs_file
? procfs_file
: stdout
,
652 "[open FAILED! (%s) line %d]\\n",
653 safe_strerror (errno
), line
);
657 fprintf (procfs_file
? procfs_file
: stdout
,
658 "%d = open (%s, ", ret
, filename
);
659 if (mode
== O_RDONLY
)
660 fprintf (procfs_file
? procfs_file
: stdout
, "O_RDONLY) %d\n",
662 else if (mode
== O_WRONLY
)
663 fprintf (procfs_file
? procfs_file
: stdout
, "O_WRONLY) %d\n",
665 else if (mode
== O_RDWR
)
666 fprintf (procfs_file
? procfs_file
: stdout
, "O_RDWR) %d\n",
670 fflush (procfs_file
);
677 close_with_trace (int fd
, char *file
, int line
)
687 fprintf (procfs_file
? procfs_file
: stdout
,
688 "%s:%d -- ", file
, line
);
690 fprintf (procfs_file
? procfs_file
: stdout
,
691 "[close FAILED! (%s)]\n", safe_strerror (errno
));
693 fprintf (procfs_file
? procfs_file
: stdout
,
694 "%d = close (%d)\n", ret
, fd
);
696 fflush (procfs_file
);
703 wait_with_trace (int *wstat
, char *file
, int line
)
711 fprintf (procfs_file
? procfs_file
: stdout
,
712 "%s:%d -- ", file
, line
);
713 fprintf (procfs_file
? procfs_file
: stdout
,
714 "wait (line %d) ", line
);
716 fflush (procfs_file
);
723 fprintf (procfs_file
? procfs_file
: stdout
,
724 "[wait FAILED! (%s)]\n", safe_strerror (errno
));
726 fprintf (procfs_file
? procfs_file
: stdout
,
727 "returned pid %d, status 0x%x\n", ret
, lstat
);
729 fflush (procfs_file
);
738 procfs_note (char *msg
, char *file
, int line
)
744 fprintf (procfs_file
? procfs_file
: stdout
,
745 "%s:%d -- ", file
, line
);
746 fprintf (procfs_file
? procfs_file
: stdout
, "%s", msg
);
748 fflush (procfs_file
);
753 proc_prettyfprint_status (long flags
, int why
, int what
, int thread
)
759 fprintf (procfs_file
? procfs_file
: stdout
,
760 "Thread %d: ", thread
);
762 proc_prettyfprint_flags (procfs_file
? procfs_file
: stdout
,
765 if (flags
& (PR_STOPPED
| PR_ISTOP
))
766 proc_prettyfprint_why (procfs_file
? procfs_file
: stdout
,
769 fflush (procfs_file
);
774 /* Provide a prototype to silence -Wmissing-prototypes. */
775 extern void _initialize_proc_api (void);
778 _initialize_proc_api (void)
780 struct cmd_list_element
*c
;
782 add_setshow_boolean_cmd ("procfs-trace", no_class
, &procfs_trace
, _("\
783 Set tracing for /proc api calls."), _("\
784 Show tracing for /proc api calls."), NULL
,
785 set_procfs_trace_cmd
,
786 NULL
, /* FIXME: i18n: */
787 &setlist
, &showlist
);
789 add_setshow_filename_cmd ("procfs-file", no_class
, &procfs_filename
, _("\
790 Set filename for /proc tracefile."), _("\
791 Show filename for /proc tracefile."), NULL
,
793 NULL
, /* FIXME: i18n: */
794 &setlist
, &showlist
);