7db944e
2008-03-30  Daniel Jacobowitz  <dan@codesourcery.com>
7db944e
7db944e
	* ia64-tdep.c (examine_prologue): Correct array access.
7db944e
7db944e
===================================================================
7db944e
RCS file: /cvs/src/src/gdb/ia64-tdep.c,v
7db944e
retrieving revision 1.172
7db944e
retrieving revision 1.173
7db944e
diff -u -r1.172 -r1.173
7db944e
--- src/gdb/ia64-tdep.c	2008/02/20 14:31:40	1.172
7db944e
+++ src/gdb/ia64-tdep.c	2008/03/31 03:38:48	1.173
7db944e
@@ -1234,7 +1234,7 @@
7db944e
 	      spill_reg   = rN;
7db944e
 	      last_prologue_pc = next_pc;
7db944e
 	    }
7db944e
-	  else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] && 
7db944e
+	  else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM-32] && 
7db944e
 		   rN < 256 && imm == 0)
7db944e
 	    {
7db944e
 	      /* mov rN, rM where rM is an input register */
c499105
c499105
c499105
c499105
https://bugzilla.redhat.com/show_bug.cgi?id=442765
c499105
c499105
http://sourceware.org/ml/gdb-patches/2008-03/msg00281.html
c499105
http://sourceware.org/ml/gdb-cvs/2008-03/msg00114.html
c499105
c499105
2008-03-21  Daniel Jacobowitz  <dan@codesourcery.com>
c499105
c499105
	* gdbthread.h (add_thread_with_info): New.
c499105
	* linux-thread-db.c: Add some documentation.
c499105
	(GET_LWP, GET_PID, GET_THREAD, is_lwp, is_thread, BUILD_LWP): Delete.
c499105
	(struct private_thread_info): Remove th_valid and ti_valid.
c499105
	Replace ti with tid.
c499105
	(thread_get_info_callback): Do not add TID to the new ptid.  Do
c499105
	not cache th or ti.
c499105
	(thread_db_map_id2thr, lwp_from_thread): Delete functions.
c499105
	(thread_from_lwp): Assert that the LWP is set.  Do not add TID to the
c499105
	new PTID.
c499105
	(attach_thread): Handle an already-existing thread.  Use
c499105
	add_thread_with_info.  Cache the th and tid.
c499105
	(detach_thread): Verify that private was set.  Remove verbose
c499105
	argument and printing.  Update caller.
c499105
	(thread_db_detach): Do not adjust inferior_ptid.
c499105
	(clear_lwpid_callback, thread_db_resume, thread_db_kill): Delete.
c499105
	(check_event, find_new_threads_callback): Do not add TID to the new PTID.
c499105
	(thread_db_wait): Do not use lwp_from_thread.
c499105
	(thread_db_pid_to_str): Use the cached TID.
c499105
	(thread_db_extra_thread_info): Check that private is set.
c499105
	(same_ptid_callback): Delete.
c499105
	(thread_db_get_thread_local_address): Do not use it or check
c499105
	is_thread.  Check that private is set.  Assume that the thread
c499105
	handle is already cached.
c499105
	(init_thread_db_ops): Remove to_resume and to_kill.
c499105
	* thread.c (add_thread_with_info): New.
c499105
	(add_thread): Use it.
c499105
	* linux-nat.c (find_thread_from_lwp): Delete.
c499105
	(exit_lwp): Do not use it.  Check print_thread_events.  Print before
c499105
	deleting the thread.
c499105
	(GET_PID, GET_LWP, BUILD_LWP, is_lwp): Move to...
c499105
	* linux-nat.h (GET_PID, GET_LWP, BUILD_LWP, is_lwp): ...here.
c499105
	* inf-ttrace.c (inf_ttrace_wait): Use print_thread_events and
c499105
	printf_unfiltered for thread exits.
c499105
	* procfs.c (procfs_wait): Likewise.
c499105
c499105
2008-03-21  Pedro Alves  <pedro@codesourcery.com>
c499105
c499105
	* gdb.threads/fork-child-threads.exp: Test next over fork.
c499105
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/gdbthread.h,v
c499105
retrieving revision 1.20
c499105
retrieving revision 1.21
c499105
diff -u -r1.20 -r1.21
c499105
--- src/gdb/gdbthread.h	2008/03/15 13:53:25	1.20
c499105
+++ src/gdb/gdbthread.h	2008/03/21 15:44:53	1.21
c499105
@@ -81,6 +81,10 @@
c499105
    about new thread.  */
c499105
 extern struct thread_info *add_thread_silent (ptid_t ptid);
c499105
 
c499105
+/* Same as add_thread, and sets the private info.  */
c499105
+extern struct thread_info *add_thread_with_info (ptid_t ptid,
c499105
+						 struct private_thread_info *);
c499105
+
c499105
 /* Delete an existing thread list entry.  */
c499105
 extern void delete_thread (ptid_t);
c499105
 
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/inf-ttrace.c,v
c499105
retrieving revision 1.27
c499105
retrieving revision 1.28
c499105
diff -u -r1.27 -r1.28
c499105
--- src/gdb/inf-ttrace.c	2008/01/29 21:11:24	1.27
c499105
+++ src/gdb/inf-ttrace.c	2008/03/21 15:44:53	1.28
c499105
@@ -964,7 +964,8 @@
c499105
       break;
c499105
 
c499105
     case TTEVT_LWP_EXIT:
c499105
-      printf_filtered(_("[%s exited]\n"), target_pid_to_str (ptid));
c499105
+      if (print_thread_events)
c499105
+	printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid));
c499105
       ti = find_thread_pid (ptid);
c499105
       gdb_assert (ti != NULL);
