GDB HEAD (partly) broken for GNU/Hurd

Thomas Schwinge tschwinge@gnu.org
Sat Oct 11 17:29:00 GMT 2008


Hello!

On Sat, Oct 11, 2008 at 12:47:39AM +0100, Pedro Alves wrote:
> On Saturday 11 October 2008 00:27:06, Thomas Schwinge wrote:
> > On HEAD, when undoing this change (and additionally commenting out the
> > two ``stop_soon = X'' lines in that file), things are fine again.

At the end of this email I'll append the patch I use to get it going
again.  Obviously this can't be installed as-is.  :-)

> Eh, I did point out at the time of that change that gnu-nat.c does
> things a bit different.  :-)

Yes, I can see that:
<http://sourceware.org/ml/gdb-patches/2008-09/msg00097.html>

> Off-hand advice:
> 
> One thing that the hurd has a bit different, is that we have
> multi-threading when going through the shell.
> 
> Could it be that target_wait is returning a specific ptid here:
> 
> fork_child.c:startup_inferior:
> 
>   while (1)
>     {
>       int resume_signal = TARGET_SIGNAL_0;
>       ptid_t resume_ptid;
> 
>       struct target_waitstatus ws;
>       memset (&ws, 0, sizeof (ws));
>       resume_ptid = target_wait (pid_to_ptid (-1), &ws);
>       ^^^^^^^^^^^
> 
> 
> Hence this a bit below:
> 
> 	  if (--pending_execs == 0)
> 	    break;
> 
> 	  /* Just make it go on.  */
> 	  target_resume (resume_ptid, 0, TARGET_SIGNAL_0);
>                          ^^^^^^^^^^^
> 	}
>     }
> 
> Doesn't resume the whole shell?

But as I see things we always have ``non_stop == 0'' and thus
``resume_ptid = pid_to_ptid (-1)'', so that should be fine, isn't it?

> If you make this change:
> -     target_resume (resume_ptid, 0, TARGET_SIGNAL_0);
> +     target_resume (minus_one_ptid, 0, TARGET_SIGNAL_0);

This didn't help.

> The other thing I suggest to look at, is to make sure the
> local `pending_execs' and the `gnu-nat.c:struct inf'::pending_execs
> aren't in conflict, but it doesn't look like it.

Doesn't look like it, no.  For another issue, see the comment in the
patch below.

> Hope this helps.

Unfortunately no luck so far.  wait_for_inferior / handle_inferior_event
(which was used in the old code) is too complex as to be quickly
understandable for me.  And I guess I'm estimating correctly that it's
``simply'' some side-effect of these that the old code works, while the
new doesn't?  Perhaps having a look at the logs I appended below some of
you GDB gurus is able to spot the obvious?


Index: fork-child.c
===================================================================
RCS file: /cvs/src/src/gdb/fork-child.c,v
retrieving revision 1.45
diff -u -p -r1.45 fork-child.c
--- fork-child.c	22 Sep 2008 15:16:51 -0000	1.45
+++ fork-child.c	11 Oct 2008 16:59:47 -0000
@@ -128,7 +128,7 @@ fork_inferior (char *exec_file_arg, char
   static char default_shell_file[] = SHELL_FILE;
   int len;
   /* Set debug_fork then attach to the child while it sleeps, to debug. */
-  static int debug_fork = 0;
+  static int debug_fork = 1;  /* Not functionally needed, but helpful for readable logging messages.  */
   /* This is set to the result of setpgrp, which if vforked, will be visible
      to you in the parent process.  It's only used by humans for debugging.  */
   static int debug_setpgrp = 657473;
@@ -427,14 +427,23 @@ startup_inferior (int ntraps)
      have stopped one instruction after execing the shell.  Here we
      must get it up to actual execution of the real program.  */
 
+  /* TODO.  How to keep this synchronized with gnu-nat.c's own counting?  */
   if (exec_wrapper)
     pending_execs++;
 
+#define NEW_CODE 0
+
+#if NEW_CODE
+#else
+  init_wait_for_inferior ();
+#endif
+
   while (1)
     {
       int resume_signal = TARGET_SIGNAL_0;
       ptid_t resume_ptid;
 
+#if NEW_CODE
       struct target_waitstatus ws;
       memset (&ws, 0, sizeof (ws));
       resume_ptid = target_wait (pid_to_ptid (-1), &ws);
@@ -486,6 +495,17 @@ startup_inferior (int ntraps)
 	    resume_signal = ws.value.sig;
 	    break;
 	}
+#else
+      struct thread_info *tp;
+
+      /* Make wait_for_inferior be quiet. */
+      current_inferior ()->stop_soon = STOP_QUIETLY;
+      wait_for_inferior (1);
+      tp = inferior_thread ();
+
+resume_signal = tp->stop_signal;
+resume_ptid = pid_to_ptid (-1);
+#endif
 
       if (resume_signal != TARGET_SIGNAL_TRAP)
 	{
@@ -519,6 +539,10 @@ startup_inferior (int ntraps)
 	  target_resume (resume_ptid, 0, TARGET_SIGNAL_0);
 	}
     }
