import gdb-19990504 snapshot
[deliverable/binutils-gdb.git] / gdb / procfs.c
index 83c0c328d08ce2d156df14d9785d65f70eb7cbb8..8a68a8964976f485d487ca2231cb845310989872 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine independent support for SVR4 /proc (process file system) for GDB.
-   Copyright 1991, 1992-97, 1998 Free Software Foundation, Inc.
+   Copyright 1991, 1992-98, 1999 Free Software Foundation, Inc.
    Written by Fred Fish at Cygnus Support.  Changes for sysv4.2mp procfs
    compatibility by Geoffrey Noer at Cygnus Solutions.
 
@@ -91,11 +91,23 @@ regardless of whether or not the actual target has floating point hardware.
 #endif
 
 /* the name of the proc status struct depends on the implementation */
-#ifdef HAVE_PSTATUS_T
-  typedef pstatus_t gdb_prstatus_t;
-#else
+/* Wrap Light Weight Process member in THE_PR_LWP macro for clearer code */
+#ifndef HAVE_PSTATUS_T
   typedef prstatus_t gdb_prstatus_t;
+#define THE_PR_LWP(a)  a
+#else  /* HAVE_PSTATUS_T */
+  typedef pstatus_t gdb_prstatus_t;
+#define THE_PR_LWP(a)  a.pr_lwp
+#if !defined(HAVE_PRRUN_T) && defined(HAVE_MULTIPLE_PROC_FDS)
+  /* Fallback definitions - for using configure information directly */
+#ifndef UNIXWARE
+#define UNIXWARE       1
 #endif
+#if !defined(PROCFS_USE_READ_WRITE) && !defined(HAVE_PROCFS_PIOCSET)
+#define PROCFS_USE_READ_WRITE  1
+#endif
+#endif /* !HAVE_PRRUN_T && HAVE_MULTIPLE_PROC_FDS */
+#endif /* HAVE_PSTATUS_T */
 
 #define MAX_SYSCALLS   256     /* Maximum number of syscalls for table */
 
@@ -137,7 +149,7 @@ regardless of whether or not the actual target has floating point hardware.
 
 #define MAX_PROC_NAME_SIZE sizeof("/proc/1234567890/status")
 
-extern struct target_ops procfs_ops;           /* Forward declaration */
+struct target_ops procfs_ops;
 
 int procfs_suppress_run = 0;   /* Non-zero if procfs should pretend not to
                                   be a runnable target.  Used by targets
@@ -221,7 +233,7 @@ struct procinfo {
   int had_event;               /* poll/select says something happened */
   int was_stopped;             /* Nonzero if was stopped prior to attach */
   int nopass_next_sigstop;     /* Don't pass a sigstop on next resume */
-#ifndef HAVE_NO_PRRUN_T
+#ifdef HAVE_PRRUN_T
   prrun_t prrun;               /* Control state when it is run */
 #endif
   gdb_prstatus_t prstatus;     /* Current process status info */
@@ -570,6 +582,10 @@ static int open_proc_file PARAMS ((int, struct procinfo *, int, int));
 
 static void close_proc_file PARAMS ((struct procinfo *));
 
+static void close_proc_file_cleanup PARAMS ((void*));
+
+static struct cleanup *make_cleanup_close_proc_file PARAMS ((struct procinfo *));
+
 static void unconditionally_kill_inferior PARAMS ((struct procinfo *));
 
 static NORETURN void proc_init_failed PARAMS ((struct procinfo *, char *, int)) ATTR_NORETURN;
@@ -653,6 +669,8 @@ struct procfs_syscall_handler
 static void procfs_resume PARAMS ((int pid, int step,
                                   enum target_signal signo));
 
+static void init_procfs_ops PARAMS ((void));
+
 /* External function prototypes that can't be easily included in any
    header file because the args are typedefs in system include files. */
 
@@ -968,8 +986,9 @@ wait_fd ()
                    printf_filtered ("LWP %d exited.\n", 
                                     (pi->pid >> 16) & 0xffff);
                  close_proc_file (pi);
