2009-10-19 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / linux-thread-db.c
index eedb2cc772373f77abc0ae8f35b645c33daca23f..c3787d5920d582b473f221689e6efde1756d5ec6 100644 (file)
@@ -509,13 +509,13 @@ enable_thread_event (int event, CORE_ADDR *bp)
   /* Set up the breakpoint.  */
   gdb_assert (exec_bfd);
   (*bp) = (gdbarch_convert_from_func_ptr_addr
-          (current_gdbarch,
+          (target_gdbarch,
            /* Do proper sign extension for the target.  */
            (bfd_get_sign_extend_vma (exec_bfd) > 0
             ? (CORE_ADDR) (intptr_t) notify.u.bptaddr
             : (CORE_ADDR) (uintptr_t) notify.u.bptaddr),
            &current_target));
-  create_thread_event_breakpoint ((*bp));
+  create_thread_event_breakpoint (target_gdbarch, *bp);
 
   return TD_OK;
 }
@@ -588,6 +588,25 @@ enable_thread_event_reporting (void)
     }
 }
 
+/* Same as thread_db_find_new_threads_1, but silently ignore errors.  */
+
+static void
+thread_db_find_new_threads_silently (ptid_t ptid)
+{
+  volatile struct gdb_exception except;
+
+  TRY_CATCH (except, RETURN_MASK_ERROR)
+    {
+      thread_db_find_new_threads_1 (ptid);
+    }
+
+  if (except.reason < 0 && info_verbose)
+  {
+    exception_fprintf (gdb_stderr, except,
+                       "Warning: thread_db_find_new_threads_silently: ");
+  }
+}
+
 /* Lookup a library in which given symbol resides.
    Note: this is looking in GDB process, not in the inferior.
    Returns library name, or NULL.  */
@@ -705,7 +724,13 @@ try_thread_db_load_1 (struct thread_db_info *info)
     push_target (&thread_db_ops);
 
   enable_thread_event_reporting ();
-  thread_db_find_new_threads_1 (inferior_ptid);
+
+  /* There appears to be a bug in glibc-2.3.6: calls to td_thr_get_info fail
+     with TD_ERR for statically linked executables if td_thr_get_info is
+     called before glibc has initialized itself.  Silently ignore such
+     errors, and let gdb enumerate threads again later.  */
+  thread_db_find_new_threads_silently (inferior_ptid);
+
   return 1;
 }
 
@@ -1201,18 +1226,15 @@ thread_db_wait (struct target_ops *ops,
 
   if (ourstatus->kind == TARGET_WAITKIND_EXECD)
     {
-      /* Breakpoints have already been marked non-inserted by the
-        layer below.  We're safe in knowing that removing them will
-        not write the shadows of the old image into the new
-        image.  */
-      remove_thread_event_breakpoints ();
-
       /* New image, it may or may not end up using thread_db.  Assume
         not unless we find otherwise.  */
       delete_thread_db_info (GET_PID (ptid));
       if (!thread_db_list)
        unpush_target (&thread_db_ops);
 
+      /* Thread event breakpoints are deleted by
+        update_breakpoints_after_exec.  */
+
       return ptid;
     }
 
@@ -1249,13 +1271,12 @@ thread_db_mourn_inferior (struct target_ops *ops)
 
   delete_thread_db_info (GET_PID (inferior_ptid));
 
-  /* Delete the old thread event breakpoints.  Mark breakpoints out,
-     so that we don't try to un-insert them.  */
-  mark_breakpoints_out ();
-  remove_thread_event_breakpoints ();
-
   target_beneath->to_mourn_inferior (target_beneath);
 
+  /* Delete the old thread event breakpoints.  Do this after mourning
+     the inferior, so that we don't try to uninsert them.  */
+  remove_thread_event_breakpoints ();
+
   /* Detach thread_db target ops.  */
   if (!thread_db_list)
     unpush_target (ops);
This page took 0.0278 seconds and 4 git commands to generate.