+#if NEW_CODE
+#else
+  current_inferior ()->stop_soon = NO_STOP_QUIETLY;
+#endif
 }
 
 /* Implement the "unset exec-wrapper" command.  */


Here is a debugging-enabled run of a thusly patched GDB HEAD:

    GNU gdb (GDB) 6.8.50.20081011-cvs
    [...]
    (gdb) set debug infrun 1
    (gdb) set debug target 1
    (gdb) r
    Starting program: /media/data/home/tschwinge/tmp/n1/hurd/ext2fs.static
    infrun: wait_for_inferior (treat_exec_as_sigtrap=1)
    target_wait (-1, status) = 25830,   status->kind = stopped, signal = SIGTRAP
    target_fetch_registers (eip) = 701e0000 0x1e70 7792
    infrun: infwait_normal_state
    infrun: TARGET_WAITKIND_STOPPED
    infrun: stop_pc = 0x1e70
    STOPPED_BY_WATCHPOINT () = 0
    infrun: context switch
    infrun: Switching context from bogus thread id 1 to Thread 25830.3
    target_fetch_registers (eip) = 701e0000 0x1e70 7792
    STOPPED_BY_WATCHPOINT () = 0
    infrun: quietly stopped
    infrun: stop_stepping
    target_terminal_init ()
    target_terminal_inferior ()
    target_resume (-1, continue, 0)
    infrun: wait_for_inferior (treat_exec_as_sigtrap=1)
    target_wait (-1, status) = 25830,   status->kind = stopped, signal = SIGTRAP
    target_fetch_registers (eip) = 30810408 0x8048130 134512944
    infrun: infwait_normal_state
    infrun: TARGET_WAITKIND_STOPPED
    infrun: stop_pc = 0x8048130
    STOPPED_BY_WATCHPOINT () = 0
    infrun: context switch
    infrun: Switching context from bogus thread id 3 to Thread 25830.4
    target_fetch_registers (eip) = 30810408 0x8048130 134512944
    STOPPED_BY_WATCHPOINT () = 0
    target_terminal_ours_for_output ()
    infrun: quietly stopped
    infrun: stop_stepping
    target_terminal_ours ()
    GNU:target_xfer_partial (9, target.xml, 0x843d140,  0x0,  0x0, 4095) = -1
    GNU:target_xfer_partial (5, (null), 0x843d140,	0x0,  0x0, 4096) = -1
    GNU:target_xfer_partial (5, (null), 0x843d140,	0x0,  0x0, 4096) = -1
    target_memory_map ()
    GNU:target_xfer_partial (2, (null), 0x15ff570,	0x0,  0x816ff14, 4) = 4, bytes =
     00 00 00 00
    GNU:target_xfer_partial (5, (null), 0x843d140,	0x0,  0x0, 4096) = -1
    GNU:target_xfer_partial (5, (null), 0x843d140,	0x0,  0x0, 4096) = -1
    GNU:target_xfer_partial (2, (null), 0x15ff510,	0x0,  0x816ff14, 4) = 4, bytes =
     00 00 00 00
    GNU:target_xfer_partial (2, (null), 0x15ff5d0,	0x0,  0x816ff14, 4) = 4, bytes =
     00 00 00 00
    GNU:target_xfer_partial (5, (null), 0x843d140,	0x0,  0x0, 4096) = -1
    infrun: proceed (addr=0xffffffff, signal=0, step=0)
    GNU:target_xfer_partial (2, (null), 0x836af1c,	0x0,  0x80deef0, 1) = 1, bytes = 55
    GNU:target_xfer_partial (2, (null), 0x0,  0x82d612b,  0x80deef0, 1) = 1, bytes = cc
    target_insert_breakpoint (0x80deef0, xxx) = 0
    infrun: resume (step=0, signal=0), trap_expected=0
    target_terminal_inferior ()
    target_resume (-1, continue, 0)
    infrun: wait_for_inferior (treat_exec_as_sigtrap=0)
    [New Thread 25830.5]
    target_wait (-1, status) = 25830,   status->kind = stopped, signal = SIGSEGV
    infrun: infwait_normal_state
    infrun: TARGET_WAITKIND_STOPPED
    target_fetch_registers (eip) = 79440b08 0x80b4479 134956153
    infrun: stop_pc = 0x80b4479
    STOPPED_BY_WATCHPOINT () = 0
    STOPPED_BY_WATCHPOINT () = 0
    target_terminal_ours_for_output ()
    infrun: random signal 11
    target_terminal_ours_for_output ()
    
    Program received signal SIGSEGV, Segmentation fault.
    infrun: stop_stepping
    GNU:target_xfer_partial (2, (null), 0x0,  0x836af1c,  0x80deef0, 1) = 1, bytes = 55
    target_remove_breakpoint (0x80deef0, xxx) = 0
    target_terminal_ours ()
    target_fetch_registers (ebp) = 18f90101 0x101f918 16906520
    GNU:target_xfer_partial (2, (null), 0x83a567c,	0x0,  0x101f8ec, 4) = 4, bytes = bc f0 13 08
    GNU:target_xfer_partial (2, (null), 0x837b994,	0x0,  0x101f8e8, 4) = 4, bytes = 00 00 00 00
    GNU:target_xfer_partial (2, (null), 0x836e19c,	0x0,  0x101f8e4, 4) = 4, bytes = 00 00 00 00
    GNU:target_xfer_partial (2, (null), 0x836e25c,	0x0,  0x101f920, 4) = 4, bytes = e8 12 17 08
    GNU:target_xfer_partial (2, (null), 0x837b814,	0x0,  0x101f924, 4) = 4, bytes = d0 fa 01 01
    convert_options (argp=0x813f0bc, parent=0x0, parent_index=0, group=0x81712e8, cvt=0x101fad0) at argp.h:579
    579	argp.h: No such file or directory.
    	in argp.h
    (gdb) info threads
    target_thread_alive (25830) = 1
    target_thread_alive (25830) = 1
    target_thread_alive (25830) = 0
    target_thread_alive (25830) = 0
    target_thread_alive (25830) = 0
    target_find_new_threads ()
    target_fetch_registers (eip) = 8c5a0b08 0x80b5a8c 134961804
      5 Thread 25830.5  0x080b5a8c in mach_msg_trap ()
    target_fetch_registers (eip) = 79440b08 0x80b4479 134956153
    target_fetch_registers (ebp) = 18f90101 0x101f918 16906520
    GNU:target_xfer_partial (2, (null), 0x838142c,	0x0,  0x101f8ec, 4) = 4, bytes = bc f0 13 08
    GNU:target_xfer_partial (2, (null), 0x837db74,	0x0,  0x101f8e8, 4) = 4, bytes = 00 00 00 00
    GNU:target_xfer_partial (2, (null), 0x83815fc,	0x0,  0x101f8e4, 4) = 4, bytes = 00 00 00 00
    GNU:target_xfer_partial (2, (null), 0x83816bc,	0x0,  0x101f920, 4) = 4, bytes = e8 12 17 08
    GNU:target_xfer_partial (2, (null), 0x83a2074,	0x0,  0x101f924, 4) = 4, bytes = d0 fa 01 01
    * 4 Thread 25830.4  convert_options (argp=0x813f0bc, parent=0x0, parent_index=0, group=0x81712e8, cvt=0x101fad0) at argp.h:579