+                 i--;                  /* don't skip deleted entry */
                  if (num_fds != 0)
-                   continue;           /* already another event to process */
+                   break;              /* already another event to process */
                  else
                    goto wait_again;    /* wait for another event */
                }
@@ -1812,7 +1831,7 @@ init_syscall_table ()
 
 LOCAL FUNCTION
 
-       procfs_kill_inferior - kill any currently inferior
+       procfs_kill_inferior - kill any current inferior
 
 SYNOPSIS
 
@@ -2599,7 +2618,7 @@ procfs_notice_signals (pid)
 
   pi = find_procinfo (pid, 0);
 
-#ifdef UNIXWARE
+#ifndef HAVE_PRRUN_T
   premptyset (&sctl.sigset);
 #else
   sctl.sigset = pi->prrun.pr_trace;
@@ -2607,7 +2626,7 @@ procfs_notice_signals (pid)
 
   notice_signals (pi, &sctl);
 
-#ifndef UNIXWARE
+#ifdef HAVE_PRRUN_T
   pi->prrun.pr_trace = sctl.sigset;
 #endif
 }
@@ -3137,11 +3156,7 @@ do_attach (pid)
       if ((pi = find_procinfo ((*lwps << 16) | pid, 1)) == 0)
        pi = init_procinfo ((*lwps << 16) | pid, 0);
 
-#ifdef UNIXWARE
-      if (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP))
-#else
-      if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP))
-#endif
+      if (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP))
        {
          pi->was_stopped = 1;
        }
@@ -3301,11 +3316,8 @@ do_detach (signal)
        }
       else
        {
-#ifdef UNIXWARE
-         if (signal || (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#else
-         if (signal || (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#endif
+         if (signal
+         || (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)))
            {
              long cmd;
              struct proc_ctl pctl;
@@ -3388,19 +3400,11 @@ scan_again:
       if (!pi->had_event)
        continue;
 
-#ifdef UNIXWARE
-      if (! (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)) )
+      if (! (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)) )
        continue;
 
-      why = pi->prstatus.pr_lwp.pr_why;
-      what = pi->prstatus.pr_lwp.pr_what;
-#else
-      if (! (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)) )
-       continue;
-
-      why = pi->prstatus.pr_why;
-      what = pi->prstatus.pr_what;
-#endif
+      why = THE_PR_LWP(pi->prstatus).pr_why;
+      what = THE_PR_LWP(pi->prstatus).pr_what;
       if (why == PR_SYSENTRY || why == PR_SYSEXIT)
        {
          int i;
@@ -3440,11 +3444,8 @@ scan_again:
       goto scan_again;
     }
 
-#ifdef UNIXWARE
-  if (!checkerr && !(pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#else
-  if (!checkerr && !(pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#endif
+  if (!checkerr
+  && !(THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)))
     {
       if (!procfs_write_pcwstop (pi))
        {
@@ -3471,21 +3472,15 @@ scan_again:
          /* NOTREACHED */
        }
     }
-#ifdef UNIXWARE
-  else if (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP))
-#else
-  else if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP))
-#endif
+  else if (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP))
     {
 #ifdef UNIXWARE
       rtnval = pi->prstatus.pr_pid;
-      why = pi->prstatus.pr_lwp.pr_why;
-      what = pi->prstatus.pr_lwp.pr_what;
 #else
       rtnval = pi->pid;
-      why = pi->prstatus.pr_why;
-      what = pi->prstatus.pr_what;
 #endif
+      why = THE_PR_LWP(pi->prstatus).pr_why;
+      what = THE_PR_LWP(pi->prstatus).pr_what;
 
       switch (why)
        {
@@ -3543,11 +3538,8 @@ scan_again:
              /* Use the signal which the kernel assigns.  This is better than
                 trying to second-guess it from the fault.  In fact, I suspect
                 that FLTACCESS can be either SIGSEGV or SIGBUS.  */
-#ifdef UNIXWARE
-              statval = ((pi->prstatus.pr_lwp.pr_info.si_signo) << 8) | 0177;
-#else
-             statval = ((pi->prstatus.pr_info.si_signo) << 8) | 0177;
-#endif
+              statval =
+                ((THE_PR_LWP(pi->prstatus).pr_info.si_signo) << 8) | 0177;
              break;
            }
          break;
@@ -3600,11 +3592,7 @@ scan_again:
   else
     {
       error ("PIOCWSTOP, stopped for unknown/unhandled reason, flags %#x",
-#ifdef UNIXWARE
-            pi->prstatus.pr_lwp.pr_flags);
-#else
-            pi->prstatus.pr_flags);
-#endif
+            THE_PR_LWP(pi->prstatus).pr_flags);
     }
 
   store_waitstatus (ourstatus, statval);
