• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisiónda33b5bf66650ddadd113bbe6eeed1ed5da37b25 (tree)
Tiempo2008-06-10 09:13:15
AutorMichael Snyder <msnyder@vmwa...>
CommiterMichael Snyder

Log Message

Daniel Jacobowitz' update to Michael Snyder's reverse debugging patches

Cambiar Resumen

Diferencia incremental

--- /dev/null
+++ b/gdb/ChangeLog.reverse
@@ -0,0 +1,70 @@
1+2007-07-13 Daniel Jacobowitz <dan@codesourcery.com>
2+
3+ * infcall.c (call_function_by_hand): Always restore inferior state
4+ for now.
5+ * infrun.c (save_inferior_status): Call to_doing_call.
6+ (restore_inferior_status): Likewise.
7+ (discard_inferior_status): Warn; this should not be reached.
8+ * remote.c (remote_doing_call): New.
9+ (init_remote_ops, init_remote_async_ops): Use it.
10+ * target.c (update_current_target): Handle to_doing_call.
11+ * target.h (struct target_ops): Add to_doing_call.
12+
13+2007-04-18 Daniel Jacobowitz <dan@codesourcery.com>
14+
15+ gdb/
16+ * infcmd.c (finish_backwards): Correct check for whether to back
17+ up after finishing.
18+
19+2007-04-18 Daniel Jacobowitz <dan@codesourcery.com>
20+
21+ gdb/
22+ * arm-tdep.c (arm_scan_epilogue): New.
23+ (arm_make_prologue_cache): Use it.
24+ (arm_epilogue_unwind_sniffer): New.
25+ (arm_gdbarch_init): Register it.
26+
27+2007-04-13 Daniel Jacobowitz <dan@codesourcery.com>
28+
29+ Updated patch based on:
30+ 2006-03-31 Michael Snyder <msnyder@redhat.com>
31+ User interface for reverse execution.
32+ * Makefile.in (reverse.c): New file.
33+ * reverse.c: New file. User interface for reverse execution.
34+
35+2007-04-13 Daniel Jacobowitz <dan@codesourcery.com>
36+
37+ Updated patch based on:
38+ 2006-03-31 Michael Snyder <msnyder@redhat.com>
39+ Execution interface for reverse execution.
40+ * breakpoint.c (breakpoint_silence): New function.
41+ * breakpoint.h (breakpoint_silence): Export.
42+ * infcmd.c (finish_command): Check for reverse exec direction.
43+ (finish_backward): New function, handle finish cmd in reverse.
44+ * infrun.c (enum inferior_stop_reason): Add NO_HISTORY reason.
45+ (handle_inferior_event): Handle TARGET_WAITKIND_NO_HISTORY.
46+ Handle stepping over a function call in reverse.
47+ Handle stepping thru a line range in reverse.
48+ Handle setting a step-resume breakpoint in reverse.
49+ Handle stepping into a function in reverse.
50+ Handle stepping between line ranges in reverse.
51+ (print_stop_reason): Print reason for NO_HISTORY.
52+
53+2007-04-13 Daniel Jacobowitz <dan@codesourcery.com>
54+
55+ Updated patch based on:
56+ 2006-03-31 Michael Snyder <msnyder@redhat.com>
57+ Target interface for reverse execution.
58+ * target.h (enum target_waitkind):
59+ Add new wait event, TARGET_WAITKIND_NO_HISTORY.
60+ (enum exec_direction_kind): New enum.
61+ (struct target_ops): New methods to_set_execdir, to_get_execdir.
62+ (target_set_execution_direction): New macro.
63+ (target_get_execution_direction): New macro.
64+ * target.c (update_current_target): Inherit new execdir methods.
65+
66+ * remote.c (remote_get_execdir, remote_set_execdir): New methods.
67+ (_initialize_remote): Add new methods to remote target vector.
68+ (remote_resume): Check for reverse exec direction, and send
69+ appropriate command to target.
70+ (remote_wait): Check target response for NO_HISTORY status.
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -552,7 +552,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c \
552552 objfiles.c osabi.c observer.c \
553553 p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
554554 prologue-value.c \
555- regcache.c reggroups.c remote.c remote-fileio.c \
555+ regcache.c reggroups.c remote.c remote-fileio.c reverse.c \
556556 scm-exp.c scm-lang.c scm-valprint.c \
557557 sentinel-frame.c \
558558 serial.c ser-base.c ser-unix.c \
@@ -952,7 +952,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
952952 std-regs.o \
953953 signals.o \
954954 gdb-events.o \
955- exec.o bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
955+ exec.o reverse.o \
956+ bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
956957 dbxread.o coffread.o coff-pe-read.o elfread.o \
957958 dwarf2read.o mipsread.o stabsread.o corefile.o \
958959 dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
@@ -2546,6 +2547,8 @@ remote-sim.o: remote-sim.c $(defs_h) $(inferior_h) $(value_h) \
25462547 remote-utils.o: remote-utils.c $(defs_h) $(gdb_string_h) $(gdbcmd_h) \
25472548 $(target_h) $(serial_h) $(gdbcore_h) $(inferior_h) $(remote_utils_h) \
25482549 $(regcache_h)
2550+reverse.o: reverse.c $(defs_h) $(gdb_string_h) $(target_h) $(cli_cmds_h) \
2551+ $(cli_decode_h) $(top_h)
25492552 rs6000-nat.o: rs6000-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
25502553 $(xcoffsolib_h) $(symfile_h) $(objfiles_h) $(libbfd_h) $(bfd_h) \
25512554 $(exceptions_h) $(gdb_stabs_h) $(regcache_h) $(arch_utils_h) \
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -888,6 +888,45 @@ arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cac
888888 cache->frameoffset = 0;
889889 }
890890
891+/* This function tries to guess whether we are in the epilogue of an
892+ ARM function. We need to detect whether the stack frame has
893+ already been destroyed - if it has, then neither the prologue
894+ scanner nor GCC's unwind tables will be valid. This is very hokey
895+ and generally unsafe. */
896+
897+static int
898+arm_scan_epilogue (struct frame_info *next_frame,
899+ struct arm_prologue_cache *cache)
900+{
901+ unsigned int insn;
902+ gdb_byte buf[4];
903+ CORE_ADDR prev_pc = frame_pc_unwind (next_frame);
904+
905+ /* Assume there is no frame until proven otherwise. */
906+ if (cache != NULL)
907+ {
908+ cache->framereg = ARM_SP_REGNUM;
909+ cache->framesize = 0;
910+ cache->frameoffset = 0;
911+ }
912+
913+ /* Check for Thumb epilogue. */
914+ if (arm_pc_is_thumb (prev_pc))
915+ /* Not yet implemented. */
916+ return 0;
917+
918+ if (target_read_memory (prev_pc, buf, 4) != 0)
919+ return 0;
920+ insn = extract_unsigned_integer (buf, 4);
921+
922+ if (insn == 0xe12fff1e) /* bx lr */
923+ /* If this is a return, we have no frame left and no saved
924+ registers. */
925+ return 1;
926+
927+ return 0;
928+}
929+
891930 static struct arm_prologue_cache *
892931 arm_make_prologue_cache (struct frame_info *next_frame)
893932 {
@@ -898,7 +937,8 @@ arm_make_prologue_cache (struct frame_info *next_frame)
898937 cache = FRAME_OBSTACK_ZALLOC (struct arm_prologue_cache);
899938 cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
900939
901- arm_scan_prologue (next_frame, cache);
940+ if (arm_scan_epilogue (next_frame, cache) == 0)
941+ arm_scan_prologue (next_frame, cache);
902942
903943 unwound_fp = frame_unwind_register_unsigned (next_frame, cache->framereg);
904944 if (unwound_fp == 0)
@@ -995,6 +1035,15 @@ arm_prologue_unwind_sniffer (struct frame_info *next_frame)
9951035 return &arm_prologue_unwind;
9961036 }
9971037
1038+static const struct frame_unwind *
1039+arm_epilogue_unwind_sniffer (struct frame_info *next_frame)
1040+{
1041+ if (arm_scan_epilogue (next_frame, NULL))
1042+ return &arm_prologue_unwind;
1043+ else
1044+ return NULL;
1045+}
1046+
9981047 static struct arm_prologue_cache *
9991048 arm_make_stub_cache (struct frame_info *next_frame)
10001049 {
@@ -2996,6 +3045,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
29963045
29973046 /* Add some default predicates. */
29983047 frame_unwind_append_sniffer (gdbarch, arm_stub_unwind_sniffer);
3048+ frame_unwind_append_sniffer (gdbarch, arm_epilogue_unwind_sniffer);
29993049 frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
30003050 frame_unwind_append_sniffer (gdbarch, arm_prologue_unwind_sniffer);
30013051
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7534,6 +7534,13 @@ breakpoint_clear_ignore_counts (void)
75347534 b->ignore_count = 0;
75357535 }
75367536
7537+void
7538+breakpoint_silence (struct breakpoint *b)
7539+{
7540+ /* Silence the breakpoint. */
7541+ b->silent = 1;
7542+}
7543+
75377544 /* Command to set ignore-count of breakpoint N to COUNT. */
75387545
75397546 static void
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -850,4 +850,7 @@ extern int deprecated_exception_catchpoints_are_fragile;
850850 reinitialized -- e.g. when program is re-run. */
851851 extern int deprecated_exception_support_initialized;
852852
853+/* Tell a breakpoint to be quiet. */
854+extern void breakpoint_silence (struct breakpoint *);
855+
853856 #endif /* !defined (BREAKPOINT_H) */
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -127,6 +127,7 @@ Copyright (C) 1988-2006 Free Software Foundation, Inc.
127127 * Commands:: @value{GDBN} commands
128128 * Running:: Running programs under @value{GDBN}
129129 * Stopping:: Stopping and continuing
130+* Reverse Execution:: Running programs backward
130131 * Stack:: Examining the stack
131132 * Source:: Examining source files
132133 * Data:: Examining data
@@ -4387,6 +4388,109 @@ Display the current scheduler locking mode.
43874388 @end table
43884389
43894390
4391+@node Reverse Execution
4392+@chapter Running programs backward
4393+
4394+When you are debugging a program, it is not unusual to realize that
4395+you have gone too far, and some event of interest has already happened.
4396+If the target environment supports it, @value{GDBN} can allow you to
4397+``rewind'' the program by running it backward.
4398+
4399+A target environment that supports reverse execution should be able
4400+to ``undo'' the changes in machine state that have taken place as the
4401+program was executing normally. Variables, registers etc. should
4402+revert to their previous values. Obviously this requires a great
4403+deal of sophistication on the part of the target environment; not
4404+all target environments can support reverse execution.
4405+
4406+When a program is executed in reverse, the instructions that
4407+have most recently been executed are ``un-executed'', in reverse
4408+order. The program counter runs backward, following the previous
4409+thread of execution in reverse. As each instruction is ``un-executed'',
4410+the values of memory and/or registers that were changed by that
4411+instruction are reverted to their previous states. After executing
4412+a piece of source code in reverse, all side effects of that code
4413+should be ``undone'', and all variables should be returned to their
4414+prior values.
4415+
4416+Assuming you are debugging in a target environment that supports
4417+reverse execution, @value{GDBN} provides the following commands.
4418+
4419+@table @code
4420+@kindex reverse-continue
4421+@kindex rc @r{(@code{reverse-continue})}
4422+@item reverse-continue @r{[}@var{ignore-count}@r{]}
4423+@itemx rc @r{[}@var{ignore-count}@r{]}
4424+Beginning at the point where your program last stopped, start executing
4425+in reverse. Reverse execution will stop for breakpoints and synchronous
4426+exceptions (signals), just like normal execution. Behavior of
4427+asynchronous signals depends on the target environment.
4428+
4429+@kindex reverse-step
4430+@kindex rs @r{(@code{step})}
4431+@item reverse-step @r{[}@var{count}@r{]}
4432+Run the program backward until control reaches the start of a
4433+different source line; then stop it, and return control to @value{GDBN}.
4434+
4435+Like the @code{step} command, @code{reverse-step} will only stop
4436+at the beginning of a source line. It ``un-executes'' the previously
4437+executed source line. If the previous source line included calls to
4438+debuggable functions, @code{reverse-step} will step (backward) into
4439+the called function, stopping at the beginning of the @emph{last}
4440+statement in the called function (typically a return statement).
4441+
4442+Also, as with the @code{step} command, if non-debuggable functions are
4443+called, @code{reverse-step} will run thru them backward without stopping.
4444+
4445+@kindex reverse-stepi
4446+@kindex rsi @r{(@code{reverse-stepi})}
4447+@item reverse-stepi @r{[}@var{count}@r{]}
4448+Reverse-execute one machine instruction. Note that the instruction
4449+to be reverse-executed is @emph{not} the one pointed to by the program
4450+counter, but the instruction executed prior to that one. For instance,
4451+if the last instruction was a jump, @code{reverse-stepi} will take you
4452+back from the destination of the jump to the jump instruction itself.
4453+
4454+@kindex reverse-next
4455+@kindex rn @r{(@code{reverse-next})}
4456+@item reverse-next @r{[}@var{count}@r{]}
4457+Run backward to the beginning of the previous line executed in
4458+the current (innermost) stack frame. If the line contains function
4459+calls, they will be ``un-executed'' without stopping. Starting from
4460+the first line of a function, @code{reverse-next} will take you back
4461+to the caller of that function, @emph{before} the function was called.
4462+
4463+@kindex reverse-nexti
4464+@kindex rni @r{(@code{reverse-nexti})}
4465+@item reverse-nexti @r{[}@var{count}@r{]}
4466+Like @code{nexti}, @code{reverse-nexti} executes a single instruction
4467+in reverse, except that called functions are ``un-executed'' atomically.
4468+That is, if the previously executed instruction was a return from
4469+another instruction, @code{reverse-nexti} will continue to execute
4470+in reverse until the call to that function (from the current stack
4471+frame) is reached.
4472+
4473+@kindex reverse-finish
4474+@item reverse-finish
4475+Just as the @code{finish} command takes you to the point where the
4476+current function returns, @code{reverse-finish} takes you to the point
4477+where it was called. Instead of ending up at the end of the current
4478+function invocation, you end up at the beginning.
4479+
4480+@item set exec-direction
4481+Set the direction of target execution.
4482+@itemx set exec-direction reverse
4483+@cindex execute forward or backward in time
4484+@value{GDBN} will perform all execution commands in reverse, until the
4485+exec-direction mode is changed to ``forward''. Affected commands include
4486+@code{step, stepi, next, nexti, continue, and finish}. The @code{return}
4487+command cannot be used in reverse mode.
4488+@item set exec-direction forward
4489+@value{GDBN} will perform all execution commands in the normal fashion.
4490+This is the default.
4491+@end table
4492+
4493+
43904494 @node Stack
43914495 @chapter Examining the Stack
43924496
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -780,7 +780,7 @@ You must use a pointer to function type variable. Command ignored."), arg_name);
780780 signal. Further execution of the FUNCTION is not
781781 allowed. */
782782
783- if (unwind_on_signal_p)
783+ if (unwind_on_signal_p || 1 /* FIXME restoring state */)
784784 {
785785 /* The user wants the context restored. */
786786
@@ -819,6 +819,12 @@ Evaluation of the expression containing the function (%s) will be abandoned."),
819819 }
820820 }
821821
822+ if (!stop_stack_dummy && 1 /* FIXME restoring state */)
823+ {
824+ error (_("\
825+The program being debugged stopped while in a function called from GDB.\n\
826+GDB has restored the context to what it was before the call."));
827+ }
822828 if (!stop_stack_dummy)
823829 {
824830 /* We hit a breakpoint inside the FUNCTION. */
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1266,6 +1266,8 @@ finish_command_continuation (struct continuation_arg *arg)
12661266 /* "finish": Set a temporary breakpoint at the place the selected
12671267 frame will return to, then continue. */
12681268
1269+static void finish_backwards (struct symbol *);
1270+
12691271 static void
12701272 finish_command (char *arg, int from_tty)
12711273 {
@@ -1306,16 +1308,6 @@ finish_command (char *arg, int from_tty)
13061308
13071309 clear_proceed_status ();
13081310
1309- sal = find_pc_line (get_frame_pc (frame), 0);
1310- sal.pc = get_frame_pc (frame);
1311-
1312- breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish);
1313-
1314- if (!target_can_async_p ())
1315- old_chain = make_cleanup_delete_breakpoint (breakpoint);
1316- else
1317- old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
1318-
13191311 /* Find the function we will return from. */
13201312
13211313 function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
@@ -1324,10 +1316,31 @@ finish_command (char *arg, int from_tty)
13241316 source. */
13251317 if (from_tty)
13261318 {
1327- printf_filtered (_("Run till exit from "));
1319+ if (target_get_execution_direction () == EXEC_REVERSE)
1320+ printf_filtered ("Run back to call of ");
1321+ else
1322+ printf_filtered ("Run till exit from ");
1323+
13281324 print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
13291325 }
13301326
1327+ if (target_get_execution_direction () == EXEC_REVERSE)
1328+ {
1329+ /* Split off at this point. */
1330+ finish_backwards (function);
1331+ return;
1332+ }
1333+
1334+ sal = find_pc_line (get_frame_pc (frame), 0);
1335+ sal.pc = get_frame_pc (frame);
1336+
1337+ breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish);
1338+
1339+ if (!target_can_async_p ())
1340+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
1341+ else
1342+ old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
1343+
13311344 /* If running asynchronously and the target support asynchronous
13321345 execution, set things up for the rest of the finish command to be
13331346 completed later on, when gdb has detected that the target has
@@ -1384,6 +1397,66 @@ finish_command (char *arg, int from_tty)
13841397 do_cleanups (old_chain);
13851398 }
13861399 }
1400+
1401+static void
1402+finish_backwards (struct symbol *function)
1403+{
1404+ struct symtab_and_line sal;
1405+ struct breakpoint *breakpoint;
1406+ struct cleanup *old_chain;
1407+ CORE_ADDR func_addr;
1408+ int back_up;
1409+
1410+ if (find_pc_partial_function (get_frame_pc (get_current_frame ()),
1411+ NULL, &func_addr, NULL) == 0)
1412+ internal_error (__FILE__, __LINE__,
1413+ "Finish: couldn't find function.");
1414+
1415+ sal = find_pc_line (func_addr, 0);
1416+
1417+ /* Let's cheat and not worry about async until later. */
1418+
1419+ /* We don't need a return value. */
1420+ proceed_to_finish = 0;
1421+ /* Special case: if we're sitting at the function entry point,
1422+ then all we need to do is take a reverse singlestep. We
1423+ don't need to set a breakpoint, and indeed it would do us
1424+ no good to do so.
1425+
1426+ Note that this can only happen at frame #0, since there's
1427+ no way that a function up the stack can have a return address
1428+ that's equal to its entry point. */
1429+
1430+ if (sal.pc != read_pc ())
1431+ {
1432+ /* Set breakpoint and continue. */
1433+ breakpoint =
1434+ set_momentary_breakpoint (sal,
1435+ get_frame_id (get_selected_frame (NULL)),
1436+ bp_breakpoint);
1437+ /* Tell the breakpoint to keep quiet. We won't be done
1438+ until we've done another reverse single-step. */
1439+ breakpoint_silence (breakpoint);
1440+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
1441+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
1442+ /* We will be stopped when proceed returns. */
1443+ back_up = bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL;
1444+ do_cleanups (old_chain);
1445+ }
1446+ else
1447+ back_up = 1;
1448+ if (back_up)
1449+ {
1450+ /* If in fact we hit the step-resume breakpoint (and not
1451+ some other breakpoint), then we're almost there --
1452+ we just need to back up by one more single-step. */
1453+ /* (Kludgy way of letting wait_for_inferior know...) */
1454+ step_range_start = step_range_end = 1;
1455+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
1456+ }
1457+ return;
1458+}
1459+
13871460
13881461
13891462 static void
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -899,7 +899,9 @@ enum inferior_stop_reason
899899 /* Inferior exited. */
900900 EXITED,
901901 /* Inferior received signal, and user asked to be notified. */
902- SIGNAL_RECEIVED
902+ SIGNAL_RECEIVED,
903+ /* Reverse execution -- target ran out of history info. */
904+ NO_HISTORY
903905 };
904906
905907 /* This structure contains what used to be local variables in
@@ -1517,6 +1519,12 @@ handle_inferior_event (struct execution_control_state *ecs)
15171519 stop_signal = ecs->ws.value.sig;
15181520 break;
15191521
1522+ case TARGET_WAITKIND_NO_HISTORY:
1523+ /* Reverse execution: target ran out of history info. */
1524+ print_stop_reason (NO_HISTORY, 0);
1525+ stop_stepping (ecs);
1526+ return;
1527+
15201528 /* We had an event in the inferior, but we are not interested
15211529 in handling it at this level. The lower layers have already
15221530 done what needs to be done, if anything.
@@ -2182,6 +2190,17 @@ process_event_stop_test:
21822190 keep_going (ecs);
21832191 return;
21842192 }
2193+ if (stop_pc == ecs->stop_func_start &&
2194+ target_get_execution_direction () == EXEC_REVERSE)
2195+ {
2196+ /* We are stepping over a function call in reverse, and
2197+ just hit the step-resume breakpoint at the start
2198+ address of the function. Go back to single-stepping,
2199+ which should take us back to the function call. */
2200+ ecs->another_trap = 1;
2201+ keep_going (ecs);
2202+ return;
2203+ }
21852204 break;
21862205
21872206 case BPSTAT_WHAT_THROUGH_SIGTRAMP:
@@ -2365,7 +2384,22 @@ process_event_stop_test:
23652384 fprintf_unfiltered (gdb_stdlog, "infrun: stepping inside range [0x%s-0x%s]\n",
23662385 paddr_nz (step_range_start),
23672386 paddr_nz (step_range_end));
2368- keep_going (ecs);
2387+
2388+ /* When stepping backward, stop at beginning of line range
2389+ (unles it's the function entry point, in which case
2390+ keep going back to the call point). */
2391+ if (stop_pc == step_range_start &&
2392+ stop_pc != ecs->stop_func_start &&
2393+ target_get_execution_direction () == EXEC_REVERSE)
2394+ {
2395+ stop_step = 1;
2396+ print_stop_reason (END_STEPPING_RANGE, 0);
2397+ stop_stepping (ecs);
2398+ }
2399+ else
2400+ {
2401+ keep_going (ecs);
2402+ }
23692403 return;
23702404 }
23712405
@@ -2454,10 +2488,31 @@ process_event_stop_test:
24542488
24552489 if (step_over_calls == STEP_OVER_ALL)
24562490 {
2457- /* We're doing a "next", set a breakpoint at callee's return
2458- address (the address at which the caller will
2459- resume). */
2460- insert_step_resume_breakpoint_at_caller (get_current_frame ());
2491+ /* We're doing a "next".
2492+
2493+ Normal (forward) execution: set a breakpoint at the
2494+ callee's return address (the address at which the caller
2495+ will resume).
2496+
2497+ Reverse (backward) execution. set the step-resume
2498+ breakpoint at the start of the function that we just
2499+ stepped into (backwards), and continue to there. When we
2500+ get there, we'll need to single-step back to the
2501+ caller. */
2502+
2503+ if (target_get_execution_direction () == EXEC_REVERSE)
2504+ {
2505+ /* FIXME: I'm not sure if we've handled the frame for
2506+ recursion. */
2507+
2508+ struct symtab_and_line sr_sal;
2509+ init_sal (&sr_sal);
2510+ sr_sal.pc = ecs->stop_func_start;
2511+ insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
2512+ }
2513+ else
2514+ insert_step_resume_breakpoint_at_caller (get_current_frame ());
2515+
24612516 keep_going (ecs);
24622517 return;
24632518 }
@@ -2518,9 +2573,22 @@ process_event_stop_test:
25182573 return;
25192574 }
25202575
2521- /* Set a breakpoint at callee's return address (the address at
2522- which the caller will resume). */
2523- insert_step_resume_breakpoint_at_caller (get_current_frame ());
2576+ if (target_get_execution_direction () == EXEC_REVERSE)
2577+ {
2578+ /* Set a breakpoint at callee's start address.
2579+ From there we can step once and be back in the caller. */
2580+ /* FIXME: I'm not sure we've handled the frame for recursion. */
2581+ struct symtab_and_line sr_sal;
2582+ init_sal (&sr_sal);
2583+ sr_sal.pc = ecs->stop_func_start;
2584+ insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
2585+ }
2586+ else
2587+ {
2588+ /* Set a breakpoint at callee's return address (the address
2589+ at which the caller will resume). */
2590+ insert_step_resume_breakpoint_at_caller (get_current_frame ());
2591+ }
25242592 keep_going (ecs);
25252593 return;
25262594 }
@@ -2649,17 +2717,38 @@ process_event_stop_test:
26492717
26502718 if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end)
26512719 {
2652- /* If this is the last line of the function, don't keep stepping
2653- (it would probably step us out of the function).
2654- This is particularly necessary for a one-line function,
2655- in which after skipping the prologue we better stop even though
2656- we will be in mid-line. */
2657- if (debug_infrun)
2658- fprintf_unfiltered (gdb_stdlog, "infrun: stepped to a different function\n");
2659- stop_step = 1;
2660- print_stop_reason (END_STEPPING_RANGE, 0);
2661- stop_stepping (ecs);
2662- return;
2720+ if (target_get_execution_direction () != EXEC_REVERSE)
2721+ {
2722+ /* If this is the last line of the function, don't keep
2723+ stepping (it would probably step us out of the function).
2724+ This is particularly necessary for a one-line function,
2725+ in which after skipping the prologue we better stop even
2726+ though we will be in mid-line. */
2727+ if (debug_infrun)
2728+ fprintf_unfiltered (gdb_stdlog,
2729+ "infrun: stepped to a different function\n");
2730+ stop_step = 1;
2731+ print_stop_reason (END_STEPPING_RANGE, 0);
2732+ stop_stepping (ecs);
2733+ return;
2734+ }
2735+ else
2736+ {
2737+ /* If we stepped backward into the last line of a function,
2738+ then we've presumably stepped thru a return. We want to
2739+ keep stepping backward until we reach the beginning of
2740+ the new line. */
2741+ step_range_start = ecs->sal.pc;
2742+ step_range_end = ecs->sal.end;
2743+ step_frame_id = get_frame_id (get_current_frame ());
2744+ ecs->current_line = ecs->sal.line;
2745+ ecs->current_symtab = ecs->sal.symtab;
2746+ /* Adjust for prologue, in case of a one-line function. */
2747+ if (in_prologue (step_range_start, ecs->stop_func_start))
2748+ step_range_start = SKIP_PROLOGUE (step_range_start);
2749+ keep_going (ecs);
2750+ return;
2751+ }
26632752 }
26642753 step_range_start = ecs->sal.pc;
26652754 step_range_end = ecs->sal.end;
@@ -2722,6 +2811,28 @@ step_into_function (struct execution_control_state *ecs)
27222811 if (s && s->language != language_asm)
27232812 ecs->stop_func_start = SKIP_PROLOGUE (ecs->stop_func_start);
27242813
2814+ if (target_get_execution_direction () == EXEC_REVERSE)
2815+ {
2816+ ecs->sal = find_pc_line (stop_pc, 0);
2817+
2818+ /* OK, we're just gonna keep stepping here. */
2819+ if (ecs->sal.pc == stop_pc)
2820+ {
2821+ /* We're there already. Just stop stepping now. */
2822+ stop_step = 1;
2823+ print_stop_reason (END_STEPPING_RANGE, 0);
2824+ stop_stepping (ecs);
2825+ return;
2826+ }
2827+ /* Else just reset the step range and keep going.
2828+ No step-resume breakpoint, they don't work for
2829+ epilogues, which can have multiple entry paths. */
2830+ step_range_start = ecs->sal.pc;
2831+ step_range_end = ecs->sal.end;
2832+ keep_going (ecs);
2833+ return;
2834+ }
2835+ /* else... */
27252836 ecs->sal = find_pc_line (ecs->stop_func_start, 0);
27262837 /* Use the step_resume_break to step until the end of the prologue,
27272838 even if that involves jumps (as it seems to on the vax under
@@ -3042,6 +3153,10 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
30423153 annotate_signal_string_end ();
30433154 ui_out_text (uiout, ".\n");
30443155 break;
3156+ case NO_HISTORY:
3157+ /* Reverse execution: target ran out of history info. */
3158+ ui_out_text (uiout, "\nNo more reverse-execution history.\n");
3159+ break;
30453160 default:
30463161 internal_error (__FILE__, __LINE__,
30473162 _("print_stop_reason: unrecognized enum value"));
@@ -3675,6 +3790,7 @@ save_inferior_status (int restore_stack_info)
36753790 inf_status->registers = regcache_dup (current_regcache);
36763791
36773792 inf_status->selected_frame_id = get_frame_id (get_selected_frame (NULL));
3793+ current_target.to_doing_call (1);
36783794 return inf_status;
36793795 }
36803796
@@ -3723,6 +3839,8 @@ restore_inferior_status (struct inferior_status *inf_status)
37233839 regcache_xfree (stop_registers);
37243840 stop_registers = inf_status->stop_registers;
37253841
3842+ current_target.to_doing_call (0);
3843+
37263844 /* The inferior can be gone if the user types "print exit(0)"
37273845 (and perhaps other times). */
37283846 if (target_has_execution)
@@ -3770,6 +3888,7 @@ make_cleanup_restore_inferior_status (struct inferior_status *inf_status)
37703888 void
37713889 discard_inferior_status (struct inferior_status *inf_status)
37723890 {
3891+ warning (_("Discarding inferior status"));
37733892 /* See save_inferior_status for info on stop_bpstat. */
37743893 bpstat_clear (&inf_status->stop_bpstat);
37753894 regcache_xfree (inf_status->registers);
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2851,7 +2851,15 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
28512851 set_thread (pid, 0); /* Run this thread. */
28522852
28532853 buf = rs->buf;
2854- if (siggnal != TARGET_SIGNAL_0)
2854+ if (target_get_execution_direction () == EXEC_REVERSE)
2855+ {
2856+ /* We don't pass signals to the target in reverse exec mode. */
2857+ if (info_verbose && siggnal != TARGET_SIGNAL_0)
2858+ warning (" - Can't pass signal %d to target in reverse: ignored.\n",
2859+ siggnal);
2860+ strcpy (buf, step ? "bs" : "bc");
2861+ }
2862+ else if (siggnal != TARGET_SIGNAL_0)
28552863 {
28562864 buf[0] = step ? 'S' : 'C';
28572865 buf[1] = tohex (((int) siggnal >> 4) & 0xf);
@@ -3125,6 +3133,11 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
31253133 switch (buf[0])
31263134 {
31273135 case 'E': /* Error of some sort. */
3136+ if (buf[1] == '0' && buf[2] == '6')
3137+ {
3138+ status->kind = TARGET_WAITKIND_NO_HISTORY;
3139+ goto got_status;
3140+ }
31283141 warning (_("Remote failure reply: %s"), buf);
31293142 continue;
31303143 case 'F': /* File-I/O request. */
@@ -6110,6 +6123,47 @@ remote_read_description (struct target_ops *target)
61106123 return NULL;
61116124 }
61126125
6126+/* Reverse execution.
6127+ FIXME: set up as a capability. */
6128+static enum exec_direction_kind remote_execdir = EXEC_FORWARD;
6129+
6130+static enum exec_direction_kind remote_get_execdir (void)
6131+{
6132+ if (remote_debug && info_verbose)
6133+ printf_filtered ("remote execdir is %s\n",
6134+ remote_execdir == EXEC_FORWARD ? "forward" :
6135+ remote_execdir == EXEC_REVERSE ? "reverse" :
6136+ "unknown");
6137+ return remote_execdir;
6138+}
6139+
6140+static int remote_set_execdir (enum exec_direction_kind dir)
6141+{
6142+ if (remote_debug && info_verbose)
6143+ printf_filtered ("Set remote execdir: %s\n",
6144+ dir == EXEC_FORWARD ? "forward" :
6145+ dir == EXEC_REVERSE ? "reverse" :
6146+ "bad direction");
6147+
6148+ /* FIXME: check target for capability. */
6149+ if (dir == EXEC_FORWARD || dir == EXEC_REVERSE)
6150+ return (remote_execdir = dir);
6151+ else
6152+ return EXEC_ERROR;
6153+}
6154+
6155+static void
6156+remote_doing_call (int starting)
6157+{
6158+ struct remote_state *rs = get_remote_state ();
6159+
6160+ if (starting)
6161+ strcpy (rs->buf, "QStartCall");
6162+ else
6163+ strcpy (rs->buf, "QEndCall");
6164+ remote_send (&rs->buf, &rs->buf_size);
6165+}
6166+
61136167 static void
61146168 init_remote_ops (void)
61156169 {
@@ -6157,11 +6211,14 @@ Specify the serial device it is connected to\n\
61576211 remote_ops.to_has_registers = 1;
61586212 remote_ops.to_has_execution = 1;
61596213 remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
6214+ remote_ops.to_get_execdir = remote_get_execdir;
6215+ remote_ops.to_set_execdir = remote_set_execdir;
61606216 remote_ops.to_magic = OPS_MAGIC;
61616217 remote_ops.to_memory_map = remote_memory_map;
61626218 remote_ops.to_flash_erase = remote_flash_erase;
61636219 remote_ops.to_flash_done = remote_flash_done;
61646220 remote_ops.to_read_description = remote_read_description;
6221+ remote_ops.to_doing_call = remote_doing_call;
61656222 }
61666223
61676224 /* Set up the extended remote vector by making a copy of the standard
@@ -6294,7 +6351,8 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
62946351 remote_async_ops.to_memory_map = remote_memory_map;
62956352 remote_async_ops.to_flash_erase = remote_flash_erase;
62966353 remote_async_ops.to_flash_done = remote_flash_done;
6297- remote_ops.to_read_description = remote_read_description;
6354+ remote_async_ops.to_read_description = remote_read_description;
6355+ remote_async_ops.to_doing_call = remote_doing_call;
62986356 }
62996357
63006358 /* Set up the async extended remote vector by making a copy of the standard
--- /dev/null
+++ b/gdb/reverse.c
@@ -0,0 +1,197 @@
1+/* Reverse execution and reverse debugging.
2+
3+ Copyright (C) 2006 Free Software Foundation, Inc.
4+
5+ This file is part of GDB.
6+
7+ This program is free software; you can redistribute it and/or modify
8+ it under the terms of the GNU General Public License as published by
9+ the Free Software Foundation; either version 2 of the License, or
10+ (at your option) any later version.
11+
12+ This program is distributed in the hope that it will be useful,
13+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ GNU General Public License for more details.
16+
17+ You should have received a copy of the GNU General Public License
18+ along with this program; if not, write to the Free Software
19+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
20+ Boston, MA 02110-1301, USA. */
21+
22+#include "defs.h"
23+#include "gdb_string.h"
24+#include "target.h"
25+#include "top.h"
26+#include "cli/cli-cmds.h"
27+#include "cli/cli-decode.h"
28+
29+/* User interface for reverse debugging:
30+ Set exec-direction / show exec-direction commands
31+ (returns error unles target implements to_set_execdir method). */
32+
33+static const char exec_forward[] = "forward";
34+static const char exec_reverse[] = "reverse";
35+static const char *exec_direction = exec_forward;
36+static const char *exec_direction_names[] = {
37+ exec_forward,
38+ exec_reverse,
39+ NULL
40+};
41+
42+static void
43+set_exec_direction_func (char *args, int from_tty,
44+ struct cmd_list_element *cmd)
45+{
46+ if (target_get_execution_direction () != EXEC_ERROR)
47+ {
48+ enum exec_direction_kind dir = EXEC_ERROR;
49+
50+ if (!strcmp (exec_direction, exec_forward))
51+ dir = EXEC_FORWARD;
52+ else if (!strcmp (exec_direction, exec_reverse))
53+ dir = EXEC_REVERSE;
54+
55+ if (target_set_execution_direction (dir) != EXEC_ERROR)
56+ return;
57+ }
58+ error (_("Target `%s' does not support execution-direction."),
59+ target_shortname);
60+}
61+
62+static void
63+show_exec_direction_func (struct ui_file *out, int from_tty,
64+ struct cmd_list_element *cmd, const char *value)
65+{
66+ enum exec_direction_kind dir = target_get_execution_direction ();
67+
68+ switch (dir) {
69+ case EXEC_FORWARD:
70+ fprintf_filtered (out, "Forward.\n");
71+ break;
72+ case EXEC_REVERSE:
73+ fprintf_filtered (out, "Reverse.\n");
74+ break;
75+ case EXEC_ERROR:
76+ default:
77+ error (_("Target `%s' does not support execution-direction."),
78+ target_shortname);
79+ break;
80+ }
81+}
82+
83+/* User interface:
84+ reverse-step, reverse-next etc.
85+ (returns error unles target implements to_set_execdir method). */
86+
87+static void execdir_default (void *notused)
88+{
89+ /* Return execution direction to default state. */
90+ target_set_execution_direction (EXEC_FORWARD);
91+}
92+
93+static void
94+exec_reverse_once (char *cmd, char *args, int from_tty)
95+{
96+ /* String buffer for command consing. */
97+ char reverse_command[512];
98+ enum exec_direction_kind dir = target_get_execution_direction ();
99+
100+ if (dir == EXEC_ERROR)
101+ error (_("Target %s does not support this command."), target_shortname);
102+
103+ if (dir == EXEC_REVERSE)
104+ error (_("Already in reverse mode. Use '%s' or 'set exec-dir forward'."),
105+ cmd);
106+
107+ if (target_set_execution_direction (EXEC_REVERSE) == EXEC_ERROR)
108+ error (_("Target %s does not support this command."), target_shortname);
109+
110+ make_cleanup (execdir_default, NULL);
111+ sprintf (reverse_command, "%s %s", cmd, args ? args : "");
112+ execute_command (reverse_command, from_tty);
113+}
114+
115+static void
116+reverse_step (char *args, int from_tty)
117+{
118+ exec_reverse_once ("step", args, from_tty);
119+}
120+
121+static void
122+reverse_stepi (char *args, int from_tty)
123+{
124+ exec_reverse_once ("stepi", args, from_tty);
125+}
126+
127+static void
128+reverse_next (char *args, int from_tty)
129+{
130+ exec_reverse_once ("next", args, from_tty);
131+}
132+
133+static void
134+reverse_nexti (char *args, int from_tty)
135+{
136+ exec_reverse_once ("nexti", args, from_tty);
137+}
138+
139+static void
140+reverse_continue (char *args, int from_tty)
141+{
142+ exec_reverse_once ("continue", args, from_tty);
143+}
144+
145+static void
146+reverse_finish (char *args, int from_tty)
147+{
148+ exec_reverse_once ("finish", args, from_tty);
149+}
150+
151+void
152+_initialize_reverse (void)
153+{
154+ add_setshow_enum_cmd ("exec-direction", class_run, exec_direction_names,
155+ &exec_direction, "Set direction of execution.\n\
156+Options are 'forward' or 'reverse'.",
157+ "Show direction of execution (forward/reverse).",
158+ "Tells gdb whether to execute forward or backward.",
159+ set_exec_direction_func, show_exec_direction_func,
160+ &setlist, &showlist);
161+
162+ add_com ("reverse-step", class_run, reverse_step, _("\
163+Step program backward until it reaches the beginning of another source line.\n\
164+Argument N means do this N times (or till program stops for another reason).")
165+ );
166+ add_com_alias ("rs", "reverse-step", class_alias, 1);
167+
168+ add_com ("reverse-next", class_run, reverse_next, _("\
169+Step program backward, proceeding through subroutine calls.\n\
170+Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
171+when they do, the call is treated as one instruction.\n\
172+Argument N means do this N times (or till program stops for another reason).")
173+ );
174+ add_com_alias ("rn", "reverse-next", class_alias, 1);
175+
176+ add_com ("reverse-stepi", class_run, reverse_stepi, _("\
177+Step backward exactly one instruction.\n\
178+Argument N means do this N times (or till program stops for another reason).")
179+ );
180+ add_com_alias ("rsi", "reverse-stepi", class_alias, 0);
181+
182+ add_com ("reverse-nexti", class_run, reverse_nexti, _("\
183+Step backward one instruction, but proceed through called subroutines.\n\
184+Argument N means do this N times (or till program stops for another reason).")
185+ );
186+ add_com_alias ("rni", "reverse-nexti", class_alias, 0);
187+
188+ add_com ("reverse-continue", class_run, reverse_continue, _("\
189+Continue program being debugged, running in reverse.\n\
190+If proceeding from breakpoint, a number N may be used as an argument,\n\
191+which means to set the ignore count of that breakpoint to N - 1 (so that\n\
192+the breakpoint won't break until the Nth time it is reached)."));
193+ add_com_alias ("rc", "reverse-continue", class_alias, 0);
194+
195+ add_com ("reverse-finish", class_run, reverse_finish, _("\
196+Execute backward until just before selected stack frame is called."));
197+}
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -466,6 +466,9 @@ update_current_target (void)
466466 INHERIT (to_find_memory_regions, t);
467467 INHERIT (to_make_corefile_notes, t);
468468 INHERIT (to_get_thread_local_address, t);
469+ INHERIT (to_get_execdir, t);
470+ INHERIT (to_set_execdir, t);
471+ INHERIT (to_doing_call, t);
469472 /* Do not inherit to_read_description. */
470473 INHERIT (to_magic, t);
471474 /* Do not inherit to_memory_map. */
@@ -644,6 +647,9 @@ update_current_target (void)
644647 de_fault (to_async,
645648 (void (*) (void (*) (enum inferior_event_type, void*), void*))
646649 tcomplain);
650+ de_fault (to_doing_call,
651+ (void (*) (int))
652+ target_ignore);
647653 current_target.to_read_description = NULL;
648654 #undef de_fault
649655
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -131,7 +131,11 @@ enum target_waitkind
131131 inferior, rather than being stuck in the remote_async_wait()
132132 function. This way the event loop is responsive to other events,
133133 like for instance the user typing. */
134- TARGET_WAITKIND_IGNORE
134+ TARGET_WAITKIND_IGNORE,
135+
136+ /* The target has run out of history information,
137+ and cannot run backward any further. */
138+ TARGET_WAITKIND_NO_HISTORY
135139 };
136140
137141 struct target_waitstatus
@@ -150,6 +154,14 @@ struct target_waitstatus
150154 value;
151155 };
152156
157+/* Reverse execution. */
158+enum exec_direction_kind
159+ {
160+ EXEC_FORWARD,
161+ EXEC_REVERSE,
162+ EXEC_ERROR
163+ };
164+
153165 /* Possible types of events that the inferior handler will have to
154166 deal with. */
155167 enum inferior_event_type
@@ -500,6 +512,13 @@ struct target_ops
500512 was available. */
501513 const struct target_desc *(*to_read_description) (struct target_ops *ops);
502514
515+ /* Set execution direction (forward/reverse). */
516+ int (*to_set_execdir) (enum exec_direction_kind);
517+ /* Get execution direction (forward/reverse). */
518+ enum exec_direction_kind (*to_get_execdir) (void);
519+
520+ void (*to_doing_call) (int starting);
521+
503522 int to_magic;
504523 /* Need sub-structure for target machine related rather than comm related?
505524 */
@@ -1194,6 +1213,18 @@ extern int target_stopped_data_address_p (struct target_ops *);
11941213 #define target_stopped_data_address_p(CURRENT_TARGET) (1)
11951214 #endif
11961215
1216+/* Forward/reverse execution direction.
1217+ These will only be implemented by a target that supports reverse execution.
1218+*/
1219+#define target_get_execution_direction() \
1220+ (current_target.to_get_execdir ? \
1221+ (*current_target.to_get_execdir) () : EXEC_ERROR)
1222+
1223+#define target_set_execution_direction(DIR) \
1224+ (current_target.to_set_execdir ? \
1225+ (*current_target.to_set_execdir) (DIR) : EXEC_ERROR)
1226+
1227+
11971228 extern const struct target_desc *target_read_description (struct target_ops *);
11981229
11991230 /* Routines for maintenance of the target structures...