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