@@ -3643,7 +3631,7 @@ DESCRIPTION
 
        If we are not delivering the same signal that the prstatus siginfo
        struct contains information about, then synthesize a siginfo struct
-       to match the signal we are doing to deliver, make it of the type
+       to match the signal we are going to deliver, make it of the type
        "generated by a user process", and send this synthesized copy.  When
        used to set the inferior's signal state, this will be required if we
        are not currently stopped because of a traced signal, or if we decide
@@ -3673,22 +3661,18 @@ set_proc_siginfo (pip, signo)
   /* With Alpha OSF/1 procfs, the kernel gets really confused if it
      receives a PIOCSSIG with a signal identical to the current signal,
      it messes up the current signal. Work around the kernel bug.  */
-#ifdef UNIXWARE
-  if (signo == pip -> prstatus.pr_lwp.pr_cursig)
-#else
-  if (signo == pip -> prstatus.pr_cursig)
-#endif
+  if (signo == THE_PR_LWP(pip->prstatus).pr_cursig)
     return;
 #endif
 
 #ifdef UNIXWARE
-  if (signo == pip->prstatus.pr_lwp.pr_info.si_signo)
+  if (signo == THE_PR_LWP(pip->prstatus).pr_info.si_signo)
     {
       memcpy ((char *) &sictl.siginfo, (char *) &pip->prstatus.pr_lwp.pr_info,
                sizeof (siginfo_t));
     }
 #else
-  if (signo == pip -> prstatus.pr_info.si_signo)
+  if (signo == THE_PR_LWP(pip->prstatus).pr_info.si_signo)
     {
       sip = &pip -> prstatus.pr_info;
     }
