Index: gdb-6.6/gdb/doc/observer.texi =================================================================== --- gdb-6.6.orig/gdb/doc/observer.texi +++ gdb-6.6/gdb/doc/observer.texi @@ -119,6 +119,10 @@ when @value{GDBN} calls this observer, t haven't been loaded yet. @end deftypefun +@deftypefun void mourn_inferior (struct target_ops *@var{target}) +@value{GDBN} has just detached from an inferior. +@end deftypefun + @deftypefun void solib_unloaded (struct so_list *@var{solib}) The shared library specified by @var{solib} has been unloaded. @end deftypefun Index: gdb-6.6/gdb/linux-nat.c =================================================================== --- gdb-6.6.orig/gdb/linux-nat.c +++ gdb-6.6/gdb/linux-nat.c @@ -803,11 +803,23 @@ iterate_over_lwps (int (*callback) (stru { struct lwp_info *lp, *lpnext; - for (lp = lwp_list; lp; lp = lpnext) + if (lwp_list != NULL) { - lpnext = lp->next; + for (lp = lwp_list; lp; lp = lpnext) + { + lpnext = lp->next; + if ((*callback) (lp, data)) + return lp; + } + } + else + { + /* We are calling iterate_over_lwps for a non-threaded program. + Initialize the lwp list to the inferior's ptid. */ + lp = add_lwp (BUILD_LWP (GET_PID (inferior_ptid), + GET_PID (inferior_ptid))); if ((*callback) (lp, data)) - return lp; + return lp; } return NULL; @@ -3262,6 +3274,18 @@ linux_nat_add_target (struct target_ops thread_db_init (t); } +/* Observer function for a mourn inferior event. This is needed + because if iterate_over_lwps is called for a non-threaded program + to handle watchpoints, the lwp list gets initialized but there is + no corresponding clean-up when the inferior is detached. In + a threaded program, the observer is simply redundant as the + same clean-up gets done in linux_nat_mourn_inferior. */ +static void +linux_nat_mourn_inferior_observer (struct target_ops *objfile) +{ + init_lwp_list (); +} + void _initialize_linux_nat (void) { @@ -3276,6 +3300,8 @@ Specify any of the following keywords fo status -- list a different bunch of random process info.\n\ all -- list all available /proc info.")); + observer_attach_mourn_inferior (linux_nat_mourn_inferior_observer); + /* Save the original signal mask. */ sigprocmask (SIG_SETMASK, NULL, &normal_mask); Index: gdb-6.6/gdb/target.c =================================================================== --- gdb-6.6.orig/gdb/target.c +++ gdb-6.6/gdb/target.c @@ -40,6 +40,7 @@ #include "gdb_assert.h" #include "gdbcore.h" #include "exceptions.h" +#include "observer.h" static void target_info (char *, int); @@ -276,6 +277,13 @@ target_load (char *arg, int from_tty) (*current_target.to_load) (arg, from_tty); } +void +target_mourn_inferior (void) +{ + (*current_target.to_mourn_inferior) (); + observer_notify_mourn_inferior (¤t_target); +} + static int nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write, struct target_ops *t) Index: gdb-6.6/gdb/target.h =================================================================== --- gdb-6.6.orig/gdb/target.h +++ gdb-6.6/gdb/target.h @@ -891,8 +891,7 @@ int target_follow_fork (int follow_child /* The inferior process has died. Do what is right. */ -#define target_mourn_inferior() \ - (*current_target.to_mourn_inferior) () +extern void target_mourn_inferior (void); /* Does target have enough data to do a run or attach command? */