2003-01-27 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / gdb / proc-api.c
CommitLineData
0fda6bd2 1/* Machine independent support for SVR4 /proc (process file system) for GDB.
b6ba6518 2 Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
0fda6bd2
JM
3 Written by Michael Snyder at Cygnus Solutions.
4 Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software Foundation,
20Inc., 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"
8e40d292 30#include "completer.h"
0fda6bd2
JM
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>
8dd72958 39#ifdef HAVE_SYS_PROC_H
0fda6bd2 40#include <sys/proc.h> /* for struct proc */
8dd72958 41#endif
6e8cb14a 42#ifdef HAVE_SYS_USER_H
0fda6bd2 43#include <sys/user.h> /* for struct user */
6e8cb14a 44#endif
0fda6bd2
JM
45#include <fcntl.h> /* for O_RDWR etc. */
46#include <sys/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
55struct trans {
56 long value; /* The numeric value */
57 char *name; /* The equivalent symbolic value */
58 char *desc; /* Short description of value */
59};
60
103b3ef5 61static int procfs_trace = 0;
0fda6bd2
JM
62static FILE *procfs_file = NULL;
63static char *procfs_filename = "procfs_trace";
64
103b3ef5
MS
65static void
66prepare_to_trace (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
0fda6bd2 74static void
fba45db2 75set_procfs_trace_cmd (char *args, int from_tty, struct cmd_list_element *c)
0fda6bd2
JM
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
83static void
fba45db2 84set_procfs_file_cmd (char *args, int from_tty, struct cmd_list_element *c)
0fda6bd2
JM
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
96static 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" },
6e8cb14a 120#if defined (PIOCGETPR)
0fda6bd2 121 { PIOCGETPR, "PIOCGETPR", "read struct proc" },
6e8cb14a
AC
122#endif
123#if defined (PIOCGETU)
0fda6bd2 124 { PIOCGETU, "PIOCGETU", "read user area" },
6e8cb14a 125#endif
0fda6bd2
JM
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 and unixware */
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
222int
fba45db2 223ioctl_with_trace (int fd, long opcode, void *ptr, char *file, int line)
0fda6bd2 224{
8e40d292
EZ
225 int i = 0;
226 int ret;
227 int arg1;
0fda6bd2 228
103b3ef5
MS
229 prepare_to_trace ();
230
0fda6bd2
JM
231 if (procfs_trace)
232 {
0fda6bd2
JM
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 }
103b3ef5 374 errno = 0;
0fda6bd2
JM
375 ret = ioctl (fd, opcode, ptr);
376 if (procfs_trace && ret < 0)
377 {
378 fprintf (procfs_file ? procfs_file : stdout,
103b3ef5 379 "[ioctl (%s) FAILED! (%s)]\n",
0fda6bd2 380 ioctl_table[i].name != NULL ?
103b3ef5
MS
381 ioctl_table[i].name : "<unknown>",
382 safe_strerror (errno));
0fda6bd2
JM
383 if (procfs_file)
384 fflush (procfs_file);
385 }
386
387 return ret;
388}
389
390#else /* NEW_PROC_API */
391
392static 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
640b227f 400#ifdef PCDSTOP /* solaris */
0fda6bd2 401 { PCDSTOP, "PCDSTOP", "post stop request" },
640b227f 402#endif
0fda6bd2 403 { PCKILL, "PCKILL", "post a signal" },
640b227f 404#ifdef PCNICE /* solaris */
0fda6bd2 405 { PCNICE, "PCNICE", "set nice priority" },
640b227f 406#endif
0fda6bd2
JM
407#ifdef PCREAD /* solaris */
408 { PCREAD, "PCREAD", "read from the address space" },
409 { PCWRITE, "PCWRITE", "write to the address space" },
410#endif
411#ifdef PCRESET /* unixware */
412 { PCRESET, "PCRESET", "unset modes" },
413#endif
414 { PCRUN, "PCRUN", "make process/lwp runnable" },
415#ifdef PCSASRS /* solaris 2.7 only */
416 { PCSASRS, "PCSASRS", "set ancillary state registers" },
417#endif
418#ifdef PCSCRED /* solaris */
419 { PCSCRED, "PCSCRED", "set process credentials" },
420#endif
421 { PCSENTRY, "PCSENTRY", "set traced syscall entry set" },
422 { PCSET, "PCSET", "set modes" },
423 { PCSEXIT, "PCSEXIT", "set traced syscall exit set" },
424 { PCSFAULT, "PCSFAULT", "set traced fault set" },
425 { PCSFPREG, "PCSFPREG", "set floating point registers" },
151fefe2 426#ifdef PCSHOLD /* solaris */
0fda6bd2 427 { PCSHOLD, "PCSHOLD", "set signal mask" },
640b227f 428#endif
0fda6bd2
JM
429 { PCSREG, "PCSREG", "set general registers" },
430 { PCSSIG, "PCSSIG", "set current signal" },
431 { PCSTOP, "PCSTOP", "post stop request and wait" },
432 { PCSTRACE, "PCSTRACE", "set traced signal set" },
433#ifdef PCSVADDR /* solaris */
434 { PCSVADDR, "PCSVADDR", "set pc virtual address" },
435#endif
436#ifdef PCSXREG /* solaris sparc only */
437 { PCSXREG, "PCSXREG", "set extra registers" },
438#endif
439#ifdef PCTWSTOP /* solaris */
440 { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
441#endif
640b227f 442#ifdef PCUNKILL /* solaris */
0fda6bd2 443 { PCUNKILL, "PCUNKILL", "delete a pending signal" },
640b227f 444#endif
0fda6bd2
JM
445#ifdef PCUNSET /* solaris */
446 { PCUNSET, "PCUNSET", "unset modes" },
447#endif
448#ifdef PCWATCH /* solaris */
449 { PCWATCH, "PCWATCH", "set/unset watched memory area" },
450#endif
451 { PCWSTOP, "PCWSTOP", "wait for process/lwp to stop, no timeout" },
452 { 0, NULL, NULL }
453};
454
455static off_t lseek_offset;
456
457int
fba45db2 458write_with_trace (int fd, void *varg, size_t len, char *file, int line)
0fda6bd2
JM
459{
460 int i;
0fda6bd2 461 int ret;
37de36c6 462 procfs_ctl_t *arg = (procfs_ctl_t *) varg;
0fda6bd2 463
103b3ef5 464 prepare_to_trace ();
0fda6bd2
JM
465 if (procfs_trace)
466 {
37de36c6 467 procfs_ctl_t opcode = arg[0];
0fda6bd2
JM
468 for (i = 0; rw_table[i].name != NULL; i++)
469 if (rw_table[i].value == opcode)
470 break;
471
472 if (info_verbose)
473 fprintf (procfs_file ? procfs_file : stdout,
474 "%s:%d -- ", file, line);
475 switch (opcode) {
476 case PCSET:
477 fprintf (procfs_file ? procfs_file : stdout,
478 "write (PCSET, %s) %s\n",
479 arg[1] == PR_FORK ? "PR_FORK" :
480 arg[1] == PR_RLC ? "PR_RLC" :
481#ifdef PR_ASYNC
482 arg[1] == PR_ASYNC ? "PR_ASYNC" :
483#endif
484 "<unknown flag>",
485 info_verbose ? rw_table[i].desc : "");
486 break;
487#ifdef PCUNSET
488 case PCUNSET:
489#endif
490#ifdef PCRESET
37de36c6 491#if PCRESET != PCUNSET
0fda6bd2 492 case PCRESET:
37de36c6 493#endif
0fda6bd2
JM
494#endif
495 fprintf (procfs_file ? procfs_file : stdout,
496 "write (PCRESET, %s) %s\n",
497 arg[1] == PR_FORK ? "PR_FORK" :
498 arg[1] == PR_RLC ? "PR_RLC" :
499#ifdef PR_ASYNC
500 arg[1] == PR_ASYNC ? "PR_ASYNC" :
501#endif
502 "<unknown flag>",
503 info_verbose ? rw_table[i].desc : "");
504 break;
505 case PCSTRACE:
506 fprintf (procfs_file ? procfs_file : stdout,
507 "write (PCSTRACE) ");
508 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
509 (sigset_t *) &arg[1], 0);
510 break;
511 case PCSFAULT:
512 fprintf (procfs_file ? procfs_file : stdout,
513 "write (PCSFAULT) ");
514 proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
515 (fltset_t *) &arg[1], 0);
516 break;
517 case PCSENTRY:
518 fprintf (procfs_file ? procfs_file : stdout,
519 "write (PCSENTRY) ");
520 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
521 (sysset_t *) &arg[1], 0);
522 break;
523 case PCSEXIT:
524 fprintf (procfs_file ? procfs_file : stdout,
525 "write (PCSEXIT) ");
526 proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
527 (sysset_t *) &arg[1], 0);
528 break;
640b227f 529#ifdef PCSHOLD
0fda6bd2
JM
530 case PCSHOLD:
531 fprintf (procfs_file ? procfs_file : stdout,
532 "write (PCSHOLD) ");
533 proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
534 (sigset_t *) &arg[1], 0);
535 break;
640b227f 536#endif
0fda6bd2
JM
537 case PCSSIG:
538 fprintf (procfs_file ? procfs_file : stdout,
539 "write (PCSSIG) ");
540 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
541 arg[1] ? ((siginfo_t *) &arg[1])->si_signo
542 : 0,
543 0);
544 fprintf (procfs_file ? procfs_file : stdout, "\n");
545 break;
546 case PCRUN:
547 fprintf (procfs_file ? procfs_file : stdout,
548 "write (PCRUN) ");
549 if (arg[1] & PRCSIG)
550 fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
551 if (arg[1] & PRCFAULT)
552 fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
553 if (arg[1] & PRSTEP)
554 fprintf (procfs_file ? procfs_file : stdout, "step ");
640b227f 555#ifdef PRSABORT
0fda6bd2
JM
556 if (arg[1] & PRSABORT)
557 fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
640b227f
JB
558#endif
559#ifdef PRSTOP
0fda6bd2
JM
560 if (arg[1] & PRSTOP)
561 fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
640b227f 562#endif
0fda6bd2
JM
563
564 fprintf (procfs_file ? procfs_file : stdout, "\n");
565 break;
566 case PCKILL:
567 fprintf (procfs_file ? procfs_file : stdout,
568 "write (PCKILL) ");
569 proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
570 arg[1], 0);
571 fprintf (procfs_file ? procfs_file : stdout, "\n");
572 break;
573 default:
574 {
37de36c6 575#ifdef BREAKPOINT
0fda6bd2
JM
576 static unsigned char break_insn[] = BREAKPOINT;
577
578 if (len == sizeof (break_insn) &&
579 memcmp (arg, &break_insn, len) == 0)
580 fprintf (procfs_file ? procfs_file : stdout,
b943d152
MS
581 "write (<breakpoint at 0x%08lx>) \n",
582 (unsigned long) lseek_offset);
37de36c6
KB
583 else
584#endif
585 if (rw_table[i].name)
0fda6bd2
JM
586 fprintf (procfs_file ? procfs_file : stdout,
587 "write (%s) %s\n",
588 rw_table[i].name,
589 info_verbose ? rw_table[i].desc : "");
590 else
591 {
592 if (lseek_offset != -1)
593 fprintf (procfs_file ? procfs_file : stdout,
b943d152
MS
594 "write (<unknown>, %lud bytes at 0x%08lx) \n",
595 (unsigned long) len, (unsigned long) lseek_offset);
0fda6bd2
JM
596 else
597 fprintf (procfs_file ? procfs_file : stdout,
b943d152
MS
598 "write (<unknown>, %lud bytes) \n",
599 (unsigned long) len);
0fda6bd2
JM
600 }
601 break;
602 }
603 }
604 if (procfs_file)
605 fflush (procfs_file);
606 }
103b3ef5 607 errno = 0;
b943d152 608 ret = write (fd, (void *) arg, len);
0fda6bd2
JM
609 if (procfs_trace && ret != len)
610 {
611 fprintf (procfs_file ? procfs_file : stdout,
103b3ef5 612 "[write (%s) FAILED! (%s)]\n",
0fda6bd2 613 rw_table[i].name != NULL ?
103b3ef5
MS
614 rw_table[i].name : "<unknown>",
615 safe_strerror (errno));
0fda6bd2
JM
616 if (procfs_file)
617 fflush (procfs_file);
618 }
619
620 lseek_offset = -1;
621 return ret;
622}
623
624off_t
fba45db2 625lseek_with_trace (int fd, off_t offset, int whence, char *file, int line)
0fda6bd2
JM
626{
627 off_t ret;
628
103b3ef5
MS
629 prepare_to_trace ();
630 errno = 0;
0fda6bd2
JM
631 ret = lseek (fd, offset, whence);
632 lseek_offset = ret;
103b3ef5 633 if (procfs_trace && (ret == -1 || errno != 0))
0fda6bd2 634 {
0fda6bd2 635 fprintf (procfs_file ? procfs_file : stdout,
103b3ef5
MS
636 "[lseek (0x%08lx) FAILED! (%s)]\n",
637 (unsigned long) offset, safe_strerror (errno));
0fda6bd2
JM
638 if (procfs_file)
639 fflush (procfs_file);
640 }
641
642 return ret;
643}
644
645#endif /* NEW_PROC_API */
646
647int
fba45db2 648open_with_trace (char *filename, int mode, char *file, int line)
0fda6bd2 649{
103b3ef5 650 int ret;
0fda6bd2 651
103b3ef5
MS
652 prepare_to_trace ();
653 errno = 0;
654 ret = open (filename, mode);
0fda6bd2
JM
655 if (procfs_trace)
656 {
0fda6bd2
JM
657 if (info_verbose)
658 fprintf (procfs_file ? procfs_file : stdout,
659 "%s:%d -- ", file, line);
103b3ef5
MS
660
661 if (errno)
662 {
663 fprintf (procfs_file ? procfs_file : stdout,
664 "[open FAILED! (%s) line %d]\\n",
665 safe_strerror (errno), line);
666 }
667 else
668 {
669 fprintf (procfs_file ? procfs_file : stdout,
670 "%d = open (%s, ", ret, filename);
671 if (mode == O_RDONLY)
672 fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
673 line);
674 else if (mode == O_WRONLY)
675 fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
676 line);
677 else if (mode == O_RDWR)
678 fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n",
679 line);
680 }
0fda6bd2
JM
681 if (procfs_file)
682 fflush (procfs_file);
683 }
684
685 return ret;
686}
687
688int
fba45db2 689close_with_trace (int fd, char *file, int line)
0fda6bd2 690{
103b3ef5 691 int ret;
0fda6bd2 692
103b3ef5
MS
693 prepare_to_trace ();
694 errno = 0;
695 ret = close (fd);
0fda6bd2
JM
696 if (procfs_trace)
697 {
0fda6bd2
JM
698 if (info_verbose)
699 fprintf (procfs_file ? procfs_file : stdout,
700 "%s:%d -- ", file, line);
103b3ef5
MS
701 if (errno)
702 fprintf (procfs_file ? procfs_file : stdout,
703 "[close FAILED! (%s)]\n", safe_strerror (errno));
704 else
705 fprintf (procfs_file ? procfs_file : stdout,
706 "%d = close (%d)\n", ret, fd);
0fda6bd2
JM
707 if (procfs_file)
708 fflush (procfs_file);
709 }
710
711 return ret;
712}
713
103b3ef5 714pid_t
fba45db2 715wait_with_trace (int *wstat, char *file, int line)
0fda6bd2
JM
716{
717 int ret, lstat = 0;
718
103b3ef5 719 prepare_to_trace ();
0fda6bd2
JM
720 if (procfs_trace)
721 {
0fda6bd2
JM
722 if (info_verbose)
723 fprintf (procfs_file ? procfs_file : stdout,
724 "%s:%d -- ", file, line);
725 fprintf (procfs_file ? procfs_file : stdout,
726 "wait (line %d) ", line);
727 if (procfs_file)
728 fflush (procfs_file);
729 }
103b3ef5 730 errno = 0;
0fda6bd2
JM
731 ret = wait (&lstat);
732 if (procfs_trace)
733 {
103b3ef5
MS
734 if (errno)
735 fprintf (procfs_file ? procfs_file : stdout,
736 "[wait FAILED! (%s)]\n", safe_strerror (errno));
737 else
738 fprintf (procfs_file ? procfs_file : stdout,
739 "returned pid %d, status 0x%x\n", ret, lstat);
0fda6bd2
JM
740 if (procfs_file)
741 fflush (procfs_file);
742 }
743 if (wstat)
744 *wstat = lstat;
745
746 return ret;
747}
748
749void
fba45db2 750procfs_note (char *msg, char *file, int line)
0fda6bd2 751{
103b3ef5 752 prepare_to_trace ();
0fda6bd2
JM
753 if (procfs_trace)
754 {
0fda6bd2
JM
755 if (info_verbose)
756 fprintf (procfs_file ? procfs_file : stdout,
757 "%s:%d -- ", file, line);
758 fprintf (procfs_file ? procfs_file : stdout, msg);
759 if (procfs_file)
760 fflush (procfs_file);
761 }
762}
763
764void
fba45db2 765proc_prettyfprint_status (long flags, int why, int what, int thread)
0fda6bd2 766{
103b3ef5 767 prepare_to_trace ();
0fda6bd2
JM
768 if (procfs_trace)
769 {
0fda6bd2
JM
770 if (thread)
771 fprintf (procfs_file ? procfs_file : stdout,
772 "Thread %d: ", thread);
773
774 proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
775 flags, 0);
776
777 if (flags & (PR_STOPPED | PR_ISTOP))
778 proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
779 why, what, 0);
780 if (procfs_file)
781 fflush (procfs_file);
782 }
783}
784
785
786void
fba45db2 787_initialize_proc_api (void)
0fda6bd2
JM
788{
789 struct cmd_list_element *c;
790
791 c = add_set_cmd ("procfs-trace", no_class,
792 var_boolean, (char *) &procfs_trace,
103b3ef5 793 "Set tracing for /proc api calls.\n", &setlist);
0fda6bd2
JM
794
795 add_show_from_set (c, &showlist);
9f60d481 796 set_cmd_sfunc (c, set_procfs_trace_cmd);
5ba2abeb 797 set_cmd_completer (c, filename_completer);
0fda6bd2
JM
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);
9f60d481 804 set_cmd_sfunc (c, set_procfs_file_cmd);
0fda6bd2 805}
This page took 0.293918 seconds and 4 git commands to generate.