c499105
       ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1;
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/linux-nat.c,v
c499105
retrieving revision 1.76
c499105
retrieving revision 1.77
c499105
diff -u -r1.76 -r1.77
c499105
--- src/gdb/linux-nat.c	2008/03/17 14:54:07	1.76
c499105
+++ src/gdb/linux-nat.c	2008/03/21 15:44:53	1.77
c499105
@@ -588,11 +588,6 @@
c499105
 static int num_lwps;
c499105
 
c499105
 
c499105
-#define GET_LWP(ptid)		ptid_get_lwp (ptid)
c499105
-#define GET_PID(ptid)		ptid_get_pid (ptid)
c499105
-#define is_lwp(ptid)		(GET_LWP (ptid) != 0)
c499105
-#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
c499105
-
c499105
 /* If the last reported event was a SIGTRAP, this variable is set to
c499105
    the process id of the LWP/thread that got it.  */
c499105
 ptid_t trap_ptid;
c499105
@@ -813,20 +808,6 @@
c499105
       p = &(*p)->next;
c499105
 }
c499105
 
c499105
-/* Callback for iterate_over_threads that finds a thread corresponding
c499105
-   to the given LWP.  */
c499105
-
c499105
-static int
c499105
-find_thread_from_lwp (struct thread_info *thr, void *dummy)
c499105
-{
c499105
-  ptid_t *ptid_p = dummy;
c499105
-
c499105
-  if (GET_LWP (thr->ptid) && GET_LWP (thr->ptid) == GET_LWP (*ptid_p))
c499105
-    return 1;
c499105
-  else
c499105
-    return 0;
c499105
-}
c499105
-
c499105
 /* Handle the exit of a single thread LP.  */
c499105
 
c499105
 static void
c499105
@@ -834,32 +815,14 @@
c499105
 {
c499105
   if (in_thread_list (lp->ptid))
c499105
     {
c499105
+      if (print_thread_events)
c499105
+	printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (lp->ptid));
c499105
+
c499105
       /* Core GDB cannot deal with us deleting the current thread.  */
c499105
       if (!ptid_equal (lp->ptid, inferior_ptid))
c499105
 	delete_thread (lp->ptid);
c499105
       else
c499105
 	record_dead_thread (lp->ptid);
c499105
-      printf_unfiltered (_("[%s exited]\n"),
c499105
-			 target_pid_to_str (lp->ptid));
c499105
-    }
c499105
-  else
c499105
-    {
c499105
-      /* Even if LP->PTID is not in the global GDB thread list, the
c499105
-	 LWP may be - with an additional thread ID.  We don't need
c499105
-	 to print anything in this case; thread_db is in use and
c499105
-	 already took care of that.  But it didn't delete the thread
c499105
-	 in order to handle zombies correctly.  */
c499105
-
c499105
-      struct thread_info *thr;
c499105
-
c499105
-      thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid);
c499105
-      if (thr)
c499105
-	{
c499105
-	  if (!ptid_equal (thr->ptid, inferior_ptid))
c499105
-	    delete_thread (thr->ptid);
c499105
-	  else
c499105
-	    record_dead_thread (thr->ptid);
c499105
-	}
c499105
     }
c499105
 
c499105
   delete_lwp (lp->ptid);
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/linux-nat.h,v
c499105
retrieving revision 1.22
c499105
retrieving revision 1.23
c499105
diff -u -r1.22 -r1.23
c499105
--- src/gdb/linux-nat.h	2008/01/23 11:26:28	1.22
c499105
+++ src/gdb/linux-nat.h	2008/03/21 15:44:53	1.23
c499105
@@ -83,6 +83,11 @@
c499105
        (LP) != NULL;							\
c499105
        (LP) = (LP)->next, (PTID) = (LP) ? (LP)->ptid : (PTID))
c499105
 
c499105
+#define GET_LWP(ptid)		ptid_get_lwp (ptid)
c499105
+#define GET_PID(ptid)		ptid_get_pid (ptid)
c499105
+#define is_lwp(ptid)		(GET_LWP (ptid) != 0)
c499105
+#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
c499105
+
c499105
 /* Attempt to initialize libthread_db.  */
c499105
 void check_for_thread_db (void);
c499105
 
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
c499105
retrieving revision 1.37
c499105
retrieving revision 1.38
c499105
diff -u -r1.37 -r1.38
c499105
--- src/gdb/linux-thread-db.c	2008/01/23 11:26:28	1.37
c499105
+++ src/gdb/linux-thread-db.c	2008/03/21 15:44:53	1.38
c499105
@@ -48,6 +48,32 @@
c499105
 #define LIBTHREAD_DB_SO "libthread_db.so.1"
c499105
 #endif
c499105
 
c499105
+/* GNU/Linux libthread_db support.
c499105
+
c499105
+   libthread_db is a library, provided along with libpthread.so, which
c499105
+   exposes the internals of the thread library to a debugger.  It
c499105
+   allows GDB to find existing threads, new threads as they are
c499105
+   created, thread IDs (usually, the result of pthread_self), and
c499105
+   thread-local variables.
c499105
+
c499105
+   The libthread_db interface originates on Solaris, where it is
c499105
+   both more powerful and more complicated.  This implementation
c499105
+   only works for LinuxThreads and NPTL, the two glibc threading
c499105
+   libraries.  It assumes that each thread is permanently assigned
c499105
+   to a single light-weight process (LWP).
c499105
+
c499105
+   libthread_db-specific information is stored in the "private" field
c499105
+   of struct thread_info.  When the field is NULL we do not yet have
c499105
+   information about the new thread; this could be temporary (created,
c499105
+   but the thread library's data structures do not reflect it yet)
c499105
+   or permanent (created using clone instead of pthread_create).
c499105
+
c499105
+   Process IDs managed by linux-thread-db.c match those used by
c499105
+   linux-nat.c: a common PID for all processes, an LWP ID for each
c499105
+   thread, and no TID.  We save the TID in private.  Keeping it out
c499105
+   of the ptid_t prevents thread IDs changing when libpthread is
c499105
+   loaded or unloaded.  */
c499105
+
c499105
 /* If we're running on GNU/Linux, we must explicitly attach to any new
c499105
    threads.  */
