aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog14
-rw-r--r--gdb/breakpoint.c17
-rw-r--r--gdb/breakpoint.h3
-rw-r--r--gdb/target.c9
-rw-r--r--gdb/thread.c4
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