/* Process record and replay target for GDB, the GNU debugger.
- Copyright (C) 2013-2015 Free Software Foundation, Inc.
+ Copyright (C) 2013-2016 Free Software Foundation, Inc.
This file is part of GDB.
}
static void
-record_full_check_insn_num (int set_terminal)
+record_full_check_insn_num (void)
{
if (record_full_insn_num == record_full_insn_max_num)
{
/* Ask user what to do. */
if (record_full_stop_at_limit)
{
- int q;
-
- if (set_terminal)
- target_terminal_ours ();
- q = yquery (_("Do you want to auto delete previous execution "
+ if (!yquery (_("Do you want to auto delete previous execution "
"log entries when record/replay buffer becomes "
- "full (record full stop-at-limit)?"));
- if (set_terminal)
- target_terminal_inferior ();
- if (q)
- record_full_stop_at_limit = 0;
- else
+ "full (record full stop-at-limit)?")))
error (_("Process record: stopped by user."));
+ record_full_stop_at_limit = 0;
}
}
}
record_full_arch_list_tail = NULL;
/* Check record_full_insn_num. */
- record_full_check_insn_num (1);
+ record_full_check_insn_num ();
/* If gdb sends a signal value to target_resume,
save it in the 'end' field of the previous instruction.
static int
record_full_message_wrapper (void *args)
{
- struct record_full_message_args *record_full_args = args;
+ struct record_full_message_args *record_full_args
+ = (struct record_full_message_args *) args;
return record_full_message (record_full_args->regcache,
record_full_args->signal);
args.regcache = regcache;
args.signal = signal;
- return catch_errors (record_full_message_wrapper, &args, NULL,
+ return catch_errors (record_full_message_wrapper, &args, "",
RETURN_MASK_ALL);
}
/* Nothing to do if the entry is flagged not_accessible. */
if (!entry->u.mem.mem_entry_not_accessible)
{
- gdb_byte *mem = (gdb_byte *) alloca (entry->u.mem.len);
+ gdb_byte *mem = (gdb_byte *) xmalloc (entry->u.mem.len);
+ struct cleanup *cleanup = make_cleanup (xfree, mem);
if (record_debug > 1)
fprintf_unfiltered (gdb_stdlog,
record_full_stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
}
}
+
+ do_cleanups (cleanup);
}
}
break;
record_full_init_record_breakpoints ();
- observer_notify_record_changed (current_inferior (), 1);
+ observer_notify_record_changed (current_inferior (), 1, "full", NULL);
}
/* "to_close" target method. Close the process record target. */
record_full_resume_step = 1;
}
else
- {
- /* This is a continue.
- Try to insert a soft single step breakpoint. */
- if (!gdbarch_software_single_step (gdbarch,
- get_current_frame ()))
- {
- /* This system don't want use soft single step.
- Use hard sigle step. */
- step = 1;
- }
- }
+ step = !insert_single_step_breakpoints (gdbarch);
}
}
target_async (1);
}
+/* "to_commit_resume" method for process record target. */
+
+static void
+record_full_commit_resume (struct target_ops *ops)
+{
+ if (!RECORD_FULL_IS_REPLAY)
+ ops->beneath->to_commit_resume (ops->beneath);
+}
+
static int record_full_get_sig = 0;
/* SIGINT signal handler, registered by "to_wait" method. */
If insert success, set step to 0. */
set_executing (inferior_ptid, 0);
reinit_frame_cache ();
- if (gdbarch_software_single_step (gdbarch,
- get_current_frame ()))
- step = 0;
+
+ step = !insert_single_step_breakpoints (gdbarch);
+
set_executing (inferior_ptid, 1);
}
"target beneath\n");
ops->beneath->to_resume (ops->beneath, ptid, step,
GDB_SIGNAL_0);
+ ops->beneath->to_commit_resume (ops->beneath);
continue;
}
}
record_full_registers_change (struct regcache *regcache, int regnum)
{
/* Check record_full_insn_num. */
- record_full_check_insn_num (0);
+ record_full_check_insn_num ();
record_full_arch_list_head = NULL;
record_full_arch_list_tail = NULL;
}
/* Check record_full_insn_num */
- record_full_check_insn_num (0);
+ record_full_check_insn_num ();
/* Record registers change to list as an instruction. */
record_full_arch_list_head = NULL;
{
struct record_full_breakpoint *bp;
int in_target_beneath = 0;
+ int ix;
if (!RECORD_FULL_IS_REPLAY)
{
really need to install regular breakpoints in the inferior.
However, we do have to insert software single-step
breakpoints, in case the target can't hardware step. To keep
- things single, we always insert. */
+ things simple, we always insert. */
struct cleanup *old_cleanups;
int ret;
in_target_beneath = 1;
}
+ /* Use the existing entries if found in order to avoid duplication
+ in record_full_breakpoints. */
+
+ for (ix = 0;
+ VEC_iterate (record_full_breakpoint_p,
+ record_full_breakpoints, ix, bp);
+ ++ix)
+ {
+ if (bp->addr == bp_tgt->placed_address
+ && bp->address_space == bp_tgt->placed_address_space)
+ {
+ gdb_assert (bp->in_target_beneath == in_target_beneath);
+ return 0;
+ }
+ }
+
bp = XNEW (struct record_full_breakpoint);
bp->addr = bp_tgt->placed_address;
bp->address_space = bp_tgt->placed_address_space;
static int
record_full_remove_breakpoint (struct target_ops *ops,
struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+ struct bp_target_info *bp_tgt,
+ enum remove_bp_reason reason)
{
struct record_full_breakpoint *bp;
int ix;
old_cleanups = record_full_gdb_operation_disable_set ();
ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch,
- bp_tgt);
+ bp_tgt, reason);
do_cleanups (old_cleanups);
if (ret != 0)
return ret;
}
- VEC_unordered_remove (record_full_breakpoint_p,
- record_full_breakpoints, ix);
+ if (reason == REMOVE_BREAKPOINT)
+ {
+ VEC_unordered_remove (record_full_breakpoint_p,
+ record_full_breakpoints, ix);
+ }
return 0;
}
}
record_full_ops.to_close = record_full_close;
record_full_ops.to_async = record_full_async;
record_full_ops.to_resume = record_full_resume;
+ record_full_ops.to_commit_resume = record_full_commit_resume;
record_full_ops.to_wait = record_full_wait;
record_full_ops.to_disconnect = record_disconnect;
record_full_ops.to_detach = record_detach;
static int
record_full_core_remove_breakpoint (struct target_ops *ops,
struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
+ struct bp_target_info *bp_tgt,
+ enum remove_bp_reason reason)
{
return 0;
}
static void
record_full_save_cleanups (void *data)
{
- bfd *obfd = data;
+ bfd *obfd = (bfd *) data;
char *pathname = xstrdup (bfd_get_filename (obfd));
gdb_bfd_unref (obfd);