From mboxrd@z Thu Jan 1 00:00:00 1970 From: "H . J . Lu" To: GDB Subject: RFC: Fix gdb 5.1 for Linuxthreads Date: Tue, 18 Sep 2001 15:22:00 -0000 Message-id: <20010918152200.A14153@lucon.org> References: <20010917124710.A21992@lucon.org> <20010917161350.A25349@lucon.org> <20010917191357.A28300@lucon.org> <20010918135555.A12648@lucon.org> X-SW-Source: 2001-09/msg00153.html 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 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 +#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 (); }