diff options
-rw-r--r-- | gdb/ChangeLog | 14 | ||||
-rw-r--r-- | gdb/breakpoint.c | 17 | ||||
-rw-r--r-- | gdb/breakpoint.h | 3 | ||||
-rw-r--r-- | gdb/target.c | 9 | ||||
-rw-r--r-- | gdb/thread.c | 4 |
5 files changed, 45 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2ef9591..41d0277 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2012-03-02 Tom Tromey <tromey@redhat.com> + Pedro Alves <palves@redhat.com> + + PR breakpoints/13776: + * breakpoint.c (breakpoint_init_inferior): Delete step-resume + breakpoints. + (delete_longjmp_breakpoint_at_next_stop): New. + * breakpoint.h (delete_longjmp_breakpoint_at_next_stop): Declare. + * target.c (generic_mourn_inferior): Call mark_breakpoints_out + before deleting the inferior. Add comments. + * thread.c (clear_thread_inferior_resources): Don't delete lonjmp + breakpoints immediately, but only on next stop. Move that code + next to where we mark other breakpoints for deletion. + 2012-03-02 Joel Brobecker <brobecker@adacore.com> * mips-linux-nat.c (mips_linux_read_description): Add missing i18n diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ce35da2..3decd92 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3341,6 +3341,10 @@ breakpoint_init_inferior (enum inf_context context) (gdb) tar rem :9999 # remote Windows gdbserver. */ + case bp_step_resume: + + /* Also remove step-resume breakpoints. */ + delete_breakpoint (b); break; @@ -6625,6 +6629,19 @@ delete_longjmp_breakpoint (int thread) } void +delete_longjmp_breakpoint_at_next_stop (int thread) +{ + struct breakpoint *b, *b_tmp; + + ALL_BREAKPOINTS_SAFE (b, b_tmp) + if (b->type == bp_longjmp || b->type == bp_exception) + { + if (b->thread == thread) + b->disposition = disp_del_at_next_stop; + } +} + +void enable_overlay_breakpoints (void) { struct breakpoint *b; diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 7e8c597..5b5172e 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -1254,6 +1254,9 @@ extern void set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame); extern void delete_longjmp_breakpoint (int thread); +/* Mark all longjmp breakpoints from THREAD for later deletion. */ +extern void delete_longjmp_breakpoint_at_next_stop (int thread); + extern void enable_overlay_breakpoints (void); extern void disable_overlay_breakpoints (void); diff --git a/gdb/target.c b/gdb/target.c index 1f408f6..d29d37a 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -3583,13 +3583,22 @@ generic_mourn_inferior (void) ptid = inferior_ptid; inferior_ptid = null_ptid; + /* Mark breakpoints uninserted in case something tries to delete a + breakpoint while we delete the inferior's threads (which would + fail, since the inferior is long gone). */ + mark_breakpoints_out (); + if (!ptid_equal (ptid, null_ptid)) { int pid = ptid_get_pid (ptid); exit_inferior (pid); } + /* Note this wipes step-resume breakpoints, so needs to be done + after exit_inferior, which ends up referencing the step-resume + breakpoints through clear_thread_inferior_resources. */ breakpoint_init_inferior (inf_exited); + registers_changed (); reopen_exec_file (); diff --git a/gdb/thread.c b/gdb/thread.c index 22d8b23..97f283c 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -113,12 +113,12 @@ clear_thread_inferior_resources (struct thread_info *tp) tp->control.exception_resume_breakpoint = NULL; } + delete_longjmp_breakpoint_at_next_stop (tp->num); + bpstat_clear (&tp->control.stop_bpstat); do_all_intermediate_continuations_thread (tp, 1); do_all_continuations_thread (tp, 1); - - delete_longjmp_breakpoint (tp->num); } static void |