gdb/
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index b0f79f108bd51fba57e640bec30675445bf4535e..de0ba581da618f03625216b11f9d61b9be120f5f 100644 (file)
@@ -679,7 +679,7 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child)
         in the foreground, the user will not be able to ctrl-c to get
         back the terminal, effectively hanging the debug session.  */
       fprintf_filtered (gdb_stderr, _("\
-Can not resume the parent process over vfork in the foreground while \n\
+Can not resume the parent process over vfork in the foreground while\n\
 holding the child stopped.  Try \"set detach-on-fork\" or \
 \"set schedule-multiple\".\n"));
       return 1;
@@ -2149,7 +2149,6 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
 {
   int pid = GET_LWP (lp->ptid);
   struct target_waitstatus *ourstatus = &lp->waitstatus;
-  struct lwp_info *new_lp = NULL;
   int event = status >> 16;
 
   if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK
@@ -2213,7 +2212,10 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
        ourstatus->kind = TARGET_WAITKIND_VFORKED;
       else
        {
+         struct lwp_info *new_lp;
+
          ourstatus->kind = TARGET_WAITKIND_IGNORE;
+
          new_lp = add_lwp (BUILD_LWP (new_pid, GET_PID (lp->ptid)));
          new_lp->cloned = 1;
          new_lp->stopped = 1;
@@ -2277,6 +2279,23 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
              linux_ops->to_resume (linux_ops, pid_to_ptid (new_pid),
                                    0, signo);
            }
+         else
+           {
+             if (status != 0)
+               {
+                 /* We created NEW_LP so it cannot yet contain STATUS.  */
+                 gdb_assert (new_lp->status == 0);
+
+                 /* Save the wait status to report later.  */
+                 if (debug_linux_nat)
+                   fprintf_unfiltered (gdb_stdlog,
+                                       "LHEW: waitpid of new LWP %ld, "
+                                       "saving status %s\n",
+                                       (long) GET_LWP (new_lp->ptid),
+                                       status_to_str (status));
+                 new_lp->status = status;
+               }
+           }
 
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
@@ -3365,6 +3384,9 @@ retry:
 
          lp = linux_nat_filter_event (lwpid, status, options);
 
+         /* STATUS is now no longer valid, use LP->STATUS instead.  */
+         status = 0;
+
          if (lp
              && ptid_is_pid (ptid)
              && ptid_get_pid (lp->ptid) != ptid_get_pid (ptid))
@@ -3373,7 +3395,7 @@ retry:
 
              if (debug_linux_nat)
                fprintf (stderr, "LWP %ld got an event %06x, leaving pending.\n",
-                        ptid_get_lwp (lp->ptid), status);
+                        ptid_get_lwp (lp->ptid), lp->status);
 
              if (WIFSTOPPED (lp->status))
                {
@@ -3410,7 +3432,7 @@ retry:
                      lp->signalled = 0;
                    }
                }
-             else if (WIFEXITED (status) || WIFSIGNALED (status))
+             else if (WIFEXITED (lp->status) || WIFSIGNALED (lp->status))
                {
                  if (debug_linux_nat)
                    fprintf (stderr, "Process %ld exited while stopping LWPs\n",
@@ -4134,8 +4156,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
                               char *note_data, int *note_size,
                               enum target_signal stop_signal)
 {
-  gdb_gregset_t gregs;
-  gdb_fpregset_t fpregs;
   unsigned long lwp = ptid_get_lwp (ptid);
   struct gdbarch *gdbarch = target_gdbarch;
   struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch);
@@ -4153,21 +4173,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
   core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
   sect_list = gdbarch_core_regset_sections (gdbarch);
 
-  if (core_regset_p
-      && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
-                                                    sizeof (gregs))) != NULL
-      && regset->collect_regset != NULL)
-    regset->collect_regset (regset, regcache, -1,
-                           &gregs, sizeof (gregs));
-  else
-    fill_gregset (regcache, &gregs, -1);
-
-  note_data = (char *) elfcore_write_prstatus (obfd,
-                                              note_data,
-                                              note_size,
-                                              lwp,
-                                              stop_signal, &gregs);
-
   /* The loop below uses the new struct core_regset_section, which stores
      the supported section names and sizes for the core file.  Note that
      note PRSTATUS needs to be treated specially.  But the other notes are
@@ -4175,12 +4180,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
   if (core_regset_p && sect_list != NULL)
     while (sect_list->sect_name != NULL)
       {
-       /* .reg was already handled above.  */
-       if (strcmp (sect_list->sect_name, ".reg") == 0)
-         {
-           sect_list++;
-           continue;
-         }
        regset = gdbarch_regset_from_core_section (gdbarch,
                                                   sect_list->sect_name,
                                                   sect_list->size);
