summaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorPedro Alves <pedro@codesourcery.com>2008-05-04 19:39:00 +0000
committerPedro Alves <pedro@codesourcery.com>2008-05-04 19:39:00 +0000
commit32281b7dbf79912926e9ce01c3034e7c8135a56d (patch)
treed98afd2703969b881d4a8b66bea53b594dc9aec4 /gdb
parentb5830bae4e60b65f37560ce1ede15e8036c20f2d (diff)
downloadgdb-32281b7dbf79912926e9ce01c3034e7c8135a56d.tar.gz
gdb/
* breakpoint.c (update_breakpoints_after_exec): Delete bp_longjmp and bp_longjmp_resume breakpoints. (breakpoint_address_is_meaningful): Claim bp_longjmp_resume as meaningful. (create_longjmp_breakpoint): Don't create bp_longjmp_resume breakpoints. Create bp_longjmp breakpoints as momentary breakpoints. (enable_longjmp_breakpoint): Delete. (set_longjmp_breakpoint): New. (disable_longjmp_breakpoint): Delete. (delete_longjmp_breakpoint): New. (set_longjmp_resume_breakpoint): Delete. (set_momentary_breakpoint_at_pc): New. (breakpoint_re_set_one): Don't delete bp_longjmp and bp_longjmp_resume breakpoints. (breakpoint_re_set): Don't create longjmp and longjmp-resume breakpoints. * infrun.c (step_resume_breakpoint): Add comment. (struct execution_control_state): Delete handling_longjmp member. (init_execution_control_state). Don't clear handling_longjmp. (context_switch): Don't context switch handling_longjmp. (handle_inferior_event): If handling a bp_longjmp breakpoint, create a bp_longjmp_resume breakpoint, and set it as current step_resume_breakpoint, then step over the longjmp breakpoint. If handling a bp_longjmp_resume breakpoint, don't delete the longjmp breakpoint, delete the longjmp-resume breakpoint, and stop stepping. (currently_stepping): Remove handling_longjmp from expression. (insert_step_resume_breakpoint_at_sal): Update comment. (insert_longjmp_resume_breakpoint): New. * breakpoint.h (set_momentary_breakpoint_at_pc): Declare. (enable_longjmp_breakpoint, disable_longjmp_breakpoint): Delete declarations. (set_longjmp_breakpoint, delete_longjmp_breakpoint): Declare. (set_longjmp_resume_breakpoint): Delete declaration. * gdbthread.h (save_infrun_state): Remove handling_longjmp parameter. (load_infrun_state): Delete *handling_longjmp parameter. * thread.c (save_infrun_state): Remove handling_longjmp parameter. Update body. (load_infrun_state): Delete *handling_longjmp parameter. Update body. * infcmd.c (disable_longjmp_breakpoint_cleanup): Delete. (delete_longjmp_breakpoint_cleanup): New. (step_1): Call set_longjmp_breakpoint instead of enable_longjmp_breakpoint. Use delete_longjmp_breakpoint_cleanup instead of disable_longjmp_breakpoint_cleanup when making cleanup. (step_1_continuation): Pass thread id in the continuation args to step_once. (step_once): Add thread parameter. Pass thread id the the continuation. gdb/testsuite/ * gdb.cp/annota2.exp: Adjust to breakpoints invalidations at different times.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog58
-rw-r--r--gdb/breakpoint.c112
-rw-r--r--gdb/breakpoint.h9
-rw-r--r--gdb/gdbthread.h3
-rw-r--r--gdb/infcmd.c41
-rw-r--r--gdb/infrun.c86
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.cp/annota2.exp4
-rw-r--r--gdb/thread.c4
9 files changed, 204 insertions, 118 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 98ce9b1471b..c933612eba3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,61 @@
+2008-05-04 Pedro Alves <pedro@codesourcery.com>
+
+ * breakpoint.c (update_breakpoints_after_exec): Delete bp_longjmp
+ and bp_longjmp_resume breakpoints.
+ (breakpoint_address_is_meaningful): Claim bp_longjmp_resume as
+ meaningful.
+ (create_longjmp_breakpoint): Don't create bp_longjmp_resume
+ breakpoints. Create bp_longjmp breakpoints as momentary
+ breakpoints.
+ (enable_longjmp_breakpoint): Delete.
+ (set_longjmp_breakpoint): New.
+ (disable_longjmp_breakpoint): Delete.
+ (delete_longjmp_breakpoint): New.
+ (set_longjmp_resume_breakpoint): Delete.
+ (set_momentary_breakpoint_at_pc): New.
+ (breakpoint_re_set_one): Don't delete bp_longjmp and
+ bp_longjmp_resume breakpoints.
+ (breakpoint_re_set): Don't create longjmp and longjmp-resume
+ breakpoints.
+
+ * infrun.c (step_resume_breakpoint): Add comment.
+ (struct execution_control_state): Delete handling_longjmp member.
+ (init_execution_control_state). Don't clear handling_longjmp.
+ (context_switch): Don't context switch handling_longjmp.
+ (handle_inferior_event): If handling a bp_longjmp breakpoint,
+ create a bp_longjmp_resume breakpoint, and set it as current
+ step_resume_breakpoint, then step over the longjmp breakpoint. If
+ handling a bp_longjmp_resume breakpoint, don't delete the longjmp
+ breakpoint, delete the longjmp-resume breakpoint, and stop
+ stepping.
+ (currently_stepping): Remove handling_longjmp from expression.
+ (insert_step_resume_breakpoint_at_sal): Update comment.
+ (insert_longjmp_resume_breakpoint): New.
+
+ * breakpoint.h (set_momentary_breakpoint_at_pc): Declare.
+ (enable_longjmp_breakpoint, disable_longjmp_breakpoint): Delete
+ declarations.
+ (set_longjmp_breakpoint, delete_longjmp_breakpoint): Declare.
+ (set_longjmp_resume_breakpoint): Delete declaration.
+
+ * gdbthread.h (save_infrun_state): Remove handling_longjmp
+ parameter.
+ (load_infrun_state): Delete *handling_longjmp parameter.
+ * thread.c (save_infrun_state): Remove handling_longjmp parameter.
+ Update body.
+ (load_infrun_state): Delete *handling_longjmp parameter. Update
+ body.
+
+ * infcmd.c (disable_longjmp_breakpoint_cleanup): Delete.
+ (delete_longjmp_breakpoint_cleanup): New.
+ (step_1): Call set_longjmp_breakpoint instead of
+ enable_longjmp_breakpoint. Use delete_longjmp_breakpoint_cleanup
+ instead of disable_longjmp_breakpoint_cleanup when making cleanup.
+ (step_1_continuation): Pass thread id in the continuation args to
+ step_once.
+ (step_once): Add thread parameter. Pass thread id the the
+ continuation.
+
2008-05-04 Jan Kratochvil <jan.kratochvil@redhat.com>
Set CU BASE_ADDRESS already from partial DIEs.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 737558e4b3b..1e7f36134e1 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -145,8 +145,6 @@ static int watchpoint_check (void *);
static void maintenance_info_breakpoints (char *, int);
-static void create_longjmp_breakpoint (char *);
-
static void create_overlay_event_breakpoint (char *);
static int hw_breakpoint_used_count (void);
@@ -1486,6 +1484,14 @@ update_breakpoints_after_exec (void)
continue;
}
+ /* Longjmp and longjmp-resume breakpoints are also meaningless
+ after an exec. */
+ if (b->type == bp_longjmp || b->type == bp_longjmp_resume)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
/* Don't delete an exec catchpoint, because else the inferior
won't stop when it ought!
@@ -4081,7 +4087,6 @@ set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab,
bp_read_watchpoint
bp_access_watchpoint
bp_catch_exec
- bp_longjmp_resume
bp_catch_fork
bp_catch_vork */
@@ -4095,7 +4100,6 @@ breakpoint_address_is_meaningful (struct breakpoint *bpt)
&& type != bp_read_watchpoint
&& type != bp_access_watchpoint
&& type != bp_catch_exec
- && type != bp_longjmp_resume
&& type != bp_catch_fork
&& type != bp_catch_vfork);
}
@@ -4453,20 +4457,9 @@ create_longjmp_breakpoint (char *func_name)
struct breakpoint *b;
struct minimal_symbol *m;
- if (func_name == NULL)
- b = create_internal_breakpoint (0, bp_longjmp_resume);
- else
- {
- if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
- return;
-
- b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
- }
-
- b->enable_state = bp_disabled;
- b->silent = 1;
- if (func_name)
- b->addr_string = xstrdup (func_name);
+ if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
+ return;
+ set_momentary_breakpoint_at_pc (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
update_global_location_list ();
}
@@ -4475,30 +4468,31 @@ create_longjmp_breakpoint (char *func_name)
set_longjmp_resume_breakpoint() to figure out where we are going. */
void
-enable_longjmp_breakpoint (void)
+set_longjmp_breakpoint (void)
{
struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- if (b->type == bp_longjmp)
+ if (gdbarch_get_longjmp_target_p (current_gdbarch))
{
- b->enable_state = bp_enabled;
- update_global_location_list ();
+ create_longjmp_breakpoint ("longjmp");
+ create_longjmp_breakpoint ("_longjmp");
+ create_longjmp_breakpoint ("siglongjmp");
+ create_longjmp_breakpoint ("_siglongjmp");
}
}
+/* Delete all longjmp breakpoints from THREAD. */
void
-disable_longjmp_breakpoint (void)
+delete_longjmp_breakpoint (int thread)
{
- struct breakpoint *b;
+ struct breakpoint *b, *temp;
- ALL_BREAKPOINTS (b)
- if (b->type == bp_longjmp
- || b->type == bp_longjmp_resume)
- {
- b->enable_state = bp_disabled;
- update_global_location_list ();
- }
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ if (b->type == bp_longjmp)
+ {
+ if (b->thread == thread)
+ delete_breakpoint (b);
+ }
}
static void
@@ -4791,30 +4785,6 @@ hw_watchpoint_used_count (enum bptype type, int *other_type_used)
return i;
}
-/* Call this after hitting the longjmp() breakpoint. Use this to set
- a new breakpoint at the target of the jmp_buf.
-
- FIXME - This ought to be done by setting a temporary breakpoint
- that gets deleted automatically... */
-
-void
-set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id)
-{
- struct breakpoint *b;
-
- ALL_BREAKPOINTS (b)
- if (b->type == bp_longjmp_resume)
- {
- b->loc->requested_address = pc;
- b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
- b->type);
- b->enable_state = bp_enabled;
- b->frame_id = frame_id;
- update_global_location_list ();
- return;
- }
-}
-
void
disable_watchpoints_before_interactive_call_start (void)
{
@@ -4878,6 +4848,19 @@ set_momentary_breakpoint (struct symtab_and_line sal, struct frame_id frame_id,
return b;
}
+
+struct breakpoint *
+set_momentary_breakpoint_at_pc (CORE_ADDR pc, enum bptype type)
+{
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (pc, 0);
+ sal.pc = pc;
+ sal.section = find_pc_overlay (pc);
+ sal.explicit_pc = 1;
+
+ return set_momentary_breakpoint (sal, null_frame_id, type);
+}
/* Tell the user we have just set a breakpoint B. */
@@ -7529,10 +7512,8 @@ breakpoint_re_set_one (void *bint)
default:
printf_filtered (_("Deleting unknown breakpoint type %d\n"), b->type);
/* fall through */
- /* Delete longjmp and overlay event breakpoints; they will be
- reset later by breakpoint_re_set. */
- case bp_longjmp:
- case bp_longjmp_resume:
+ /* Delete overlay event breakpoints; they will be reset later by
+ breakpoint_re_set. */
case bp_overlay_event:
delete_breakpoint (b);
break;
@@ -7554,6 +7535,8 @@ breakpoint_re_set_one (void *bint)
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_step_resume:
+ case bp_longjmp:
+ case bp_longjmp_resume:
break;
}
@@ -7581,15 +7564,6 @@ breakpoint_re_set (void)
}
set_language (save_language);
input_radix = save_input_radix;
-
- if (gdbarch_get_longjmp_target_p (current_gdbarch))
- {
- create_longjmp_breakpoint ("longjmp");
- create_longjmp_breakpoint ("_longjmp");
- create_longjmp_breakpoint ("siglongjmp");
- create_longjmp_breakpoint ("_siglongjmp");
- create_longjmp_breakpoint (NULL);
- }
create_overlay_event_breakpoint ("_ovly_debug_event");
}
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index d37e7905d4c..80544e4dedd 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -687,6 +687,9 @@ extern void breakpoint_re_set_thread (struct breakpoint *);
extern struct breakpoint *set_momentary_breakpoint
(struct symtab_and_line, struct frame_id, enum bptype);
+extern struct breakpoint *set_momentary_breakpoint_at_pc
+ (CORE_ADDR pc, enum bptype type);
+
extern void set_ignore_count (int, int, int);
extern void set_default_breakpoint (int, CORE_ADDR, struct symtab *, int);
@@ -755,12 +758,12 @@ extern void update_breakpoints_after_exec (void);
inferior_ptid. */
extern int detach_breakpoints (int);
-extern void enable_longjmp_breakpoint (void);
-extern void disable_longjmp_breakpoint (void);
+extern void set_longjmp_breakpoint (void);
+extern void delete_longjmp_breakpoint (int thread);
+
extern void enable_overlay_breakpoints (void);
extern void disable_overlay_breakpoints (void);
-extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_id);
/* These functions respectively disable or reenable all currently
enabled watchpoints. When disabled, the watchpoints are marked
call_disabled. When reenabled, they are marked enabled.
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index e8bfde4831d..5f9e98523f9 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -50,7 +50,6 @@ struct thread_info
int current_line;
struct symtab *current_symtab;
int trap_expected;
- int handling_longjmp;
int stepping_over_breakpoint;
/* This is set TRUE when a catchpoint of a shared library event
@@ -123,7 +122,6 @@ extern void save_infrun_state (ptid_t ptid,
CORE_ADDR step_range_start,
CORE_ADDR step_range_end,
const struct frame_id *step_frame_id,
- int handling_longjmp,
int another_trap,
int stepping_through_solib_after_catch,
bpstat stepping_through_solib_catchpoints,
@@ -139,7 +137,6 @@ extern void load_infrun_state (ptid_t ptid,
CORE_ADDR *step_range_start,
CORE_ADDR *step_range_end,
struct frame_id *step_frame_id,
- int *handling_longjmp,
int *another_trap,
int *stepping_through_solib_affter_catch,
bpstat *stepping_through_solib_catchpoints,
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 3165a26f3f7..b75c5244130 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -107,7 +107,7 @@ static void signal_command (char *, int);
static void jump_command (char *, int);
static void step_1 (int, int, char *);
-static void step_once (int skip_subroutines, int single_inst, int count);
+static void step_once (int skip_subroutines, int single_inst, int count, int thread);
static void step_1_continuation (struct continuation_arg *arg, int error_p);
static void next_command (char *, int);
@@ -693,9 +693,10 @@ nexti_command (char *count_string, int from_tty)
}
static void
-disable_longjmp_breakpoint_cleanup (void *ignore)
+delete_longjmp_breakpoint_cleanup (void *arg)
{
- disable_longjmp_breakpoint ();
+ int thread = * (int *) arg;
+ delete_longjmp_breakpoint (thread);
}
static void
@@ -705,6 +706,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
struct frame_info *frame;
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
int async_exec = 0;
+ int *thread_p = NULL;
ERROR_NO_INFERIOR;
@@ -728,8 +730,17 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
if (!single_inst || skip_subroutines) /* leave si command alone */
{
- enable_longjmp_breakpoint ();
- make_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
+ thread_p = xmalloc (sizeof (int));
+ make_cleanup (xfree, thread_p);
+
+ if (in_thread_list (inferior_ptid))
+ *thread_p = pid_to_thread_id (inferior_ptid);
+ else
+ *thread_p = -1;
+
+ set_longjmp_breakpoint ();
+
+ make_cleanup (delete_longjmp_breakpoint_cleanup, thread_p);
}
/* In synchronous case, all is well, just use the regular for loop. */
@@ -790,10 +801,11 @@ which has no line number information.\n"), name);
and handle them one at the time, through step_once(). */
else
{
- step_once (skip_subroutines, single_inst, count);
- /* We are running, and the contination is installed. It will
+ step_once (skip_subroutines, single_inst, count, *thread_p);
+ /* We are running, and the continuation is installed. It will
disable the longjmp breakpoint as appropriate. */
discard_cleanups (cleanups);
+ xfree (thread_p);
}
}
@@ -808,10 +820,12 @@ step_1_continuation (struct continuation_arg *arg, int error_p)
int count;
int skip_subroutines;
int single_inst;
+ int thread;
skip_subroutines = arg->data.integer;
single_inst = arg->next->data.integer;
count = arg->next->next->data.integer;
+ thread = arg->next->next->next->data.integer;
if (error_p || !step_multi || !stop_step)
{
@@ -819,11 +833,11 @@ step_1_continuation (struct continuation_arg *arg, int error_p)
that is not stepping, or there are no further steps
to make. Cleanup. */
if (!single_inst || skip_subroutines)
- disable_longjmp_breakpoint ();
+ delete_longjmp_breakpoint (thread);
step_multi = 0;
}
else
- step_once (skip_subroutines, single_inst, count - 1);
+ step_once (skip_subroutines, single_inst, count - 1, thread);
}
/* Do just one step operation. If count >1 we will have to set up a
@@ -834,11 +848,12 @@ step_1_continuation (struct continuation_arg *arg, int error_p)
called in case of step n with n>1, after the first step operation has
been completed.*/
static void
-step_once (int skip_subroutines, int single_inst, int count)
+step_once (int skip_subroutines, int single_inst, int count, int thread)
{
struct continuation_arg *arg1;
struct continuation_arg *arg2;
struct continuation_arg *arg3;
+ struct continuation_arg *arg4;
struct frame_info *frame;
if (count > 0)
@@ -894,12 +909,16 @@ which has no line number information.\n"), name);
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
arg3 =
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg4 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
arg1->next = arg2;
arg1->data.integer = skip_subroutines;
arg2->next = arg3;
arg2->data.integer = single_inst;
- arg3->next = NULL;
+ arg3->next = arg4;
arg3->data.integer = count;
+ arg4->next = NULL;
+ arg4->data.integer = thread;
add_intermediate_continuation (step_1_continuation, arg1);
}
}
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 8c4c410e3a9..a1bb28713d3 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -279,6 +279,7 @@ struct regcache *stop_registers;
static int stop_print_frame;
+/* Step-resume or longjmp-resume breakpoint. */
static struct breakpoint *step_resume_breakpoint = NULL;
/* This is a cached copy of the pid/waitstatus of the last event
@@ -1380,7 +1381,6 @@ struct execution_control_state
struct symtab_and_line sal;
int current_line;
struct symtab *current_symtab;
- int handling_longjmp; /* FIXME */
ptid_t ptid;
ptid_t saved_inferior_ptid;
int step_after_step_resume_breakpoint;
@@ -1402,6 +1402,8 @@ static void insert_step_resume_breakpoint_at_frame (struct frame_info *step_fram
static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
static void insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
struct frame_id sr_id);
+static void insert_longjmp_resume_breakpoint (CORE_ADDR);
+
static void stop_stepping (struct execution_control_state *ecs);
static void prepare_to_wait (struct execution_control_state *ecs);
static void keep_going (struct execution_control_state *ecs);
@@ -1546,7 +1548,6 @@ init_execution_control_state (struct execution_control_state *ecs)
ecs->stepping_over_breakpoint = 0;
ecs->random_signal = 0;
ecs->step_after_step_resume_breakpoint = 0;
- ecs->handling_longjmp = 0; /* FIXME */
ecs->stepping_through_solib_after_catch = 0;
ecs->stepping_through_solib_catchpoints = NULL;
ecs->sal = find_pc_line (prev_pc, 0);
@@ -1601,7 +1602,7 @@ context_switch (struct execution_control_state *ecs)
stepping_over_breakpoint, step_resume_breakpoint,
step_range_start,
step_range_end, &step_frame_id,
- ecs->handling_longjmp, ecs->stepping_over_breakpoint,
+ ecs->stepping_over_breakpoint,
ecs->stepping_through_solib_after_catch,
ecs->stepping_through_solib_catchpoints,
ecs->current_line, ecs->current_symtab);
@@ -1611,7 +1612,7 @@ context_switch (struct execution_control_state *ecs)
&stepping_over_breakpoint, &step_resume_breakpoint,
&step_range_start,
&step_range_end, &step_frame_id,
- &ecs->handling_longjmp, &ecs->stepping_over_breakpoint,
+ &ecs->stepping_over_breakpoint,
&ecs->stepping_through_solib_after_catch,
&ecs->stepping_through_solib_catchpoints,
&ecs->current_line, &ecs->current_symtab);
@@ -2574,38 +2575,50 @@ process_event_stop_test:
switch (what.main_action)
{
case BPSTAT_WHAT_SET_LONGJMP_RESUME:
- /* If we hit the breakpoint at longjmp, disable it for the
- duration of this command. Then, install a temporary
- breakpoint at the target of the jmp_buf. */
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
- disable_longjmp_breakpoint ();
+ /* If we hit the breakpoint at longjmp while stepping, we
+ install a momentary breakpoint at the target of the
+ jmp_buf. */
+
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
+
+ ecs->stepping_over_breakpoint = 1;
+
if (!gdbarch_get_longjmp_target_p (current_gdbarch)
|| !gdbarch_get_longjmp_target (current_gdbarch,
get_current_frame (), &jmp_buf_pc))
{
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "\
+infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
keep_going (ecs);
return;
}
- /* Need to blow away step-resume breakpoint, as it
- interferes with us */
+ /* We're going to replace the current step-resume breakpoint
+ with a longjmp-resume breakpoint. */
if (step_resume_breakpoint != NULL)
- {
- delete_step_resume_breakpoint (&step_resume_breakpoint);
- }
+ delete_step_resume_breakpoint (&step_resume_breakpoint);
+
+ /* Insert a breakpoint at resume address. */
+ insert_longjmp_resume_breakpoint (jmp_buf_pc);
- set_longjmp_resume_breakpoint (jmp_buf_pc, null_frame_id);
- ecs->handling_longjmp = 1; /* FIXME */
keep_going (ecs);
return;
case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
- disable_longjmp_breakpoint ();
- ecs->handling_longjmp = 0; /* FIXME */
- break;
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
+
+ gdb_assert (step_resume_breakpoint != NULL);
+ delete_step_resume_breakpoint (&step_resume_breakpoint);
+
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
case BPSTAT_WHAT_SINGLE:
if (debug_infrun)
@@ -3168,9 +3181,8 @@ process_event_stop_test:
static int
currently_stepping (struct execution_control_state *ecs)
{
- return ((!ecs->handling_longjmp
- && ((step_range_end && step_resume_breakpoint == NULL)
- || stepping_over_breakpoint))
+ return (((step_range_end && step_resume_breakpoint == NULL)
+ || stepping_over_breakpoint)
|| ecs->stepping_through_solib_after_catch
|| bpstat_should_step ());
}
@@ -3257,8 +3269,8 @@ static void
insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
struct frame_id sr_id)
{
- /* There should never be more than one step-resume breakpoint per
- thread, so we should never be setting a new
+ /* There should never be more than one step-resume or longjmp-resume
+ breakpoint per thread, so we should never be setting a new
step_resume_breakpoint when one is already active. */
gdb_assert (step_resume_breakpoint == NULL);
@@ -3326,6 +3338,28 @@ insert_step_resume_breakpoint_at_caller (struct frame_info *next_frame)
insert_step_resume_breakpoint_at_sal (sr_sal, frame_unwind_id (next_frame));
}
+/* Insert a "longjmp-resume" breakpoint at PC. This is used to set a
+ new breakpoint at the target of a jmp_buf. The handling of
+ longjmp-resume uses the same mechanisms used for handling
+ "step-resume" breakpoints. */
+
+static void
+insert_longjmp_resume_breakpoint (CORE_ADDR pc)
+{
+ /* There should never be more than one step-resume or longjmp-resume
+ breakpoint per thread, so we should never be setting a new
+ longjmp_resume_breakpoint when one is already active. */
+ gdb_assert (step_resume_breakpoint == NULL);
+
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: inserting longjmp-resume breakpoint at 0x%s\n",
+ paddr_nz (pc));
+
+ step_resume_breakpoint =
+ set_momentary_breakpoint_at_pc (pc, bp_longjmp_resume);
+}
+
static void
stop_stepping (struct execution_control_state *ecs)
{
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 7071545c0c3..1e930350b67 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-05-04 Pedro Alves <pedro@codesourcery.com>
+
+ * gdb.cp/annota2.exp: Adjust to breakpoints invalidations at
+ different times.
+
2008-05-04 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.dwarf2/dw2-ranges.S: Merge the secondary section with `.fini'.
diff --git a/gdb/testsuite/gdb.cp/annota2.exp b/gdb/testsuite/gdb.cp/annota2.exp
index 2dd9f4bfaef..72911061b6d 100644
--- a/gdb/testsuite/gdb.cp/annota2.exp
+++ b/gdb/testsuite/gdb.cp/annota2.exp
@@ -190,9 +190,9 @@ gdb_expect {
#
send_gdb "next\n"
gdb_expect {
- -re "\r\n\032\032post-prompt\r\n\r\n\032\032starting\r\n\r\n(\032\032frames-invalid\r\n\r\n)*\032\032watchpoint 3\r\n.*atchpoint 3: a.x\r\n\r\nOld value = 0\r\nNew value = 1\r\n\r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n.*$srcfile\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n$decimal\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n.*$gdb_prompt$" \
+ -re "\r\n\032\032post-prompt\r\n\r\n(\032\032breakpoints-invalid\r\n\r\n)*\032\032starting\r\n\r\n(\032\032frames-invalid\r\n\r\n)*\032\032watchpoint 3\r\n.*atchpoint 3: a.x\r\n\r\nOld value = 0\r\nNew value = 1\r\n\r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n.*$srcfile\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n$decimal\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n.*$gdb_prompt$" \
{ pass "watch triggered on a.x" }
- -re "\r\n\032\032post-prompt\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
+ -re "\r\n\032\032post-prompt\r\n\r\n(\032\032breakpoints-invalid\r\n\r\n)*\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
{ kfail "gdb/38" "watch triggered on a.x" }
-re ".*$gdb_prompt$" { fail "watch triggered on a.x" }
timeout { fail "watch triggered on a.x (timeout)" }
diff --git a/gdb/thread.c b/gdb/thread.c
index 3de3289a480..c36bb4a12f0 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -319,7 +319,6 @@ load_infrun_state (ptid_t ptid,
CORE_ADDR *step_range_start,
CORE_ADDR *step_range_end,
struct frame_id *step_frame_id,
- int *handling_longjmp,
int *stepping_over_breakpoint,
int *stepping_through_solib_after_catch,
bpstat *stepping_through_solib_catchpoints,
@@ -340,7 +339,6 @@ load_infrun_state (ptid_t ptid,
*step_range_start = tp->step_range_start;
*step_range_end = tp->step_range_end;
*step_frame_id = tp->step_frame_id;
- *handling_longjmp = tp->handling_longjmp;
*stepping_over_breakpoint = tp->stepping_over_breakpoint;
*stepping_through_solib_after_catch =
tp->stepping_through_solib_after_catch;
@@ -360,7 +358,6 @@ save_infrun_state (ptid_t ptid,
CORE_ADDR step_range_start,
CORE_ADDR step_range_end,
const struct frame_id *step_frame_id,
- int handling_longjmp,
int stepping_over_breakpoint,
int stepping_through_solib_after_catch,
bpstat stepping_through_solib_catchpoints,
@@ -381,7 +378,6 @@ save_infrun_state (ptid_t ptid,
tp->step_range_start = step_range_start;
tp->step_range_end = step_range_end;
tp->step_frame_id = (*step_frame_id);
- tp->handling_longjmp = handling_longjmp;
tp->stepping_over_breakpoint = stepping_over_breakpoint;
tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;