* corelow.c (core_close): Don't hardcode the core's pid.
[deliverable/binutils-gdb.git] / gdb / bsd-uthread.c
index 172192e4d22f5e1488315e031074d570d20aeb2f..ecbad76782c205019f4fcdd6557d038566b8b6c7 100644 (file)
@@ -1,12 +1,12 @@
 /* BSD user-level threads support.
 
-   Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "gdbcore.h"
@@ -147,6 +145,13 @@ bsd_uthread_lookup_offset (const char *name, struct objfile *objfile)
   return read_memory_unsigned_integer (addr, 4);
 }
 
+static CORE_ADDR
+bsd_uthread_read_memory_address (CORE_ADDR addr)
+{
+  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+  return read_memory_typed_address (addr, ptr_type);
+}
+
 /* If OBJFILE contains the symbols corresponding to one of the
    supported user-level threads libraries, activate the thread stratum
    implemented by this module.  */
@@ -194,18 +199,12 @@ bsd_uthread_activate (struct objfile *objfile)
   return 1;
 }
 
-/* Deactivate the thread stratum implemented by this module.  */
+/* Cleanup due to deactivation.  */
 
 static void
-bsd_uthread_deactivate (void)
+bsd_uthread_close (int quitting)
 {
-  /* Skip if the thread stratum has already been deactivated.  */
-  if (!bsd_uthread_active)
-    return;
-
   bsd_uthread_active = 0;
-  unpush_target (bsd_uthread_ops_hack);
-
   bsd_uthread_thread_run_addr = 0;
   bsd_uthread_thread_list_addr = 0;
   bsd_uthread_thread_state_offset = 0;
@@ -214,6 +213,18 @@ bsd_uthread_deactivate (void)
   bsd_uthread_solib_name = NULL;
 }
 
+/* Deactivate the thread stratum implemented by this module.  */
+
+static void
+bsd_uthread_deactivate (void)
+{
+  /* Skip if the thread stratum has already been deactivated.  */
+  if (!bsd_uthread_active)
+    return;
+
+  unpush_target (bsd_uthread_ops_hack);
+}
+
 void
 bsd_uthread_inferior_created (struct target_ops *ops, int from_tty)
 {
@@ -241,7 +252,7 @@ bsd_uthread_solib_loaded (struct so_list *so)
 
          if (bsd_uthread_activate (so->objfile))
            {
-             bsd_uthread_solib_name == so->so_original_name;
+             bsd_uthread_solib_name = so->so_original_name;
              return;
            }
        }
@@ -259,16 +270,17 @@ bsd_uthread_solib_unloaded (struct so_list *so)
 }
 
 static void