c499105
 
c499105
@@ -119,19 +145,7 @@
c499105
 static void thread_db_find_new_threads (void);
c499105
 static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
c499105
 			   const td_thrinfo_t *ti_p);
c499105
-static void detach_thread (ptid_t ptid, int verbose);
c499105
-
c499105
-
c499105
-/* Building process ids.  */
c499105
-
c499105
-#define GET_PID(ptid)		ptid_get_pid (ptid)
c499105
-#define GET_LWP(ptid)		ptid_get_lwp (ptid)
c499105
-#define GET_THREAD(ptid)	ptid_get_tid (ptid)
c499105
-
c499105
-#define is_lwp(ptid)		(GET_LWP (ptid) != 0)
c499105
-#define is_thread(ptid)		(GET_THREAD (ptid) != 0)
c499105
-
c499105
-#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
c499105
+static void detach_thread (ptid_t ptid);
c499105
 
c499105
 
c499105
 /* Use "struct private_thread_info" to cache thread state.  This is
c499105
@@ -143,11 +157,8 @@
c499105
   unsigned int dying:1;
c499105
 
c499105
   /* Cached thread state.  */
c499105
-  unsigned int th_valid:1;
c499105
-  unsigned int ti_valid:1;
c499105
-
c499105
   td_thrhandle_t th;
c499105
-  td_thrinfo_t ti;
c499105
+  thread_t tid;
c499105
 };
c499105
 
c499105
 
c499105
@@ -257,7 +268,7 @@
c499105
 	   thread_db_err_str (err));
c499105
 
c499105
   /* Fill the cache.  */
c499105
-  thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid);
c499105
+  thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0);
c499105
   thread_info = find_thread_pid (thread_ptid);
c499105
 
c499105
   /* In the case of a zombie thread, don't continue.  We don't want to
c499105
@@ -266,13 +277,6 @@
c499105
     {
c499105
       if (infop != NULL)
c499105
         *(struct thread_info **) infop = thread_info;
c499105
-      if (thread_info != NULL)
c499105
-	{
c499105
-	  memcpy (&thread_info->private->th, thp, sizeof (*thp));
c499105
-	  thread_info->private->th_valid = 1;
c499105
-	  memcpy (&thread_info->private->ti, &ti, sizeof (ti));
c499105
-	  thread_info->private->ti_valid = 1;
c499105
-	}
c499105
       return TD_THR_ZOMBIE;
c499105
     }
c499105
 
c499105
@@ -284,39 +288,11 @@
c499105
       gdb_assert (thread_info != NULL);
c499105
     }
c499105
 
c499105
-  memcpy (&thread_info->private->th, thp, sizeof (*thp));
c499105
-  thread_info->private->th_valid = 1;
c499105
-  memcpy (&thread_info->private->ti, &ti, sizeof (ti));
c499105
-  thread_info->private->ti_valid = 1;
c499105
-
c499105
   if (infop != NULL)
c499105
     *(struct thread_info **) infop = thread_info;
c499105
 
c499105
   return 0;
c499105
 }
c499105
-
c499105
-/* Accessor functions for the thread_db information, with caching.  */
c499105
-
c499105
-static void
c499105
-thread_db_map_id2thr (struct thread_info *thread_info, int fatal)
c499105
-{
c499105
-  td_err_e err;
c499105
-
c499105
-  if (thread_info->private->th_valid)
c499105
-    return;
c499105
-
c499105
-  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid),
c499105
-			    &thread_info->private->th);
c499105
-  if (err != TD_OK)
c499105
-    {
c499105
-      if (fatal)
c499105
-	error (_("Cannot find thread %ld: %s"),
c499105
-	       (long) GET_THREAD (thread_info->ptid),
c499105
-	       thread_db_err_str (err));
c499105
-    }
c499105
-  else
c499105
-    thread_info->private->th_valid = 1;
c499105
-}
c499105
 
c499105
 /* Convert between user-level thread ids and LWP ids.  */
c499105
 
c499105
@@ -328,10 +304,9 @@
c499105
   struct thread_info *thread_info;
c499105
   ptid_t thread_ptid;
c499105
 
c499105
-  if (GET_LWP (ptid) == 0)
c499105
-    ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid));
c499105
-
c499105
-  gdb_assert (is_lwp (ptid));
c499105
+  /* This ptid comes from linux-nat.c, which should always fill in the
c499105
+     LWP.  */
c499105
+  gdb_assert (GET_LWP (ptid) != 0);
c499105
 
c499105
   err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
c499105
   if (err != TD_OK)
c499105
@@ -352,16 +327,8 @@
c499105
       && thread_info == NULL)
c499105
     return pid_to_ptid (-1);
c499105
 
c499105
-  gdb_assert (thread_info && thread_info->private->ti_valid);
c499105
-
c499105
-  return ptid_build (GET_PID (ptid), GET_LWP (ptid),
c499105
-		     thread_info->private->ti.ti_tid);
c499105
-}
c499105
-
c499105
-static ptid_t
c499105
-lwp_from_thread (ptid_t ptid)
c499105
-{
c499105
-  return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid));
c499105
+  gdb_assert (ptid_get_tid (ptid) == 0);
c499105
+  return ptid;
c499105
 }
c499105
 
c499105
 
c499105
@@ -672,7 +639,8 @@
c499105
 attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
c499105
 	       const td_thrinfo_t *ti_p)