@@ -3777,13 +3761,8 @@ procfs_resume (pid, step, signo)
        an inferior to continue running at the same time as gdb.  (FIXME?)  */
     signal_to_pass = 0;
   else if (signo == TARGET_SIGNAL_TSTP
-#ifdef UNIXWARE
-          && pi->prstatus.pr_lwp.pr_cursig == SIGTSTP
-          && pi->prstatus.pr_lwp.pr_action.sa_handler == SIG_DFL
-#else
-          && pi->prstatus.pr_cursig == SIGTSTP
-          && pi->prstatus.pr_action.sa_handler == SIG_DFL
-#endif
+          && THE_PR_LWP(pi->prstatus).pr_cursig == SIGTSTP
+          && THE_PR_LWP(pi->prstatus).pr_action.sa_handler == SIG_DFL
           )
 
     /* We are about to pass the inferior a SIGTSTP whose action is
@@ -4049,6 +4028,20 @@ close_proc_file (pip)
     }
 }
 
+static void
+close_proc_file_cleanup (pip)
+     void *pip;
+{
+  close_proc_file ((struct procinfo *) pip);
+}
+
+static struct cleanup *
+make_cleanup_close_proc_file (pip)
+     struct procinfo *pip;
+{
+  return make_cleanup (close_proc_file_cleanup, pip);
+}
+
 /*
 
 LOCAL FUNCTION
@@ -4120,14 +4113,6 @@ open_proc_file (pid, pip, mode, control)
       return 0;
     }
 
-  sprintf (pip->pathname, MAP_PROC_NAME_FMT, tmp);
-  if ((pip->map_fd = open (pip->pathname, O_RDONLY)) < 0)
-    {
-      close (pip->status_fd);
-      close (pip->as_fd);
-      return 0;
-    }
-
   if (control)
     {
       sprintf (pip->pathname, CTL_PROC_NAME_FMT, tmp);
@@ -4256,19 +4241,10 @@ info_proc_stop (pip, summary)
   int why;
   int what;
 
-#ifdef UNIXWARE
-  why = pip -> prstatus.pr_lwp.pr_why;
-  what = pip -> prstatus.pr_lwp.pr_what;
-#else
-  why = pip -> prstatus.pr_why;
-  what = pip -> prstatus.pr_what;
-#endif
+  why = THE_PR_LWP(pip->prstatus).pr_why;
+  what = THE_PR_LWP(pip->prstatus).pr_what;
 
-#ifdef UNIXWARE
-  if (pip -> prstatus.pr_lwp.pr_flags & PR_STOPPED)
-#else
-  if (pip -> prstatus.pr_flags & PR_STOPPED)
-#endif
+  if (THE_PR_LWP(pip->prstatus).pr_flags & PR_STOPPED)
     {
       printf_filtered ("%-32s", "Reason for stopping:");
       if (!summary)
@@ -4359,22 +4335,12 @@ info_proc_siginfo (pip, summary)
 {
   struct siginfo *sip;
 
-#ifdef UNIXWARE
-  if ((pip -> prstatus.pr_lwp.pr_flags & PR_STOPPED) &&
-      (pip -> prstatus.pr_lwp.pr_why == PR_SIGNALLED ||
-       pip -> prstatus.pr_lwp.pr_why == PR_FAULTED))
-#else
-  if ((pip -> prstatus.pr_flags & PR_STOPPED) &&
-      (pip -> prstatus.pr_why == PR_SIGNALLED ||
-       pip -> prstatus.pr_why == PR_FAULTED))
-#endif
+  if ((THE_PR_LWP(pip->prstatus).pr_flags & PR_STOPPED) &&
+      (THE_PR_LWP(pip->prstatus).pr_why == PR_SIGNALLED ||
+       THE_PR_LWP(pip->prstatus).pr_why == PR_FAULTED))
     {
       printf_filtered ("%-32s", "Additional signal/fault info:");
-#ifdef UNIXWARE
-      sip = &pip -> prstatus.pr_lwp.pr_info;
-#else
-      sip = &pip -> prstatus.pr_info;
-#endif
+      sip = &(THE_PR_LWP(pip->prstatus).pr_info);
       if (summary)
        {
          printf_filtered ("%s ", signalname (sip -> si_signo));
@@ -4812,7 +4778,7 @@ info_proc (args, from_tty)
        {
          nomem (0);
        }
-      make_cleanup (freeargv, (char *) argv);
+      make_cleanup_freeargv (argv);
 
       while (*argv != NULL)
        {
@@ -4874,7 +4840,7 @@ info_proc (args, from_tty)
                  /* NOTREACHED */
                }
              pid = pip->pid;