-bsd_uthread_mourn_inferior (void)
+bsd_uthread_mourn_inferior (struct target_ops *ops)
 {
-  find_target_beneath (bsd_uthread_ops_hack)->to_mourn_inferior ();
+  struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
+  beneath->to_mourn_inferior (beneath);
   bsd_uthread_deactivate ();
 }
 
 static void
 bsd_uthread_fetch_registers (struct regcache *regcache, int regnum)
 {
-  struct gdbarch *gdbarch = current_gdbarch;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
   CORE_ADDR active_addr;
@@ -281,8 +293,7 @@ bsd_uthread_fetch_registers (struct regcache *regcache, int regnum)
      thread structure.  This can go once we fix the underlying target.  */
   regnum = -1;
 
-  active_addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
-                                          builtin_type_void_data_ptr);
+  active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
   if (addr != 0 && addr != active_addr)
     {
       bsd_uthread_check_magic (addr);
@@ -294,13 +305,12 @@ bsd_uthread_fetch_registers (struct regcache *regcache, int regnum)
 static void
 bsd_uthread_store_registers (struct regcache *regcache, int regnum)
 {
-  struct gdbarch *gdbarch = current_gdbarch;
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
   CORE_ADDR active_addr;
 
-  active_addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
-                                          builtin_type_void_data_ptr);
+  active_addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
   if (addr != 0 && addr != active_addr)
     {
       bsd_uthread_check_magic (addr);
@@ -330,17 +340,24 @@ bsd_uthread_xfer_partial (struct target_ops *ops, enum target_object object,
 }
 
 static ptid_t
-bsd_uthread_wait (ptid_t ptid, struct target_waitstatus *status)
+bsd_uthread_wait (struct target_ops *ops,
+                 ptid_t ptid, struct target_waitstatus *status)
 {
   CORE_ADDR addr;
+  struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
 
   /* Pass the request to the layer beneath.  */
-  ptid = find_target_beneath (bsd_uthread_ops_hack)->to_wait (ptid, status);
+  ptid = beneath->to_wait (beneath, ptid, status);
+
+  /* If the process is no longer alive, there's no point in figuring
+     out the thread ID.  It will fail anyway.  */
+  if (status->kind == TARGET_WAITKIND_SIGNALLED
+      || status->kind == TARGET_WAITKIND_EXITED)
+    return ptid;
 
   /* Fetch the corresponding thread ID, and augment the returned
      process ID with it.  */
-  addr = read_memory_typed_address (bsd_uthread_thread_run_addr,
-                                   builtin_type_void_data_ptr);
+  addr = bsd_uthread_read_memory_address (bsd_uthread_thread_run_addr);
   if (addr != 0)
     {
       gdb_byte buf[4];
@@ -357,14 +374,16 @@ bsd_uthread_wait (ptid_t ptid, struct target_waitstatus *status)
        }
     }
 
-  /* HACK: Twiddle INFERIOR_PTID such that the initial thread of a
-     process isn't recognized as a new thread.  */
-  if (ptid_get_tid (ptid) != 0 && !in_thread_list (ptid)
-      && ptid_get_tid (inferior_ptid) == 0)
-    {
-      add_thread (ptid);
-      inferior_ptid = ptid;
-    }
+  /* If INFERIOR_PTID doesn't have a tid member yet, and we now have a
+     ptid with tid set, then ptid is still the initial thread of
+     the process.  Notify GDB core about it.  */
+  if (ptid_get_tid (inferior_ptid) == 0
+      && ptid_get_tid (ptid) != 0 && !in_thread_list (ptid))
+    thread_change_ptid (inferior_ptid, ptid);
+
+  /* Don't let the core see a ptid without a corresponding thread.  */
+  if (!in_thread_list (ptid) || is_exited (ptid))
+    add_thread (ptid);
 
   return ptid;
 }
@@ -403,17 +422,23 @@ bsd_uthread_find_new_threads (void)
   int offset = bsd_uthread_thread_next_offset;
   CORE_ADDR addr;
 
-  addr = read_memory_typed_address (bsd_uthread_thread_list_addr,
-                                   builtin_type_void_data_ptr);
+  addr = bsd_uthread_read_memory_address (bsd_uthread_thread_list_addr);
   while (addr != 0)
     {
       ptid_t ptid = ptid_build (pid, 0, addr);
 
-      if (!in_thread_list (ptid))
-       add_thread (ptid);
+      if (!in_thread_list (ptid) || is_exited (ptid))
+       {
+         /* If INFERIOR_PTID doesn't have a tid member yet, then ptid
+            is still the initial thread of the process.  Notify GDB
+            core about it.  */
+         if (ptid_get_tid (inferior_ptid) == 0)
+           thread_change_ptid (inferior_ptid, ptid);
+         else
+           add_thread (ptid);
+       }
 
-      addr = read_memory_typed_address (addr + offset,
-                                       builtin_type_void_data_ptr);
+      addr = bsd_uthread_read_memory_address (addr + offset);
     }
 }
 
@@ -464,7 +489,7 @@ bsd_uthread_extra_thread_info (struct thread_info *info)
 }
 
 static char *
-bsd_uthread_pid_to_str (ptid_t ptid)
+bsd_uthread_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   if (ptid_get_tid (ptid) != 0)
     {
@@ -486,6 +511,7 @@ bsd_uthread_target (void)
   t->to_shortname = "bsd-uthreads";
   t->to_longname = "BSD user-level threads";
   t->to_doc = "BSD user-level threads";
+  t->to_close = bsd_uthread_close;
   t->to_mourn_inferior = bsd_uthread_mourn_inferior;
   t->to_fetch_registers = bsd_uthread_fetch_registers;
   t->to_store_registers = bsd_uthread_store_registers;
This page took 0.025936 seconds and 4 git commands to generate.