c499105
 {
c499105
-  struct thread_info *tp;
c499105
+  struct private_thread_info *private;
c499105
+  struct thread_info *tp = NULL;
c499105
   td_err_e err;
c499105
 
c499105
   /* If we're being called after a TD_CREATE event, we may already
c499105
@@ -690,10 +658,21 @@
c499105
       tp = find_thread_pid (ptid);
c499105
       gdb_assert (tp != NULL);
c499105
 
c499105
-      if (!tp->private->dying)
c499105
-        return;
c499105
+      /* If tp->private is NULL, then GDB is already attached to this
c499105
+	 thread, but we do not know anything about it.  We can learn
c499105
+	 about it here.  This can only happen if we have some other
c499105
+	 way besides libthread_db to notice new threads (i.e.
c499105
+	 PTRACE_EVENT_CLONE); assume the same mechanism notices thread
c499105
+	 exit, so this can not be a stale thread recreated with the
c499105
+	 same ID.  */
c499105
+      if (tp->private != NULL)
c499105
+	{
c499105
+	  if (!tp->private->dying)
c499105
+	    return;
c499105
 
c499105
-      delete_thread (ptid);
c499105
+	  delete_thread (ptid);
c499105
+	  tp = NULL;
c499105
+	}
c499105
     }
c499105
 
c499105
   check_thread_signals ();
c499105
@@ -702,13 +681,28 @@
c499105
     return;			/* A zombie thread -- do not attach.  */
c499105
 
c499105
   /* Under GNU/Linux, we have to attach to each and every thread.  */
c499105
-  if (lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0)
c499105
+  if (tp == NULL
c499105
+      && lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0)
c499105
     return;
c499105
 
c499105
+  /* Construct the thread's private data.  */
c499105
+  private = xmalloc (sizeof (struct private_thread_info));
c499105
+  memset (private, 0, sizeof (struct private_thread_info));
c499105
+
c499105
+  /* A thread ID of zero may mean the thread library has not initialized
c499105
+     yet.  But we shouldn't even get here if that's the case.  FIXME:
c499105
+     if we change GDB to always have at least one thread in the thread
c499105
+     list this will have to go somewhere else; maybe private == NULL
c499105
+     until the thread_db target claims it.  */
c499105
+  gdb_assert (ti_p->ti_tid != 0);
c499105
+  private->th = *th_p;
c499105
+  private->tid = ti_p->ti_tid;
c499105
+
c499105
   /* Add the thread to GDB's thread list.  */
c499105
-  tp = add_thread (ptid);
c499105
-  tp->private = xmalloc (sizeof (struct private_thread_info));
c499105
-  memset (tp->private, 0, sizeof (struct private_thread_info));
c499105
+  if (tp == NULL)
c499105
+    tp = add_thread_with_info (ptid, private);
c499105
+  else
c499105
+    tp->private = private;
c499105
 
c499105
   /* Enable thread event reporting for this thread.  */
c499105
   err = td_thr_event_enable_p (th_p, 1);
c499105
@@ -718,22 +712,20 @@
c499105
 }
c499105
 
c499105
 static void
c499105
-detach_thread (ptid_t ptid, int verbose)
c499105
+detach_thread (ptid_t ptid)
c499105
 {
c499105
   struct thread_info *thread_info;
c499105
 
c499105
-  if (verbose)
c499105
-    printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid));
c499105
-
c499105
   /* Don't delete the thread now, because it still reports as active
c499105
      until it has executed a few instructions after the event
c499105
      breakpoint - if we deleted it now, "info threads" would cause us
c499105
      to re-attach to it.  Just mark it as having had a TD_DEATH
c499105
      event.  This means that we won't delete it from our thread list
c499105
      until we notice that it's dead (via prune_threads), or until
c499105
-     something re-uses its thread ID.  */
c499105
+     something re-uses its thread ID.  We'll report the thread exit
c499105
+     when the underlying LWP dies.  */
c499105
   thread_info = find_thread_pid (ptid);
c499105
-  gdb_assert (thread_info != NULL);
c499105
+  gdb_assert (thread_info != NULL && thread_info->private != NULL);
c499105
   thread_info->private->dying = 1;
c499105
 }
c499105
 
c499105
@@ -742,47 +734,12 @@
c499105
 {
c499105
   disable_thread_event_reporting ();
c499105
 
c499105
-  /* There's no need to save & restore inferior_ptid here, since the
c499105
-     inferior is not supposed to survive this function call.  */
c499105
-  inferior_ptid = lwp_from_thread (inferior_ptid);
c499105
-
c499105
   target_beneath->to_detach (args, from_tty);
c499105
 
c499105
   /* Should this be done by detach_command?  */
c499105
   target_mourn_inferior ();
c499105
 }
c499105
 
c499105
-static int
c499105
-clear_lwpid_callback (struct thread_info *thread, void *dummy)
c499105
-{
c499105
-  /* If we know that our thread implementation is 1-to-1, we could save
c499105
-     a certain amount of information; it's not clear how much, so we
c499105
-     are always conservative.  */
c499105
-
c499105
-  thread->private->th_valid = 0;
c499105
-  thread->private->ti_valid = 0;
c499105
-
c499105
-  return 0;
c499105
-}
c499105
-
c499105
-static void
c499105
-thread_db_resume (ptid_t ptid, int step, enum target_signal signo)
c499105
-{
c499105
-  struct cleanup *old_chain = save_inferior_ptid ();
c499105
-
c499105
-  if (GET_PID (ptid) == -1)
c499105
-    inferior_ptid = lwp_from_thread (inferior_ptid);
c499105
-  else if (is_thread (ptid))
c499105
-    ptid = lwp_from_thread (ptid);
c499105
-
c499105
-  /* Clear cached data which may not be valid after the resume.  */
c499105
-  iterate_over_threads (clear_lwpid_callback, NULL);
c499105
-
c499105
-  target_beneath->to_resume (ptid, step, signo);
c499105
-
c499105
-  do_cleanups (old_chain);
c499105
-}
c499105
-
c499105
 /* Check if PID is currently stopped at the location of a thread event
c499105
    breakpoint location.  If it is, read the event message and act upon
c499105
    the event.  */