-             make_cleanup (close_proc_file, pip);
+             make_cleanup_close_proc_file (pip);
            }
          else if (**argv != '\000')
            {
@@ -4926,7 +4892,7 @@ No process.  Start debugging a program or specify an explicit process ID.");
          if (!open_proc_file ((*lwps << 16) | pid, pip, O_RDONLY, 0))
            continue;
 
-         make_cleanup (close_proc_file, pip);
+         make_cleanup_close_proc_file (pip);
 
          if (!procfs_read_status (pip))
            {
@@ -5434,11 +5400,8 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
      in the child and continue the parent.  */
 
   /* Third arg is pointer to new thread id. */
-#ifdef UNIXWARE
-  lwp_id = read_memory_integer (pi->prstatus.pr_lwp.pr_sysarg[2], sizeof (int));
-#else
-  lwp_id = read_memory_integer (pi->prstatus.pr_sysarg[2], sizeof (int));
-#endif
+  lwp_id = read_memory_integer (
+     THE_PR_LWP(pi->prstatus).pr_sysarg[2], sizeof (int));
 
   lwp_id = (lwp_id << 16) | PIDGET (pi->pid);
 
@@ -5469,11 +5432,7 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
      SUSPENDED or RUNNABLE.  If runnable, we will simply signal it to run.
      If suspended, we flag it to be continued later, when it has an event.  */
 
-#ifdef UNIXWARE
-  if (childpi->prstatus.pr_lwp.pr_why == PR_SUSPENDED)
-#else
-  if (childpi->prstatus.pr_why == PR_SUSPENDED)
-#endif
+  if (THE_PR_LWP(childpi->prstatus).pr_why == PR_SUSPENDED)
     childpi->new_child = 1;    /* Flag this as an unseen child process */
   else
     {
@@ -5751,33 +5710,17 @@ procfs_pid_to_str (pid)
   return buf;
 }
 #endif /* TIDGET */
-\f
-struct target_ops procfs_ops;
 
-void
-_initialize_procfs ()
+\f
+static void
+init_procfs_ops ()
 {
-#ifdef HAVE_OPTIONAL_PROC_FS
-  char procname[MAX_PROC_NAME_SIZE];
-  int fd;
-
-  /* If we have an optional /proc filesystem (e.g. under OSF/1),
-     don't add procfs support if we cannot access the running
-     GDB via /proc.  */
-  sprintf (procname, STATUS_PROC_NAME_FMT, getpid ());
-  if ((fd = open (procname, O_RDONLY)) < 0)
-    return;
-  close (fd);
-#endif
   procfs_ops.to_shortname = "procfs";
   procfs_ops.to_longname = "Unix /proc child process";
   procfs_ops.to_doc = "Unix /proc child process (started by the \"run\" command).";
   procfs_ops.to_open = procfs_open;
-  procfs_ops.to_close = 0;
   procfs_ops.to_attach = procfs_attach;
-  procfs_ops.to_require_attach = procfs_attach;
   procfs_ops.to_detach = procfs_detach;
-  procfs_ops.to_require_detach = procfs_detach;
   procfs_ops.to_resume = procfs_resume;
   procfs_ops.to_wait = procfs_wait;
   procfs_ops.to_fetch_registers = procfs_fetch_registers;
@@ -5793,8 +5736,6 @@ _initialize_procfs ()
   procfs_ops.to_terminal_ours = terminal_ours;
   procfs_ops.to_terminal_info = child_terminal_info;
   procfs_ops.to_kill = procfs_kill_inferior;
-  procfs_ops.to_load = 0;
-  procfs_ops.to_lookup_symbol = 0;
   procfs_ops.to_create_inferior = procfs_create_inferior;
   procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
   procfs_ops.to_can_run = procfs_can_run;
@@ -5807,11 +5748,26 @@ _initialize_procfs ()
   procfs_ops.to_has_stack = 1;
   procfs_ops.to_has_registers = 1;
   procfs_ops.to_has_execution = 1;
-  procfs_ops.to_has_thread_control = tc_none;
-  procfs_ops.to_sections = 0;
-  procfs_ops.to_sections_end = 0;
   procfs_ops.to_magic = OPS_MAGIC;
+}
+
+void
+_initialize_procfs ()
+{
+#ifdef HAVE_OPTIONAL_PROC_FS
+  char procname[MAX_PROC_NAME_SIZE];
+  int fd;
+
+  /* If we have an optional /proc filesystem (e.g. under OSF/1),
+     don't add procfs support if we cannot access the running
+     GDB via /proc.  */
+  sprintf (procname, STATUS_PROC_NAME_FMT, getpid ());
+  if ((fd = open (procname, O_RDONLY)) < 0)
+    return;
+  close (fd);
+#endif
 
+  init_procfs_ops ();
   add_target (&procfs_ops);
 
   add_info ("processes", info_proc, 
This page took 0.029027 seconds and 4 git commands to generate.