From 8bea4e01db202d301348221cff486a4fe78e86a1 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Fri, 31 Jul 2009 14:31:16 +0000 Subject: * breakpoint.h (enum enable_state): Add bp_startup_disabled. (disable_breakpoints_before_startup): Add prototype. (enable_breakpoints_after_startup): Likewise. * breakpoint.c (executing_startup): New static variable. (describe_other_breakpoints): Handle bp_startup_disabled. (check_duplicates_for): Likewise. (disable_breakpoints_before_startup): New function. (enable_breakpoints_after_startup): New function. (create_breakpoint): Mark new breakpoints as bp_startup_disabled if executing_startup flag is true. (break_command_really): Likewise. (breakpoint_re_set_one): Skip bp_startup_disabled breakpoints. --- gdb/ChangeLog | 16 +++++++++++++ gdb/breakpoint.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- gdb/breakpoint.h | 19 ++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9677954..cc82712 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2009-07-31 Ulrich Weigand + + * breakpoint.h (enum enable_state): Add bp_startup_disabled. + (disable_breakpoints_before_startup): Add prototype. + (enable_breakpoints_after_startup): Likewise. + + * breakpoint.c (executing_startup): New static variable. + (describe_other_breakpoints): Handle bp_startup_disabled. + (check_duplicates_for): Likewise. + (disable_breakpoints_before_startup): New function. + (enable_breakpoints_after_startup): New function. + (create_breakpoint): Mark new breakpoints as bp_startup_disabled + if executing_startup flag is true. + (break_command_really): Likewise. + (breakpoint_re_set_one): Skip bp_startup_disabled breakpoints. + 2009-07-31 Julian Brown * arm-linux-tdep.c (arch-utils.h, inferior.h, gdbthread.h, symfile.h): diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 3a18c8f..3e324c2 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -319,6 +319,9 @@ static int executing_breakpoint_commands; /* Are overlay event breakpoints enabled? */ static int overlay_events_enabled; +/* Are we executing startup code? */ +static int executing_startup; + /* Walk the following statement or block through all breakpoints. ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current breakpoint. */ @@ -4140,7 +4143,8 @@ describe_other_breakpoints (struct gdbarch *gdbarch, CORE_ADDR pc, printf_filtered (" (thread %d)", b->thread); printf_filtered ("%s%s ", ((b->enable_state == bp_disabled - || b->enable_state == bp_call_disabled) + || b->enable_state == bp_call_disabled + || b->enable_state == bp_startup_disabled) ? " (disabled)" : b->enable_state == bp_permanent ? " (permanent)" @@ -4211,6 +4215,7 @@ check_duplicates_for (CORE_ADDR address, struct obj_section *section) ALL_BP_LOCATIONS (b) if (b->owner->enable_state != bp_disabled && b->owner->enable_state != bp_call_disabled + && b->owner->enable_state != bp_startup_disabled && b->enabled && !b->shlib_disabled && b->address == address /* address / overlay match */ @@ -4247,6 +4252,7 @@ check_duplicates_for (CORE_ADDR address, struct obj_section *section) if (b->owner->enable_state != bp_permanent && b->owner->enable_state != bp_disabled && b->owner->enable_state != bp_call_disabled + && b->owner->enable_state != bp_startup_disabled && b->enabled && !b->shlib_disabled && b->address == address /* address / overlay match */ && (!overlay_debugging || b->section == section) @@ -5095,6 +5101,52 @@ enable_watchpoints_after_interactive_call_stop (void) } } +void +disable_breakpoints_before_startup (void) +{ + struct breakpoint *b; + int found = 0; + + ALL_BREAKPOINTS (b) + { + if ((b->type == bp_breakpoint + || b->type == bp_hardware_breakpoint) + && breakpoint_enabled (b)) + { + b->enable_state = bp_startup_disabled; + found = 1; + } + } + + if (found) + update_global_location_list (0); + + executing_startup = 1; +} + +void +enable_breakpoints_after_startup (void) +{ + struct breakpoint *b; + int found = 0; + + executing_startup = 0; + + ALL_BREAKPOINTS (b) + { + if ((b->type == bp_breakpoint + || b->type == bp_hardware_breakpoint) + && b->enable_state == bp_startup_disabled) + { + b->enable_state = bp_enabled; + found = 1; + } + } + + if (found) + breakpoint_re_set (); +} + /* Set a breakpoint that will evaporate an end of command at address specified by SAL. @@ -5438,6 +5490,11 @@ create_breakpoint (struct gdbarch *gdbarch, b->enable_state = enabled ? bp_enabled : bp_disabled; b->disposition = disposition; + if (enabled && executing_startup + && (b->type == bp_breakpoint + || b->type == bp_hardware_breakpoint)) + b->enable_state = bp_startup_disabled; + loc = b->loc; } else @@ -5993,6 +6050,11 @@ break_command_really (struct gdbarch *gdbarch, b->ops = ops; b->enable_state = enabled ? bp_enabled : bp_disabled; + if (enabled && executing_startup + && (b->type == bp_breakpoint + || b->type == bp_hardware_breakpoint)) + b->enable_state = bp_startup_disabled; + mention (b); } @@ -7792,6 +7854,10 @@ breakpoint_re_set_one (void *bint) case bp_breakpoint: case bp_hardware_breakpoint: case bp_tracepoint: + /* Do not attempt to re-set breakpoints disabled during startup. */ + if (b->enable_state == bp_startup_disabled) + return 0; + if (b->addr_string == NULL) { /* Anything without a string can't be re-set. */ diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 6731e68..d8fe047 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -135,6 +135,12 @@ enum enable_state automatically enabled and reset when the call "lands" (either completes, or stops at another eventpoint). */ + bp_startup_disabled,/* The eventpoint has been disabled during inferior + startup. This is necessary on some targets where + the main executable will get relocated during + startup, making breakpoint addresses invalid. + The eventpoint will be automatically enabled and + reset once inferior startup is complete. */ bp_permanent /* There is a breakpoint instruction hard-wired into the target's code. Don't try to write another breakpoint instruction on top of it, or restore @@ -810,6 +816,19 @@ extern void disable_watchpoints_before_interactive_call_start (void); extern void enable_watchpoints_after_interactive_call_stop (void); +/* These functions disable and re-enable all breakpoints during + inferior startup. They are intended to be called from solib + code where necessary. This is needed on platforms where the + main executable is relocated at some point during startup + processing, making breakpoint addresses invalid. + + If additional breakpoints are created after the routine + disable_breakpoints_before_startup but before the routine + enable_breakpoints_after_startup was called, they will also + be marked as disabled. */ +extern void disable_breakpoints_before_startup (void); +extern void enable_breakpoints_after_startup (void); + /* For script interpreters that need to define breakpoint commands after they've already read the commands into a struct command_line. */ extern enum command_control_type commands_from_control_command -- cgit v1.1