gdb in ports

John Baldwin jhb at freebsd.org
Tue May 12 19:41:32 UTC 2015


On Tuesday, May 12, 2015 06:06:38 PM Tijl Coosemans wrote:
> On Mon, 11 May 2015 16:21:42 -0400 Jason Woodward <woodwardj at averesystems.com> wrote:
> > Hi all,
> > 
> > I had sent this to Luca but maybe others might have an idea...
> > 
> > 
> > I'm running into some difficulty debugging a live, multithreaded
> > application.  This seems to be the case with the 7.8.x gdbs and 7.9 (both
> > 9.2 and 10 release).  When I attach, I see duplicates for the first thread:
> > 
> >   5    Thread 817ff2c00 (LWP 100541) 0x000000080bd6286c in poll () at
> > poll.S:3
> >   4    Thread 80efe8c00 (LWP 100546) 0x000000080bd6286c in poll () at
> > poll.S:3
> >   3    Thread 80efe9000 (LWP 100878) 0x000000080bd6286c in poll () at
> > poll.S:3
> > * 2    Thread 80efe9400 (LWP 101124) 0x000000080bd6286c in poll () at
> > poll.S:3
> > * 1    Thread 80efe9400 (LWP 101124) 0x000000080bd6286c in poll () at
> > poll.S:3
> > 
> > Trying to select 1 or 2 always ends up selecting 2:
> > 
> > (gdb) thread 1
> > [Switching to thread 2 (Thread 80efe9400 (LWP 101124))]
> > #0  0x000000080bd6286c in poll () at poll.S:3
> > 3       in poll.S
> > (gdb) thread 2
> > [Switching to thread 2 (Thread 80efe9400 (LWP 101124))]
> > #0  0x000000080bd6286c in poll () at poll.S:33       in poll.S
> > (gdb)
> > 
> > On top of this, when stepping through it seems threads that start and stop
> > quickly have some sort of race condition that results in the thread
> > tracking getting messed up.  Sometimes I'll end up on thread 74, other
> > times I will be on a thread that has gone away and "info threads" does not
> > show me associated with any of the active threads.  With 7.8.x I would see:
> > 
> >   Id   Target Id         Frame
> >   75   Cannot find thread, Thread ID=101080, no thread to satisfy query
> > 
> > 
> > Unsure if related, but after stepping through with 7.9, the following
> > happens in fbsd_thread_wait():
> > 
> > infrun.c:5530: internal-error: switch_back_to_stepped_thread: Assertion
> > `!tp->control.trap_expected' failed.
> > A problem internal to GDB has been detected,
> > further debugging may prove unreliable.
> > Quit this debugging session? (y or n) y
> > 
> > This is a bug, please report it.  For instructions, see:
> > <http://www.gnu.org/software/gdb/bugs/>.
> > 
> > infrun.c:5530: internal-error: switch_back_to_stepped_thread: Assertion
> > `!tp->control.trap_expected' failed.
> > A problem internal to GDB has been detected,further debugging may prove
> > unreliable.
> > Create a core file of GDB? (y or n) n
> 
> CC jhb.  Maybe he can help.

So one of the changes made after fbsd-threads.c had been first ported to GDB 7
was to remove a call to 'init_thread_list()' in fbsd_thread_activate().  There
is an open PR against 7.9 where the solution I've come up with for now is to
put that back for cores to ignore the threads that GDB creates as LWPs when it
walks the core dump notes.  I've included that diff below.  You could try using
that for live debugging, but I think that isn't the real solution.  Instead,
when we attach threads we should be doing a change_ptid() to change the "main"
thread to be a thread instead of a process.

Try this:

Index: fbsd-threads.c
===================================================================
--- fbsd-threads.c	(revision 385904)
+++ fbsd-threads.c	(working copy)
@@ -320,16 +320,36 @@ get_current_thread (void)
   lwp = get_current_lwp (proc_handle.pid);
   tmp = BUILD_LWP (lwp, proc_handle.pid);
   ptid = thread_from_lwp (tmp, &th, &ti);
-  if (in_thread_list (inferior_ptid) )
+  if (in_thread_list (inferior_ptid))
     {
-      struct thread_info * ti_inf = inferior_thread();
-      ti_inf->ptid = ptid;
+      struct private_thread_info *private;
+      struct thread_info *tp;
+      td_err_e err;
+
+      thread_change_ptid (inferior_ptid, ptid);
+
+      /* Add thread with info */
+      private = xcalloc(1, sizeof(struct private_thread_info));
+      gdb_assert(private != NULL);
+      // Thread name is assigned when printed
+
+      tp = find_thread_ptid (ptid);
+      gdb_assert(tp->private == NULL);
+      tp->private = private;
+      tp->private_dtor = free_private_thread_info;
+      if (target_has_execution)
+	{
+	  /* Enable thread event reporting for this thread. */
+	  err = td_thr_event_enable_p (th_p, 1);
+	  if (err != TD_OK)
+	    error ("Cannot enable thread event reporting for %s: %s",
+		   target_pid_to_str (ptid), thread_db_err_str (err));
+	}
     }
-  if (!in_thread_list (ptid))
+  else if (!in_thread_list (ptid))
     {
       attach_thread (ptid, &th, &ti, 1);
     }
-  inferior_ptid = ptid;
 }
 
 static CORE_ADDR
@@ -441,8 +461,10 @@ fbsd_thread_activate (void)
   fbsd_thread_active = 1;
   if (target_has_execution)
     enable_thread_event_reporting ();
+  else
+    init_thread_list ();
+  get_current_thread ();
   fbsd_thread_update_thread_list (NULL);
-  get_current_thread ();
 }
 
 static void
@@ -667,13 +689,11 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *
   if (!in_thread_list (ptid))
   {
     /* Add thread with info */
-    private = xmalloc(sizeof(struct private_thread_info));
+    private = xcalloc(1, sizeof(struct private_thread_info));
     gdb_assert(private != NULL);
     // Thread name is assigned when printed
-    memset(private, 0, sizeof(struct private_thread_info));
 
     tp = add_thread_with_info(ptid, private);
-    tp->private = private;
     tp->private_dtor = free_private_thread_info;
   }


-- 
John Baldwin


More information about the freebsd-ports mailing list