2011-02-28 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index ec0433f5a6ecd602006f1e592c3e0c45e2a77b31..98e85e913a76e31ff0e9071d781aabbe52292630 100644 (file)
 #include "inf-ptrace.h"
 #include "auxv.h"
 #include <sys/param.h>         /* for MAXPATHLEN */
-#include <sys/procfs.h>                /* for elf_gregset etc. */
+#include <sys/procfs.h>                /* for elf_gregset etc.  */
 #include "elf-bfd.h"           /* for elfcore_write_* */
 #include "gregset.h"           /* for gregset */
 #include "gdbcore.h"           /* for get_exec_file */
 #include <ctype.h>             /* for isdigit */
-#include "gdbthread.h"         /* for struct thread_info etc. */
+#include "gdbthread.h"         /* for struct thread_info etc.  */
 #include "gdb_stat.h"          /* for struct stat */
 #include <fcntl.h>             /* for O_RDONLY */
 #include "inf-loop.h"
@@ -68,7 +68,7 @@
 # endif
 #endif /* HAVE_PERSONALITY */
 
-/* This comment documents high-level logic of this file. 
+/* This comment documents high-level logic of this file.
 
 Waiting for events in sync mode
 ===============================
@@ -76,12 +76,12 @@ Waiting for events in sync mode
 When waiting for an event in a specific thread, we just use waitpid, passing
 the specific pid, and not passing WNOHANG.
 
-When waiting for an event in all threads, waitpid is not quite good. Prior to
+When waiting for an event in all threads, waitpid is not quite good.  Prior to
 version 2.4, Linux can either wait for event in main thread, or in secondary
-threads. (2.4 has the __WALL flag).  So, if we use blocking waitpid, we might
+threads.  (2.4 has the __WALL flag).  So, if we use blocking waitpid, we might
 miss an event.  The solution is to use non-blocking waitpid, together with
 sigsuspend.  First, we use non-blocking waitpid to get an event in the main 
-process, if any. Second, we use non-blocking waitpid with the __WCLONED
+process, if any.  Second, we use non-blocking waitpid with the __WCLONED
 flag to check for events in cloned processes.  If nothing is found, we use
 sigsuspend to wait for SIGCHLD.  When SIGCHLD arrives, it means something
 happened to a child process -- and SIGCHLD will be delivered both for events
@@ -90,7 +90,7 @@ an event, we get back to calling nonblocking waitpid with and without
 __WCLONED.
 
 Note that SIGCHLD should be blocked between waitpid and sigsuspend calls,
-so that we don't miss a signal. If SIGCHLD arrives in between, when it's
+so that we don't miss a signal.  If SIGCHLD arrives in between, when it's
 blocked, the signal becomes pending and sigsuspend immediately
 notices it and returns.
 
@@ -167,7 +167,7 @@ blocked.  */
 #define PTRACE_SETOPTIONS      0x4200
 #define PTRACE_GETEVENTMSG     0x4201
 
-/* options set using PTRACE_SETOPTIONS */
+/* Options set using PTRACE_SETOPTIONS.  */
 #define PTRACE_O_TRACESYSGOOD  0x00000001
 #define PTRACE_O_TRACEFORK     0x00000002
 #define PTRACE_O_TRACEVFORK    0x00000004
@@ -297,7 +297,7 @@ static int linux_supports_tracesysgood_flag = -1;
 
 static int linux_supports_tracevforkdone_flag = -1;
 
-/* Async mode support */
+/* Async mode support */
 
 /* Zero if the async mode, although enabled, is masked, which means
    linux_nat_wait should behave as if async mode was off.  */
@@ -698,7 +698,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
     {
       struct lwp_info *child_lp = NULL;
 
-      /* We're already attached to the parent, by default. */
+      /* We're already attached to the parent, by default.  */
 
       /* Detach new forked process?  */
       if (detach_fork)
@@ -974,36 +974,34 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 }
 
 \f
-static void
+static int
 linux_child_insert_fork_catchpoint (int pid)
 {
-  if (! linux_supports_tracefork (pid))
-    error (_("Your system does not support fork catchpoints."));
+  return !linux_supports_tracefork (pid);
 }
 
-static void
+static int
 linux_child_insert_vfork_catchpoint (int pid)
 {
-  if (!linux_supports_tracefork (pid))
-    error (_("Your system does not support vfork catchpoints."));
+  return !linux_supports_tracefork (pid);
 }
 
-static void
+static int
 linux_child_insert_exec_catchpoint (int pid)
 {
-  if (!linux_supports_tracefork (pid))
-    error (_("Your system does not support exec catchpoints."));
+  return !linux_supports_tracefork (pid);
 }
 
 static int
 linux_child_set_syscall_catchpoint (int pid, int needed, int any_count,
                                    int table_size, int *table)
 {
-  if (! linux_supports_tracesysgood (pid))
-    error (_("Your system does not support syscall catchpoints."));
+  if (!linux_supports_tracesysgood (pid))
+    return 1;
+
   /* On GNU/Linux, we ignore the arguments.  It means that we only
      enable the syscall catchpoints, but do not disable them.
-     
+
      Also, we do not use the `table' information because we do not
      filter system calls here.  We let GDB do the logic for us.  */
   return 0;
@@ -2726,7 +2724,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 
              save_sigtrap (lp);
 
-             /* Now resume this LWP and get the SIGSTOP event. */
+             /* Now resume this LWP and get the SIGSTOP event.  */
              errno = 0;
              ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
              if (debug_linux_nat)
@@ -2741,12 +2739,12 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                                      target_pid_to_str (lp->ptid));
                }
              /* Hold this event/waitstatus while we check to see if
-                there are any more (we still want to get that SIGSTOP). */
+                there are any more (we still want to get that SIGSTOP).  */
              stop_wait_callback (lp, NULL);
 
              /* Hold the SIGTRAP for handling by linux_nat_wait.  If
                 there's another event, throw it back into the
-                queue. */
+                queue.  */
              if (lp->status)
                {
                  if (debug_linux_nat)
@@ -2757,14 +2755,14 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                  kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
                }
 
-             /* Save the sigtrap event. */
+             /* Save the sigtrap event.  */
              lp->status = status;
              return 0;
            }
          else
            {
              /* The thread was stopped with a signal other than
-                SIGSTOP, and didn't accidentally trip a breakpoint. */
+                SIGSTOP, and didn't accidentally trip a breakpoint.  */
 
              if (debug_linux_nat)
                {
@@ -2773,7 +2771,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                                      status_to_str ((int) status),
                                      target_pid_to_str (lp->ptid));
                }
-             /* Now resume this LWP and get the SIGSTOP event. */
+             /* Now resume this LWP and get the SIGSTOP event.  */
              errno = 0;
              ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
              if (debug_linux_nat)
@@ -2783,7 +2781,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                                    errno ? safe_strerror (errno) : "OK");
 
              /* Hold this event/waitstatus while we check to see if
-                there are any more (we still want to get that SIGSTOP). */
+                there are any more (we still want to get that SIGSTOP).  */
              stop_wait_callback (lp, NULL);
 
              /* If the lp->status field is still empty, use it to
@@ -2830,7 +2828,7 @@ status_callback (struct lwp_info *lp, void *data)
   if (lp->waitstatus.kind != TARGET_WAITKIND_IGNORE)
     {
       /* A ptrace event, like PTRACE_FORK|VFORK|EXEC, syscall event,
-        or a pending process exit.  Note that `W_EXITCODE(0,0) ==
+        or a pending process exit.  Note that `W_EXITCODE(0,0) ==
         0', so a clean process exit can not be stored pending in
         lp->status, it is indistinguishable from
         no-pending-status.  */
@@ -2887,7 +2885,7 @@ select_event_lwp_callback (struct lwp_info *lp, void *data)
 
   gdb_assert (selector != NULL);
 
-  /* Select only resumed LWPs that have a SIGTRAP event pending. */
+  /* Select only resumed LWPs that have a SIGTRAP event pending.  */
   if (lp->resumed && linux_nat_lp_status_is_event (lp))
     if ((*selector)-- == 0)
       return 1;
@@ -3065,8 +3063,8 @@ linux_nat_filter_event (int lwpid, int status, int options)
     }
 
   /* Make sure we don't report an event for the exit of an LWP not in
-     our list, i.e.  not part of the current process.  This can happen
-     if we detach from a program we original forked and then it
+     our list, i.e. not part of the current process.  This can happen
+     if we detach from a program we originally forked and then it
      exits.  */
   if (!WIFSTOPPED (status) && !lp)
     return NULL;
@@ -4080,6 +4078,43 @@ linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
+static char *
+linux_nat_thread_name (struct thread_info *thr)
+{
+  int pid = ptid_get_pid (thr->ptid);
+  long lwp = ptid_get_lwp (thr->ptid);
+#define FORMAT "/proc/%d/task/%ld/comm"
+  char buf[sizeof (FORMAT) + 30];
+  FILE *comm_file;
+  char *result = NULL;
+
+  snprintf (buf, sizeof (buf), FORMAT, pid, lwp);
+  comm_file = fopen (buf, "r");
+  if (comm_file)
+    {
+      /* Not exported by the kernel, so we define it here.  */
+#define COMM_LEN 16
+      static char line[COMM_LEN + 1];
+
+      if (fgets (line, sizeof (line), comm_file))
+       {
+         char *nl = strchr (line, '\n');
+
+         if (nl)
+           *nl = '\0';
+         if (*line != '\0')
+           result = line;
+       }
+
+      fclose (comm_file);
+    }
+
+#undef COMM_LEN
+#undef FORMAT
+
+  return result;
+}
+
 /* Accepts an integer PID; Returns a string representing a file that
    can be opened to get the symbols for the child process.  */
 
@@ -4569,7 +4604,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
        }
       else
        {
-         /* [...] (future options here) */
+         /* [...] (future options here) */
        }
       argv++;
     }
@@ -4769,9 +4804,9 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
            printf_filtered (_("Start of stack: 0x%lx\n"), ltmp);
 #if 0  /* Don't know how architecture-dependent the rest is...
           Anyway the signal bitmap info is available from "status".  */
-         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch? */
+         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch?  */
            printf_filtered (_("Kernel stack pointer: 0x%lx\n"), ltmp);
-         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch? */
+         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch?  */
            printf_filtered (_("Kernel instr pointer: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("Pending signals bitmap: 0x%lx\n"), ltmp);
@@ -4781,7 +4816,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
            printf_filtered (_("Ignored signals bitmap: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("Catched signals bitmap: 0x%lx\n"), ltmp);
-         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch? */
+         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch?  */
            printf_filtered (_("wchan (system call): 0x%lx\n"), ltmp);
 #endif
          do_cleanups (cleanup);
@@ -5110,16 +5145,16 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
 
                  if ((f = fopen (pathname, "r")) != NULL)
                    {
-                     size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
+                     size_t length = fread (cmd, 1, sizeof (cmd) - 1, f);
 
-                     if (len > 0)
+                     if (length > 0)
                        {
                          int i;
 
-                         for (i = 0; i < len; i++)
+                         for (i = 0; i < length; i++)
                            if (cmd[i] == '\0')
                              cmd[i] = ' ';
-                         cmd[len] = '\0';
+                         cmd[length] = '\0';
 
                          obstack_xml_printf (
                            &obstack,
@@ -5685,6 +5720,7 @@ linux_nat_add_target (struct target_ops *t)
   t->to_mourn_inferior = linux_nat_mourn_inferior;
   t->to_thread_alive = linux_nat_thread_alive;
   t->to_pid_to_str = linux_nat_pid_to_str;
+  t->to_thread_name = linux_nat_thread_name;
   t->to_has_thread_control = tc_schedlock;
   t->to_thread_address_space = linux_nat_thread_address_space;
   t->to_stopped_by_watchpoint = linux_nat_stopped_by_watchpoint;
This page took 0.028533 seconds and 4 git commands to generate.