@@ -4188,12 +4187,16 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
        gdb_regset = xmalloc (sect_list->size);
        regset->collect_regset (regset, regcache, -1,
                                gdb_regset, sect_list->size);
-       note_data = (char *) elfcore_write_register_note (obfd,
-                                                         note_data,
-                                                         note_size,
-                                                         sect_list->sect_name,
-                                                         gdb_regset,
-                                                         sect_list->size);
+
+       if (strcmp (sect_list->sect_name, ".reg") == 0)
+         note_data = (char *) elfcore_write_prstatus
+                               (obfd, note_data, note_size,
+                                lwp, stop_signal, gdb_regset);
+       else
+         note_data = (char *) elfcore_write_register_note
+                               (obfd, note_data, note_size,
+                                sect_list->sect_name, gdb_regset,
+                                sect_list->size);
        xfree (gdb_regset);
        sect_list++;
       }
@@ -4203,6 +4206,24 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
      the new support, the code below should be deleted.  */
   else
     {
+      gdb_gregset_t gregs;
+      gdb_fpregset_t fpregs;
+
+      if (core_regset_p
+         && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+                                                        sizeof (gregs))) != NULL
+         && regset->collect_regset != NULL)
+       regset->collect_regset (regset, regcache, -1,
+                               &gregs, sizeof (gregs));
+      else
+       fill_gregset (regcache, &gregs, -1);
+
+      note_data = (char *) elfcore_write_prstatus (obfd,
+                                                  note_data,
+                                                  note_size,
+                                                  lwp,
+                                                  stop_signal, &gregs);
+
       if (core_regset_p
           && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
                                                         sizeof (fpregs))) != NULL
@@ -4948,6 +4969,45 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
 
   gdb_assert (object == TARGET_OBJECT_OSDATA);
 
+  if (!annex)
+    {
+      if (offset == 0)
+       {
+         if (len_avail != -1 && len_avail != 0)
+           obstack_free (&obstack, NULL);
+         len_avail = 0;
+         buf = NULL;
+         obstack_init (&obstack);
+         obstack_grow_str (&obstack, "<osdata type=\"types\">\n");
+
+         obstack_xml_printf (
+                             &obstack,
+                             "<item>"
+                             "<column name=\"Type\">processes</column>"
+                             "<column name=\"Description\">Listing of all processes</column>"
+                             "</item>");
+
+         obstack_grow_str0 (&obstack, "</osdata>\n");
+         buf = obstack_finish (&obstack);
+         len_avail = strlen (buf);
+       }
+
+      if (offset >= len_avail)
+       {
+         /* Done.  Get rid of the obstack.  */
+         obstack_free (&obstack, NULL);
+         buf = NULL;
+         len_avail = 0;
+         return 0;
+       }
+
+      if (len > len_avail - offset)
+       len = len_avail - offset;
+      memcpy (readbuf, buf + offset, len);
+
+      return len;
+    }
+
   if (strcmp (annex, "processes") != 0)
     return 0;
 
@@ -5509,15 +5569,21 @@ linux_nat_core_of_thread_1 (ptid_t ptid)
   make_cleanup (xfree, content);
 
   p = strchr (content, '(');
-  p = strchr (p, ')') + 2; /* skip ")" and a whitespace. */
+
+  /* Skip ")".  */
+  if (p != NULL)
+    p = strchr (p, ')');
+  if (p != NULL)
+    p++;
 
   /* If the first field after program name has index 0, then core number is
      the field with index 36.  There's no constant for that anywhere.  */
-  p = strtok_r (p, " ", &ts);
-  for (i = 0; i != 36; ++i)
+  if (p != NULL)
+    p = strtok_r (p, " ", &ts);
+  for (i = 0; p != NULL && i != 36; ++i)
     p = strtok_r (NULL, " ", &ts);
 
-  if (sscanf (p, "%d", &core) == 0)
+  if (p == NULL || sscanf (p, "%d", &core) == 0)
     core = -1;
 
   do_cleanups (back_to);
This page took 0.0267 seconds and 4 git commands to generate.