gdb: 2012-04-12 Yao Qi * breakpoint.c (iterate_over_bp_locations): New. * breakpoint.h: Declare. New typedef walk_bp_location_callback. * record.c (record_open): Call record_init_record_breakpoints. (record_sync_record_breakpoints): New. (record_init_record_breakpoints): New. * NEWS: Mention supporting breakpoint always-inserted mode in record target. --- gdb/NEWS | 2 ++ gdb/breakpoint.c | 13 +++++++++++++ gdb/breakpoint.h | 4 ++++ gdb/record.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 0 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index c287ffa..9b190e4 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -82,6 +82,8 @@ * Ada support for GDB/MI Variable Objects has been added. +* GDB can now support breakpoint always-inserted mode in record target. + * New commands ** "catch load" and "catch unload" can be used to stop when a shared diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index be536bc..0df0a81 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2425,6 +2425,19 @@ insert_breakpoints (void) insert_breakpoint_locations (); } +/* Invoke CALLBACK for each of bp_location. */ + +void +iterate_over_bp_locations (walk_bp_location_callback callback) +{ + struct bp_location *loc, **loc_tmp; + + ALL_BP_LOCATIONS (loc, loc_tmp) + { + callback (loc); + } +} + /* This is used when we need to synch breakpoint conditions between GDB and the target. It is the case with deleting and disabling of breakpoints when using always-inserted mode. */ diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index e0eeeaa..c0b1bad 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -1131,6 +1131,10 @@ extern void delete_breakpoint (struct breakpoint *); extern void breakpoint_auto_delete (bpstat); +typedef void (*walk_bp_location_callback) (void *data); + +extern void iterate_over_bp_locations (walk_bp_location_callback); + /* Return the chain of command lines to execute when this breakpoint is hit. */ extern struct command_line *breakpoint_commands (struct breakpoint *b); diff --git a/gdb/record.c b/gdb/record.c index 9b7ee2f..946ca95 100644 --- a/gdb/record.c +++ b/gdb/record.c @@ -896,6 +896,8 @@ record_open_1 (char *name, int from_tty) push_target (&record_ops); } +static void record_init_record_breakpoints (void); + /* "to_open" target method. Open the process record target. */ static void @@ -993,6 +995,8 @@ record_open (char *name, int from_tty) record_async_inferior_event_token = create_async_event_handler (record_async_inferior_event_handler, NULL); + + record_init_record_breakpoints (); } /* "to_close" target method. Close the process record target. */ @@ -1744,6 +1748,34 @@ DEF_VEC_P(record_breakpoint_p); active. */ VEC(record_breakpoint_p) *record_breakpoints = NULL; +static void +record_sync_record_breakpoints (void *data) +{ + struct bp_location *loc = (struct bp_location *) data; + + if (loc->inserted) + { + struct record_breakpoint *bp = XNEW (struct record_breakpoint); + + bp->addr = loc->target_info.placed_address; + bp->address_space = loc->target_info.placed_address_space; + + bp->in_target_beneath = 1; + + VEC_safe_push (record_breakpoint_p, record_breakpoints, bp); + } +} + +/* Sync existing breakpoints to record_breakpoints. */ + +static void +record_init_record_breakpoints (void) +{ + VEC_free (record_breakpoint_p, record_breakpoints); + + iterate_over_bp_locations (record_sync_record_breakpoints); +} + /* Behavior is conditional on RECORD_IS_REPLAY. We will not actually insert or remove breakpoints in the real target when replaying, nor when recording. */ -- 1.7.0.4