* Re: GDB MI Reverse Commands added [1 of 3]
2009-08-26 14:38 GDB MI Reverse Commands added [1 of 3] Jakob Engblom
@ 2009-08-27 1:13 ` Michael Snyder
2009-08-31 13:26 ` Jakob Engblom
2009-08-27 2:06 ` Michael Snyder
2009-08-27 3:11 ` Hui Zhu
2 siblings, 1 reply; 27+ messages in thread
From: Michael Snyder @ 2009-08-27 1:13 UTC (permalink / raw)
To: Jakob Engblom; +Cc: gdb-patches
Jakob Engblom wrote:
> Here are the patches adding the MI commands for reverse execution to gdb.
>
> Changelog entry: "Added reverse debugging support to gdb MI"
Jakob, thanks for this contribution. We need an actual
contributor's name for the changelog! Here's the format:
2009-06-17 Ulrich Weigand <uweigand@de.ibm.com>
* mi/mi-main.c (mi_cmd_data_list_register_names): Use selected
frame architecture instead of current_gdbarch.
(mi_cmd_data_list_changed_registers): Likewise.
(mi_cmd_data_list_register_values): Likewise. Pass selected
frame to get_register.
By the way, some of these changes don't actually seem to change
anything. I guess we can apply them as is, but could you just
check to see if something went wrong or got left out?
I'm looking at for instance these...
> *************** mi_cmd_exec_interrupt (char *command, ch
> *** 252,258 ****
> {
> if (!any_running ())
> error ("Inferior not running.");
> !
> interrupt_target_1 (1);
> }
> else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
> --- 307,313 ----
> {
> if (!any_running ())
> error ("Inferior not running.");
> !
> interrupt_target_1 (1);
> }
> else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
> *************** void
> *** 349,355 ****
> mi_cmd_thread_info (char *command, char **argv, int argc)
> {
> int thread = -1;
> !
> if (argc != 0 && argc != 1)
> error ("Invalid MI command");
>
> --- 404,410 ----
> mi_cmd_thread_info (char *command, char **argv, int argc)
> {
> int thread = -1;
> !
> if (argc != 0 && argc != 1)
> error ("Invalid MI command");
>
> *************** print_one_inferior (struct inferior *inf
> *** 367,373 ****
> ui_out_field_fmt (uiout, "id", "%d", inferior->pid);
> ui_out_field_string (uiout, "type", "process");
> ui_out_field_int (uiout, "pid", inferior->pid);
> !
> do_cleanups (back_to);
> return 0;
> }
> --- 422,428 ----
> ui_out_field_fmt (uiout, "id", "%d", inferior->pid);
> ui_out_field_string (uiout, "type", "process");
> ui_out_field_int (uiout, "pid", inferior->pid);
> !
> do_cleanups (back_to);
> return 0;
> }
> *************** mi_cmd_list_thread_groups (char *command
> *** 433,446 ****
> int pid = atoi (id);
> if (!in_inferior_list (pid))
> error ("Invalid thread group id '%s'", id);
> ! print_thread_info (uiout, -1, pid);
> }
> else
> {
> make_cleanup_ui_out_list_begin_end (uiout, "groups");
> iterate_over_inferiors (print_one_inferior, NULL);
> }
> !
> do_cleanups (back_to);
> }
>
> --- 488,501 ----
> int pid = atoi (id);
> if (!in_inferior_list (pid))
> error ("Invalid thread group id '%s'", id);
> ! print_thread_info (uiout, -1, pid);
> }
> else
> {
> make_cleanup_ui_out_list_begin_end (uiout, "groups");
> iterate_over_inferiors (print_one_inferior, NULL);
> }
> !
> do_cleanups (back_to);
> }
>
> *************** get_register (struct frame_info *frame,
> *** 713,719 ****
> }
>
> /* Write given values into registers. The registers and values are
> ! given as pairs. The corresponding MI command is
> -data-write-register-values <format> [<regnum1> <value1>...<regnumN>
> <valueN>]*/
> void
> mi_cmd_data_write_register_values (char *command, char **argv, int argc)
> --- 768,774 ----
> }
>
> /* Write given values into registers. The registers and values are
> ! given as pairs. The corresponding MI command is
> -data-write-register-values <format> [<regnum1> <value1>...<regnumN>
> <valueN>]*/
> void
> mi_cmd_data_write_register_values (char *command, char **argv, int argc)
> *************** mi_cmd_data_evaluate_expression (char *c
> *** 810,816 ****
> /* DATA-MEMORY-READ:
>
> ADDR: start address of data to be dumped.
> ! WORD-FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
> NR_ROW: Number of rows.
> --- 865,871 ----
> /* DATA-MEMORY-READ:
>
> ADDR: start address of data to be dumped.
> ! WORD-FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
> NR_ROW: Number of rows.
> *************** mi_cmd_data_evaluate_expression (char *c
> *** 823,829 ****
>
> {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
>
> ! Returns:
> The number of bytes read is SIZE*ROW*COL. */
>
> void
> --- 878,884 ----
>
> {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
>
> ! Returns:
> The number of bytes read is SIZE*ROW*COL. */
>
> void
> *************** mi_cmd_data_read_memory (char *command,
> *** 1019,1025 ****
> ADDR: start address of the row in the memory grid where the memory
> cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
> the location to write to.
> ! FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
> VALUE: value to be written into the memory address.
> --- 1074,1080 ----
> ADDR: start address of the row in the memory grid where the memory
> cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
> the location to write to.
> ! FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
> VALUE: value to be written into the memory address.
> *************** mi_cmd_enable_timings (char *command, ch
> *** 1112,1118 ****
> }
> else
> goto usage_error;
> !
> return;
>
> usage_error:
> --- 1167,1173 ----
> }
> else
> goto usage_error;
> !
> return;
>
> usage_error:
> *************** mi_cmd_list_features (char *command, cha
> *** 1125,1140 ****
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> ui_out_field_string (uiout, NULL, "frozen-varobjs");
> ui_out_field_string (uiout, NULL, "pending-breakpoints");
> ui_out_field_string (uiout, NULL, "thread-info");
> !
> #if HAVE_PYTHON
> ui_out_field_string (uiout, NULL, "python");
> #endif
> !
> do_cleanups (cleanup);
> return;
> }
> --- 1180,1195 ----
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> ui_out_field_string (uiout, NULL, "frozen-varobjs");
> ui_out_field_string (uiout, NULL, "pending-breakpoints");
> ui_out_field_string (uiout, NULL, "thread-info");
> !
> #if HAVE_PYTHON
> ui_out_field_string (uiout, NULL, "python");
> #endif
> !
> do_cleanups (cleanup);
> return;
> }
> *************** mi_cmd_list_target_features (char *comma
> *** 1148,1158 ****
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> if (target_can_async_p ())
> ui_out_field_string (uiout, NULL, "async");
> !
> do_cleanups (cleanup);
> return;
> }
> --- 1203,1213 ----
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> if (target_can_async_p ())
> ui_out_field_string (uiout, NULL, "async");
> !
> do_cleanups (cleanup);
> return;
> }
... and so on...
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: GDB MI Reverse Commands added [1 of 3]
2009-08-27 1:13 ` Michael Snyder
@ 2009-08-31 13:26 ` Jakob Engblom
2009-08-31 19:56 ` Michael Snyder
0 siblings, 1 reply; 27+ messages in thread
From: Jakob Engblom @ 2009-08-31 13:26 UTC (permalink / raw)
To: 'Michael Snyder'; +Cc: gdb-patches
> 2009-06-17 Ulrich Weigand <uweigand@de.ibm.com>
>
> * mi/mi-main.c (mi_cmd_data_list_register_names): Use selected
> frame architecture instead of current_gdbarch.
> (mi_cmd_data_list_changed_registers): Likewise.
> (mi_cmd_data_list_register_values): Likewise. Pass selected
> frame to get_register.
Here is the changelog entry for the actual commands:
mi/
* mi-main.c: Added the --reverse flag to the following MI commands:
exec-continue, exec-finish, exec-next, exec-step, exec-next-instruction,
exec-step-instruction. This is to support reverse execution over the MI
interface to gdb. (th@virtutech.com).
/jakob
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: GDB MI Reverse Commands added [1 of 3]
2009-08-31 13:26 ` Jakob Engblom
@ 2009-08-31 19:56 ` Michael Snyder
2009-09-01 6:37 ` Jakob Engblom
0 siblings, 1 reply; 27+ messages in thread
From: Michael Snyder @ 2009-08-31 19:56 UTC (permalink / raw)
To: Jakob Engblom; +Cc: gdb-patches
Jakob Engblom wrote:
>> 2009-06-17 Ulrich Weigand <uweigand@de.ibm.com>
>>
>> * mi/mi-main.c (mi_cmd_data_list_register_names): Use selected
>> frame architecture instead of current_gdbarch.
>> (mi_cmd_data_list_changed_registers): Likewise.
>> (mi_cmd_data_list_register_values): Likewise. Pass selected
>> frame to get_register.
>
> Here is the changelog entry for the actual commands:
>
> mi/
> * mi-main.c: Added the --reverse flag to the following MI commands:
> exec-continue, exec-finish, exec-next, exec-step, exec-next-instruction,
> exec-step-instruction. This is to support reverse execution over the MI
> interface to gdb. (th@virtutech.com).
Thanks Jakob. Still looking for an author's name.
Something of this form (assuming you were the author):
2009-08-31 Jakob Engblom <jakob@virtutech.com>
Have we asked you about copyright assignment yet?
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: GDB MI Reverse Commands added [1 of 3]
2009-08-31 19:56 ` Michael Snyder
@ 2009-09-01 6:37 ` Jakob Engblom
2009-09-01 19:08 ` Michael Snyder
0 siblings, 1 reply; 27+ messages in thread
From: Jakob Engblom @ 2009-09-01 6:37 UTC (permalink / raw)
To: 'Michael Snyder'; +Cc: gdb-patches
> >> 2009-06-17 Ulrich Weigand <uweigand@de.ibm.com>
> >>
> >> * mi/mi-main.c (mi_cmd_data_list_register_names): Use selected
> >> frame architecture instead of current_gdbarch.
> >> (mi_cmd_data_list_changed_registers): Likewise.
> >> (mi_cmd_data_list_register_values): Likewise. Pass selected
> >> frame to get_register.
> >
> > Here is the changelog entry for the actual commands:
> >
> > mi/
> > * mi-main.c: Added the --reverse flag to the following MI commands:
> > exec-continue, exec-finish, exec-next, exec-step, exec-next-instruction,
> > exec-step-instruction. This is to support reverse execution over the MI
> > interface to gdb. (th@virtutech.com).
>
> Thanks Jakob. Still looking for an author's name.
> Something of this form (assuming you were the author):
>
> 2009-08-31 Jakob Engblom <jakob@virtutech.com>
Did not see that... I thought it was just the email being asked for.
Anyhow, in the case of patch 1 of 3, it would be:
2009-08-31 Tomas Holmberg >th@virtutech.com>
> Have we asked you about copyright assignment yet?
No.
/jakob
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: GDB MI Reverse Commands added [1 of 3]
2009-09-01 6:37 ` Jakob Engblom
@ 2009-09-01 19:08 ` Michael Snyder
0 siblings, 0 replies; 27+ messages in thread
From: Michael Snyder @ 2009-09-01 19:08 UTC (permalink / raw)
To: Jakob Engblom; +Cc: gdb-patches, tromey
Jakob Engblom wrote:
> Did not see that... I thought it was just the email being asked for.
>
> Anyhow, in the case of patch 1 of 3, it would be:
>
> 2009-08-31 Tomas Holmberg >th@virtutech.com>
Thanks.
>> Have we asked you about copyright assignment yet?
>
> No.
Oh. Well in that case, we need a copyright assignment.
Tom?
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: GDB MI Reverse Commands added [1 of 3]
2009-08-26 14:38 GDB MI Reverse Commands added [1 of 3] Jakob Engblom
2009-08-27 1:13 ` Michael Snyder
@ 2009-08-27 2:06 ` Michael Snyder
2009-08-31 13:15 ` Jakob Engblom
` (3 more replies)
2009-08-27 3:11 ` Hui Zhu
2 siblings, 4 replies; 27+ messages in thread
From: Michael Snyder @ 2009-08-27 2:06 UTC (permalink / raw)
To: Jakob Engblom; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 304 bytes --]
Jakob Engblom wrote:
> Here are the patches adding the MI commands for reverse execution to gdb.
>
> Changelog entry: "Added reverse debugging support to gdb MI"
Group, this patch seemed to have gotten a little munged in email.
I've taken the liberty of re-diffing it, to restore white space context.
[-- Attachment #2: msnyder.txt --]
[-- Type: text/plain, Size: 11983 bytes --]
Index: mi-main.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
retrieving revision 1.156
diff -u -p -r1.156 mi-main.c
--- mi-main.c 2 Jul 2009 17:25:59 -0000 1.156
+++ mi-main.c 27 Aug 2009 01:45:23 -0000
@@ -88,8 +88,8 @@ static void mi_cmd_execute (struct mi_pa
static void mi_execute_cli_command (const char *cmd, int args_p,
const char *args);
-static void mi_execute_async_cli_command (char *cli_command,
- char **argv, int argc);
+static void mi_execute_async_cli_command (char *cli_command,
+ char **argv, int argc);
static int register_changed_p (int regnum, struct regcache *,
struct regcache *);
static void get_register (struct frame_info *, int regnum, int format);
@@ -119,35 +119,50 @@ void
mi_cmd_exec_next (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("next", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("next", argv, argc);
}
void
mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("nexti", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("nexti", argv, argc);
}
void
mi_cmd_exec_step (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("step", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("step", argv, argc);
}
void
mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("stepi", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("stepi", argv, argc);
}
void
mi_cmd_exec_finish (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("finish", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("finish", argv, argc);
}
void
@@ -175,7 +190,7 @@ mi_cmd_exec_jump (char *args, char **arg
/* FIXME: Should call a libgdb function, not a cli wrapper. */
return mi_execute_async_cli_command ("jump", argv, argc);
}
-
+
static int
proceed_thread_callback (struct thread_info *thread, void *arg)
{
@@ -193,8 +208,8 @@ proceed_thread_callback (struct thread_i
return 0;
}
-void
-mi_cmd_exec_continue (char *command, char **argv, int argc)
+static void
+exec_continue (char **argv, int argc)
{
if (argc == 0)
continue_1 (0);
@@ -212,10 +227,50 @@ mi_cmd_exec_continue (char *command, cha
old_chain = make_cleanup_restore_current_thread ();
iterate_over_threads (proceed_thread_callback, &pid);
- do_cleanups (old_chain);
+ do_cleanups (old_chain);
}
else
- error ("Usage: -exec-continue [--all|--thread-group id]");
+ error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
+}
+
+/* continue in reverse direction:
+ XXX: code duplicated from reverse.c */
+
+static void
+exec_direction_default (void *notused)
+{
+ /* Return execution direction to default state. */
+ execution_direction = EXEC_FORWARD;
+}
+
+static void
+exec_reverse_continue (char **argv, int argc)
+{
+ 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."));
+
+ if (!target_can_execute_reverse)
+ error (_("Target %s does not support this command."), target_shortname);
+
+ old_chain = make_cleanup (exec_direction_default, NULL);
+ execution_direction = EXEC_REVERSE;
+ exec_continue (argv, argc);
+ do_cleanups (old_chain);
+}
+
+void
+mi_cmd_exec_continue (char *command, char **argv, int argc)
+{
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ exec_reverse_continue (argv + 1, argc - 1);
+ else
+ exec_continue (argv, argc);
}
static int
@@ -252,7 +307,7 @@ mi_cmd_exec_interrupt (char *command, ch
{
if (!any_running ())
error ("Inferior not running.");
-
+
interrupt_target_1 (1);
}
else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
@@ -349,7 +404,7 @@ void
mi_cmd_thread_info (char *command, char **argv, int argc)
{
int thread = -1;
-
+
if (argc != 0 && argc != 1)
error ("Invalid MI command");
@@ -367,7 +422,7 @@ print_one_inferior (struct inferior *inf
ui_out_field_fmt (uiout, "id", "%d", inferior->pid);
ui_out_field_string (uiout, "type", "process");
ui_out_field_int (uiout, "pid", inferior->pid);
-
+
do_cleanups (back_to);
return 0;
}
@@ -433,14 +488,14 @@ mi_cmd_list_thread_groups (char *command
int pid = atoi (id);
if (!in_inferior_list (pid))
error ("Invalid thread group id '%s'", id);
- print_thread_info (uiout, -1, pid);
+ print_thread_info (uiout, -1, pid);
}
else
{
make_cleanup_ui_out_list_begin_end (uiout, "groups");
iterate_over_inferiors (print_one_inferior, NULL);
}
-
+
do_cleanups (back_to);
}
@@ -713,7 +768,7 @@ get_register (struct frame_info *frame,
}
/* Write given values into registers. The registers and values are
- given as pairs. The corresponding MI command is
+ given as pairs. The corresponding MI command is
-data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/
void
mi_cmd_data_write_register_values (char *command, char **argv, int argc)
@@ -810,7 +865,7 @@ mi_cmd_data_evaluate_expression (char *c
/* DATA-MEMORY-READ:
ADDR: start address of data to be dumped.
- WORD-FORMAT: a char indicating format for the ``word''. See
+ WORD-FORMAT: a char indicating format for the ``word''. See
the ``x'' command.
WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
NR_ROW: Number of rows.
@@ -823,7 +878,7 @@ mi_cmd_data_evaluate_expression (char *c
{addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
- Returns:
+ Returns:
The number of bytes read is SIZE*ROW*COL. */
void
@@ -1019,7 +1074,7 @@ mi_cmd_data_read_memory (char *command,
ADDR: start address of the row in the memory grid where the memory
cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
the location to write to.
- FORMAT: a char indicating format for the ``word''. See
+ FORMAT: a char indicating format for the ``word''. See
the ``x'' command.
WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
VALUE: value to be written into the memory address.
@@ -1112,7 +1167,7 @@ mi_cmd_enable_timings (char *command, ch
}
else
goto usage_error;
-
+
return;
usage_error:
@@ -1125,16 +1180,16 @@ mi_cmd_list_features (char *command, cha
if (argc == 0)
{
struct cleanup *cleanup = NULL;
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
ui_out_field_string (uiout, NULL, "frozen-varobjs");
ui_out_field_string (uiout, NULL, "pending-breakpoints");
ui_out_field_string (uiout, NULL, "thread-info");
-
+
#if HAVE_PYTHON
ui_out_field_string (uiout, NULL, "python");
#endif
-
+
do_cleanups (cleanup);
return;
}
@@ -1148,11 +1203,11 @@ mi_cmd_list_target_features (char *comma
if (argc == 0)
{
struct cleanup *cleanup = NULL;
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
if (target_can_async_p ())
ui_out_field_string (uiout, NULL, "async");
-
+
do_cleanups (cleanup);
return;
}
@@ -1196,8 +1251,8 @@ captured_mi_execute_command (struct ui_o
/* Print the result if there were no errors.
Remember that on the way out of executing a command, you have
- to directly use the mi_interp's uiout, since the command could
- have reset the interpreter, in which case the current uiout
+ to directly use the mi_interp's uiout, since the command could
+ have reset the interpreter, in which case the current uiout
will most likely crash in the mi_out_* routines. */
if (!running_result_record_printed)
{
@@ -1244,7 +1299,7 @@ captured_mi_execute_command (struct ui_o
mi_out_put (uiout, raw_stdout);
mi_out_rewind (uiout);
mi_print_timing_maybe ();
- fputs_unfiltered ("\n", raw_stdout);
+ fputs_unfiltered ("\n", raw_stdout);
}
else
mi_out_rewind (uiout);
@@ -1302,9 +1357,9 @@ mi_execute_command (char *cmd, int from_
}
if (/* The notifications are only output when the top-level
- interpreter (specified on the command line) is MI. */
+ interpreter (specified on the command line) is MI. */
ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
- /* Don't try report anything if there are no threads --
+ /* Don't try report anything if there are no threads --
the program is dead. */
&& thread_count () != 0
/* -thread-select explicitly changes thread. If frontend uses that
@@ -1328,10 +1383,10 @@ mi_execute_command (char *cmd, int from_
}
if (report_change)
- {
+ {
struct thread_info *ti = inferior_thread ();
target_terminal_ours ();
- fprintf_unfiltered (mi->event_channel,
+ fprintf_unfiltered (mi->event_channel,
"thread-selected,id=\"%d\"",
ti->num);
gdb_flush (mi->event_channel);
@@ -1446,7 +1501,7 @@ mi_execute_async_cli_command (char *cli_
run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
else
run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
- old_cleanups = make_cleanup (xfree, run);
+ old_cleanups = make_cleanup (xfree, run);
execute_command ( /*ui */ run, 0 /*from_tty */ );
@@ -1551,7 +1606,7 @@ mi_load_progress (const char *section_na
uiout = saved_uiout;
}
-static void
+static void
timestamp (struct mi_timestamp *tv)
{
long usec;
@@ -1571,7 +1626,7 @@ timestamp (struct mi_timestamp *tv)
#endif
}
-static void
+static void
print_diff_now (struct mi_timestamp *start)
{
struct mi_timestamp now;
@@ -1588,20 +1643,20 @@ mi_print_timing_maybe (void)
print_diff_now (current_command_ts);
}
-static long
+static long
timeval_diff (struct timeval start, struct timeval end)
{
return ((end.tv_sec - start.tv_sec) * 1000000L)
+ (end.tv_usec - start.tv_usec);
}
-static void
+static void
print_diff (struct mi_timestamp *start, struct mi_timestamp *end)
{
fprintf_unfiltered
(raw_stdout,
- ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
- timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
- timeval_diff (start->utime, end->utime) / 1000000.0,
+ ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
+ timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
+ timeval_diff (start->utime, end->utime) / 1000000.0,
timeval_diff (start->stime, end->stime) / 1000000.0);
}
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: GDB MI Reverse Commands added [1 of 3]
2009-08-27 2:06 ` Michael Snyder
@ 2009-08-31 13:15 ` Jakob Engblom
2009-08-31 20:29 ` Tom Tromey
` (2 subsequent siblings)
3 siblings, 0 replies; 27+ messages in thread
From: Jakob Engblom @ 2009-08-31 13:15 UTC (permalink / raw)
To: gdb-patches
>
> Group, this patch seemed to have gotten a little munged in email.
> I've taken the liberty of re-diffing it, to restore white space context.
This looks much better. Thanks.
/jakob
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-08-27 2:06 ` Michael Snyder
2009-08-31 13:15 ` Jakob Engblom
@ 2009-08-31 20:29 ` Tom Tromey
2009-09-02 8:16 ` Vladimir Prus
2009-12-15 19:39 ` Michael Snyder
3 siblings, 0 replies; 27+ messages in thread
From: Tom Tromey @ 2009-08-31 20:29 UTC (permalink / raw)
To: Michael Snyder; +Cc: Jakob Engblom, gdb-patches
Michael> Group, this patch seemed to have gotten a little munged in
Michael> email. I've taken the liberty of re-diffing it, to restore
Michael> white space context.
Thanks.
I have a few nits to pick.
Jakob> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
Space before (".
There are a number of these.
Jakob> +/* continue in reverse direction:
Jakob> + XXX: code duplicated from reverse.c */
We're trying not to add new FIXME-type comments.
In this particular case I think it is ok to just drop the comment.
However, if you prefer, I think you could add a new exported
"make_cleanup_..." function in reverse.c.
Tom
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-08-27 2:06 ` Michael Snyder
2009-08-31 13:15 ` Jakob Engblom
2009-08-31 20:29 ` Tom Tromey
@ 2009-09-02 8:16 ` Vladimir Prus
2009-09-10 21:09 ` Michael Snyder
2010-01-13 20:32 ` Jakob Engblom
2009-12-15 19:39 ` Michael Snyder
3 siblings, 2 replies; 27+ messages in thread
From: Vladimir Prus @ 2009-09-02 8:16 UTC (permalink / raw)
To: gdb-patches
Michael Snyder wrote:
> Index: mi-main.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
> retrieving revision 1.156
> diff -u -p -r1.156 mi-main.c
> --- mi-main.c   2 Jul 2009 17:25:59 -0000       1.156
> +++ mi-main.c   27 Aug 2009 01:45:23 -0000
> @@ -88,8 +88,8 @@ static void mi_cmd_execute (struct mi_pa
>
> static void mi_execute_cli_command (const char *cmd, int args_p,
> const char *args);
> -static void mi_execute_async_cli_command (char *cli_command,
> -Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â char **argv, int argc);
> +static void mi_execute_async_cli_command (char *cli_command,
> +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â char **argv, int argc);
> static int register_changed_p (int regnum, struct regcache *,
> struct regcache *);
> static void get_register (struct frame_info *, int regnum, int format);
> @@ -119,35 +119,50 @@ void
> mi_cmd_exec_next (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. Â */
> - Â mi_execute_async_cli_command ("next", argv, argc);
> + Â if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> + Â Â mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
> + Â else
> + Â Â mi_execute_async_cli_command ("next", argv, argc);
> }
>
> void
> mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. Â */
> - Â mi_execute_async_cli_command ("nexti", argv, argc);
> + Â if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> + Â Â mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
> + Â else
> + Â Â mi_execute_async_cli_command ("nexti", argv, argc);
> }
>
> void
> mi_cmd_exec_step (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. Â */
> - Â mi_execute_async_cli_command ("step", argv, argc);
> + Â if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> + Â Â mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
> + Â else
> + Â Â mi_execute_async_cli_command ("step", argv, argc);
> }
>
> void
> mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. Â */
> - Â mi_execute_async_cli_command ("stepi", argv, argc);
> + Â if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> + Â Â mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
> + Â else
> + Â Â mi_execute_async_cli_command ("stepi", argv, argc);
> }
>
> void
> mi_cmd_exec_finish (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. Â */
> - Â mi_execute_async_cli_command ("finish", argv, argc);
> + Â if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> + Â Â mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
> + Â else
> + Â Â mi_execute_async_cli_command ("finish", argv, argc);
> }
What will happen if MI client does not pass --reverse, but
execution_direction is set to reverse via CLI? It seems that this will execute
finish in reverse? I think this is not desirable -- rather -exec-finish
should always be forward. On the other hand, this is something that
I probably can fix as a follow-up patch, somewhere in MI core.
> void
> @@ -175,7 +190,7 @@ mi_cmd_exec_jump (char *args, char **arg
> /* FIXME: Should call a libgdb function, not a cli wrapper. Â */
> return mi_execute_async_cli_command ("jump", argv, argc);
> }
> -
> +
Stray whitespace change. The patch has a few of those, I imagine
that whoever ends up applying the patch to CVS once the copyright
assignment is sorted can undo this damage.
> static int
> proceed_thread_callback (struct thread_info *thread, void *arg)
> {
> @@ -193,8 +208,8 @@ proceed_thread_callback (struct thread_i
> return 0;
> }
>
> -void
> -mi_cmd_exec_continue (char *command, char **argv, int argc)
> +static void
> +exec_continue (char **argv, int argc)
> {
> if (argc == 0)
> continue_1 (0);
> @@ -212,10 +227,50 @@ mi_cmd_exec_continue (char *command, cha
>
> old_chain = make_cleanup_restore_current_thread ();
> iterate_over_threads (proceed_thread_callback, &pid);
> - Â Â Â do_cleanups (old_chain);
> + Â Â Â do_cleanups (old_chain);
> }
> else
> - Â Â error ("Usage: -exec-continue [--all|--thread-group id]");
> + Â Â error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
> +}
> +
> +/* continue in reverse direction:
> + Â XXX: code duplicated from reverse.c */
> +
> +static void
> +exec_direction_default (void *notused)
> +{
> + Â /* Return execution direction to default state. Â */
> + Â execution_direction = EXEC_FORWARD;
> +}
> +
> +static void
> +exec_reverse_continue (char **argv, int argc)
> +{
> + Â 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."));
> +
> + Â if (!target_can_execute_reverse)
> + Â Â error (_("Target %s does not support this command."), target_shortname);
> +
> + Â old_chain = make_cleanup (exec_direction_default, NULL);
> + Â execution_direction = EXEC_REVERSE;
> + Â exec_continue (argv, argc);
> + Â do_cleanups (old_chain);
> +}
Why is this code "duplicated from reverse.c"? In other words, cannot
mi_cmd_exec_continue call 'reverse_continue'? If this is not possible,
there should be a comment explaining why.
Otherwise, this is OK. Thanks!
- Volodya
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-09-02 8:16 ` Vladimir Prus
@ 2009-09-10 21:09 ` Michael Snyder
2009-09-10 21:10 ` Michael Snyder
2010-01-13 20:32 ` Jakob Engblom
1 sibling, 1 reply; 27+ messages in thread
From: Michael Snyder @ 2009-09-10 21:09 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb-patches, jakob
Maybe these questions were intended for Jakob?
Vladimir Prus wrote:
> Michael Snyder wrote:
>
>> Index: mi-main.c
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
>> retrieving revision 1.156
>> diff -u -p -r1.156 mi-main.c
>> --- mi-main.c 2 Jul 2009 17:25:59 -0000 1.156
>> +++ mi-main.c 27 Aug 2009 01:45:23 -0000
>> @@ -88,8 +88,8 @@ static void mi_cmd_execute (struct mi_pa
>>
>> static void mi_execute_cli_command (const char *cmd, int args_p,
>> const char *args);
>> -static void mi_execute_async_cli_command (char *cli_command,
>> - char **argv, int argc);
>> +static void mi_execute_async_cli_command (char *cli_command,
>> + char **argv, int argc);
>> static int register_changed_p (int regnum, struct regcache *,
>> struct regcache *);
>> static void get_register (struct frame_info *, int regnum, int format);
>> @@ -119,35 +119,50 @@ void
>> mi_cmd_exec_next (char *command, char **argv, int argc)
>> {
>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>> - mi_execute_async_cli_command ("next", argv, argc);
>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>> + mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
>> + else
>> + mi_execute_async_cli_command ("next", argv, argc);
>> }
>>
>> void
>> mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
>> {
>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>> - mi_execute_async_cli_command ("nexti", argv, argc);
>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>> + mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
>> + else
>> + mi_execute_async_cli_command ("nexti", argv, argc);
>> }
>>
>> void
>> mi_cmd_exec_step (char *command, char **argv, int argc)
>> {
>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>> - mi_execute_async_cli_command ("step", argv, argc);
>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>> + mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
>> + else
>> + mi_execute_async_cli_command ("step", argv, argc);
>> }
>>
>> void
>> mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
>> {
>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>> - mi_execute_async_cli_command ("stepi", argv, argc);
>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>> + mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
>> + else
>> + mi_execute_async_cli_command ("stepi", argv, argc);
>> }
>>
>> void
>> mi_cmd_exec_finish (char *command, char **argv, int argc)
>> {
>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>> - mi_execute_async_cli_command ("finish", argv, argc);
>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>> + mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
>> + else
>> + mi_execute_async_cli_command ("finish", argv, argc);
>> }
>
> What will happen if MI client does not pass --reverse, but
> execution_direction is set to reverse via CLI? It seems that this will execute
> finish in reverse? I think this is not desirable -- rather -exec-finish
> should always be forward. On the other hand, this is something that
> I probably can fix as a follow-up patch, somewhere in MI core.
>
>> void
>> @@ -175,7 +190,7 @@ mi_cmd_exec_jump (char *args, char **arg
>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>> return mi_execute_async_cli_command ("jump", argv, argc);
>> }
>> -
>> +
>
> Stray whitespace change. The patch has a few of those, I imagine
> that whoever ends up applying the patch to CVS once the copyright
> assignment is sorted can undo this damage.
>
>> static int
>> proceed_thread_callback (struct thread_info *thread, void *arg)
>> {
>> @@ -193,8 +208,8 @@ proceed_thread_callback (struct thread_i
>> return 0;
>> }
>>
>> -void
>> -mi_cmd_exec_continue (char *command, char **argv, int argc)
>> +static void
>> +exec_continue (char **argv, int argc)
>> {
>> if (argc == 0)
>> continue_1 (0);
>> @@ -212,10 +227,50 @@ mi_cmd_exec_continue (char *command, cha
>>
>> old_chain = make_cleanup_restore_current_thread ();
>> iterate_over_threads (proceed_thread_callback, &pid);
>> - do_cleanups (old_chain);
>> + do_cleanups (old_chain);
>> }
>> else
>> - error ("Usage: -exec-continue [--all|--thread-group id]");
>> + error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
>> +}
>> +
>> +/* continue in reverse direction:
>> + XXX: code duplicated from reverse.c */
>> +
>> +static void
>> +exec_direction_default (void *notused)
>> +{
>> + /* Return execution direction to default state. */
>> + execution_direction = EXEC_FORWARD;
>> +}
>> +
>> +static void
>> +exec_reverse_continue (char **argv, int argc)
>> +{
>> + 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."));
>> +
>> + if (!target_can_execute_reverse)
>> + error (_("Target %s does not support this command."), target_shortname);
>> +
>> + old_chain = make_cleanup (exec_direction_default, NULL);
>> + execution_direction = EXEC_REVERSE;
>> + exec_continue (argv, argc);
>> + do_cleanups (old_chain);
>> +}
>
> Why is this code "duplicated from reverse.c"? In other words, cannot
> mi_cmd_exec_continue call 'reverse_continue'? If this is not possible,
> there should be a comment explaining why.
>
> Otherwise, this is OK. Thanks!
>
> - Volodya
>
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-09-10 21:09 ` Michael Snyder
@ 2009-09-10 21:10 ` Michael Snyder
0 siblings, 0 replies; 27+ messages in thread
From: Michael Snyder @ 2009-09-10 21:10 UTC (permalink / raw)
To: Michael Snyder; +Cc: Vladimir Prus, gdb-patches, jakob
Oh, excuse me, reading email out of date order.
I see the questions have been answered.
Please disregard. ;-)
Michael Snyder wrote:
> Maybe these questions were intended for Jakob?
>
>
>
> Vladimir Prus wrote:
>> Michael Snyder wrote:
>>
>>> Index: mi-main.c
>>> ===================================================================
>>> RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
>>> retrieving revision 1.156
>>> diff -u -p -r1.156 mi-main.c
>>> --- mi-main.c 2 Jul 2009 17:25:59 -0000 1.156
>>> +++ mi-main.c 27 Aug 2009 01:45:23 -0000
>>> @@ -88,8 +88,8 @@ static void mi_cmd_execute (struct mi_pa
>>>
>>> static void mi_execute_cli_command (const char *cmd, int args_p,
>>> const char *args);
>>> -static void mi_execute_async_cli_command (char *cli_command,
>>> - char **argv, int argc);
>>> +static void mi_execute_async_cli_command (char *cli_command,
>>> + char **argv, int argc);
>>> static int register_changed_p (int regnum, struct regcache *,
>>> struct regcache *);
>>> static void get_register (struct frame_info *, int regnum, int format);
>>> @@ -119,35 +119,50 @@ void
>>> mi_cmd_exec_next (char *command, char **argv, int argc)
>>> {
>>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>>> - mi_execute_async_cli_command ("next", argv, argc);
>>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>>> + mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
>>> + else
>>> + mi_execute_async_cli_command ("next", argv, argc);
>>> }
>>>
>>> void
>>> mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
>>> {
>>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>>> - mi_execute_async_cli_command ("nexti", argv, argc);
>>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>>> + mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
>>> + else
>>> + mi_execute_async_cli_command ("nexti", argv, argc);
>>> }
>>>
>>> void
>>> mi_cmd_exec_step (char *command, char **argv, int argc)
>>> {
>>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>>> - mi_execute_async_cli_command ("step", argv, argc);
>>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>>> + mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
>>> + else
>>> + mi_execute_async_cli_command ("step", argv, argc);
>>> }
>>>
>>> void
>>> mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
>>> {
>>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>>> - mi_execute_async_cli_command ("stepi", argv, argc);
>>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>>> + mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
>>> + else
>>> + mi_execute_async_cli_command ("stepi", argv, argc);
>>> }
>>>
>>> void
>>> mi_cmd_exec_finish (char *command, char **argv, int argc)
>>> {
>>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>>> - mi_execute_async_cli_command ("finish", argv, argc);
>>> + if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
>>> + mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
>>> + else
>>> + mi_execute_async_cli_command ("finish", argv, argc);
>>> }
>> What will happen if MI client does not pass --reverse, but
>> execution_direction is set to reverse via CLI? It seems that this will execute
>> finish in reverse? I think this is not desirable -- rather -exec-finish
>> should always be forward. On the other hand, this is something that
>> I probably can fix as a follow-up patch, somewhere in MI core.
>>
>>> void
>>> @@ -175,7 +190,7 @@ mi_cmd_exec_jump (char *args, char **arg
>>> /* FIXME: Should call a libgdb function, not a cli wrapper. */
>>> return mi_execute_async_cli_command ("jump", argv, argc);
>>> }
>>> -
>>> +
>> Stray whitespace change. The patch has a few of those, I imagine
>> that whoever ends up applying the patch to CVS once the copyright
>> assignment is sorted can undo this damage.
>>
>>> static int
>>> proceed_thread_callback (struct thread_info *thread, void *arg)
>>> {
>>> @@ -193,8 +208,8 @@ proceed_thread_callback (struct thread_i
>>> return 0;
>>> }
>>>
>>> -void
>>> -mi_cmd_exec_continue (char *command, char **argv, int argc)
>>> +static void
>>> +exec_continue (char **argv, int argc)
>>> {
>>> if (argc == 0)
>>> continue_1 (0);
>>> @@ -212,10 +227,50 @@ mi_cmd_exec_continue (char *command, cha
>>>
>>> old_chain = make_cleanup_restore_current_thread ();
>>> iterate_over_threads (proceed_thread_callback, &pid);
>>> - do_cleanups (old_chain);
>>> + do_cleanups (old_chain);
>>> }
>>> else
>>> - error ("Usage: -exec-continue [--all|--thread-group id]");
>>> + error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
>>> +}
>>> +
>>> +/* continue in reverse direction:
>>> + XXX: code duplicated from reverse.c */
>>> +
>>> +static void
>>> +exec_direction_default (void *notused)
>>> +{
>>> + /* Return execution direction to default state. */
>>> + execution_direction = EXEC_FORWARD;
>>> +}
>>> +
>>> +static void
>>> +exec_reverse_continue (char **argv, int argc)
>>> +{
>>> + 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."));
>>> +
>>> + if (!target_can_execute_reverse)
>>> + error (_("Target %s does not support this command."), target_shortname);
>>> +
>>> + old_chain = make_cleanup (exec_direction_default, NULL);
>>> + execution_direction = EXEC_REVERSE;
>>> + exec_continue (argv, argc);
>>> + do_cleanups (old_chain);
>>> +}
>> Why is this code "duplicated from reverse.c"? In other words, cannot
>> mi_cmd_exec_continue call 'reverse_continue'? If this is not possible,
>> there should be a comment explaining why.
>>
>> Otherwise, this is OK. Thanks!
>>
>> - Volodya
>>
>>
>>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: GDB MI Reverse Commands added [1 of 3]
2009-09-02 8:16 ` Vladimir Prus
2009-09-10 21:09 ` Michael Snyder
@ 2010-01-13 20:32 ` Jakob Engblom
2010-01-13 20:36 ` Vladimir Prus
1 sibling, 1 reply; 27+ messages in thread
From: Jakob Engblom @ 2010-01-13 20:32 UTC (permalink / raw)
To: 'Vladimir Prus', gdb-patches
[-- Attachment #1: Type: text/plain, Size: 740 bytes --]
Here is an updated patch for the MI reverse commands, against the latest gdb 7 from cvs.
It removes the buggy whitespace changes, and also removes the small duplication of code with reverse.c (it was really only the setting of the default direction of execution that was duplicated).
In my build, this version passes all the mi-reverse.exp tests.
Best regards,
/jakob
_______________________________________________________
Jakob Engblom, PhD, Technical Marketing Manager
Virtutech Direct: +46 8 690 07 47
Drottningholmsvägen 22 Mobile: +46 709 242 646
11243 Stockholm Web: www.virtutech.com
Sweden
________________________________________________________
[-- Attachment #2: gdb-mi-reverse-gdb7.diff --]
[-- Type: application/octet-stream, Size: 5636 bytes --]
Index: gdb/mi/mi-main.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
retrieving revision 1.163
diff -c -p -r1.163 mi-main.c
*** gdb/mi/mi-main.c 12 Jan 2010 23:05:52 -0000 1.163
--- gdb/mi/mi-main.c 13 Jan 2010 20:16:03 -0000
*************** void
*** 121,155 ****
mi_cmd_exec_next (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! mi_execute_async_cli_command ("next", argv, argc);
}
void
mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! mi_execute_async_cli_command ("nexti", argv, argc);
}
void
mi_cmd_exec_step (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! mi_execute_async_cli_command ("step", argv, argc);
}
void
mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! mi_execute_async_cli_command ("stepi", argv, argc);
}
void
mi_cmd_exec_finish (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! mi_execute_async_cli_command ("finish", argv, argc);
}
void
--- 121,170 ----
mi_cmd_exec_next (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
! mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
! else
! mi_execute_async_cli_command ("next", argv, argc);
}
void
mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
! mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
! else
! mi_execute_async_cli_command ("nexti", argv, argc);
}
void
mi_cmd_exec_step (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
! mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
! else
! mi_execute_async_cli_command ("step", argv, argc);
}
void
mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
! mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
! else
! mi_execute_async_cli_command ("stepi", argv, argc);
}
void
mi_cmd_exec_finish (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
! mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
! else
! mi_execute_async_cli_command ("finish", argv, argc);
}
void
*************** proceed_thread_callback (struct thread_i
*** 195,202 ****
return 0;
}
! void
! mi_cmd_exec_continue (char *command, char **argv, int argc)
{
if (argc == 0)
continue_1 (0);
--- 210,217 ----
return 0;
}
! static void
! exec_continue (char **argv, int argc)
{
if (argc == 0)
continue_1 (0);
*************** mi_cmd_exec_continue (char *command, cha
*** 217,223 ****
do_cleanups (old_chain);
}
else
! error ("Usage: -exec-continue [--all|--thread-group id]");
}
static int
--- 232,271 ----
do_cleanups (old_chain);
}
else
! error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
! }
!
! /* Function found in gdb/reverse.c */
! void exec_direction_default(void *);
!
! static void
! exec_reverse_continue (char **argv, int argc)
! {
! 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."));
!
! if (!target_can_execute_reverse)
! error (_("Target %s does not support this command."), target_shortname);
!
! old_chain = make_cleanup (exec_direction_default, NULL);
! execution_direction = EXEC_REVERSE;
! exec_continue (argv, argc);
! do_cleanups (old_chain);
! }
!
! void
! mi_cmd_exec_continue (char *command, char **argv, int argc)
! {
! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
! exec_reverse_continue (argv + 1, argc - 1);
! else
! exec_continue (argv, argc);
}
static int
Index: gdb/reverse.c
===================================================================
RCS file: /cvs/src/src/gdb/reverse.c,v
retrieving revision 1.8
diff -c -p -r1.8 reverse.c
*** gdb/reverse.c 1 Jan 2010 07:31:41 -0000 1.8
--- gdb/reverse.c 13 Jan 2010 20:16:04 -0000
***************
*** 29,35 ****
/* User interface:
reverse-step, reverse-next etc. */
! static void
exec_direction_default (void *notused)
{
/* Return execution direction to default state. */
--- 29,35 ----
/* User interface:
reverse-step, reverse-next etc. */
! void
exec_direction_default (void *notused)
{
/* Return execution direction to default state. */
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2010-01-13 20:32 ` Jakob Engblom
@ 2010-01-13 20:36 ` Vladimir Prus
2010-01-13 20:44 ` Michael Snyder
0 siblings, 1 reply; 27+ messages in thread
From: Vladimir Prus @ 2010-01-13 20:36 UTC (permalink / raw)
To: Jakob Engblom; +Cc: gdb-patches
On Wednesday 13 January 2010 23:32:01 Jakob Engblom wrote:
> Here is an updated patch for the MI reverse commands, against the latest gdb 7 from cvs.
>
> It removes the buggy whitespace changes, and also removes the small duplication of code with reverse.c (it was really only the setting of the default direction of execution that was duplicated).
>
> In my build, this version passes all the mi-reverse.exp tests.
This patch is OK, thanks.
- Volodya
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: GDB MI Reverse Commands added [1 of 3]
2010-01-13 20:36 ` Vladimir Prus
@ 2010-01-13 20:44 ` Michael Snyder
0 siblings, 0 replies; 27+ messages in thread
From: Michael Snyder @ 2010-01-13 20:44 UTC (permalink / raw)
To: Vladimir Prus; +Cc: Jakob Engblom, gdb-patches
Vladimir Prus wrote:
> On Wednesday 13 January 2010 23:32:01 Jakob Engblom wrote:
>
>> Here is an updated patch for the MI reverse commands, against the latest gdb 7 from cvs.
>>
>> It removes the buggy whitespace changes, and also removes the small duplication of code with reverse.c (it was really only the setting of the default direction of execution that was duplicated).
>>
>> In my build, this version passes all the mi-reverse.exp tests.
>
> This patch is OK, thanks.
Volodya, I don't think Jakob has write privs.
One of us will have to check this in...
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: GDB MI Reverse Commands added [1 of 3]
2009-08-27 2:06 ` Michael Snyder
` (2 preceding siblings ...)
2009-09-02 8:16 ` Vladimir Prus
@ 2009-12-15 19:39 ` Michael Snyder
2009-12-16 7:54 ` Vladimir Prus
3 siblings, 1 reply; 27+ messages in thread
From: Michael Snyder @ 2009-12-15 19:39 UTC (permalink / raw)
To: Vladimir Prus; +Cc: Jakob Engblom, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 790 bytes --]
Michael Snyder wrote:
> Jakob Engblom wrote:
>> Here are the patches adding the MI commands for reverse execution to gdb.
>>
>> Changelog entry: "Added reverse debugging support to gdb MI"
>
> Group, this patch seemed to have gotten a little munged in email.
> I've taken the liberty of re-diffing it, to restore white space context.
>
Vladimir, as far as I can tell, this seems to be the most recent
version of part 1 of this patch, awaiting approval now that the
copyright paperwork is completed.
2009-08-31 Tomas Holmberg >th@virtutech.com>
* mi/mi-main.c: Added the --reverse flag to the following MI
commands: exec-continue, exec-finish, exec-next, exec-step,
exec-next-instruction, exec-step-instruction. This is to
support reverse execution over the MI interface to gdb.
[-- Attachment #2: part1.txt --]
[-- Type: text/plain, Size: 11983 bytes --]
Index: mi-main.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
retrieving revision 1.156
diff -u -p -r1.156 mi-main.c
--- mi-main.c 2 Jul 2009 17:25:59 -0000 1.156
+++ mi-main.c 27 Aug 2009 01:45:23 -0000
@@ -88,8 +88,8 @@ static void mi_cmd_execute (struct mi_pa
static void mi_execute_cli_command (const char *cmd, int args_p,
const char *args);
-static void mi_execute_async_cli_command (char *cli_command,
- char **argv, int argc);
+static void mi_execute_async_cli_command (char *cli_command,
+ char **argv, int argc);
static int register_changed_p (int regnum, struct regcache *,
struct regcache *);
static void get_register (struct frame_info *, int regnum, int format);
@@ -119,35 +119,50 @@ void
mi_cmd_exec_next (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("next", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("next", argv, argc);
}
void
mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("nexti", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("nexti", argv, argc);
}
void
mi_cmd_exec_step (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("step", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("step", argv, argc);
}
void
mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("stepi", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("stepi", argv, argc);
}
void
mi_cmd_exec_finish (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("finish", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("finish", argv, argc);
}
void
@@ -175,7 +190,7 @@ mi_cmd_exec_jump (char *args, char **arg
/* FIXME: Should call a libgdb function, not a cli wrapper. */
return mi_execute_async_cli_command ("jump", argv, argc);
}
-
+
static int
proceed_thread_callback (struct thread_info *thread, void *arg)
{
@@ -193,8 +208,8 @@ proceed_thread_callback (struct thread_i
return 0;
}
-void
-mi_cmd_exec_continue (char *command, char **argv, int argc)
+static void
+exec_continue (char **argv, int argc)
{
if (argc == 0)
continue_1 (0);
@@ -212,10 +227,50 @@ mi_cmd_exec_continue (char *command, cha
old_chain = make_cleanup_restore_current_thread ();
iterate_over_threads (proceed_thread_callback, &pid);
- do_cleanups (old_chain);
+ do_cleanups (old_chain);
}
else
- error ("Usage: -exec-continue [--all|--thread-group id]");
+ error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
+}
+
+/* continue in reverse direction:
+ XXX: code duplicated from reverse.c */
+
+static void
+exec_direction_default (void *notused)
+{
+ /* Return execution direction to default state. */
+ execution_direction = EXEC_FORWARD;
+}
+
+static void
+exec_reverse_continue (char **argv, int argc)
+{
+ 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."));
+
+ if (!target_can_execute_reverse)
+ error (_("Target %s does not support this command."), target_shortname);
+
+ old_chain = make_cleanup (exec_direction_default, NULL);
+ execution_direction = EXEC_REVERSE;
+ exec_continue (argv, argc);
+ do_cleanups (old_chain);
+}
+
+void
+mi_cmd_exec_continue (char *command, char **argv, int argc)
+{
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ exec_reverse_continue (argv + 1, argc - 1);
+ else
+ exec_continue (argv, argc);
}
static int
@@ -252,7 +307,7 @@ mi_cmd_exec_interrupt (char *command, ch
{
if (!any_running ())
error ("Inferior not running.");
-
+
interrupt_target_1 (1);
}
else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
@@ -349,7 +404,7 @@ void
mi_cmd_thread_info (char *command, char **argv, int argc)
{
int thread = -1;
-
+
if (argc != 0 && argc != 1)
error ("Invalid MI command");
@@ -367,7 +422,7 @@ print_one_inferior (struct inferior *inf
ui_out_field_fmt (uiout, "id", "%d", inferior->pid);
ui_out_field_string (uiout, "type", "process");
ui_out_field_int (uiout, "pid", inferior->pid);
-
+
do_cleanups (back_to);
return 0;
}
@@ -433,14 +488,14 @@ mi_cmd_list_thread_groups (char *command
int pid = atoi (id);
if (!in_inferior_list (pid))
error ("Invalid thread group id '%s'", id);
- print_thread_info (uiout, -1, pid);
+ print_thread_info (uiout, -1, pid);
}
else
{
make_cleanup_ui_out_list_begin_end (uiout, "groups");
iterate_over_inferiors (print_one_inferior, NULL);
}
-
+
do_cleanups (back_to);
}
@@ -713,7 +768,7 @@ get_register (struct frame_info *frame,
}
/* Write given values into registers. The registers and values are
- given as pairs. The corresponding MI command is
+ given as pairs. The corresponding MI command is
-data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/
void
mi_cmd_data_write_register_values (char *command, char **argv, int argc)
@@ -810,7 +865,7 @@ mi_cmd_data_evaluate_expression (char *c
/* DATA-MEMORY-READ:
ADDR: start address of data to be dumped.
- WORD-FORMAT: a char indicating format for the ``word''. See
+ WORD-FORMAT: a char indicating format for the ``word''. See
the ``x'' command.
WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
NR_ROW: Number of rows.
@@ -823,7 +878,7 @@ mi_cmd_data_evaluate_expression (char *c
{addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
- Returns:
+ Returns:
The number of bytes read is SIZE*ROW*COL. */
void
@@ -1019,7 +1074,7 @@ mi_cmd_data_read_memory (char *command,
ADDR: start address of the row in the memory grid where the memory
cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
the location to write to.
- FORMAT: a char indicating format for the ``word''. See
+ FORMAT: a char indicating format for the ``word''. See
the ``x'' command.
WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
VALUE: value to be written into the memory address.
@@ -1112,7 +1167,7 @@ mi_cmd_enable_timings (char *command, ch
}
else
goto usage_error;
-
+
return;
usage_error:
@@ -1125,16 +1180,16 @@ mi_cmd_list_features (char *command, cha
if (argc == 0)
{
struct cleanup *cleanup = NULL;
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
ui_out_field_string (uiout, NULL, "frozen-varobjs");
ui_out_field_string (uiout, NULL, "pending-breakpoints");
ui_out_field_string (uiout, NULL, "thread-info");
-
+
#if HAVE_PYTHON
ui_out_field_string (uiout, NULL, "python");
#endif
-
+
do_cleanups (cleanup);
return;
}
@@ -1148,11 +1203,11 @@ mi_cmd_list_target_features (char *comma
if (argc == 0)
{
struct cleanup *cleanup = NULL;
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
if (target_can_async_p ())
ui_out_field_string (uiout, NULL, "async");
-
+
do_cleanups (cleanup);
return;
}
@@ -1196,8 +1251,8 @@ captured_mi_execute_command (struct ui_o
/* Print the result if there were no errors.
Remember that on the way out of executing a command, you have
- to directly use the mi_interp's uiout, since the command could
- have reset the interpreter, in which case the current uiout
+ to directly use the mi_interp's uiout, since the command could
+ have reset the interpreter, in which case the current uiout
will most likely crash in the mi_out_* routines. */
if (!running_result_record_printed)
{
@@ -1244,7 +1299,7 @@ captured_mi_execute_command (struct ui_o
mi_out_put (uiout, raw_stdout);
mi_out_rewind (uiout);
mi_print_timing_maybe ();
- fputs_unfiltered ("\n", raw_stdout);
+ fputs_unfiltered ("\n", raw_stdout);
}
else
mi_out_rewind (uiout);
@@ -1302,9 +1357,9 @@ mi_execute_command (char *cmd, int from_
}
if (/* The notifications are only output when the top-level
- interpreter (specified on the command line) is MI. */
+ interpreter (specified on the command line) is MI. */
ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
- /* Don't try report anything if there are no threads --
+ /* Don't try report anything if there are no threads --
the program is dead. */
&& thread_count () != 0
/* -thread-select explicitly changes thread. If frontend uses that
@@ -1328,10 +1383,10 @@ mi_execute_command (char *cmd, int from_
}
if (report_change)
- {
+ {
struct thread_info *ti = inferior_thread ();
target_terminal_ours ();
- fprintf_unfiltered (mi->event_channel,
+ fprintf_unfiltered (mi->event_channel,
"thread-selected,id=\"%d\"",
ti->num);
gdb_flush (mi->event_channel);
@@ -1446,7 +1501,7 @@ mi_execute_async_cli_command (char *cli_
run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
else
run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
- old_cleanups = make_cleanup (xfree, run);
+ old_cleanups = make_cleanup (xfree, run);
execute_command ( /*ui */ run, 0 /*from_tty */ );
@@ -1551,7 +1606,7 @@ mi_load_progress (const char *section_na
uiout = saved_uiout;
}
-static void
+static void
timestamp (struct mi_timestamp *tv)
{
long usec;
@@ -1571,7 +1626,7 @@ timestamp (struct mi_timestamp *tv)
#endif
}
-static void
+static void
print_diff_now (struct mi_timestamp *start)
{
struct mi_timestamp now;
@@ -1588,20 +1643,20 @@ mi_print_timing_maybe (void)
print_diff_now (current_command_ts);
}
-static long
+static long
timeval_diff (struct timeval start, struct timeval end)
{
return ((end.tv_sec - start.tv_sec) * 1000000L)
+ (end.tv_usec - start.tv_usec);
}
-static void
+static void
print_diff (struct mi_timestamp *start, struct mi_timestamp *end)
{
fprintf_unfiltered
(raw_stdout,
- ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
- timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
- timeval_diff (start->utime, end->utime) / 1000000.0,
+ ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
+ timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
+ timeval_diff (start->utime, end->utime) / 1000000.0,
timeval_diff (start->stime, end->stime) / 1000000.0);
}
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-12-15 19:39 ` Michael Snyder
@ 2009-12-16 7:54 ` Vladimir Prus
2009-12-16 7:57 ` Vladimir Prus
0 siblings, 1 reply; 27+ messages in thread
From: Vladimir Prus @ 2009-12-16 7:54 UTC (permalink / raw)
To: Michael Snyder; +Cc: Jakob Engblom, gdb-patches
On Tuesday 15 December 2009 22:37:09 Michael Snyder wrote:
> Vladimir, as far as I can tell, this seems to be the most recent
> version of part 1 of this patch, awaiting approval now that the
> copyright paperwork is completed.
>
> 2009-08-31 Tomas Holmberg >th@virtutech.com>
> * mi/mi-main.c: Added the --reverse flag to the following MI
> commands: exec-continue, exec-finish, exec-next, exec-step,
> exec-next-instruction, exec-step-instruction. This is to
> support reverse execution over the MI interface to gdb.
Michael,
thanks. This patch is OK, with the following fixes:
> Index: mi-main.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
> retrieving revision 1.156
> diff -u -p -r1.156 mi-main.c
> --- mi-main.c 2 Jul 2009 17:25:59 -0000 1.156
> +++ mi-main.c 27 Aug 2009 01:45:23 -0000
> @@ -88,8 +88,8 @@ static void mi_cmd_execute (struct mi_pa
>
> static void mi_execute_cli_command (const char *cmd, int args_p,
> const char *args);
> -static void mi_execute_async_cli_command (char *cli_command,
> - char **argv, int argc);
> +static void mi_execute_async_cli_command (char *cli_command,
> + char **argv, int argc);
This is spurious formatting change that must be undone. There's a lot of
similar changes in the patch — that must be similarly undone.
> +/* continue in reverse direction:
> + XXX: code duplicated from reverse.c */
> +
> +static void
> +exec_direction_default (void *notused)
> +{
> + /* Return execution direction to default state. */
> + execution_direction = EXEC_FORWARD;
> +}
It should be straight-forward to make the function in reverse.c globally
visible, and remove this copy-paste.
Thanks,
Volodya
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-12-16 7:54 ` Vladimir Prus
@ 2009-12-16 7:57 ` Vladimir Prus
2009-12-17 14:40 ` Jakob Engblom
0 siblings, 1 reply; 27+ messages in thread
From: Vladimir Prus @ 2009-12-16 7:57 UTC (permalink / raw)
To: Michael Snyder; +Cc: Jakob Engblom, gdb-patches
On Wednesday 16 December 2009 10:54:35 Vladimir Prus wrote:
> On Tuesday 15 December 2009 22:37:09 Michael Snyder wrote:
>
> > Vladimir, as far as I can tell, this seems to be the most recent
> > version of part 1 of this patch, awaiting approval now that the
> > copyright paperwork is completed.
> >
> > 2009-08-31 Tomas Holmberg >th@virtutech.com>
> > * mi/mi-main.c: Added the --reverse flag to the following MI
> > commands: exec-continue, exec-finish, exec-next, exec-step,
> > exec-next-instruction, exec-step-instruction. This is to
> > support reverse execution over the MI interface to gdb.
>
> Michael,
>
> thanks. This patch is OK, with the following fixes:
>
> > Index: mi-main.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
> > retrieving revision 1.156
> > diff -u -p -r1.156 mi-main.c
> > --- mi-main.c 2 Jul 2009 17:25:59 -0000 1.156
> > +++ mi-main.c 27 Aug 2009 01:45:23 -0000
> > @@ -88,8 +88,8 @@ static void mi_cmd_execute (struct mi_pa
> >
> > static void mi_execute_cli_command (const char *cmd, int args_p,
> > const char *args);
> > -static void mi_execute_async_cli_command (char *cli_command,
> > - char **argv, int argc);
> > +static void mi_execute_async_cli_command (char *cli_command,
> > + char **argv, int argc);
>
> This is spurious formatting change that must be undone. There's a lot of
> similar changes in the patch — that must be similarly undone.
>
> > +/* continue in reverse direction:
> > + XXX: code duplicated from reverse.c */
> > +
> > +static void
> > +exec_direction_default (void *notused)
> > +{
> > + /* Return execution direction to default state. */
> > + execution_direction = EXEC_FORWARD;
> > +}
>
> It should be straight-forward to make the function in reverse.c globally
> visible, and remove this copy-paste.
As a side remark, it's not very good that --reverse should be the first option to
-exec-continue (which takes other options). I'll probably fix that later, as I
have a patch that touches option parsing.
- Volodya
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: GDB MI Reverse Commands added [1 of 3]
2009-12-16 7:57 ` Vladimir Prus
@ 2009-12-17 14:40 ` Jakob Engblom
2009-12-21 10:06 ` Vladimir Prus
0 siblings, 1 reply; 27+ messages in thread
From: Jakob Engblom @ 2009-12-17 14:40 UTC (permalink / raw)
To: 'Vladimir Prus', 'Michael Snyder'; +Cc: gdb-patches
> > > +/* continue in reverse direction:
> > > + XXX: code duplicated from reverse.c */
> > > +
> > > +static void
> > > +exec_direction_default (void *notused)
> > > +{
> > > + /* Return execution direction to default state. */
> > > + execution_direction = EXEC_FORWARD;
> > > +}
> >
> > It should be straight-forward to make the function in reverse.c globally
> > visible, and remove this copy-paste.
I just updated my cvs tree, and it seems that the main reverse function has changed its name. As far as I can tell (I did not do all of this code myself, rather I have to blame some colleagues), the current reversing function that we want to call is:
static void
exec_reverse_once (char *cmd, char *args, int from_tty)
{
...
}
From
void
mi_cmd_exec_continue (char *command, char **argv, int argc)
{
if (argc > 0 && strcmp (argv[0], "--reverse") == 0)
exec_reverse_continue (argv + 1, argc - 1);
else
exec_continue (argv, argc);
}
Where exec_reverse_continue() should be replaced with exec_reverse_once().
Can someone familiar with the main reverse code illuminate me on how to call into the reverse code in teh right way? It seems that the reverse.c code has already changed from the code that was (bad style) copied into mi-main.c... which is exactly what we want to avoid in the first place.
Or is the logical thing to do from MI to just call
static void
reverse_continue (char *args, int from_tty)
{
exec_reverse_once ("continue", args, from_tty);
}
As the implementation of reverse continue? This does looks like the we submitted has rotted since the patch was submitted...
/jakob
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-12-17 14:40 ` Jakob Engblom
@ 2009-12-21 10:06 ` Vladimir Prus
2009-12-22 11:34 ` Jakob Engblom
0 siblings, 1 reply; 27+ messages in thread
From: Vladimir Prus @ 2009-12-21 10:06 UTC (permalink / raw)
To: Jakob Engblom; +Cc: 'Michael Snyder', gdb-patches
On Thursday 17 December 2009 17:40:16 Jakob Engblom wrote:
> > > > +/* continue in reverse direction:
> > > > + XXX: code duplicated from reverse.c */
> > > > +
> > > > +static void
> > > > +exec_direction_default (void *notused)
> > > > +{
> > > > + /* Return execution direction to default state. */
> > > > + execution_direction = EXEC_FORWARD;
> > > > +}
> > >
> > > It should be straight-forward to make the function in reverse.c globally
> > > visible, and remove this copy-paste.
>
> I just updated my cvs tree, and it seems that the main reverse function has changed its name. As far as I can tell (I did not do all of this code myself, rather I have to blame some colleagues), the current reversing function that we want to call is:
>
> static void
> exec_reverse_once (char *cmd, char *args, int from_tty)
> {
> ...
> }
>
> From
>
> void
> mi_cmd_exec_continue (char *command, char **argv, int argc)
> {
> if (argc > 0 && strcmp (argv[0], "--reverse") == 0)
> exec_reverse_continue (argv + 1, argc - 1);
> else
> exec_continue (argv, argc);
> }
>
> Where exec_reverse_continue() should be replaced with exec_reverse_once().
>
> Can someone familiar with the main reverse code illuminate me on how to call into the reverse code in teh right way? It seems that the reverse.c code has already changed from the code that was (bad style) copied into mi-main.c... which is exactly what we want to avoid in the first place.
>
> Or is the logical thing to do from MI to just call
>
> static void
> reverse_continue (char *args, int from_tty)
> {
> exec_reverse_once ("continue", args, from_tty);
> }
>
> As the implementation of reverse continue? This does looks like the we submitted has rotted since the patch was submitted...
Just to clarify -- who's got the ball here? Calling 'reverse_continue' sounds like reasonable thing to me
if one wants to do a reverse continue ;-)
- Volodya
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: GDB MI Reverse Commands added [1 of 3]
2009-12-21 10:06 ` Vladimir Prus
@ 2009-12-22 11:34 ` Jakob Engblom
2009-12-22 11:48 ` Vladimir Prus
2009-12-22 18:22 ` Michael Snyder
0 siblings, 2 replies; 27+ messages in thread
From: Jakob Engblom @ 2009-12-22 11:34 UTC (permalink / raw)
To: 'Vladimir Prus'
Cc: 'Michael Snyder', gdb-patches, 'Hui Zhu'
> > Can someone familiar with the main reverse code illuminate me on how to call
> into the reverse code in teh right way? It seems that the reverse.c code has
> already changed from the code that was (bad style) copied into mi-main.c...
> which is exactly what we want to avoid in the first place.
> >
> > Or is the logical thing to do from MI to just call
> >
> > static void
> > reverse_continue (char *args, int from_tty)
> > {
> > exec_reverse_once ("continue", args, from_tty);
> > }
> >
> > As the implementation of reverse continue? This does looks like the we
> submitted has rotted since the patch was submitted...
>
> Just to clarify -- who's got the ball here? Calling 'reverse_continue' sounds
> like reasonable thing to me
> if one wants to do a reverse continue ;-)
I think the ball is mine.
But I need to understand how to put the two things together, and for that I need
some help by the people who did reverse.c.
In particular, from MI, what should the "from_tty" argument be? And the "args"?
MI args look different from the command-line arguments to me, so how can one
convert between the two?
I also have a gdb 7.0-compatible version of the current patch brewing, the one
submitted in August was really against 6.8, and is thus really a bit out of
date. We are currently shipping this patch with Simics, along with a patched
gdb that supports reverse over MI for the benefit of our Eclipse integration.
Best regards,
/jakob
_______________________________________________________
Jakob Engblom, PhD, Technical Marketing Manager
Virtutech Direct: +46 8 690 07 47
Drottningholmsvägen 22 Mobile: +46 709 242 646
11243 Stockholm Web: www.virtutech.com
Sweden
________________________________________________________
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-12-22 11:34 ` Jakob Engblom
@ 2009-12-22 11:48 ` Vladimir Prus
2010-01-13 13:15 ` Jakob Engblom
2009-12-22 18:22 ` Michael Snyder
1 sibling, 1 reply; 27+ messages in thread
From: Vladimir Prus @ 2009-12-22 11:48 UTC (permalink / raw)
To: Jakob Engblom; +Cc: 'Michael Snyder', gdb-patches, 'Hui Zhu'
On Tuesday 22 December 2009 14:34:00 Jakob Engblom wrote:
> > > Can someone familiar with the main reverse code illuminate me on how to call
> > into the reverse code in teh right way? It seems that the reverse.c code has
> > already changed from the code that was (bad style) copied into mi-main.c...
> > which is exactly what we want to avoid in the first place.
> > >
> > > Or is the logical thing to do from MI to just call
> > >
> > > static void
> > > reverse_continue (char *args, int from_tty)
> > > {
> > > exec_reverse_once ("continue", args, from_tty);
> > > }
> > >
> > > As the implementation of reverse continue? This does looks like the we
> > submitted has rotted since the patch was submitted...
> >
> > Just to clarify -- who's got the ball here? Calling 'reverse_continue' sounds
> > like reasonable thing to me
> > if one wants to do a reverse continue ;-)
>
> I think the ball is mine.
>
> But I need to understand how to put the two things together, and for that I need
> some help by the people who did reverse.c.
>
> In particular, from MI, what should the "from_tty" argument be? And the "args"?
> MI args look different from the command-line arguments to me, so how can one
> convert between the two?
The from_tty should be 0. 'args' are probably not used for continue anyway,
and surely are not used for MI -exec-continue, so can be NULL.
Hope this helps.
- Volodya
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: GDB MI Reverse Commands added [1 of 3]
2009-12-22 11:48 ` Vladimir Prus
@ 2010-01-13 13:15 ` Jakob Engblom
0 siblings, 0 replies; 27+ messages in thread
From: Jakob Engblom @ 2010-01-13 13:15 UTC (permalink / raw)
To: gdb-patches
>
> The from_tty should be 0. 'args' are probably not used for continue anyway,
> and surely are not used for MI -exec-continue, so can be NULL.
The MI continue command certainly has some arguments, about thread management.
But I guess these are not supposed to propagate into the main gdb handling of
continue.
The forwards-continue command in MI currently calls "continue_1()" to get the
job done, with arguments "0" for default, and "1" to handle all threads. There
seems to be a lack of symmetry between reverse and normal continue.
Best regards,
/jakob
_______________________________________________________
Jakob Engblom, PhD, Technical Marketing Manager
Virtutech Direct: +46 8 690 07 47
Drottningholmsvägen 22 Mobile: +46 709 242 646
11243 Stockholm Web: www.virtutech.com
Sweden
________________________________________________________
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: GDB MI Reverse Commands added [1 of 3]
2009-12-22 11:34 ` Jakob Engblom
2009-12-22 11:48 ` Vladimir Prus
@ 2009-12-22 18:22 ` Michael Snyder
2010-01-13 13:16 ` Jakob Engblom
2010-02-12 21:33 ` Michael Snyder
1 sibling, 2 replies; 27+ messages in thread
From: Michael Snyder @ 2009-12-22 18:22 UTC (permalink / raw)
To: Jakob Engblom; +Cc: 'Vladimir Prus', gdb-patches, 'Hui Zhu'
Jakob Engblom wrote:
>>> Can someone familiar with the main reverse code illuminate me on how to call
>> into the reverse code in teh right way? It seems that the reverse.c code has
>> already changed from the code that was (bad style) copied into mi-main.c...
>> which is exactly what we want to avoid in the first place.
>>> Or is the logical thing to do from MI to just call
>>>
>>> static void
>>> reverse_continue (char *args, int from_tty)
>>> {
>>> exec_reverse_once ("continue", args, from_tty);
>>> }
>>>
>>> As the implementation of reverse continue? This does looks like the we
>> submitted has rotted since the patch was submitted...
>>
>> Just to clarify -- who's got the ball here? Calling 'reverse_continue' sounds
>> like reasonable thing to me
>> if one wants to do a reverse continue ;-)
>
> I think the ball is mine.
>
> But I need to understand how to put the two things together, and for that I need
> some help by the people who did reverse.c.
That would be me, but I'm confused.
What changed? Reverse.c didn't change (I don't think...)
If MI used to work, why doesn't it work any more?
> In particular, from MI, what should the "from_tty" argument be?
AFAIK, that should always be zero. "from_tty" really means "from_CLI".
> And the "args"?
> MI args look different from the command-line arguments to me, so how can one
> convert between the two?
That would depend entirely on the command.
But please let's start with my first question --
why are we having to do this? What is it that
changed, making these changes necessary?
> I also have a gdb 7.0-compatible version of the current patch brewing, the one
> submitted in August was really against 6.8, and is thus really a bit out of
> date. We are currently shipping this patch with Simics, along with a patched
> gdb that supports reverse over MI for the benefit of our Eclipse integration.
>
> Best regards,
>
> /jakob
>
> _______________________________________________________
>
> Jakob Engblom, PhD, Technical Marketing Manager
>
> Virtutech Direct: +46 8 690 07 47
> Drottningholmsvägen 22 Mobile: +46 709 242 646
> 11243 Stockholm Web: www.virtutech.com
> Sweden
> ________________________________________________________
>
>
>
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread* RE: GDB MI Reverse Commands added [1 of 3]
2009-12-22 18:22 ` Michael Snyder
@ 2010-01-13 13:16 ` Jakob Engblom
2010-02-12 21:33 ` Michael Snyder
1 sibling, 0 replies; 27+ messages in thread
From: Jakob Engblom @ 2010-01-13 13:16 UTC (permalink / raw)
To: 'Michael Snyder'
Cc: 'Vladimir Prus', gdb-patches, 'Hui Zhu'
I am now on parental leave, really, but I just gave it a try to try to get the
MI reverse commands fixed. In particular, making them compatible with gdb7. We
have an internal version at VT that does that, but that also contains the
offending piece of code that is duplicated from reverse.c.
In our code, and in the submitted patches, in mi-main.c, we have:
----
static void
exec_continue (char **argv, int argc)
{
if (argc == 0)
continue_1 (0);
else if (argc == 1 && strcmp (argv[0], "--all") == 0)
continue_1 (1);
else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
{
struct cleanup *old_chain;
int pid;
if (argv[1] == NULL || argv[1] == '\0')
error ("Thread group id not specified");
pid = atoi (argv[1]);
if (!in_inferior_list (pid))
error ("Invalid thread group id '%s'", argv[1]);
old_chain = make_cleanup_restore_current_thread ();
iterate_over_threads (proceed_thread_callback, &pid);
do_cleanups (old_chain);
}
else
error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
}
/* continue in reverse direction:
XXX: code duplicated from reverse.c */
static void
exec_direction_default (void *notused)
{
/* Return execution direction to default state. */
execution_direction = EXEC_FORWARD;
}
static void
exec_reverse_continue (char **argv, int argc)
{
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."));
if (!target_can_execute_reverse)
error (_("Target %s does not support this command."), target_shortname);
old_chain = make_cleanup (exec_direction_default, NULL);
execution_direction = EXEC_REVERSE;
exec_continue (argv, argc);
do_cleanups (old_chain);
}
void
mi_cmd_exec_continue (char *command, char **argv, int argc)
{
if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
exec_reverse_continue (argv + 1, argc - 1);
else
exec_continue (argv, argc);
}
----
This code is much more complex than for the other MI reverse commands, where the
logic is very simple:
----
void
mi_cmd_exec_step (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
else
mi_execute_async_cli_command ("step", argv, argc);
}
----
To me, it is not clear why MI has to do such a special thing with the "continue"
command at all. I assume there is a good reason for having the management of
-all and -thread-group inside the MI code?
Note that the standard gdb7 non-reversible MI does this for the continue
command:
----
void
mi_cmd_exec_continue (char *command, char **argv, int argc)
{
if (argc == 0)
continue_1 (0);
else if (argc == 1 && strcmp (argv[0], "--all") == 0)
continue_1 (1);
else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
{
struct cleanup *old_chain;
int pid;
if (argv[1] == NULL || argv[1] == '\0')
error ("Thread group id not specified");
pid = atoi (argv[1]);
if (!in_inferior_list (pid))
error ("Invalid thread group id '%s'", argv[1]);
old_chain = make_cleanup_restore_current_thread ();
iterate_over_threads (proceed_thread_callback, &pid);
do_cleanups (old_chain);
}
else
error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
}
----
Given this, the safest thing to do appears to be to maintain the current special
handling for reverse continue. This works as a wrapper around the core code
from mi_cmd_exec_continue, with an additional setting of direction before
calling it.
/jakob
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: GDB MI Reverse Commands added [1 of 3]
2009-12-22 18:22 ` Michael Snyder
2010-01-13 13:16 ` Jakob Engblom
@ 2010-02-12 21:33 ` Michael Snyder
1 sibling, 0 replies; 27+ messages in thread
From: Michael Snyder @ 2010-02-12 21:33 UTC (permalink / raw)
To: Michael Snyder
Cc: Jakob Engblom, 'Vladimir Prus', gdb-patches, 'Hui Zhu'
[-- Attachment #1: Type: text/plain, Size: 58 bytes --]
per private email from Volodya, checked in as follows:
[-- Attachment #2: main.txt --]
[-- Type: text/plain, Size: 4150 bytes --]
2010-02-12 Tomas Holmberg <th@virtutech.com>
* mi/mi-main.c: Added the --reverse flag to the following MI
commands: exec-continue, exec-finish, exec-next, exec-step,
exec-next-instruction, exec-step-instruction. This is to
support reverse execution over the MI interface to gdb.
Index: mi/mi-main.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
retrieving revision 1.164
retrieving revision 1.165
diff -u -p -r1.164 -r1.165
--- mi/mi-main.c 4 Feb 2010 07:37:36 -0000 1.164
+++ mi/mi-main.c 12 Feb 2010 21:28:25 -0000 1.165
@@ -121,35 +121,50 @@ void
mi_cmd_exec_next (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("next", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("next", argv, argc);
}
void
mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("nexti", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("nexti", argv, argc);
}
void
mi_cmd_exec_step (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("step", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("step", argv, argc);
}
void
mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("stepi", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("stepi", argv, argc);
}
void
mi_cmd_exec_finish (char *command, char **argv, int argc)
{
/* FIXME: Should call a libgdb function, not a cli wrapper. */
- mi_execute_async_cli_command ("finish", argv, argc);
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
+ else
+ mi_execute_async_cli_command ("finish", argv, argc);
}
void
@@ -195,8 +210,8 @@ proceed_thread_callback (struct thread_i
return 0;
}
-void
-mi_cmd_exec_continue (char *command, char **argv, int argc)
+static void
+exec_continue (char **argv, int argc)
{
if (argc == 0)
continue_1 (0);
@@ -217,7 +232,47 @@ mi_cmd_exec_continue (char *command, cha
do_cleanups (old_chain);
}
else
- error ("Usage: -exec-continue [--all|--thread-group id]");
+ error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
+}
+
+/* continue in reverse direction:
+ XXX: code duplicated from reverse.c */
+
+static void
+exec_direction_default (void *notused)
+{
+ /* Return execution direction to default state. */
+ execution_direction = EXEC_FORWARD;
+}
+
+static void
+exec_reverse_continue (char **argv, int argc)
+{
+ 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."));
+
+ if (!target_can_execute_reverse)
+ error (_("Target %s does not support this command."), target_shortname);
+
+ old_chain = make_cleanup (exec_direction_default, NULL);
+ execution_direction = EXEC_REVERSE;
+ exec_continue (argv, argc);
+ do_cleanups (old_chain);
+}
+
+void
+mi_cmd_exec_continue (char *command, char **argv, int argc)
+{
+ if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
+ exec_reverse_continue (argv + 1, argc - 1);
+ else
+ exec_continue (argv, argc);
}
static int
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: GDB MI Reverse Commands added [1 of 3]
2009-08-26 14:38 GDB MI Reverse Commands added [1 of 3] Jakob Engblom
2009-08-27 1:13 ` Michael Snyder
2009-08-27 2:06 ` Michael Snyder
@ 2009-08-27 3:11 ` Hui Zhu
2 siblings, 0 replies; 27+ messages in thread
From: Hui Zhu @ 2009-08-27 3:11 UTC (permalink / raw)
To: Jakob Engblom; +Cc: gdb-patches
Cool! Thanks for your work. :)
Hui
On Wed, Aug 26, 2009 at 22:37, Jakob Engblom<jakob@virtutech.com> wrote:
> Here are the patches adding the MI commands for reverse execution to gdb.
>
> Changelog entry: "Added reverse debugging support to gdb MI"
>
> cvs diff: Diffing gdb/mi
> Index: gdb/mi/mi-main.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/mi/mi-main.c,v
> retrieving revision 1.156
> diff -c -p -r1.156 mi-main.c
> *** gdb/mi/mi-main.c 2 Jul 2009 17:25:59 -0000 1.156
> --- gdb/mi/mi-main.c 25 Aug 2009 14:40:18 -0000
> *************** static void mi_cmd_execute (struct mi_pa
> *** 88,94 ****
>
> static void mi_execute_cli_command (const char *cmd, int args_p,
> const char *args);
> ! static void mi_execute_async_cli_command (char *cli_command,
> char **argv, int argc);
> static int register_changed_p (int regnum, struct regcache *,
> struct regcache *);
> --- 88,94 ----
>
> static void mi_execute_cli_command (const char *cmd, int args_p,
> const char *args);
> ! static void mi_execute_async_cli_command (char *cli_command,
> char **argv, int argc);
> static int register_changed_p (int regnum, struct regcache *,
> struct regcache *);
> *************** void
> *** 119,153 ****
> mi_cmd_exec_next (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! mi_execute_async_cli_command ("next", argv, argc);
> }
>
> void
> mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! mi_execute_async_cli_command ("nexti", argv, argc);
> }
>
> void
> mi_cmd_exec_step (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! mi_execute_async_cli_command ("step", argv, argc);
> }
>
> void
> mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! mi_execute_async_cli_command ("stepi", argv, argc);
> }
>
> void
> mi_cmd_exec_finish (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! mi_execute_async_cli_command ("finish", argv, argc);
> }
>
> void
> --- 119,168 ----
> mi_cmd_exec_next (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> ! mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
> ! else
> ! mi_execute_async_cli_command ("next", argv, argc);
> }
>
> void
> mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> ! mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
> ! else
> ! mi_execute_async_cli_command ("nexti", argv, argc);
> }
>
> void
> mi_cmd_exec_step (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> ! mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
> ! else
> ! mi_execute_async_cli_command ("step", argv, argc);
> }
>
> void
> mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> ! mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
> ! else
> ! mi_execute_async_cli_command ("stepi", argv, argc);
> }
>
> void
> mi_cmd_exec_finish (char *command, char **argv, int argc)
> {
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> ! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> ! mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
> ! else
> ! mi_execute_async_cli_command ("finish", argv, argc);
> }
>
> void
> *************** mi_cmd_exec_jump (char *args, char **arg
> *** 175,181 ****
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> return mi_execute_async_cli_command ("jump", argv, argc);
> }
> !
> static int
> proceed_thread_callback (struct thread_info *thread, void *arg)
> {
> --- 190,196 ----
> /* FIXME: Should call a libgdb function, not a cli wrapper. */
> return mi_execute_async_cli_command ("jump", argv, argc);
> }
> !
> static int
> proceed_thread_callback (struct thread_info *thread, void *arg)
> {
> *************** proceed_thread_callback (struct thread_i
> *** 193,200 ****
> return 0;
> }
>
> ! void
> ! mi_cmd_exec_continue (char *command, char **argv, int argc)
> {
> if (argc == 0)
> continue_1 (0);
> --- 208,215 ----
> return 0;
> }
>
> ! static void
> ! exec_continue (char **argv, int argc)
> {
> if (argc == 0)
> continue_1 (0);
> *************** mi_cmd_exec_continue (char *command, cha
> *** 212,221 ****
>
> old_chain = make_cleanup_restore_current_thread ();
> iterate_over_threads (proceed_thread_callback, &pid);
> ! do_cleanups (old_chain);
> }
> else
> ! error ("Usage: -exec-continue [--all|--thread-group id]");
> }
>
> static int
> --- 227,276 ----
>
> old_chain = make_cleanup_restore_current_thread ();
> iterate_over_threads (proceed_thread_callback, &pid);
> ! do_cleanups (old_chain);
> }
> else
> ! error ("Usage: -exec-continue [--reverse] [--all|--thread-group id]");
> ! }
> !
> ! /* continue in reverse direction:
> ! XXX: code duplicated from reverse.c */
> !
> ! static void
> ! exec_direction_default (void *notused)
> ! {
> ! /* Return execution direction to default state. */
> ! execution_direction = EXEC_FORWARD;
> ! }
> !
> ! static void
> ! exec_reverse_continue (char **argv, int argc)
> ! {
> ! 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."));
> !
> ! if (!target_can_execute_reverse)
> ! error (_("Target %s does not support this command."), target_shortname);
> !
> ! old_chain = make_cleanup (exec_direction_default, NULL);
> ! execution_direction = EXEC_REVERSE;
> ! exec_continue (argv, argc);
> ! do_cleanups (old_chain);
> ! }
> !
> ! void
> ! mi_cmd_exec_continue (char *command, char **argv, int argc)
> ! {
> ! if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
> ! exec_reverse_continue (argv + 1, argc - 1);
> ! else
> ! exec_continue (argv, argc);
> }
>
> static int
> *************** mi_cmd_exec_interrupt (char *command, ch
> *** 252,258 ****
> {
> if (!any_running ())
> error ("Inferior not running.");
> !
> interrupt_target_1 (1);
> }
> else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
> --- 307,313 ----
> {
> if (!any_running ())
> error ("Inferior not running.");
> !
> interrupt_target_1 (1);
> }
> else if (argc == 2 && strcmp (argv[0], "--thread-group") == 0)
> *************** void
> *** 349,355 ****
> mi_cmd_thread_info (char *command, char **argv, int argc)
> {
> int thread = -1;
> !
> if (argc != 0 && argc != 1)
> error ("Invalid MI command");
>
> --- 404,410 ----
> mi_cmd_thread_info (char *command, char **argv, int argc)
> {
> int thread = -1;
> !
> if (argc != 0 && argc != 1)
> error ("Invalid MI command");
>
> *************** print_one_inferior (struct inferior *inf
> *** 367,373 ****
> ui_out_field_fmt (uiout, "id", "%d", inferior->pid);
> ui_out_field_string (uiout, "type", "process");
> ui_out_field_int (uiout, "pid", inferior->pid);
> !
> do_cleanups (back_to);
> return 0;
> }
> --- 422,428 ----
> ui_out_field_fmt (uiout, "id", "%d", inferior->pid);
> ui_out_field_string (uiout, "type", "process");
> ui_out_field_int (uiout, "pid", inferior->pid);
> !
> do_cleanups (back_to);
> return 0;
> }
> *************** mi_cmd_list_thread_groups (char *command
> *** 433,446 ****
> int pid = atoi (id);
> if (!in_inferior_list (pid))
> error ("Invalid thread group id '%s'", id);
> ! print_thread_info (uiout, -1, pid);
> }
> else
> {
> make_cleanup_ui_out_list_begin_end (uiout, "groups");
> iterate_over_inferiors (print_one_inferior, NULL);
> }
> !
> do_cleanups (back_to);
> }
>
> --- 488,501 ----
> int pid = atoi (id);
> if (!in_inferior_list (pid))
> error ("Invalid thread group id '%s'", id);
> ! print_thread_info (uiout, -1, pid);
> }
> else
> {
> make_cleanup_ui_out_list_begin_end (uiout, "groups");
> iterate_over_inferiors (print_one_inferior, NULL);
> }
> !
> do_cleanups (back_to);
> }
>
> *************** get_register (struct frame_info *frame,
> *** 713,719 ****
> }
>
> /* Write given values into registers. The registers and values are
> ! given as pairs. The corresponding MI command is
> -data-write-register-values <format> [<regnum1> <value1>...<regnumN>
> <valueN>]*/
> void
> mi_cmd_data_write_register_values (char *command, char **argv, int argc)
> --- 768,774 ----
> }
>
> /* Write given values into registers. The registers and values are
> ! given as pairs. The corresponding MI command is
> -data-write-register-values <format> [<regnum1> <value1>...<regnumN>
> <valueN>]*/
> void
> mi_cmd_data_write_register_values (char *command, char **argv, int argc)
> *************** mi_cmd_data_evaluate_expression (char *c
> *** 810,816 ****
> /* DATA-MEMORY-READ:
>
> ADDR: start address of data to be dumped.
> ! WORD-FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
> NR_ROW: Number of rows.
> --- 865,871 ----
> /* DATA-MEMORY-READ:
>
> ADDR: start address of data to be dumped.
> ! WORD-FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
> NR_ROW: Number of rows.
> *************** mi_cmd_data_evaluate_expression (char *c
> *** 823,829 ****
>
> {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
>
> ! Returns:
> The number of bytes read is SIZE*ROW*COL. */
>
> void
> --- 878,884 ----
>
> {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
>
> ! Returns:
> The number of bytes read is SIZE*ROW*COL. */
>
> void
> *************** mi_cmd_data_read_memory (char *command,
> *** 1019,1025 ****
> ADDR: start address of the row in the memory grid where the memory
> cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
> the location to write to.
> ! FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
> VALUE: value to be written into the memory address.
> --- 1074,1080 ----
> ADDR: start address of the row in the memory grid where the memory
> cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
> the location to write to.
> ! FORMAT: a char indicating format for the ``word''. See
> the ``x'' command.
> WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
> VALUE: value to be written into the memory address.
> *************** mi_cmd_enable_timings (char *command, ch
> *** 1112,1118 ****
> }
> else
> goto usage_error;
> !
> return;
>
> usage_error:
> --- 1167,1173 ----
> }
> else
> goto usage_error;
> !
> return;
>
> usage_error:
> *************** mi_cmd_list_features (char *command, cha
> *** 1125,1140 ****
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> ui_out_field_string (uiout, NULL, "frozen-varobjs");
> ui_out_field_string (uiout, NULL, "pending-breakpoints");
> ui_out_field_string (uiout, NULL, "thread-info");
> !
> #if HAVE_PYTHON
> ui_out_field_string (uiout, NULL, "python");
> #endif
> !
> do_cleanups (cleanup);
> return;
> }
> --- 1180,1195 ----
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> ui_out_field_string (uiout, NULL, "frozen-varobjs");
> ui_out_field_string (uiout, NULL, "pending-breakpoints");
> ui_out_field_string (uiout, NULL, "thread-info");
> !
> #if HAVE_PYTHON
> ui_out_field_string (uiout, NULL, "python");
> #endif
> !
> do_cleanups (cleanup);
> return;
> }
> *************** mi_cmd_list_target_features (char *comma
> *** 1148,1158 ****
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> if (target_can_async_p ())
> ui_out_field_string (uiout, NULL, "async");
> !
> do_cleanups (cleanup);
> return;
> }
> --- 1203,1213 ----
> if (argc == 0)
> {
> struct cleanup *cleanup = NULL;
> ! cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
>
> if (target_can_async_p ())
> ui_out_field_string (uiout, NULL, "async");
> !
> do_cleanups (cleanup);
> return;
> }
> *************** captured_mi_execute_command (struct ui_o
> *** 1196,1203 ****
> /* Print the result if there were no errors.
>
> Remember that on the way out of executing a command, you have
> ! to directly use the mi_interp's uiout, since the command could
> ! have reset the interpreter, in which case the current uiout
> will most likely crash in the mi_out_* routines. */
> if (!running_result_record_printed)
> {
> --- 1251,1258 ----
> /* Print the result if there were no errors.
>
> Remember that on the way out of executing a command, you have
> ! to directly use the mi_interp's uiout, since the command could
> ! have reset the interpreter, in which case the current uiout
> will most likely crash in the mi_out_* routines. */
> if (!running_result_record_printed)
> {
> *************** captured_mi_execute_command (struct ui_o
> *** 1244,1250 ****
> mi_out_put (uiout, raw_stdout);
> mi_out_rewind (uiout);
> mi_print_timing_maybe ();
> ! fputs_unfiltered ("\n", raw_stdout);
> }
> else
> mi_out_rewind (uiout);
> --- 1299,1305 ----
> mi_out_put (uiout, raw_stdout);
> mi_out_rewind (uiout);
> mi_print_timing_maybe ();
> ! fputs_unfiltered ("\n", raw_stdout);
> }
> else
> mi_out_rewind (uiout);
> *************** mi_execute_command (char *cmd, int from_
> *** 1302,1310 ****
> }
>
> if (/* The notifications are only output when the top-level
> ! interpreter (specified on the command line) is MI. */
> ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
> ! /* Don't try report anything if there are no threads --
> the program is dead. */
> && thread_count () != 0
> /* -thread-select explicitly changes thread. If frontend uses that
> --- 1357,1365 ----
> }
>
> if (/* The notifications are only output when the top-level
> ! interpreter (specified on the command line) is MI. */
> ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
> ! /* Don't try report anything if there are no threads --
> the program is dead. */
> && thread_count () != 0
> /* -thread-select explicitly changes thread. If frontend uses that
> *************** mi_execute_command (char *cmd, int from_
> *** 1328,1337 ****
> }
>
> if (report_change)
> ! {
> struct thread_info *ti = inferior_thread ();
> target_terminal_ours ();
> ! fprintf_unfiltered (mi->event_channel,
> "thread-selected,id=\"%d\"",
> ti->num);
> gdb_flush (mi->event_channel);
> --- 1383,1392 ----
> }
>
> if (report_change)
> ! {
> struct thread_info *ti = inferior_thread ();
> target_terminal_ours ();
> ! fprintf_unfiltered (mi->event_channel,
> "thread-selected,id=\"%d\"",
> ti->num);
> gdb_flush (mi->event_channel);
> *************** mi_execute_async_cli_command (char *cli_
> *** 1446,1452 ****
> run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
> else
> run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
> ! old_cleanups = make_cleanup (xfree, run);
>
> execute_command ( /*ui */ run, 0 /*from_tty */ );
>
> --- 1501,1507 ----
> run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
> else
> run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
> ! old_cleanups = make_cleanup (xfree, run);
>
> execute_command ( /*ui */ run, 0 /*from_tty */ );
>
> *************** mi_load_progress (const char *section_na
> *** 1551,1557 ****
> uiout = saved_uiout;
> }
>
> ! static void
> timestamp (struct mi_timestamp *tv)
> {
> long usec;
> --- 1606,1612 ----
> uiout = saved_uiout;
> }
>
> ! static void
> timestamp (struct mi_timestamp *tv)
> {
> long usec;
> *************** timestamp (struct mi_timestamp *tv)
> *** 1571,1577 ****
> #endif
> }
>
> ! static void
> print_diff_now (struct mi_timestamp *start)
> {
> struct mi_timestamp now;
> --- 1626,1632 ----
> #endif
> }
>
> ! static void
> print_diff_now (struct mi_timestamp *start)
> {
> struct mi_timestamp now;
> *************** mi_print_timing_maybe (void)
> *** 1588,1607 ****
> print_diff_now (current_command_ts);
> }
>
> ! static long
> timeval_diff (struct timeval start, struct timeval end)
> {
> return ((end.tv_sec - start.tv_sec) * 1000000L)
> + (end.tv_usec - start.tv_usec);
> }
>
> ! static void
> print_diff (struct mi_timestamp *start, struct mi_timestamp *end)
> {
> fprintf_unfiltered
> (raw_stdout,
> ! ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
> ! timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
> ! timeval_diff (start->utime, end->utime) / 1000000.0,
> timeval_diff (start->stime, end->stime) / 1000000.0);
> }
> --- 1643,1662 ----
> print_diff_now (current_command_ts);
> }
>
> ! static long
> timeval_diff (struct timeval start, struct timeval end)
> {
> return ((end.tv_sec - start.tv_sec) * 1000000L)
> + (end.tv_usec - start.tv_usec);
> }
>
> ! static void
> print_diff (struct mi_timestamp *start, struct mi_timestamp *end)
> {
> fprintf_unfiltered
> (raw_stdout,
> ! ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
> ! timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
> ! timeval_diff (start->utime, end->utime) / 1000000.0,
> timeval_diff (start->stime, end->stime) / 1000000.0);
> }
>
>
> Best regards,
>
> /jakob
>
> _______________________________________________________
>
> Jakob Engblom, PhD, Technical Marketing Manager
>
> Virtutech Direct: +46 8 690 07 47
> Drottningholmsvägen 22 Mobile: +46 709 242 646
> 11243 Stockholm Web: www.virtutech.com
> Sweden
> ________________________________________________________
>
>
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread