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