This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
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 ();
}