This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[reverse] PATCH: Several interface changes
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Cc: Michael Snyder <msnyder at vmware dot com>, teawater <teawater at gmail dot com>
- Date: Tue, 7 Oct 2008 17:09:48 +0100
- Subject: [reverse] PATCH: Several interface changes
On Monday 06 October 2008 23:11:14, Michael Snyder wrote:
> Pedro Alves wrote:
> > A per-target property may seems to make sense on
> > single-threaded,single-inferior targets, but when you add support
> > for multi-inferiors per target (e.g., extended-remote has some of it now,
> > and I'm going to push more of it), or multi-threaded support, the
> > per-target setting may not make sense anymore --- explicit requests
> > at the target resume interface (just like your new packets) may make
> > more sense. Imagine forward execution non-stop debugging in all threads
> > but one, which the user is examining in reverse. What's the target
> > direction in this case?
>
> Yakkk!!!
:-) Here's an alternative interface I was considering and envisioning
when I mentioned the above. Consider this just a suggestion. If it
looks bad, let's quickly forget about it.
> > The question to me is --- when/why does the target (as in, the debug
> > API abstraction) ever need to know about the current direction that
> > it couldn't get from the core's request?
So, after last night's discussion, I came up with the attached to
see how it would look like. The major change is that I consider the
reverse/forward-direction thing a property or the command the user
requested, and as such, belongs together with the other thread
stepping state we keep in struct thread_info, and the
target_ops implementation, adjusts itself to the direction GDB
requests with target_resume. I've extended target_resume's interface
to accept this instead of a `step' boolean:
enum target_resume_kind
{
/* Continue forward. */
rk_continue,
/* Step forward. */
rk_step,
/* Continue in the reverse direction. */
rk_continue_reverse,
/* Step in the reverse direction. */
rk_step_reverse,
};
(notice that the order of the things in the enum allows me to
miss some conversions --- I'm lazy).
I can't say if I like this new target_resume interface or
not. I just tried doing it to see how it would look.
(I can imagine that we're in the future going to extend the
target_resume interface to be more like gdbserver's, but, well,
that's another issue.)
So, the interface at the command level implementation is just
like it was before:
1) call clear_proceed_status ();
2) /* construct the step/continue request */
3) call proceed (...);
Where in #2, you can set the thread to go backwards by
doing:
thread->reverse = 1;
The attached patch applies against the reverse-20080930-branch.
Other things I've done in the patch:
* Added support for a "Tnn nohistory" stop reply that translates
to TARGET_WAITKIND_NO_HISTORY. When going multi-threaded, or
multi-process this will allow things like "T05;thread:pPID.TID;nohistory"
for free. I absolutelly didn't test this. I've no reverse aware target
at hand.
* At places, error out if async + reverse or non-stop + reverse
was requested.
* Added a target_can_reverse_p method, so infcmd.c can check if the
target supports reverse execution before calling into the target. Not
strictly necessary, though, but I thought this was nicer this way.
I checked that I can use the record target on x86 (actually x86_64
with -m32) as good as without the patch, but it's quite possible I
broke things badly.
--
Pedro Alves
2008-10-07 Pedro Alves <pedro@codesourcery.com>
* gdbthread.h (struct thread_info) <reverse>: New field.
* inf-ptrace.c (inf_ptrace_resume): Adjust.
* infcmd.c (continue_1): Rename to ...
(continue_1_1): ... this. Add `reverse' parameter. Adjust.
(continue_command): Error out in reverse + async. Call
continue_1_1 instead of continue_1.
(step_1): Error out in reverse + async or if the target doesn't
support reverse execution. Set the current thread's execution
direction. Adjust calls to step_once.
(struct step_1_continuation_args) <reverse>: New field.
(step_1_continuation): Adjust.
(step_once): Add new `reverse' parameter. Adjust.
(finish_command): Adjust.
* inferior.h (set_execution_direction, execution_direction):
Declare.
* infrun.c (displaced_step_fixup): Adjust.
(clear_proceed_status): Clear tp->reverse.
(proceed, handle_inferior_event): Adjust.
* linux-nat.c (resume_callback, linux_nat_resume): Adjust.
* record.c (record_beneath_to_resume): Adjust.
(record_is_replay): New.
(record_resume): Adjust.
(record_wait, record_store_registers, record_xfer_partial)
(record_insert_breakpoint, record_remove_breakpoint): Use
record_is_replay instead of RECORD_IS_REPLAY.
(record_get_exec_direction, record_set_exec_direction): Delete.
(record_can_reverse_p): New.
(init_record_ops): Register record_can_reverse_p. Don't register
record_get_exec_direction or record_set_exec_direction.
(cmd_record_delete): Adjust.
* record.h (RECORD_IS_REPLAY): Delete.
(record_beneath_to_resume): Adjust.
* remote.c (remote_vcont_resume, remote_resume): Adjust.
(remote_wait): Accept a "nohistory" special register in T stop
replies, and translate that to TARGET_WAITKIND_NO_HISTORY.
(remote_can_reverse_p): New.
(remote_get_exec_direction, remote_set_exec_direction): Delete.
(init_remote_ops): Don't register remote_get_exec_direction or
remote_set_exec_direction. Register remote_can_reverse_p.
* reverse.c: Include "inferior.h".
(current_execution_direction): New global.
(set_execution_direction, execution_direction): New.
(set_exec_direction_func, show_exec_direction_func): Rewrite,
don't throw errors.
(exec_direction_default): Rename to ...
(exec_direction_forward): ... this.
(exec_reverse_once): Don't check for target support here.
Adjust.
* target.c (update_current_target): Don't inherit
to_get_exec_direction or to_set_exec_direction. Inherit and
de_fault to_can_reverse_p. Adjust.
(target_resume, debug_to_resume): Adjust.
* target.h (enum target_resume_kind): New.
(struct target_ops) <to_resume>: Adjust to take it.
<to_set_exec_direction, exec_direction_kind>: Delete fields.
<to_can_reverse_p>: New field.
(target_resume): Adjust.
(target_can_reverse_p): New.
(target_get_execution_direction, target_set_execution_direction): Delete.
* fork-child.c (startup_inferior): Adjust.
* i386-linux-nat.c (i386_linux_resume): Adjust.
---
gdb/fork-child.c | 4 +-
gdb/gdbthread.h | 3 +
gdb/i386-linux-nat.c | 4 +-
gdb/inf-ptrace.c | 4 +-
gdb/infcmd.c | 68 ++++++++++++++++++++++++++++++++------
gdb/inferior.h | 6 +++
gdb/infrun.c | 36 ++++++++++++--------
gdb/linux-nat.c | 8 ++--
gdb/record.c | 82 ++++++++++++++++++++++-----------------------
gdb/record.h | 5 +-
gdb/remote.c | 72 +++++++++++++++++++++-------------------
gdb/reverse.c | 91 +++++++++++++++++++++++++++++++--------------------
gdb/target.c | 41 +++++++++++++++++-----
gdb/target.h | 57 +++++++++++++++++++------------
14 files changed, 307 insertions(+), 174 deletions(-)
Index: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/gdbthread.h 2008-10-07 16:20:31.000000000 +0100
@@ -168,6 +168,9 @@ struct thread_info
at. */
bpstat stop_bpstat;
+ /* True if this thread is stepping/continuing in reverse. */
+ int reverse;
+
/* Private data used by the target vector implementation. */
struct private_thread_info *private;
};
Index: src/gdb/inf-ptrace.c
===================================================================
--- src.orig/gdb/inf-ptrace.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/inf-ptrace.c 2008-10-07 16:20:31.000000000 +0100
@@ -352,10 +352,12 @@ inf_ptrace_stop (ptid_t ptid)
that signal. */
static void
-inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
+inf_ptrace_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal signal)
{
pid_t pid = ptid_get_pid (ptid);
int request = PT_CONTINUE;
+ int step = (how == rk_step);
if (pid == -1)
/* Resume all threads. Traditionally ptrace() only supports
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/infcmd.c 2008-10-07 16:20:31.000000000 +0100
@@ -105,7 +105,8 @@ 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, int thread);
+static void step_once (int skip_subroutines, int single_inst, int count, int reverse,
+ int thread);
static void next_command (char *, int);
@@ -586,11 +587,19 @@ proceed_thread_callback (struct thread_i
return 0;
}
-void
-continue_1 (int all_threads)
+/* Helper for continue_1. */
+
+/* If ALL_THREADS, continue all threads forward. If REVERSE, do so in
+ reverse execution mode. */
+
+static void
+continue_1_1 (int all_threads, int reverse)
{
ERROR_NO_INFERIOR;
+ if (non_stop && reverse)
+ error (_("Non-stop mode not supported with reverse execution."));
+
if (non_stop && all_threads)
{
/* Don't error out if the current thread is running, because
@@ -609,16 +618,31 @@ continue_1 (int all_threads)
{
ensure_not_running ();
clear_proceed_status ();
+
+ inferior_thread ()->reverse = reverse;
+
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
}
}
+/* This should be renamed as it's a public function --- it is used by
+ MI. */
+
+/* If ALL_THREADS, continue all threads forward. */
+
+void
+continue_1 (int all_threads)
+{
+ continue_1_1 (all_threads, 0);
+}
+
/* continue [-a] [proceed-count] [&] */
void
continue_command (char *args, int from_tty)
{
int async_exec = 0;
int all_threads = 0;
+ int reverse_exec = (execution_direction () == EXEC_REVERSE);
ERROR_NO_INFERIOR;
/* Find out whether we must run in the background. */
@@ -630,6 +654,13 @@ continue_command (char *args, int from_t
if (async_exec && !target_can_async_p ())
error (_("Asynchronous execution not supported on this target."));
+ if (reverse_exec && !target_can_reverse_p ())
+ error (_("Reverse execution not supported on this target."));
+
+ if (async_exec && reverse_exec)
+ error (_("\
+Asynchronous execution not supported with reverse execution."));
+
/* If we are not asked to run in the bg, then prepare to run in the
foreground, synchronously. */
if (!async_exec && target_can_async_p ())
@@ -701,7 +732,7 @@ Can't resume all threads and specify pro
if (from_tty)
printf_filtered (_("Continuing.\n"));
- continue_1 (all_threads);
+ continue_1_1 (all_threads, reverse_exec);
}
/* Step until outside of current statement. */
@@ -748,6 +779,7 @@ step_1 (int skip_subroutines, int single
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
int async_exec = 0;
int thread = -1;
+ int reverse_exec = (execution_direction () == EXEC_REVERSE);
ERROR_NO_INFERIOR;
ensure_not_running ();
@@ -760,6 +792,13 @@ step_1 (int skip_subroutines, int single
if (async_exec && !target_can_async_p ())
error (_("Asynchronous execution not supported on this target."));
+ if (reverse_exec && !target_can_reverse_p ())
+ error (_("Reverse execution not supported on this target."));
+
+ if (async_exec && reverse_exec)
+ error (_("\
+Asynchronous execution not supported with reverse execution."));
+
/* If we don't get a request of running in the bg, then we need
to simulate synchronous (fg) execution. */
if (!async_exec && target_can_async_p ())
@@ -788,6 +827,7 @@ step_1 (int skip_subroutines, int single
struct thread_info *tp = inferior_thread ();
clear_proceed_status ();
tp->step_frame_id = get_frame_id (get_current_frame ());
+ tp->reverse = reverse_exec;
if (!single_inst)
{
@@ -838,7 +878,7 @@ which has no line number information.\n"
and handle them one at the time, through step_once(). */
else
{
- step_once (skip_subroutines, single_inst, count, thread);
+ step_once (skip_subroutines, single_inst, count, reverse_exec, thread);
/* We are running, and the continuation is installed. It will
disable the longjmp breakpoint as appropriate. */
discard_cleanups (cleanups);
@@ -850,6 +890,7 @@ struct step_1_continuation_args
int count;
int skip_subroutines;
int single_inst;
+ int reverse;
int thread;
};
@@ -872,7 +913,8 @@ step_1_continuation (void *args)
{
/* There are more steps to make, and we did stop due to
ending a stepping range. Do another step. */
- step_once (a->skip_subroutines, a->single_inst, a->count - 1, a->thread);
+ step_once (a->skip_subroutines, a->single_inst, a->count - 1,
+ a->reverse, a->thread);
return;
}
tp->step_multi = 0;
@@ -892,7 +934,8 @@ step_1_continuation (void *args)
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, int thread)
+step_once (int skip_subroutines, int single_inst, int count, int reverse,
+ int thread)
{
struct frame_info *frame;
struct step_1_continuation_args *args;
@@ -906,6 +949,8 @@ step_once (int skip_subroutines, int sin
struct thread_info *tp = inferior_thread ();
clear_proceed_status ();
+ tp->reverse = reverse;
+
frame = get_current_frame ();
if (!frame) /* Avoid coredump here. Why tho? */
error (_("No current frame"));
@@ -956,6 +1001,7 @@ which has no line number information.\n"
args->skip_subroutines = skip_subroutines;
args->single_inst = single_inst;
args->count = count;
+ args->reverse = reverse;
args->thread = thread;
add_intermediate_continuation (tp, step_1_continuation, args, xfree);
}
@@ -1454,7 +1500,7 @@ finish_command (char *arg, int from_tty)
error (_("Asynchronous execution not supported on this target."));
/* Don't try to async in reverse. */
- if (async_exec && target_get_execution_direction () == EXEC_REVERSE)
+ if (async_exec && execution_direction () == EXEC_REVERSE)
error (_("Asynchronous 'finish' not supported in reverse."));
/* If we are not asked to run in the bg, then prepare to run in the
@@ -1478,6 +1524,8 @@ finish_command (char *arg, int from_tty)
clear_proceed_status ();
+ tp->reverse = (execution_direction () == EXEC_REVERSE);
+
/* Find the function we will return from. */
function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
@@ -1486,7 +1534,7 @@ finish_command (char *arg, int from_tty)
source. */
if (from_tty)
{
- if (target_get_execution_direction () == EXEC_REVERSE)
+ if (tp->reverse)
printf_filtered (_("Run back to call of "));
else
printf_filtered (_("Run till exit from "));
@@ -1494,7 +1542,7 @@ finish_command (char *arg, int from_tty)
print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
}
- if (target_get_execution_direction () == EXEC_REVERSE)
+ if (tp->reverse)
{
/* Split off at this point. */
finish_backward (function, tp);
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/inferior.h 2008-10-07 16:20:31.000000000 +0100
@@ -250,6 +250,12 @@ extern void error_is_running (void);
/* Calls error_is_running if the current thread is running. */
extern void ensure_not_running (void);
+/* From reverse.c */
+
+extern void set_execution_direction (enum exec_direction_kind dir);
+
+extern enum exec_direction_kind execution_direction (void);
+
/* From infcmd.c */
extern void tty_command (char *, int);
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/infrun.c 2008-10-07 16:20:31.000000000 +0100
@@ -807,7 +807,7 @@ displaced_step_fixup (ptid_t event_ptid,
displaced_step_ptid = null_ptid;
displaced_step_prepare (ptid);
- target_resume (ptid, 1, TARGET_SIGNAL_0);
+ target_resume (ptid, rk_step, TARGET_SIGNAL_0);
}
}
@@ -1071,7 +1071,12 @@ a command like `return' or `jump' to con
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
}
- target_resume (resume_ptid, step, sig);
+ if (step)
+ target_resume (resume_ptid,
+ tp->reverse ? rk_step_reverse : rk_step, sig);
+ else
+ target_resume (resume_ptid,
+ tp->reverse ? rk_continue_reverse : rk_continue, sig);
/* Avoid confusing the next resume, if the next stop/resume
happens to apply to another thread. */
@@ -1101,6 +1106,7 @@ clear_proceed_status (void)
tp->step_range_end = 0;
tp->step_frame_id = null_frame_id;
tp->step_over_calls = STEP_OVER_UNDEBUGGABLE;
+ tp->reverse = 0;
tp->stop_step = 0;
@@ -1202,8 +1208,9 @@ proceed (CORE_ADDR addr, enum target_sig
if (addr == (CORE_ADDR) -1)
{
+ tp = inferior_thread ();
if (pc == stop_pc && breakpoint_here_p (pc)
- && target_get_execution_direction () != EXEC_REVERSE)
+ && !tp->reverse)
/* There is a breakpoint at the address we will resume at,
step one instruction before inserting breakpoints so that
we do not stop right away (and report a second hit at this
@@ -2149,7 +2156,9 @@ handle_inferior_event (struct execution_
case TARGET_WAITKIND_SYSCALL_RETURN:
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
- target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
+ target_resume (ecs->ptid,
+ ecs->event_thread->reverse ? rk_step_reverse : rk_step,
+ TARGET_SIGNAL_0);
prepare_to_wait (ecs);
return;
@@ -2197,7 +2206,9 @@ targets should add new threads to the th
in either the OS or the native code). Therefore we need to
continue all threads in order to make progress. */
- target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
+ /* Can we step backwards into a threads deletion? Ah, right, we
+ don't support multi-threading in reverse yet. */
+ target_resume (RESUME_ALL, rk_continue, TARGET_SIGNAL_0);
prepare_to_wait (ecs);
return;
}
@@ -2501,7 +2512,7 @@ targets should add new threads to the th
if (!HAVE_STEPPABLE_WATCHPOINT)
remove_breakpoints ();
registers_changed ();
- target_resume (ecs->ptid, 1, TARGET_SIGNAL_0); /* Single step */
+ target_resume (ecs->ptid, rk_step, TARGET_SIGNAL_0); /* Single step */
waiton_ptid = ecs->ptid;
if (HAVE_STEPPABLE_WATCHPOINT)
infwait_state = infwait_step_watch_state;
@@ -2886,7 +2897,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
return;
}
if (stop_pc == ecs->stop_func_start
- && target_get_execution_direction () == EXEC_REVERSE)
+ && ecs->event_thread->reverse)
{
/* We are stepping over a function call in reverse, and
just hit the step-resume breakpoint at the start
@@ -3070,7 +3081,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
keep going back to the call point). */
if (stop_pc == ecs->event_thread->step_range_start
&& stop_pc != ecs->stop_func_start
- && target_get_execution_direction () == EXEC_REVERSE)
+ && ecs->event_thread->reverse)
{
ecs->event_thread->stop_step = 1;
print_stop_reason (END_STEPPING_RANGE, 0);
@@ -3140,7 +3151,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
ecs->event_thread->step_frame_id)
&& (frame_id_eq (frame_unwind_id (get_current_frame ()),
ecs->event_thread->step_frame_id)
- || target_get_execution_direction () == EXEC_REVERSE))
+ || ecs->event_thread->reverse))
{
CORE_ADDR real_stop_pc;
@@ -3178,7 +3189,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
get there, we'll need to single-step back to the
caller. */
- if (target_get_execution_direction () == EXEC_REVERSE)
+ if (ecs->event_thread->reverse)
{
struct symtab_and_line sr_sal;
init_sal (&sr_sal);
@@ -3230,7 +3241,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
/* Find start of appropriate source line (either first or
last line in callee, depending on execution
direction). */
- if (target_get_execution_direction () == EXEC_REVERSE)
+ if (ecs->event_thread->reverse)
stepped_into_function_backward (ecs);
else
stepped_into_function (ecs);
@@ -3250,7 +3261,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
return;
}
- if (target_get_execution_direction () == EXEC_REVERSE)
+ if (ecs->event_thread->reverse)
{
/* Set a breakpoint at callee's start address.
From there we can step once and be back in the caller. */
@@ -4800,7 +4811,6 @@ show_non_stop (struct ui_file *file, int
value);
}
-
void
_initialize_infrun (void)
{
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/linux-nat.c 2008-10-07 16:20:31.000000000 +0100
@@ -1714,7 +1714,7 @@ resume_callback (struct lwp_info *lp, vo
if (lp->stopped && lp->status == 0)
{
linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
- 0, TARGET_SIGNAL_0);
+ rk_continue, TARGET_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"RC: PTRACE_CONT %s, 0, 0 (resume sibling)\n",
@@ -1748,10 +1748,12 @@ resume_set_callback (struct lwp_info *lp
}
static void
-linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
+linux_nat_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal signo)
{
struct lwp_info *lp;
int resume_all;
+ int step = (how == rk_step);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
@@ -1859,7 +1861,7 @@ linux_nat_resume (ptid_t ptid, int step,
if (resume_all)
iterate_over_lwps (resume_callback, NULL);
- linux_ops->to_resume (ptid, step, signo);
+ linux_ops->to_resume (ptid, how, signo);
memset (&lp->siginfo, 0, sizeof (lp->siginfo));
if (debug_linux_nat)
Index: src/gdb/record.c
===================================================================
--- src.orig/gdb/record.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/record.c 2008-10-07 16:20:31.000000000 +0100
@@ -53,7 +53,8 @@ int record_will_store_registers = 0;
extern struct bp_location *bp_location_chain;
/* The real beneath function pointers. */
-void (*record_beneath_to_resume) (ptid_t, int, enum target_signal);
+void (*record_beneath_to_resume) (ptid_t, enum target_resume_kind,
+ enum target_signal);
ptid_t (*record_beneath_to_wait) (ptid_t, struct target_waitstatus *);
void (*record_beneath_to_store_registers) (struct regcache *, int regno);
LONGEST (*record_beneath_to_xfer_partial) (struct target_ops * ops,
@@ -432,15 +433,35 @@ record_close (int quitting)
record_list_release (record_list);
}
+static int record_is_replay;
+
static void
-record_resume (ptid_t ptid, int step, enum target_signal siggnal)
+record_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal siggnal)
{
- record_resume_step = step;
+ record_resume_step = (how == rk_step || how == rk_step_reverse);
+
+ switch (how)
+ {
+ case rk_step_reverse:
+ case rk_continue_reverse:
+ record_exec_direction = EXEC_REVERSE;
+ break;
+ case rk_step:
+ case rk_continue:
+ record_exec_direction = EXEC_FORWARD;
+ break;
+ }
- if (!RECORD_IS_REPLAY)
+ record_is_replay = (record_list->next != NULL
+ || how == rk_step_reverse
+ || how == rk_continue_reverse);
+
+ if (!record_is_replay)
{
record_message (current_gdbarch);
- record_beneath_to_resume (ptid, 1, siggnal);
+
+ record_beneath_to_resume (ptid, rk_step, siggnal);
}
}
@@ -487,10 +508,8 @@ record_wait (ptid_t ptid, struct target_
record_resume_step);
}
- if (!RECORD_IS_REPLAY)
- {
- return record_beneath_to_wait (ptid, status);
- }
+ if (!record_is_replay)
+ return record_beneath_to_wait (ptid, status);
else
{
struct sigaction act, old_act;
@@ -597,8 +616,8 @@ record_wait (ptid_t ptid, struct target_
if (record_debug > 1)
{
fprintf_unfiltered (gdb_stdlog,
- "Process record: record_end 0x%s to inferior need_dasm = %d.\n",
- paddr_nz ((CORE_ADDR)record_list),
+ "Process record: record_end %p to inferior need_dasm = %d.\n",
+ record_list,
record_list->u.need_dasm);
}
@@ -809,7 +828,7 @@ record_store_registers (struct regcache
{
if (!record_not_record)
{
- if (RECORD_IS_REPLAY)
+ if (record_is_replay)
{
int n;
struct cleanup *old_cleanups;
@@ -874,7 +893,7 @@ record_xfer_partial (struct target_ops *
&& (object == TARGET_OBJECT_MEMORY
|| object == TARGET_OBJECT_RAW_MEMORY) && writebuf)
{
- if (RECORD_IS_REPLAY)
+ if (record_is_replay)
{
/* Let user choice if he want to write memory or not. */
if (!nquery (_("Because GDB is in replay mode, writing to memory will destroy the record from this point forward. Write memory at address 0x%s?"),
@@ -931,7 +950,7 @@ record_xfer_partial (struct target_ops *
static int
record_insert_breakpoint (struct bp_target_info *bp_tgt)
{
- if (!RECORD_IS_REPLAY)
+ if (!record_is_replay)
{
return record_beneath_to_insert_breakpoint (bp_tgt);
}
@@ -942,7 +961,7 @@ record_insert_breakpoint (struct bp_targ
static int
record_remove_breakpoint (struct bp_target_info *bp_tgt)
{
- if (!RECORD_IS_REPLAY)
+ if (!record_is_replay)
{
return record_beneath_to_remove_breakpoint (bp_tgt);
}
@@ -950,31 +969,13 @@ record_remove_breakpoint (struct bp_targ
return 0;
}
-static enum exec_direction_kind
-record_get_exec_direction (void)
-{
- if (record_debug > 1)
- printf_filtered ("Process record: exec direction is %s\n",
- record_exec_direction == EXEC_FORWARD ? "forward" :
- record_exec_direction == EXEC_REVERSE ? "reverse" :
- "unknown");
- return record_exec_direction;
-}
-
static int
-record_set_exec_direction (enum exec_direction_kind dir)
+record_can_reverse_p (void)
{
- if (record_debug)
- printf_filtered ("Process record: set exec direction: %s\n",
- dir == EXEC_FORWARD ? "forward" :
- dir == EXEC_REVERSE ? "reverse" :
- "bad direction");
-
- /* FIXME: check target for capability. */
- if (dir == EXEC_FORWARD || dir == EXEC_REVERSE)
- return (record_exec_direction = dir);
- else
- return EXEC_ERROR;
+ /* Sure we can! */
+
+ /* Actually, we should check for architecture support here. */
+ return 1;
}
static void
@@ -997,8 +998,7 @@ init_record_ops (void)
record_ops.to_xfer_partial = record_xfer_partial;
record_ops.to_insert_breakpoint = record_insert_breakpoint;
record_ops.to_remove_breakpoint = record_remove_breakpoint;
- record_ops.to_get_exec_direction = record_get_exec_direction;
- record_ops.to_set_exec_direction = record_set_exec_direction;
+ record_ops.to_can_reverse_p = record_can_reverse_p;
record_ops.to_stratum = record_stratum;
record_ops.to_magic = OPS_MAGIC;
}
@@ -1026,7 +1026,7 @@ cmd_record_delete (char *args, int from_
{
if (RECORD_IS_USED)
{
- if (RECORD_IS_REPLAY)
+ if (record_is_replay)
{
if (!from_tty || query (_("Process record: delete the log from this point forward and begin to record the running message at current PC?")))
{
Index: src/gdb/record.h
===================================================================
--- src.orig/gdb/record.h 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/record.h 2008-10-07 16:20:31.000000000 +0100
@@ -22,8 +22,6 @@
#define RECORD_IS_USED \
(current_target.beneath == &record_ops)
-#define RECORD_IS_REPLAY \
- (record_list->next || record_exec_direction == EXEC_REVERSE)
#define RECORD_TARGET_SUPPORT_RECORD_WAIT (record_ops.beneath->to_support_record_wait)
typedef struct record_reg_s
@@ -85,7 +83,8 @@ extern int record_arch_list_add_end (int
extern void record_message (struct gdbarch *gdbarch);
extern void record_not_record_set (void);
-extern void (*record_beneath_to_resume) (ptid_t, int, enum target_signal);
+extern void (*record_beneath_to_resume) (ptid_t, enum target_resume_kind,
+ enum target_signal);
extern ptid_t (*record_beneath_to_wait) (ptid_t, struct target_waitstatus *);
extern void (*record_beneath_to_store_registers) (struct regcache *, int regno);
extern LONGEST (*record_beneath_to_xfer_partial) (struct target_ops * ops,
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/remote.c 2008-10-07 16:20:31.000000000 +0100
@@ -91,8 +91,8 @@ static void remote_prepare_to_store (str
static void remote_fetch_registers (struct regcache *regcache, int regno);
-static void remote_resume (ptid_t ptid, int step,
- enum target_signal siggnal);
+static void remote_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal siggnal);
static void remote_open (char *name, int from_tty);
static void extended_remote_open (char *name, int from_tty);
@@ -3256,11 +3256,18 @@ remote_vcont_probe (struct remote_state
moment. */
static int
-remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_vcont_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *p;
char *endp;
+ int step = rk_step;
+
+ /* There are no vCont packets supporting reverse execution
+ (yet). */
+ if (how == rk_step_reverse || rk_continue_reverse)
+ return 0;
if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
remote_vcont_probe (rs);
@@ -3362,10 +3369,12 @@ static enum target_signal last_sent_sign
static int last_sent_step;
static void
-remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *buf;
+ int step = (how == rk_step);
last_sent_signal = siggnal;
last_sent_step = step;
@@ -3374,7 +3383,7 @@ remote_resume (ptid_t ptid, int step, en
remote_pass_signals ();
/* The vCont packet doesn't need to specify threads via Hc. */
- if (remote_vcont_resume (ptid, step, siggnal))
+ if (remote_vcont_resume (ptid, how, siggnal))
goto done;
/* All other supported resume packets do use Hc, so set the continue
@@ -3385,7 +3394,7 @@ remote_resume (ptid_t ptid, int step, en
set_continue_thread (ptid);
buf = rs->buf;
- if (target_get_execution_direction () == EXEC_REVERSE)
+ if (how == rk_step_reverse || how == rk_continue_reverse)
{
/* We don't pass signals to the target in reverse exec mode. */
if (info_verbose && siggnal != TARGET_SIGNAL_0)
@@ -3616,6 +3625,7 @@ remote_wait (ptid_t ptid, struct target_
ptid_t event_ptid = null_ptid;
ULONGEST addr;
int solibs_changed = 0;
+ int nohistory = 0;
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
@@ -3734,6 +3744,16 @@ Packet: '%s'\n"),
solibs_changed = 1;
p = p_temp;
}
+ else if (strncmp (p, "nohistory", p1 - p) == 0)
+ {
+ p1++;
+ p_temp = p1;
+ while (*p_temp && *p_temp != ';')
+ p_temp++;
+
+ nohistory = 1;
+ p = p_temp;
+ }
else
{
/* Silently skip unknown optional info. */
@@ -3779,6 +3799,8 @@ Packet: '%s'\n"),
case 'S': /* Old style status, just signal only. */
if (solibs_changed)
status->kind = TARGET_WAITKIND_LOADED;
+ else if (nohistory)
+ status->kind = TARGET_WAITKIND_NO_HISTORY;
else
{
status->kind = TARGET_WAITKIND_STOPPED;
@@ -7560,35 +7582,20 @@ remote_command (char *args, int from_tty
help_list (remote_cmdlist, "remote ", -1, gdb_stdout);
}
+static int
+remote_can_reverse_p (void)
+{
+ /* We can either detect that the remote side doesn't support the
+ reverse resume packets, or add a qSupported feature later. */
+
+ /* Unconditionaly assume we can for now. */
+ return 1;
+}
+
/* Reverse execution.
TODO: set up as a capability. */
static enum exec_direction_kind remote_exec_direction = EXEC_FORWARD;
-static enum exec_direction_kind remote_get_exec_direction (void)
-{
- if (remote_debug && info_verbose)
- printf_filtered ("remote exec direction is %s\n",
- remote_exec_direction == EXEC_FORWARD ? _("forward") :
- remote_exec_direction == EXEC_REVERSE ? _("reverse") :
- "unknown");
- return remote_exec_direction;
-}
-
-static int remote_set_exec_direction (enum exec_direction_kind dir)
-{
- if (remote_debug && info_verbose)
- printf_filtered ("Set remote exec direction: %s\n",
- dir == EXEC_FORWARD ? _("forward") :
- dir == EXEC_REVERSE ? _("reverse") :
- "bad direction");
-
- /* TODO: check target for capability. */
- if (dir == EXEC_FORWARD || dir == EXEC_REVERSE)
- return (remote_exec_direction = dir);
- else
- return EXEC_ERROR;
-}
-
static void
init_remote_ops (void)
{
@@ -7637,8 +7644,6 @@ Specify the serial device it is connecte
remote_ops.to_has_registers = 1;
remote_ops.to_has_execution = 1;
remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
- remote_ops.to_get_exec_direction = remote_get_exec_direction;
- remote_ops.to_set_exec_direction = remote_set_exec_direction;
remote_ops.to_magic = OPS_MAGIC;
remote_ops.to_memory_map = remote_memory_map;
remote_ops.to_flash_erase = remote_flash_erase;
@@ -7651,6 +7656,7 @@ Specify the serial device it is connecte
remote_ops.to_async_mask = remote_async_mask;
remote_ops.to_terminal_inferior = remote_terminal_inferior;
remote_ops.to_terminal_ours = remote_terminal_ours;
+ remote_ops.to_can_reverse_p = remote_can_reverse_p;
}
/* Set up the extended remote vector by making a copy of the standard
Index: src/gdb/reverse.c
===================================================================
--- src.orig/gdb/reverse.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/reverse.c 2008-10-07 16:36:35.000000000 +0100
@@ -25,6 +25,30 @@
#include "top.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
+#include "inferior.h"
+
+/* The default current (user command level) execution direction. All
+ targets that support execution should be able to go forward. */
+
+enum exec_direction_kind current_exec_direction = EXEC_FORWARD;
+
+/* Set the default desired direction. We don't check for availability
+ here, because the user may set this before the target is
+ connected/open. If the target doesn't support reverse, either the
+ execution command issued, or target_resume will take care of
+ erroring out. */
+
+void
+set_execution_direction (enum exec_direction_kind dir)
+{
+ current_exec_direction = dir;
+}
+
+enum exec_direction_kind
+execution_direction (void)
+{
+ return current_exec_direction;
+}
/* User interface for reverse debugging:
Set exec-direction / show exec-direction commands (returns error
@@ -43,50 +67,51 @@ static void
set_exec_direction_func (char *args, int from_tty,
struct cmd_list_element *cmd)
{
- if (target_get_execution_direction () != EXEC_ERROR)
- {
- enum exec_direction_kind dir = EXEC_ERROR;
+ enum exec_direction_kind dir;
- if (!strcmp (exec_direction, exec_forward))
- dir = EXEC_FORWARD;
- else if (!strcmp (exec_direction, exec_reverse))
- dir = EXEC_REVERSE;
-
- if (target_set_execution_direction (dir) != EXEC_ERROR)
- return;
+ if (!strcmp (exec_direction, exec_forward))
+ dir = EXEC_FORWARD;
+ else if (!strcmp (exec_direction, exec_reverse))
+ dir = EXEC_REVERSE;
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ "unhandled execution direction");
+ return;
}
+
+ set_execution_direction (dir);
}
static void
show_exec_direction_func (struct ui_file *out, int from_tty,
struct cmd_list_element *cmd, const char *value)
{
- enum exec_direction_kind dir = target_get_execution_direction ();
+ enum exec_direction_kind dir = execution_direction ();
- switch (dir) {
- case EXEC_FORWARD:
- fprintf_filtered (out, _("Forward\n"));
- break;
- case EXEC_REVERSE:
- fprintf_filtered (out, _("Reverse\n"));
- break;
- case EXEC_ERROR:
- default:
- fprintf_filtered, (out,
- _("Forward (target `%s' does not support exec-direction)\n"),
- target_shortname);
- break;
+ switch (dir)
+ {
+ case EXEC_FORWARD:
+ fprintf_filtered (out, _("Forward\n"));
+ break;
+ case EXEC_REVERSE:
+ fprintf_filtered (out, _("Reverse\n"));
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "unhandled execution direction");
+ break;
}
}
/* User interface:
- reverse-step, reverse-next etc. (returns error unles
- target implements to_set_exec_direction method). */
+ reverse-step, reverse-next etc. */
-static void exec_direction_default (void *notused)
+static void
+exec_direction_forward (void *notused)
{
/* Return execution direction to default state. */
- target_set_execution_direction (EXEC_FORWARD);
+ set_execution_direction (EXEC_FORWARD);
}
static void
@@ -94,20 +119,16 @@ exec_reverse_once (char *cmd, char *args
{
/* String buffer for command consing. */
char reverse_command[512];
- enum exec_direction_kind dir = target_get_execution_direction ();
+ enum exec_direction_kind dir = execution_direction ();
struct cleanup *old_chain;
- if (dir == EXEC_ERROR)
- error (_("Target %s does not support this command."), target_shortname);
-
if (dir == EXEC_REVERSE)
error (_("Already in reverse mode. Use '%s' or 'set exec-dir forward'."),
cmd);
- if (target_set_execution_direction (EXEC_REVERSE) == EXEC_ERROR)
- error (_("Target %s does not support this command."), target_shortname);
+ set_execution_direction (EXEC_REVERSE);
- old_chain = make_cleanup (exec_direction_default, NULL);
+ old_chain = make_cleanup (exec_direction_forward, NULL);
sprintf (reverse_command, "%s %s", cmd, args ? args : "");
execute_command (reverse_command, from_tty);
do_cleanups (old_chain);
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/target.c 2008-10-07 16:39:33.000000000 +0100
@@ -104,7 +104,8 @@ static void debug_to_attach (char *, int
static void debug_to_detach (char *, int);
-static void debug_to_resume (ptid_t, int, enum target_signal);
+static void debug_to_resume (ptid_t, enum target_resume_kind,
+ enum target_signal);
static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
@@ -465,14 +466,13 @@ update_current_target (void)
INHERIT (to_find_memory_regions, t);
INHERIT (to_make_corefile_notes, t);
INHERIT (to_get_thread_local_address, t);
- INHERIT (to_get_exec_direction, t);
- INHERIT (to_set_exec_direction, t);
/* Do not inherit to_read_description. */
/* Do not inherit to_search_memory. */
INHERIT (to_magic, t);
/* Do not inherit to_memory_map. */
/* Do not inherit to_flash_erase. */
/* Do not inherit to_flash_done. */
+ INHERIT (to_can_reverse_p, t);
/* Set the real beneath function pointers. */
if (t != &record_ops)
@@ -526,7 +526,8 @@ update_current_target (void)
(void (*) (char *, int))
target_ignore);
de_fault (to_resume,
- (void (*) (ptid_t, int, enum target_signal))
+ (void (*) (ptid_t, enum target_resume_kind,
+ enum target_signal))
noprocess);
de_fault (to_wait,
(ptid_t (*) (ptid_t, struct target_waitstatus *))
@@ -661,6 +662,7 @@ update_current_target (void)
de_fault (to_async_mask,
(int (*) (int))
return_one);
+ de_fault (to_can_reverse_p, return_zero);
current_target.to_read_description = NULL;
#undef de_fault
@@ -1836,10 +1838,11 @@ target_disconnect (char *args, int from_
}
void
-target_resume (ptid_t ptid, int step, enum target_signal signal)
+target_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal signal)
{
dcache_invalidate (target_dcache);
- (*current_target.to_resume) (ptid, step, signal);
+ (*current_target.to_resume) (ptid, how, signal);
set_executing (ptid, 1);
set_running (ptid, 1);
}
@@ -2527,12 +2530,30 @@ debug_to_detach (char *args, int from_tt
}
static void
-debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal)
+debug_to_resume (ptid_t ptid, enum target_resume_kind how, enum target_signal siggnal)
{
- debug_target.to_resume (ptid, step, siggnal);
+ const char *howstr;
- fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", PIDGET (ptid),
- step ? "step" : "continue",
+ debug_target.to_resume (ptid, how, siggnal);
+
+ switch (how)
+ {
+ case rk_step:
+ howstr = "step";
+ break;
+ case rk_continue:
+ howstr = "continue";
+ break;
+ case rk_step_reverse:
+ howstr = "step reverse";
+ break;
+ case rk_continue_reverse:
+ howstr = "continue reverse";
+ break;
+ }
+
+ fprintf_unfiltered (gdb_stdlog, "target_resume (%s, %s, %s)\n",
+ target_pid_to_str (ptid), howstr,
target_signal_to_name (siggnal));
}
Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/target.h 2008-10-07 16:20:31.000000000 +0100
@@ -152,6 +152,29 @@ struct target_waitstatus
value;
};
+/* I'm explicitly leaving the order as
+
+ rk_continue == 0
+ rk_step == 1
+
+ to be compatible with the old interface, so I can avoid fixing up
+ all the target_resume callers for now. */
+
+enum target_resume_kind
+ {
+ /* Continue forward. */
+ rk_continue,
+
+ /* Step forward. */
+ rk_step,
+
+ /* Continue in the reverse direction. */
+ rk_continue_reverse,
+
+ /* Step in the reverse direction. */
+ rk_step_reverse,
+ };
+
/* Reverse execution. */
enum exec_direction_kind
{
@@ -340,7 +363,7 @@ struct target_ops
void (*to_post_attach) (int);
void (*to_detach) (char *, int);
void (*to_disconnect) (struct target_ops *, char *, int);
- void (*to_resume) (ptid_t, int, enum target_signal);
+ void (*to_resume) (ptid_t, enum target_resume_kind, enum target_signal);
ptid_t (*to_wait) (ptid_t, struct target_waitstatus *);
void (*to_fetch_registers) (struct regcache *, int);
void (*to_store_registers) (struct regcache *, int);
@@ -536,10 +559,8 @@ struct target_ops
const gdb_byte *pattern, ULONGEST pattern_len,
CORE_ADDR *found_addrp);
- /* Set execution direction (forward/reverse). */
- int (*to_set_exec_direction) (enum exec_direction_kind);
- /* Get execution direction (forward/reverse). */
- enum exec_direction_kind (*to_get_exec_direction) (void);
+ /* Returns true if the target supports reverse execution. */
+ int (*to_can_reverse_p) (void);
/* Default value is 0. Mean that this target doesn't support record wait.
Need the help of infrun.c(handle_inferior_event). Set to 1 if this
@@ -618,12 +639,13 @@ extern void target_detach (char *, int);
extern void target_disconnect (char *, int);
-/* Resume execution of the target process PTID. STEP says whether to
- single-step or to run free; SIGGNAL is the signal to be given to
- the target, or TARGET_SIGNAL_0 for no signal. The caller may not
- pass TARGET_SIGNAL_DEFAULT. */
+/* Resume execution of the target process PTID. HOW says how to
+ proceed; SIGGNAL is the signal to be given to the target, or
+ TARGET_SIGNAL_0 for no signal. The caller may not pass
+ TARGET_SIGNAL_DEFAULT. */
-extern void target_resume (ptid_t ptid, int step, enum target_signal signal);
+extern void target_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal signal);
/* Wait for process pid to do something. PTID = -1 to wait for any
pid to do something. Return pid of child, or -1 in case of error;
@@ -992,6 +1014,9 @@ extern int target_async_permitted;
int target_supports_non_stop (void);
+#define target_can_reverse_p() \
+ (current_target.to_can_reverse_p ())
+
/* Put the target in async mode with the specified callback function. */
#define target_async(CALLBACK,CONTEXT) \
(current_target.to_async ((CALLBACK), (CONTEXT)))
@@ -1150,18 +1175,6 @@ extern int target_stopped_data_address_p
#define target_watchpoint_addr_within_range(target, addr, start, length) \
(*target.to_watchpoint_addr_within_range) (target, addr, start, length)
-/* Forward/reverse execution direction.
- These will only be implemented by a target that supports reverse execution.
-*/
-#define target_get_execution_direction() \
- (current_target.to_get_exec_direction ? \
- (*current_target.to_get_exec_direction) () : EXEC_ERROR)
-
-#define target_set_execution_direction(DIR) \
- (current_target.to_set_exec_direction ? \
- (*current_target.to_set_exec_direction) (DIR) : EXEC_ERROR)
-
-
extern const struct target_desc *target_read_description (struct target_ops *);
/* Utility implementation of searching memory. */
Index: src/gdb/fork-child.c
===================================================================
--- src.orig/gdb/fork-child.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/fork-child.c 2008-10-07 16:20:31.000000000 +0100
@@ -490,7 +490,7 @@ startup_inferior (int ntraps)
if (resume_signal != TARGET_SIGNAL_TRAP)
{
/* Let shell child handle its own signals in its own way. */
- target_resume (resume_ptid, 0, resume_signal);
+ target_resume (resume_ptid, rk_continue, resume_signal);
}
else
{
@@ -516,7 +516,7 @@ startup_inferior (int ntraps)
break;
/* Just make it go on. */
- target_resume (resume_ptid, 0, TARGET_SIGNAL_0);
+ target_resume (resume_ptid, rk_continue, TARGET_SIGNAL_0);
}
}
}
Index: src/gdb/i386-linux-nat.c
===================================================================
--- src.orig/gdb/i386-linux-nat.c 2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/i386-linux-nat.c 2008-10-07 16:20:31.000000000 +0100
@@ -744,9 +744,11 @@ static const unsigned char linux_syscall
If SIGNAL is nonzero, give it that signal. */
static void
-i386_linux_resume (ptid_t ptid, int step, enum target_signal signal)
+i386_linux_resume (ptid_t ptid, enum target_resume_kind how,
+ enum target_signal signal)
{
int pid = PIDGET (ptid);
+ int step = (how == rk_step);
int request = PTRACE_CONT;