/* Machine independent support for SVR4 /proc (process file system) for GDB.
- Copyright 1999 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
Written by Michael Snyder at Cygnus Solutions.
Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
#include "defs.h"
#include "gdbcmd.h"
+#include "completer.h"
#if defined (NEW_PROC_API)
#define _STRUCTURED_PROC 1
#include <sys/types.h>
#include <sys/procfs.h>
#include <sys/proc.h> /* for struct proc */
+#ifdef HAVE_SYS_USER_H
#include <sys/user.h> /* for struct user */
+#endif
#include <fcntl.h> /* for O_RDWR etc. */
#include <sys/wait.h>
char *desc; /* Short description of value */
};
-static int procfs_trace = 1;
-/*static int info_verbose = 1;*/ /* kludge */
+static int procfs_trace = 0;
static FILE *procfs_file = NULL;
static char *procfs_filename = "procfs_trace";
static void
-set_procfs_trace_cmd (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+prepare_to_trace (void)
+{
+ if (procfs_trace) /* if procfs tracing turned on */
+ if (procfs_file == NULL) /* if output file not yet open */
+ if (procfs_filename != NULL) /* if output filename known */
+ procfs_file = fopen (procfs_filename, "a"); /* open output file */
+}
+
+static void
+set_procfs_trace_cmd (char *args, int from_tty, struct cmd_list_element *c)
{
#if 0 /* not sure what I might actually need to do here, if anything */
if (procfs_file)
}
static void
-set_procfs_file_cmd (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+set_procfs_file_cmd (char *args, int from_tty, struct cmd_list_element *c)
{
/* Just changed the filename for procfs tracing.
If a file was already open, close it. */
{ PIOCGETPTIMER, "PIOCGETPTIMER", "get process timers" },
#endif /* irix event counters */
{ PIOCGENTRY, "PIOCGENTRY", "get traced syscall entry set" },
+#if defined (PIOCGETPR)
{ PIOCGETPR, "PIOCGETPR", "read struct proc" },
+#endif
+#if defined (PIOCGETU)
{ PIOCGETU, "PIOCGETU", "read user area" },
+#endif
#if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
{ PIOCGETUTK, "PIOCGETUTK", "get the utask struct" },
#endif
};
int
-ioctl_with_trace (fd, opcode, ptr, file, line)
- int fd;
- long opcode;
- void *ptr;
- char *file;
- int line;
+ioctl_with_trace (int fd, long opcode, void *ptr, char *file, int line)
{
- int i, ret, arg1;
+ int i = 0;
+ int ret;
+ int arg1;
+
+ prepare_to_trace ();
if (procfs_trace)
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
for (i = 0; ioctl_table[i].name != NULL; i++)
if (ioctl_table[i].value == opcode)
break;
if (procfs_file)
fflush (procfs_file);
}
+ errno = 0;
ret = ioctl (fd, opcode, ptr);
if (procfs_trace && ret < 0)
{
fprintf (procfs_file ? procfs_file : stdout,
- "[ioctl (%s) FAILED!]\n",
+ "[ioctl (%s) FAILED! (%s)]\n",
ioctl_table[i].name != NULL ?
- ioctl_table[i].name : "<unknown>");
+ ioctl_table[i].name : "<unknown>",
+ safe_strerror (errno));
if (procfs_file)
fflush (procfs_file);
}
static off_t lseek_offset;
int
-write_with_trace (fd, arg, len, file, line)
- int fd;
- int *arg;
- size_t len;
- char *file;
- int line;
+write_with_trace (int fd, void *varg, size_t len, char *file, int line)
{
int i;
int ret;
- int opcode = arg[0];
+ procfs_ctl_t *arg = (procfs_ctl_t *) varg;
+ prepare_to_trace ();
if (procfs_trace)
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
+ procfs_ctl_t opcode = arg[0];
for (i = 0; rw_table[i].name != NULL; i++)
if (rw_table[i].value == opcode)
break;
case PCUNSET:
#endif
#ifdef PCRESET
+#if PCRESET != PCUNSET
case PCRESET:
+#endif
#endif
fprintf (procfs_file ? procfs_file : stdout,
"write (PCRESET, %s) %s\n",
break;
default:
{
+#ifdef BREAKPOINT
static unsigned char break_insn[] = BREAKPOINT;
if (len == sizeof (break_insn) &&
fprintf (procfs_file ? procfs_file : stdout,
"write (<breakpoint at 0x%08lx>) \n",
(unsigned long) lseek_offset);
- else if (rw_table[i].name)
+ else
+#endif
+ if (rw_table[i].name)
fprintf (procfs_file ? procfs_file : stdout,
"write (%s) %s\n",
rw_table[i].name,
if (procfs_file)
fflush (procfs_file);
}
+ errno = 0;
ret = write (fd, (void *) arg, len);
if (procfs_trace && ret != len)
{
fprintf (procfs_file ? procfs_file : stdout,
- "[write (%s) FAILED!\n",
+ "[write (%s) FAILED! (%s)]\n",
rw_table[i].name != NULL ?
- rw_table[i].name : "<unknown>");
+ rw_table[i].name : "<unknown>",
+ safe_strerror (errno));
if (procfs_file)
fflush (procfs_file);
}
}
off_t
-lseek_with_trace (fd, offset, whence, file, line)
- int fd;
- off_t offset;
- int whence;
- char *file;
- int line;
+lseek_with_trace (int fd, off_t offset, int whence, char *file, int line)
{
off_t ret;
-#if 0 /* don't need output, just need address */
- if (procfs_trace)
- {
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
- if (info_verbose)
- fprintf (procfs_file ? procfs_file : stdout,
- "%s:%d -- ", file, line);
- fprintf (procfs_file ? procfs_file : stdout,
- "lseek (0x%08x, %s) \n", offset,
- whence == SEEK_SET ? "SEEK_SET" :
- whence == SEEK_CUR ? "SEEK_CUR" :
- whence == SEEK_END ? "SEEK_END" :
- "<unknown whence>");
- if (procfs_file)
- fflush (procfs_file);
- }
-#endif
+ prepare_to_trace ();
+ errno = 0;
ret = lseek (fd, offset, whence);
lseek_offset = ret;
- if (procfs_trace && ret == -1)
+ if (procfs_trace && (ret == -1 || errno != 0))
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
fprintf (procfs_file ? procfs_file : stdout,
- "[lseek (0x%08lx) FAILED!\n", (unsigned long) offset);
+ "[lseek (0x%08lx) FAILED! (%s)]\n",
+ (unsigned long) offset, safe_strerror (errno));
if (procfs_file)
fflush (procfs_file);
}
#endif /* NEW_PROC_API */
int
-open_with_trace (filename, mode, file, line)
- char *filename;
- int mode;
- char *file;
- int line;
+open_with_trace (char *filename, int mode, char *file, int line)
{
- int ret = open (filename, mode);
+ int ret;
+ prepare_to_trace ();
+ errno = 0;
+ ret = open (filename, mode);
if (procfs_trace)
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
if (info_verbose)
fprintf (procfs_file ? procfs_file : stdout,
"%s:%d -- ", file, line);
- fprintf (procfs_file ? procfs_file : stdout,
- "%d = open (%s, ", ret, filename);
- if (mode == O_RDONLY)
- fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n", line);
- else if (mode == O_WRONLY)
- fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n", line);
- else if (mode == O_RDWR)
- fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n", line);
+
+ if (errno)
+ {
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[open FAILED! (%s) line %d]\\n",
+ safe_strerror (errno), line);
+ }
+ else
+ {
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%d = open (%s, ", ret, filename);
+ if (mode == O_RDONLY)
+ fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
+ line);
+ else if (mode == O_WRONLY)
+ fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
+ line);
+ else if (mode == O_RDWR)
+ fprintf (procfs_file ? procfs_file : stdout, "O_RDWR) %d\n",
+ line);
+ }
if (procfs_file)
fflush (procfs_file);
}
}
int
-close_with_trace (fd, file, line)
- int fd;
- char *file;
- int line;
+close_with_trace (int fd, char *file, int line)
{
- int ret = close (fd);
+ int ret;
+ prepare_to_trace ();
+ errno = 0;
+ ret = close (fd);
if (procfs_trace)
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
if (info_verbose)
fprintf (procfs_file ? procfs_file : stdout,
"%s:%d -- ", file, line);
- fprintf (procfs_file ? procfs_file : stdout,
- "%d = close (%d)\n", ret, fd);
+ if (errno)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[close FAILED! (%s)]\n", safe_strerror (errno));
+ else
+ fprintf (procfs_file ? procfs_file : stdout,
+ "%d = close (%d)\n", ret, fd);
if (procfs_file)
fflush (procfs_file);
}
return ret;
}
-int
-wait_with_trace (wstat, file, line)
- int *wstat;
- char *file;
- int line;
+pid_t
+wait_with_trace (int *wstat, char *file, int line)
{
int ret, lstat = 0;
+ prepare_to_trace ();
if (procfs_trace)
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
if (info_verbose)
fprintf (procfs_file ? procfs_file : stdout,
"%s:%d -- ", file, line);
if (procfs_file)
fflush (procfs_file);
}
+ errno = 0;
ret = wait (&lstat);
if (procfs_trace)
{
- fprintf (procfs_file ? procfs_file : stdout,
- "returned pid %d, status 0x%x\n", ret, lstat);
+ if (errno)
+ fprintf (procfs_file ? procfs_file : stdout,
+ "[wait FAILED! (%s)]\n", safe_strerror (errno));
+ else
+ fprintf (procfs_file ? procfs_file : stdout,
+ "returned pid %d, status 0x%x\n", ret, lstat);
if (procfs_file)
fflush (procfs_file);
}
}
void
-procfs_note (msg, file, line)
- char *msg;
- char *file;
- int line;
+procfs_note (char *msg, char *file, int line)
{
+ prepare_to_trace ();
if (procfs_trace)
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
if (info_verbose)
fprintf (procfs_file ? procfs_file : stdout,
"%s:%d -- ", file, line);
}
void
-proc_prettyfprint_status (flags, why, what, thread)
- long flags;
- int why;
- int what;
- int thread;
+proc_prettyfprint_status (long flags, int why, int what, int thread)
{
+ prepare_to_trace ();
if (procfs_trace)
{
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-
if (thread)
fprintf (procfs_file ? procfs_file : stdout,
"Thread %d: ", thread);
void
-_initialize_proc_api ()
+_initialize_proc_api (void)
{
struct cmd_list_element *c;
c = add_set_cmd ("procfs-trace", no_class,
var_boolean, (char *) &procfs_trace,
- "Set tracing for /proc ioctl calls.\n", &setlist);
+ "Set tracing for /proc api calls.\n", &setlist);
add_show_from_set (c, &showlist);
c->function.sfunc = set_procfs_trace_cmd;
+ c->completer = filename_completer;
c = add_set_cmd ("procfs-file", no_class, var_filename,
(char *) &procfs_filename,
add_show_from_set (c, &showlist);
c->function.sfunc = set_procfs_file_cmd;
-
-#ifdef TRACE_PROCFS
- if (procfs_file == NULL && procfs_filename != NULL)
- procfs_file = fopen (procfs_filename, "a");
-#endif
}