diff options
author | Pedro Alves <palves@redhat.com> | 2015-03-04 20:41:15 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-03-04 20:41:15 +0000 |
commit | 9e8915c6cee5c37637521b424d723e990e06d597 (patch) | |
tree | 42ec607db6c86af4d136c70e2c588b5cd87bfbbd /gdb/record-btrace.c | |
parent | 15c66dd626380fbd7db6538b0c21d1fe86dda6c9 (diff) | |
download | gdb-9e8915c6cee5c37637521b424d723e990e06d597.zip gdb-9e8915c6cee5c37637521b424d723e990e06d597.tar.gz gdb-9e8915c6cee5c37637521b424d723e990e06d597.tar.bz2 |
record-full/record-btrace: software/hardware breakpoint trap
This adjusts the record targets to tell the core whether a trap was
caused by a breakpoint. Targets that can do this should report
breakpoint traps with the PC already adjusted, so this removes the
re-incrementing record-full was doing.
These targets need to be adjusted before process_stratum targets
beneath are, otherwise target_supports_stopped_by_sw_breakpoint,
etc. would fall through to the target beneath while
recording/replaying, and the core would get confused.
Tested on x86-64 Fedora 20, native and gdbserver.
gdb/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* btrace.h: Include target/waitstatus.h.
(struct btrace_thread_info) <stop_reason>: New field.
* record-btrace.c (record_btrace_step_thread): Use
record_check_stopped_by_breakpoint instead of breakpoint_here_p.
(record_btrace_decr_pc_after_break): Delete.
(record_btrace_stopped_by_sw_breakpoint)
(record_btrace_supports_stopped_by_sw_breakpoint)
(record_btrace_stopped_by_hw_breakpoint)
(record_btrace_supports_stopped_by_hw_breakpoint): New functions.
(init_record_btrace_ops): Install them.
* record-full.c (record_full_hw_watchpoint): Delete and replace
with ...
(record_full_stop_reason): ... this throughout.
(record_full_exec_insn): Adjust.
(record_full_wait_1): Adjust. No longer re-increment the PC.
(record_full_wait_1): Adjust. Use
record_check_stopped_by_breakpoint instead of breakpoint_here_p.
(record_full_stopped_by_watchpoint): Adjust.
(record_full_stopped_by_sw_breakpoint)
(record_full_supports_stopped_by_sw_breakpoint)
(record_full_supports_stopped_by_sw_breakpoint)
(record_full_stopped_by_hw_breakpoint)
(record_full_supports_stopped_by_hw_breakpoint): New functions.
(init_record_full_ops, init_record_full_core_ops): Install them.
* record.c (record_check_stopped_by_breakpoint): New function.
* record.h: Include target/waitstatus.h.
(record_check_stopped_by_breakpoint): New declaration.
Diffstat (limited to 'gdb/record-btrace.c')
-rw-r--r-- | gdb/record-btrace.c | 69 |
1 files changed, 58 insertions, 11 deletions
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index af7b65f..f2d35a3 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -1954,7 +1954,8 @@ record_btrace_step_thread (struct thread_info *tp) target_pid_to_str (tp->ptid), core_addr_to_string_nz (insn->pc)); - if (breakpoint_here_p (aspace, insn->pc)) + if (record_check_stopped_by_breakpoint (aspace, insn->pc, + &btinfo->stop_reason)) return btrace_step_stopped (); } @@ -1986,7 +1987,8 @@ record_btrace_step_thread (struct thread_info *tp) target_pid_to_str (tp->ptid), core_addr_to_string_nz (insn->pc)); - if (breakpoint_here_p (aspace, insn->pc)) + if (record_check_stopped_by_breakpoint (aspace, insn->pc, + &btinfo->stop_reason)) return btrace_step_stopped (); } } @@ -2044,18 +2046,58 @@ record_btrace_can_execute_reverse (struct target_ops *self) return 1; } -/* The to_decr_pc_after_break method of target record-btrace. */ +/* The to_stopped_by_sw_breakpoint method of target record-btrace. */ -static CORE_ADDR -record_btrace_decr_pc_after_break (struct target_ops *ops, - struct gdbarch *gdbarch) +static int +record_btrace_stopped_by_sw_breakpoint (struct target_ops *ops) { - /* When replaying, we do not actually execute the breakpoint instruction - so there is no need to adjust the PC after hitting a breakpoint. */ if (record_btrace_is_replaying (ops)) - return 0; + { + struct thread_info *tp = inferior_thread (); + + return tp->btrace.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT; + } + + return ops->beneath->to_stopped_by_sw_breakpoint (ops->beneath); +} + +/* The to_supports_stopped_by_sw_breakpoint method of target + record-btrace. */ + +static int +record_btrace_supports_stopped_by_sw_breakpoint (struct target_ops *ops) +{ + if (record_btrace_is_replaying (ops)) + return 1; + + return ops->beneath->to_supports_stopped_by_sw_breakpoint (ops->beneath); +} + +/* The to_stopped_by_sw_breakpoint method of target record-btrace. */ + +static int +record_btrace_stopped_by_hw_breakpoint (struct target_ops *ops) +{ + if (record_btrace_is_replaying (ops)) + { + struct thread_info *tp = inferior_thread (); + + return tp->btrace.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT; + } + + return ops->beneath->to_stopped_by_hw_breakpoint (ops->beneath); +} + +/* The to_supports_stopped_by_hw_breakpoint method of target + record-btrace. */ + +static int +record_btrace_supports_stopped_by_hw_breakpoint (struct target_ops *ops) +{ + if (record_btrace_is_replaying (ops)) + return 1; - return ops->beneath->to_decr_pc_after_break (ops->beneath, gdbarch); + return ops->beneath->to_supports_stopped_by_hw_breakpoint (ops->beneath); } /* The to_update_thread_list method of target record-btrace. */ @@ -2238,7 +2280,12 @@ init_record_btrace_ops (void) ops->to_goto_record_end = record_btrace_goto_end; ops->to_goto_record = record_btrace_goto; ops->to_can_execute_reverse = record_btrace_can_execute_reverse; - ops->to_decr_pc_after_break = record_btrace_decr_pc_after_break; + ops->to_stopped_by_sw_breakpoint = record_btrace_stopped_by_sw_breakpoint; + ops->to_supports_stopped_by_sw_breakpoint + = record_btrace_supports_stopped_by_sw_breakpoint; + ops->to_stopped_by_hw_breakpoint = record_btrace_stopped_by_hw_breakpoint; + ops->to_supports_stopped_by_hw_breakpoint + = record_btrace_supports_stopped_by_hw_breakpoint; ops->to_execution_direction = record_btrace_execution_direction; ops->to_prepare_to_generate_core = record_btrace_prepare_to_generate_core; ops->to_done_generating_core = record_btrace_done_generating_core; |