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