This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RFC: Fix gdb 5.1 for Linuxthreads


On Tue, Sep 18, 2001 at 01:55:55PM -0700, H . J . Lu wrote:
> On Mon, Sep 17, 2001 at 07:13:57PM -0700, H . J . Lu wrote:
> > > 
> > > The more I looked at it, the more borken gdb is with linuxthreads:
> > > 
> > > # gcc -g ex11.c -lpthread -lrt -D_GNU_SOURCE -static
> > > # a.out
> > > # gdb a.out
> > > ...
> > > (gdb) att 14226
> > > Attaching to program: /home/hjl/bugs/gdb/thread/a.out, process 14226
> > > ...
> > > lin-lwp.c:620: gdb-internal-error: stop_wait_callback: Assertion `pid ==
> > > GET_LWP (lp->ptid)' failed.
> > > An internal GDB error was detected.  This may make further
> > 
> > It looks like with gdb 5.1, I have to attach the very first thread. Is
> > that documented anywhere? Shouldn't gdb find the very first thread
> > and attach it for me?
> 
> It seems that the Linuxthreads support in gdb 5.1 is very fragile. In
> some aspects, it is worse than gdb 4.17/4.18 with various Linuxthreads
> patches. The problem seems to be gdb starts with the none-threaded mode
> and the Linuxthreads support is only activated at very late time. In
> some cases, it is too late. One problem seems to call wait () on cloned
> processes. Can't we treat none-threaded Linux procceses as a
> Linuxthreads with one thread? That is what gdb 4.17 does.
> 

This patch seems to work for me. Any comments? It also fixes debugging
the statically linked linuxthreads binaries.


H.J.
----
2001-09-18  H.J. Lu  (hjl@gnu.org)

	* config/nm-linux.h: Include <sys/types.h> and "gdb_wait.h".
	(linux_wait): Declared.
	(GDB_WAIT): Defined.

	* lin-lwp.c (linux_wait): New.

	* defs.h (GDB_WAIT): Defined if not defined.

	* i386mach-nat.c (store_inferior_registers): Replace
	wait with GDB_WAIT.
	* infptrace.c (ptrace_wait): Likewise.
	* lynx-nat.c (child_wait): Likewise.
	* proc-api.c (wait_with_trace): Likewise.
	* procfs.c (procfs_wait): Likewise.
	(unconditionally_kill_inferior): Likewise.
	* rs6000-nat.c (exec_one_dummy_insn): Likewise.
	* symm-nat.c (child_wait): Likewise.
	(kill_inferior): Likewise.

	* lin-lwp.c (stop_wait_callback): Check errno == EINTR for
	retry.

--- gdb/config/nm-linux.h.thread	Fri Jul 13 12:13:18 2001
+++ gdb/config/nm-linux.h	Tue Sep 18 14:58:55 2001
@@ -69,3 +69,8 @@ extern int linuxthreads_prepare_to_proce
 #define REALTIME_LO	__SIGRTMIN
 #define REALTIME_HI	(__SIGRTMAX + 1)
 #endif
+
+#include <sys/types.h>
+#include "gdb_wait.h"
+extern pid_t linux_wait (WAITTYPE *);
+#define GDB_WAIT(w) linux_wait ((w))
--- gdb/defs.h.thread	Mon Aug  6 17:13:15 2001
+++ gdb/defs.h	Tue Sep 18 14:33:01 2001
@@ -1416,6 +1416,10 @@ extern int use_windows;
 #define MERGEPID(PID, TID) ptid_build (PID, TID, 0)
 #endif
 
+#ifndef GDB_WAIT
+#define GDB_WAIT(w) wait ((w))
+#endif
+
 /* Define well known filenos if the system does not define them.  */
 #ifndef STDIN_FILENO
 #define STDIN_FILENO   0
--- gdb/i386mach-nat.c.thread	Fri May  4 10:05:21 2001
+++ gdb/i386mach-nat.c	Tue Sep 18 14:37:39 2001
@@ -99,7 +99,7 @@ store_inferior_registers (int regno)
               (PTRACE_ARG3_TYPE) stack, 0xc589);
       ptrace (PTRACE_SINGLESTEP, PIDGET (inferior_ptid),
               (PTRACE_ARG3_TYPE) stack, 0);
-      wait (0);
+      GDB_WAIT (0);
       ptrace (PTRACE_POKEDATA, PIDGET (inferior_ptid),
               (PTRACE_ARG3_TYPE) stack, stuff);
       inferior_registers.r_reg[EAX] = reg;
--- gdb/infptrace.c.thread	Mon Aug  6 17:13:19 2001
+++ gdb/infptrace.c	Tue Sep 18 14:33:54 2001
@@ -203,7 +203,7 @@ ptrace_wait (ptid_t ptid, int *status)
 {
   int wstate;
 
-  wstate = wait (status);
+  wstate = GDB_WAIT (status);
   target_post_wait (pid_to_ptid (wstate), *status);
   return wstate;
 }
--- gdb/lin-lwp.c.thread	Fri Jul 13 12:12:44 2001
+++ gdb/lin-lwp.c	Tue Sep 18 15:04:46 2001
@@ -610,8 +610,11 @@ stop_wait_callback (struct lwp_info *lp,
 
       gdb_assert (lp->status == 0);
 
-      pid = waitpid (GET_LWP (lp->ptid), &status,
-		     is_cloned (lp->ptid) ? __WCLONE : 0);
+      do
+	pid = waitpid (GET_LWP (lp->ptid), &status,
+		       is_cloned (lp->ptid) ? __WCLONE : 0);
+      while (pid == -1 && errno == EINTR);
+
       if (pid == -1 && errno == ECHILD)
 	/* OK, the proccess has disappeared.  We'll catch the actual
 	   exit event in lin_lwp_wait.  */
@@ -1443,3 +1446,15 @@ lin_thread_get_thread_signals (sigset_t 
   /* ... except during a sigsuspend.  */
   sigdelset (&suspend_mask, cancel);
 }
+
+pid_t
+linux_wait (WAITTYPE *w)
+{
+  pid_t pid;
+
+  pid = waitpid (WAIT_ANY, w, 0);
+  if (pid == -1 && errno == ECHILD)
+    pid = waitpid (WAIT_ANY, w, __WCLONE);
+
+  return pid;
+}
--- gdb/lynx-nat.c.thread	Fri Jul 13 12:12:45 2001
+++ gdb/lynx-nat.c	Tue Sep 18 14:35:05 2001
@@ -600,7 +600,7 @@ child_wait (ptid_t ptid, struct target_w
 
       set_sigint_trap ();	/* Causes SIGINT to be passed on to the
 				   attached process. */
-      pid = wait (&status);
+      pid = GDB_WAIT (&status);
 
       save_errno = errno;
 
--- gdb/proc-api.c.thread	Fri Jul 13 12:12:54 2001
+++ gdb/proc-api.c	Tue Sep 18 14:35:22 2001
@@ -712,7 +712,7 @@ wait_with_trace (int *wstat, char *file,
 	fflush (procfs_file);
     }
   errno = 0;
-  ret = wait (&lstat);
+  ret = GDB_WAIT (&lstat);
   if (procfs_trace)
     {
       if (errno)
--- gdb/procfs.c.thread	Fri Jul 13 12:12:55 2001
+++ gdb/procfs.c	Tue Sep 18 14:37:07 2001
@@ -3983,7 +3983,7 @@ wait_again:
 	      int wait_retval;
 
 	      /* /proc file not found; presumably child has terminated. */
-	      wait_retval = wait (&wstat); /* "wait" for the child's exit  */
+	      wait_retval = GDB_WAIT (&wstat); /* "wait" for the child's exit  */
 
 	      if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */
 		error ("procfs: couldn't stop process %d: wait returned %d\n",
@@ -4071,7 +4071,7 @@ wait_again:
 		      }
 		    else
 		      {
-			int temp = wait (&wstat);
+			int temp = GDB_WAIT (&wstat);
 
 			/* FIXME: shouldn't I make sure I get the right
 			   event from the right process?  If (for
@@ -4743,7 +4743,7 @@ unconditionally_kill_inferior (procinfo 
 
       ret = waitpid (pi->pid, &status, 0);
 #else
-      wait (NULL);
+      GDB_WAIT (NULL);
 #endif
     }
 }
--- gdb/rs6000-nat.c.thread	Fri May  4 10:05:30 2001
+++ gdb/rs6000-nat.c	Tue Sep 18 14:35:28 2001
@@ -492,7 +492,7 @@ exec_one_dummy_insn (void)
 
   do
     {
-      pid = wait (&status);
+      pid = GDB_WAIT (&status);
     }
   while (pid != PIDGET (inferior_ptid));
 
--- gdb/symm-nat.c.thread	Mon Aug  6 17:13:46 2001
+++ gdb/symm-nat.c	Tue Sep 18 14:35:35 2001
@@ -597,7 +597,7 @@ child_wait (ptid_t ptid, struct target_w
 
   do
     {
-      pid = wait (&status);
+      pid = GDB_WAIT (&status);
       save_errno = errno;
 
       if (pid == -1)
@@ -656,7 +656,7 @@ kill_inferior (void)
   detach (SIGKILL);
 #else /* ATTACH_DETACH */
   ptrace (PT_KILL, PIDGET (inferior_ptid), 0, 0);
-  wait ((int *) NULL);
+  GDB_WAIT ((int *) NULL);
 #endif /* ATTACH_DETACH */
   target_mourn_inferior ();
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]