From: Pedro Alves Date: Sun, 4 May 2008 19:39:00 +0000 (+0000) Subject: gdb/ X-Git-Tag: msnyder-reverse-20080609-branchpoint~322 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=611c83ae477b587e7d93636cc6c241d063bb799b;p=platform%2Fupstream%2Fbinutils.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 98ce9b1..c933612 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,61 @@ +2008-05-04 Pedro Alves + + * 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 Set CU BASE_ADDRESS already from partial DIEs. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 737558e..1e7f361 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 d37e790..80544e4 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 e8bfde4..5f9e985 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 3165a26..b75c524 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 8c4c410..a1bb287 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 7071545..1e93035 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-05-04 Pedro Alves + + * gdb.cp/annota2.exp: Adjust to breakpoints invalidations at + different times. + 2008-05-04 Jan Kratochvil * 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 2dd9f4b..7291106 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 3de3289..c36bb4a 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;