c499105
@@ -833,7 +790,7 @@
c499105
       if (err != TD_OK)
c499105
 	error (_("Cannot get thread info: %s"), thread_db_err_str (err));
c499105
 
c499105
-      ptid = ptid_build (GET_PID (ptid), ti.ti_lid, ti.ti_tid);
c499105
+      ptid = ptid_build (GET_PID (ptid), ti.ti_lid, 0);
c499105
 
c499105
       switch (msg.event)
c499105
 	{
c499105
@@ -849,7 +806,7 @@
c499105
 	  if (!in_thread_list (ptid))
c499105
 	    error (_("Spurious thread death event."));
c499105
 
c499105
-	  detach_thread (ptid, print_thread_events);
c499105
+	  detach_thread (ptid);
c499105
 
c499105
 	  break;
c499105
 
c499105
@@ -865,9 +822,6 @@
c499105
 {
c499105
   extern ptid_t trap_ptid;
c499105
 
c499105
-  if (GET_PID (ptid) != -1 && is_thread (ptid))
c499105
-    ptid = lwp_from_thread (ptid);
c499105
-
c499105
   ptid = target_beneath->to_wait (ptid, ourstatus);
c499105
 
c499105
   if (ourstatus->kind == TARGET_WAITKIND_EXITED
c499105
@@ -913,15 +867,6 @@
c499105
 }
c499105
 
c499105
 static void
c499105
-thread_db_kill (void)
c499105
-{
c499105
-  /* There's no need to save & restore inferior_ptid here, since the
c499105
-     inferior isn't supposed to survive this function call.  */
c499105
-  inferior_ptid = lwp_from_thread (inferior_ptid);
c499105
-  target_beneath->to_kill ();
c499105
-}
c499105
-
c499105
-static void
c499105
 thread_db_mourn_inferior (void)
c499105
 {
c499105
   /* Forget about the child's process ID.  We shouldn't need it
c499105
@@ -954,7 +899,7 @@
c499105
   if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
c499105
     return 0;			/* A zombie -- ignore.  */
c499105
 
c499105
-  ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid);
c499105
+  ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0);
c499105
 
c499105
   if (ti.ti_tid == 0)
c499105
     {
c499105
@@ -994,18 +939,17 @@
c499105
 static char *
c499105
 thread_db_pid_to_str (ptid_t ptid)
c499105
 {
c499105
-  if (is_thread (ptid))
c499105
+  struct thread_info *thread_info = find_thread_pid (ptid);
c499105
+
c499105
+  if (thread_info != NULL && thread_info->private != NULL)
c499105
     {
c499105
       static char buf[64];
c499105
-      struct thread_info *thread_info;
c499105
+      thread_t tid;
c499105
 
c499105
+      tid = thread_info->private->tid;
c499105
       thread_info = find_thread_pid (ptid);
c499105
-      if (thread_info == NULL)
c499105
-	snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld) (Missing)",
c499105
-		  GET_THREAD (ptid), GET_LWP (ptid));
c499105
-      else
c499105
-	snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
c499105
-		  GET_THREAD (ptid), GET_LWP (ptid));
c499105
+      snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)",
c499105
+		tid, GET_LWP (ptid));
c499105
 
c499105
       return buf;
c499105
     }
c499105
@@ -1022,22 +966,15 @@
c499105
 static char *
c499105
 thread_db_extra_thread_info (struct thread_info *info)
c499105
 {
c499105
+  if (info->private == NULL)
c499105
+    return NULL;
c499105
+
c499105
   if (info->private->dying)
c499105
     return "Exiting";
c499105
 
c499105
   return NULL;
c499105
 }
c499105
 
c499105
-/* Return 1 if this thread has the same LWP as the passed PTID.  */
c499105
-
c499105
-static int
c499105
-same_ptid_callback (struct thread_info *thread, void *arg)
c499105
-{
c499105
-  ptid_t *ptid_p = arg;
c499105
-
c499105
-  return GET_LWP (thread->ptid) == GET_LWP (*ptid_p);
c499105
-}
c499105
-
c499105
 /* Get the address of the thread local variable in load module LM which
c499105
    is stored at OFFSET within the thread local storage for thread PTID.  */
c499105
 
c499105
@@ -1046,26 +983,19 @@
c499105
 				    CORE_ADDR lm,
c499105
 				    CORE_ADDR offset)
