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