... as compared to plain GDB HEAD:

    (gdb) set debug infrun 1
    (gdb) set debug target 1
    (gdb) r
    Starting program: /media/data/home/tschwinge/tmp/n1/hurd/ext2fs.static 
    target_wait (-1, status) = 25945,   status->kind = stopped, signal = SIGTRAP
    target_terminal_init ()
    target_terminal_inferior ()
    target_resume (-1, continue, 0)
    target_wait (-1, status) = 25945,   status->kind = stopped, signal = SIGTRAP
    target_terminal_ours ()
    GNU:target_xfer_partial (9, target.xml, 0x843b360,  0x0,  0x0, 4095) = -1
    GNU:target_xfer_partial (5, (null), 0x843b360,  0x0,  0x0, 4096) = -1
    GNU:target_xfer_partial (5, (null), 0x843b360,  0x0,  0x0, 4096) = -1
    target_memory_map ()
    GNU:target_xfer_partial (2, (null), 0x15ff570,  0x0,  0x816ff14, 4) = 4, bytes =
     00 00 00 00
    target_terminal_ours ()
    Can't fetch registers from thread bogus thread id 1: No such thread


Thanks for your help!


Regards,
 Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 191 bytes
Desc: Digital signature
URL: <http://sourceware.org/pipermail/gdb/attachments/20081011/40bc7d5a/attachment.sig>


More information about the Gdb mailing list