c499105
 {
c499105
+  struct thread_info *thread_info;
c499105
+
c499105
   /* If we have not discovered any threads yet, check now.  */
c499105
-  if (!is_thread (ptid) && !have_threads ())
c499105
+  if (!have_threads ())
c499105
     thread_db_find_new_threads ();
c499105
 
c499105
-  /* Try to find a matching thread if we still have the LWP ID instead
c499105
-     of the thread ID.  */
c499105
-  if (!is_thread (ptid))
c499105
-    {
c499105
-      struct thread_info *thread;
c499105
-
c499105
-      thread = iterate_over_threads (same_ptid_callback, &ptid);
c499105
-      if (thread != NULL)
c499105
-	ptid = thread->ptid;
c499105
-    }
c499105
+  /* Find the matching thread.  */
c499105
+  thread_info = find_thread_pid (ptid);
c499105
 
c499105
-  if (is_thread (ptid))
c499105
+  if (thread_info != NULL && thread_info->private != NULL)
c499105
     {
c499105
       td_err_e err;
c499105
       void *address;
c499105
-      struct thread_info *thread_info;
c499105
 
c499105
       /* glibc doesn't provide the needed interface.  */
c499105
       if (!td_thr_tls_get_addr_p)
c499105
@@ -1075,11 +1005,6 @@
c499105
       /* Caller should have verified that lm != 0.  */
c499105
       gdb_assert (lm != 0);
c499105
 
c499105
-      /* Get info about the thread.  */
c499105
-      thread_info = find_thread_pid (ptid);
c499105
-      gdb_assert (thread_info);
c499105
-      thread_db_map_id2thr (thread_info, 1);
c499105
-
c499105
       /* Finally, get the address of the variable.  */
c499105
       err = td_thr_tls_get_addr_p (&thread_info->private->th,
c499105
 				   (void *)(size_t) lm,
c499105
@@ -1122,9 +1047,7 @@
c499105
   thread_db_ops.to_longname = "multi-threaded child process.";
c499105
   thread_db_ops.to_doc = "Threads and pthreads support.";
c499105
   thread_db_ops.to_detach = thread_db_detach;
c499105
-  thread_db_ops.to_resume = thread_db_resume;
c499105
   thread_db_ops.to_wait = thread_db_wait;
c499105
-  thread_db_ops.to_kill = thread_db_kill;
c499105
   thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
c499105
   thread_db_ops.to_find_new_threads = thread_db_find_new_threads;
c499105
   thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/procfs.c,v
c499105
retrieving revision 1.86
c499105
retrieving revision 1.87
c499105
diff -u -r1.86 -r1.87
c499105
--- src/gdb/procfs.c	2008/03/12 20:00:21	1.86
c499105
+++ src/gdb/procfs.c	2008/03/21 15:44:53	1.87
c499105
@@ -4034,8 +4034,9 @@
c499105
 	      case PR_SYSENTRY:
c499105
 		if (syscall_is_lwp_exit (pi, what))
c499105
 		  {
c499105
-		    printf_filtered (_("[%s exited]\n"),
c499105
-				     target_pid_to_str (retval));
c499105
+		    if (print_thread_events)
c499105
+		      printf_unfiltered (_("[%s exited]\n"),
c499105
+					 target_pid_to_str (retval));
c499105
 		    delete_thread (retval);
c499105
 		    status->kind = TARGET_WAITKIND_SPURIOUS;
c499105
 		    return retval;
c499105
@@ -4165,8 +4166,9 @@
c499105
 		  }
c499105
 		else if (syscall_is_lwp_exit (pi, what))
c499105
 		  {
c499105
-		    printf_filtered (_("[%s exited]\n"),
c499105
-				     target_pid_to_str (retval));
c499105
+		    if (print_thread_events)
c499105
+		      printf_unfiltered (_("[%s exited]\n"),
c499105
+					 target_pid_to_str (retval));
c499105
 		    delete_thread (retval);
c499105
 		    status->kind = TARGET_WAITKIND_SPURIOUS;
c499105
 		    return retval;
8b1b3fd
Index: gdb-6.8/gdb/thread.c
c499105
===================================================================
8b1b3fd
--- gdb-6.8.orig/gdb/thread.c	2008-03-12 23:22:06.000000000 +0100
8b1b3fd
+++ gdb-6.8/gdb/thread.c	2008-07-14 10:24:32.000000000 +0200
8b1b3fd
@@ -131,16 +131,24 @@ add_thread_silent (ptid_t ptid)
c499105
 }
c499105
 
c499105
 struct thread_info *
c499105
-add_thread (ptid_t ptid)
c499105
+add_thread_with_info (ptid_t ptid, struct private_thread_info *private)
c499105
 {
c499105
   struct thread_info *result = add_thread_silent (ptid);
c499105
 
c499105
+  result->private = private;
c499105
+
c499105
   if (print_thread_events)
c499105
     printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
8b1b3fd
   
c499105
   return result;
c499105
 }
c499105
 
c499105
+struct thread_info *
c499105
+add_thread (ptid_t ptid)
c499105
+{
c499105
+  return add_thread_with_info (ptid, NULL);
c499105
+}
c499105
+
c499105
 void
c499105
 delete_thread (ptid_t ptid)
c499105
 {
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/testsuite/gdb.threads/fork-child-threads.exp,v
c499105
retrieving revision 1.1
c499105
retrieving revision 1.2
c499105
diff -u -r1.1 -r1.2
c499105
--- src/gdb/testsuite/gdb.threads/fork-child-threads.exp	2008/01/02 13:36:38	1.1
c499105
+++ src/gdb/testsuite/gdb.threads/fork-child-threads.exp	2008/03/21 15:44:53	1.2
c499105
@@ -38,6 +38,10 @@
c499105
 
c499105
 gdb_test "set follow-fork-mode child"
c499105
 gdb_breakpoint "start"
c499105
+
c499105
+# Make sure we can step over fork without losing our breakpoint.
c499105
+gdb_test "next" ".*pthread_create \\(&thread, NULL, start, NULL\\);.*" "next over fork"
c499105
+
c499105
 gdb_test "continue" "Breakpoint 2, start.*" "get to the spawned thread"
c499105
 
c499105
 # Wrong:
c499105
c499105
http://sourceware.org/ml/gdb-patches/2008-04/msg00238.html
c499105
http://sourceware.org/ml/gdb-cvs/2008-04/msg00068.html
c499105
c499105
2008-04-14  Daniel Jacobowitz  <dan@codesourcery.com>
c499105
c499105
	* linux-thread-db.c (have_threads_callback): Check thread->private.
c499105
c499105
===================================================================
c499105
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
c499105
retrieving revision 1.40
c499105
retrieving revision 1.41
c499105
diff -u -r1.40 -r1.41
c499105
--- src/gdb/linux-thread-db.c	2008/03/25 12:26:21	1.40
c499105
+++ src/gdb/linux-thread-db.c	2008/04/14 14:02:23	1.41
c499105
@@ -235,7 +235,7 @@
c499105
 static int
c499105
 have_threads_callback (struct thread_info *thread, void *dummy)
c499105
 {
c499105
-  return 1;
c499105
+  return thread->private != NULL;
c499105
 }
c499105
 
c499105
 static int
4824eee
4824eee
4824eee
4824eee
2008-05-03  Jan Kratochvil  <jan.kratochvil@redhat.com>
4824eee
4824eee
	* gdb.base/dfp-test.exp: Fix random FAIL risk on calling functions.
4824eee
4824eee
===================================================================
4824eee
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/dfp-test.exp,v
4824eee
retrieving revision 1.5
4824eee
retrieving revision 1.6
4824eee
diff -u -r1.5 -r1.6
4824eee
--- src/gdb/testsuite/gdb.base/dfp-test.exp	2008/01/30 03:19:26	1.5
4824eee
+++ src/gdb/testsuite/gdb.base/dfp-test.exp	2008/05/03 21:56:38	1.6
4824eee
@@ -252,16 +252,16 @@
4824eee
 
4824eee
 # Test calling inferior function with DFP arguments or return value.
4824eee
 
4824eee
-send_gdb "call arg0_32 (1.2df, 2.2df, 3.2df, 4.2df, 5.2df, 6.2df)\n"
4824eee
-gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_32 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Call function with correct _Decimal32 arguments."
4824eee
+gdb_test "call arg0_32 (1.2df, 2.2df, 3.2df, 4.2df, 5.2df, 6.2df)" "Breakpoint.*arg0_32.*" "Call function with correct _Decimal32 arguments."
4824eee
+gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_32 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Backtrace function with correct _Decimal32 arguments."
4824eee
 gdb_test "finish" " = 1.2" "Correct _Decimal32 return value from called function."
4824eee
 
4824eee
-send_gdb "call arg0_64 (1.2dd, 2.2dd, 3.2dd, 4.2dd, 5.2dd, 6.2dd)\n"
4824eee
-gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_64 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Call function with correct _Decimal64 arguments."
4824eee
+gdb_test "call arg0_64 (1.2dd, 2.2dd, 3.2dd, 4.2dd, 5.2dd, 6.2dd)" "Breakpoint.*arg0_64.*" "Call function with correct _Decimal64 arguments."
4824eee
+gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_64 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Backtrace function with correct _Decimal64 arguments."
4824eee
 gdb_test "finish" " = 1.2" "Correct _Decimal64 return value from called function."
4824eee
 
4824eee
-send_gdb "call arg0_128 (1.2dl, 2.2dl, 3.2dl, 4.2dl, 5.2dl, 6.2dl)\n"
4824eee
-gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_128 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Call function with correct _Decimal128 arguments."
4824eee
+gdb_test "call arg0_128 (1.2dl, 2.2dl, 3.2dl, 4.2dl, 5.2dl, 6.2dl)" "Breakpoint.*arg0_128.*" "Call function with correct _Decimal128 arguments."
4824eee
+gdb_test "backtrace 1" "\n#\[0-9\]+  arg0_128 \\(arg0=1.2, arg1=2.2, arg2=3.2, arg3=4.2, arg4=5.2, arg5=6.2\\).*" "Backtrace function with correct _Decimal128 arguments."
4824eee
 gdb_test "finish" " = 1.2" "Correct _Decimal128 return value from called function."
4824eee
 
4824eee
 gdb_test "call decimal_dec128_align (double_val1, dec128_val2, double_val3, double_val4, double_val5, double_val6, double_val7, double_val8, double_val9, double_val10, double_val11, double_val12, double_val13, double_val14)" " = 1" \
5ca2edc
5ca2edc
5ca2edc
5ca2edc
gdb/
5ca2edc
2008-07-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
5ca2edc
5ca2edc
	* breakpoint.c (bpstat_copy): Call RELEASE_VALUE on the new OLD_VAL.
5ca2edc
5ca2edc
gdb/testsuite/
5ca2edc
2008-07-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
5ca2edc
5ca2edc
	* gdb.base/value-double-free.exp, gdb.base/value-double-free.c: New.
5ca2edc
5ca2edc
===================================================================
5ca2edc
RCS file: /cvs/src/src/gdb/breakpoint.c,v
5ca2edc
retrieving revision 1.327
5ca2edc
retrieving revision 1.328
5ca2edc
diff -u -r1.327 -r1.328
5ca2edc
--- src/gdb/breakpoint.c	2008/06/28 09:42:15	1.327
5ca2edc
+++ src/gdb/breakpoint.c	2008/07/07 22:39:58	1.328
5ca2edc
@@ -1996,7 +1996,10 @@
5ca2edc
       if (bs->commands != NULL)
5ca2edc
 	tmp->commands = copy_command_lines (bs->commands);
5ca2edc
       if (bs->old_val != NULL)
5ca2edc
-	tmp->old_val = value_copy (bs->old_val);
5ca2edc
+	{
5ca2edc
+	  tmp->old_val = value_copy (bs->old_val);
5ca2edc
+	  release_value (tmp->old_val);
5ca2edc
+	}
5ca2edc
 
5ca2edc
       if (p == NULL)
5ca2edc
 	/* This is the first thing in the chain.  */
5ca2edc
/cvs/src/src/gdb/testsuite/gdb.base/value-double-free.c,v  -->  standard output
5ca2edc
revision 1.1
5ca2edc
--- src/gdb/testsuite/gdb.base/value-double-free.c
5ca2edc
+++ src/gdb/testsuite/gdb.base/value-double-free.c	2008-07-07 22:40:47.485459000 +0000
5ca2edc
@@ -0,0 +1,36 @@
5ca2edc
+/* This testcase is part of GDB, the GNU debugger.
5ca2edc
+
5ca2edc
+   Copyright 2008 Free Software Foundation, Inc.
5ca2edc
+
5ca2edc
+   This program is free software; you can redistribute it and/or modify
5ca2edc
+   it under the terms of the GNU General Public License as published by
5ca2edc
+   the Free Software Foundation; either version 3 of the License, or
5ca2edc
+   (at your option) any later version.
5ca2edc
+
5ca2edc
+   This program is distributed in the hope that it will be useful,
5ca2edc
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
5ca2edc
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5ca2edc
+   GNU General Public License for more details.
5ca2edc
+
5ca2edc
+   You should have received a copy of the GNU General Public License
5ca2edc
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
5ca2edc
+
5ca2edc
+   Please email any bugs, comments, and/or additions to this file to:
5ca2edc
+   bug-gdb@prep.ai.mit.edu  */
5ca2edc
+
5ca2edc
+volatile int var;
5ca2edc
+
5ca2edc
+void
5ca2edc
+empty (void)
5ca2edc
+{
5ca2edc
+}
5ca2edc
+
5ca2edc
+int
5ca2edc
+main (void)
5ca2edc
+{
5ca2edc
+  var = 1;
5ca2edc
+  /* Workaround PR 38: We may miss the first watchpoint hit as we stop on the
5ca2edc
+     exact instruction which would cause the watchpoint hit.  */
5ca2edc
+  var = 2;
5ca2edc
+  return 0;
5ca2edc
+}
5ca2edc
/cvs/src/src/gdb/testsuite/gdb.base/value-double-free.exp,v  -->  standard output
5ca2edc
revision 1.1
5ca2edc
--- src/gdb/testsuite/gdb.base/value-double-free.exp
5ca2edc
+++ src/gdb/testsuite/gdb.base/value-double-free.exp	2008-07-07 22:40:48.139680000 +0000
5ca2edc
@@ -0,0 +1,38 @@
5ca2edc
+# Copyright 2008 Free Software Foundation, Inc.
5ca2edc
+
5ca2edc
+# This program is free software; you can redistribute it and/or modify
5ca2edc
+# it under the terms of the GNU General Public License as published by
5ca2edc
+# the Free Software Foundation; either version 3 of the License, or
5ca2edc
+# (at your option) any later version.
5ca2edc
+#
5ca2edc
+# This program is distributed in the hope that it will be useful,
5ca2edc
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
5ca2edc
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5ca2edc
+# GNU General Public License for more details.
5ca2edc
+#
5ca2edc
+# You should have received a copy of the GNU General Public License
5ca2edc
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
5ca2edc
+
5ca2edc
+set testfile value-double-free
5ca2edc
+set srcfile ${testfile}.c
5ca2edc
+set binfile ${objdir}/${subdir}/${testfile}
5ca2edc
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
5ca2edc
+    untested "Couldn't compile test program"
5ca2edc
+    return -1
5ca2edc
+}
5ca2edc
+
5ca2edc
+# Get things started.
5ca2edc
+
5ca2edc
+gdb_exit
5ca2edc
+gdb_start
5ca2edc
+gdb_reinitialize_dir $srcdir/$subdir
5ca2edc
+gdb_load ${binfile}
5ca2edc
+
5ca2edc
+if ![runto_main] {
5ca2edc
+    return -1
5ca2edc
+}
5ca2edc
+gdb_test "watch var" "atchpoint \[0-9\]+: var"
5ca2edc
+gdb_test "continue" "atchpoint \[0-9\]+: var.*Old value = 0.*New value = \[12\].*"
5ca2edc
+gdb_test "print empty()" " = void"
5ca2edc
+# We did segfault here.
5ca2edc
+gdb_test "help help"
535451a
535451a
535451a
535451a
http://sourceware.org/ml/gdb-patches/2008-03/msg00356.html
535451a
http://sourceware.org/ml/gdb-cvs/2008-03/msg00130.html
535451a
535451a
2008-03-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
535451a
535451a
	Fix random false FAILs on i386.
535451a
	* gdb.base/prelink.exp: Use `--no-exec-shield' for prelink.
535451a
535451a
===================================================================
535451a
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/prelink.exp,v
535451a
retrieving revision 1.7
535451a
retrieving revision 1.8
535451a
diff -u -r1.7 -r1.8
535451a
--- src/gdb/testsuite/gdb.base/prelink.exp	2008/01/01 22:53:19	1.7
535451a
+++ src/gdb/testsuite/gdb.base/prelink.exp	2008/03/24 15:16:12	1.8
535451a
@@ -47,7 +47,15 @@
535451a
     return -1
535451a
 }
535451a
 
535451a
-if {[catch "system \"prelink -qNR ${libfile}\""] != 0} {
535451a
+# `--no-exec-shield' is for i386 where prelink in the exec-shield mode is
535451a
+# forced to push all the libraries tight together to fit into the first two
535451a
+# memory areas (either the ASCII Shield area or at least below the executable).
535451a
+# In this case its -R option cannot be applied and we falsely FAIL here as if
535451a
+# the system is already prelinked prelink has no choice how to randomize the
535451a
+# single new unprelinked library address without wasting the first one/two
535451a
+# memory areas.  We do not care of the efficiency of loading such resulting
535451a
+# exec-shield unfriendly prelinked library.
535451a
+if {[catch "system \"prelink -qNR --no-exec-shield ${libfile}\""] != 0} {
535451a
     # Maybe we don't have prelink.
535451a
     return -1
535451a
 }
535451a
@@ -92,7 +100,7 @@
535451a
     untested "${testfile}.so was not prelinked, maybe system libraries are not prelinked?"
535451a
     return 0
535451a
 }
535451a
-catch "system \"prelink -qNR ${libfile}\""
535451a
+catch "system \"prelink -qNR --no-exec-shield ${libfile}\""
535451a
 
535451a
 # Start with a fresh gdb
535451a