* [PATCH v2] gdb: add 'maintenance print record-instruction' command @ 2022-12-12 10:44 Bruno Larsen 2022-12-12 13:54 ` Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Bruno Larsen @ 2022-12-12 10:44 UTC (permalink / raw) To: gdb-patches; +Cc: Bruno Larsen While chasing some reverse debugging bugs, I found myself wondering what was recorded by GDB to undo and redo a certain instruction. This commit implements a simple way of printing that information. --- gdb/NEWS | 6 ++++ gdb/doc/gdb.texinfo | 8 +++++ gdb/record-full.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/gdb/NEWS b/gdb/NEWS index c4ccfcc9e32..d6ce6bf86a0 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -103,6 +103,12 @@ * New commands +maintenance print record-instruction [ N ] + Print the recorded information for a given instruction. If N is not given + prints how GDB would undo the last instruction executed. If N is negative, + prints how GDB would undo the N-th previous instruction, and if N is + positive, it prints how GDB will redo the N-th following instruction. + maintenance set ignore-prologue-end-flag on|off maintenance show ignore-prologue-end-flag This setting, which is off by default, controls whether GDB ignores the diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 5b566669975..807af351e79 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -40531,6 +40531,14 @@ that symbol is described. The type chain produced by this command is a recursive definition of the data type as stored in @value{GDBN}'s data structures, including its flags and contained types. +@kindex maint print record-instruction +@item maint print record-instruction +@itemx maint print record-instruction @var{N} +@cindex print how GDB recorded a given instruction. If N is not positive +number, it prints the values stored by the inferior before the N-th previous +instruction was exectued. If N is positive, print the values after the N-th +following instruction is executed. If N is not given, 0 is assumed. + @kindex maint selftest @cindex self tests @item maint selftest @r{[}-verbose@r{]} @r{[}@var{filter}@r{]} diff --git a/gdb/record-full.c b/gdb/record-full.c index 48b92281fe6..25e1fd22c6f 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -2764,6 +2764,79 @@ set_record_full_insn_max_num (const char *args, int from_tty, } } +/* Implement the 'maintenance print record-instruction' command. */ + +static void +maintenance_print_record_instruction (const char *args, int from_tty) +{ + struct record_full_entry* to_print = record_full_list; + + if (args != nullptr) + { + int offset = value_as_long (parse_and_eval (args)); + if (offset > 0) + { + /* Move forward OFFSET instructions. We know we found the + end of an instruction when to_print->type is 0. */ + while (to_print->next != nullptr && offset > 0) + { + to_print = to_print->next; + if (to_print->type == record_full_end) + offset--; + } + if (offset != 0) + error (_("Not enough recorded history")); + } + else + { + while (to_print->prev != nullptr && offset < 0) + { + to_print = to_print->prev; + if (to_print->type == record_full_end) + offset++; + } + if (offset != 0) + error (_("Not enough recorded history")); + } + } + gdb_assert (to_print != nullptr); + + /* Go back to the start of the instruction. */ + while (to_print->prev != nullptr && to_print->prev->type != record_full_end) + to_print = to_print->prev; + + while (to_print->type != record_full_end) + { + switch (to_print->type) + { + case record_full_reg: + { + gdb_byte* b = record_full_get_loc (to_print); + gdb_printf ("Register %%%s changed:", + gdbarch_register_name (target_gdbarch (), + to_print->u.reg.num)); + for (int i = 0; i < to_print->u.reg.len; i++) + gdb_printf (" %02x",b[i]); + gdb_printf ("\n"); + break; + } + case record_full_mem: + { + gdb_byte* b = record_full_get_loc (to_print); + gdb_printf ("%d bytes of memory at address %s changed from:", + to_print->u.mem.len, + print_core_address (target_gdbarch (), + to_print->u.mem.addr)); + for (int i = 0; i < to_print->u.mem.len; i++) + gdb_printf (" %02x",b[i]); + gdb_printf ("\n"); + break; + } + } + to_print = to_print->next; + } +} + void _initialize_record_full (); void _initialize_record_full () @@ -2868,4 +2941,12 @@ When ON, query if PREC cannot record memory change of next instruction."), c = add_alias_cmd ("memory-query", record_full_memory_query_cmds.show, no_class, 1,&show_record_cmdlist); deprecate_cmd (c, "show record full memory-query"); + + add_cmd ("record-instruction", class_maintenance, + maintenance_print_record_instruction, + _("\ +Print a recorded instruction.\nIf no argument is provided, print the last \ +instruction recorded.\nIf a negative argument is given, prints how the nth \ +previous instruction will be undone.\nIf a positive argument is given, prints \ +how the nth following instruction will be redone."), &maintenanceprintlist); } -- 2.38.1 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] gdb: add 'maintenance print record-instruction' command 2022-12-12 10:44 [PATCH v2] gdb: add 'maintenance print record-instruction' command Bruno Larsen @ 2022-12-12 13:54 ` Eli Zaretskii 2022-12-14 0:46 ` Lancelot SIX 2022-12-16 13:25 ` Pedro Alves 2 siblings, 0 replies; 7+ messages in thread From: Eli Zaretskii @ 2022-12-12 13:54 UTC (permalink / raw) To: Bruno Larsen; +Cc: gdb-patches > Cc: Bruno Larsen <blarsen@redhat.com> > Date: Mon, 12 Dec 2022 11:44:17 +0100 > From: Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org> > > While chasing some reverse debugging bugs, I found myself wondering what > was recorded by GDB to undo and redo a certain instruction. This commit > implements a simple way of printing that information. > --- > gdb/NEWS | 6 ++++ > gdb/doc/gdb.texinfo | 8 +++++ > gdb/record-full.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 95 insertions(+) Thanks. > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -103,6 +103,12 @@ > > * New commands > > +maintenance print record-instruction [ N ] > + Print the recorded information for a given instruction. If N is not given > + prints how GDB would undo the last instruction executed. If N is negative, > + prints how GDB would undo the N-th previous instruction, and if N is > + positive, it prints how GDB will redo the N-th following instruction. This part is OK. > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -40531,6 +40531,14 @@ that symbol is described. The type chain produced by this command is > a recursive definition of the data type as stored in @value{GDBN}'s > data structures, including its flags and contained types. > > +@kindex maint print record-instruction > +@item maint print record-instruction > +@itemx maint print record-instruction @var{N} > +@cindex print how GDB recorded a given instruction. If N is not positive ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some editing snafu happened here, it seems? > +number, it prints the values stored by the inferior before the N-th previous > +instruction was exectued. If N is positive, print the values after the N-th > +following instruction is executed. If N is not given, 0 is assumed. In all places where you use "M" (upper-case), you should use "@var{n}" (with @var and in lower-case). The gdb.texinfo part is OK with those nits fixed. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] gdb: add 'maintenance print record-instruction' command 2022-12-12 10:44 [PATCH v2] gdb: add 'maintenance print record-instruction' command Bruno Larsen 2022-12-12 13:54 ` Eli Zaretskii @ 2022-12-14 0:46 ` Lancelot SIX 2022-12-14 10:04 ` Lancelot SIX 2022-12-16 10:03 ` Bruno Larsen 2022-12-16 13:25 ` Pedro Alves 2 siblings, 2 replies; 7+ messages in thread From: Lancelot SIX @ 2022-12-14 0:46 UTC (permalink / raw) To: Bruno Larsen; +Cc: gdb-patches Hi Bruno, I have a couple more comments and suggestions below. On Mon, Dec 12, 2022 at 11:44:17AM +0100, Bruno Larsen via Gdb-patches wrote: > While chasing some reverse debugging bugs, I found myself wondering what > was recorded by GDB to undo and redo a certain instruction. This commit > implements a simple way of printing that information. > --- > gdb/NEWS | 6 ++++ > gdb/doc/gdb.texinfo | 8 +++++ > gdb/record-full.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 95 insertions(+) > > diff --git a/gdb/NEWS b/gdb/NEWS > index c4ccfcc9e32..d6ce6bf86a0 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -103,6 +103,12 @@ > > * New commands > > +maintenance print record-instruction [ N ] > + Print the recorded information for a given instruction. If N is not given > + prints how GDB would undo the last instruction executed. If N is negative, > + prints how GDB would undo the N-th previous instruction, and if N is > + positive, it prints how GDB will redo the N-th following instruction. > + > maintenance set ignore-prologue-end-flag on|off > maintenance show ignore-prologue-end-flag > This setting, which is off by default, controls whether GDB ignores the > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index 5b566669975..807af351e79 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -40531,6 +40531,14 @@ that symbol is described. The type chain produced by this command is > a recursive definition of the data type as stored in @value{GDBN}'s > data structures, including its flags and contained types. > > +@kindex maint print record-instruction > +@item maint print record-instruction > +@itemx maint print record-instruction @var{N} > +@cindex print how GDB recorded a given instruction. If N is not positive > +number, it prints the values stored by the inferior before the N-th previous > +instruction was exectued. If N is positive, print the values after the N-th > +following instruction is executed. If N is not given, 0 is assumed. > + > @kindex maint selftest > @cindex self tests > @item maint selftest @r{[}-verbose@r{]} @r{[}@var{filter}@r{]} > diff --git a/gdb/record-full.c b/gdb/record-full.c > index 48b92281fe6..25e1fd22c6f 100644 > --- a/gdb/record-full.c > +++ b/gdb/record-full.c > @@ -2764,6 +2764,79 @@ set_record_full_insn_max_num (const char *args, int from_tty, > } > } > > +/* Implement the 'maintenance print record-instruction' command. */ > + > +static void > +maintenance_print_record_instruction (const char *args, int from_tty) > +{ > + struct record_full_entry* to_print = record_full_list; > + > + if (args != nullptr) > + { > + int offset = value_as_long (parse_and_eval (args)); > + if (offset > 0) > + { > + /* Move forward OFFSET instructions. We know we found the > + end of an instruction when to_print->type is 0. */ I think the literal 0 in the comment is a left-over from V1, right? > + while (to_print->next != nullptr && offset > 0) > + { > + to_print = to_print->next; > + if (to_print->type == record_full_end) > + offset--; > + } > + if (offset != 0) > + error (_("Not enough recorded history")); > + } > + else > + { > + while (to_print->prev != nullptr && offset < 0) > + { > + to_print = to_print->prev; > + if (to_print->type == record_full_end) > + offset++; > + } > + if (offset != 0) > + error (_("Not enough recorded history")); > + } > + } > + gdb_assert (to_print != nullptr); > + > + /* Go back to the start of the instruction. */ > + while (to_print->prev != nullptr && to_print->prev->type != record_full_end) > + to_print = to_print->prev; > + > + while (to_print->type != record_full_end) > + { > + switch (to_print->type) > + { > + case record_full_reg: > + { > + gdb_byte* b = record_full_get_loc (to_print); ^^ The space comes before the * here. > + gdb_printf ("Register %%%s changed:", The '%' prefix for register names is specific to the att assembler syntax. Do we want this here? I think in most places GDB uses the plain register name without such prefix. > + gdbarch_register_name (target_gdbarch (), > + to_print->u.reg.num)); > + for (int i = 0; i < to_print->u.reg.len; i++) > + gdb_printf (" %02x",b[i]); ^ Space after the ",". > + gdb_printf ("\n"); Did you consider printing the register value instead of the bytes composing the value? I think something like this could do: auto mark = value_mark (); type *regtype = gdbarch_register_type (target_gdbarch (), to_print->u.reg.num); value *val = value_from_contents (regtype, record_full_get_loc (to_print)); gdb_printf ("Register %s changed: %s\n", gdbarch_register_name (target_gdbarch (), to_print->u.reg.num), hex_string (value_as_long (val))); value_free_to_mark (mark); This would however not work for vector registers (anything which does not fit in a long long). You might want to use something like `value_print` to handle all cases, unless its output is too fancy: struct value_print_options opts; get_user_print_options (&opts); auto mark = value_mark (); type *regtype = gdbarch_register_type (target_gdbarch (), to_print->u.reg.num); value *val = value_from_contents (regtype, record_full_get_loc (to_print)); gdb_printf ("Register %s changed: %s\n", gdbarch_register_name (target_gdbarch (), to_print->u.reg.num)); value_print (val, gdb_stdout, &opts); gdb_printf ("\n"); value_free_to_mark (mark); Not sure if there is a cleaner way to achieve this, but it should do the trick. > + break; > + } > + case record_full_mem: > + { > + gdb_byte* b = record_full_get_loc (to_print); Same here, the space shoud be before the "*". > + gdb_printf ("%d bytes of memory at address %s changed from:", > + to_print->u.mem.len, > + print_core_address (target_gdbarch (), > + to_print->u.mem.addr)); > + for (int i = 0; i < to_print->u.mem.len; i++) > + gdb_printf (" %02x",b[i]); Space after the ",". Best, Lancelot. > + gdb_printf ("\n"); > + break; > + } > + } > + to_print = to_print->next; > + } > +} > + > void _initialize_record_full (); > void > _initialize_record_full () > @@ -2868,4 +2941,12 @@ When ON, query if PREC cannot record memory change of next instruction."), > c = add_alias_cmd ("memory-query", record_full_memory_query_cmds.show, > no_class, 1,&show_record_cmdlist); > deprecate_cmd (c, "show record full memory-query"); > + > + add_cmd ("record-instruction", class_maintenance, > + maintenance_print_record_instruction, > + _("\ > +Print a recorded instruction.\nIf no argument is provided, print the last \ > +instruction recorded.\nIf a negative argument is given, prints how the nth \ > +previous instruction will be undone.\nIf a positive argument is given, prints \ > +how the nth following instruction will be redone."), &maintenanceprintlist); > } > -- > 2.38.1 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] gdb: add 'maintenance print record-instruction' command 2022-12-14 0:46 ` Lancelot SIX @ 2022-12-14 10:04 ` Lancelot SIX 2022-12-14 16:30 ` Tom Tromey 2022-12-16 10:03 ` Bruno Larsen 1 sibling, 1 reply; 7+ messages in thread From: Lancelot SIX @ 2022-12-14 10:04 UTC (permalink / raw) To: Bruno Larsen, gdb-patches > struct value_print_options opts; > get_user_print_options (&opts); > auto mark = value_mark (); Hi, I forgot about scoped_value_mark which is probably much better than manually doing the value_mark () ; value_free_to_mark () dance. Lancelot. > type *regtype = gdbarch_register_type (target_gdbarch (), > to_print->u.reg.num); > value *val > = value_from_contents (regtype, record_full_get_loc (to_print)); > > gdb_printf ("Register %s changed: %s\n", > gdbarch_register_name (target_gdbarch (), > to_print->u.reg.num)); > value_print (val, gdb_stdout, &opts); > gdb_printf ("\n"); > value_free_to_mark (mark); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] gdb: add 'maintenance print record-instruction' command 2022-12-14 10:04 ` Lancelot SIX @ 2022-12-14 16:30 ` Tom Tromey 0 siblings, 0 replies; 7+ messages in thread From: Tom Tromey @ 2022-12-14 16:30 UTC (permalink / raw) To: Lancelot SIX via Gdb-patches; +Cc: Bruno Larsen, Lancelot SIX Lancelot> I forgot about scoped_value_mark which is probably much better than Lancelot> manually doing the value_mark () ; value_free_to_mark () dance. You don't normally need to bother with this at all, it's automatically managed by the command loop. Tom ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] gdb: add 'maintenance print record-instruction' command 2022-12-14 0:46 ` Lancelot SIX 2022-12-14 10:04 ` Lancelot SIX @ 2022-12-16 10:03 ` Bruno Larsen 1 sibling, 0 replies; 7+ messages in thread From: Bruno Larsen @ 2022-12-16 10:03 UTC (permalink / raw) To: Lancelot SIX; +Cc: gdb-patches On 14/12/2022 01:46, Lancelot SIX wrote: > Hi Bruno, > > I have a couple more comments and suggestions below. > > On Mon, Dec 12, 2022 at 11:44:17AM +0100, Bruno Larsen via Gdb-patches wrote: >> While chasing some reverse debugging bugs, I found myself wondering what >> was recorded by GDB to undo and redo a certain instruction. This commit >> implements a simple way of printing that information. >> --- >> gdb/NEWS | 6 ++++ >> gdb/doc/gdb.texinfo | 8 +++++ >> gdb/record-full.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ >> 3 files changed, 95 insertions(+) >> >> diff --git a/gdb/NEWS b/gdb/NEWS >> index c4ccfcc9e32..d6ce6bf86a0 100644 >> --- a/gdb/NEWS >> +++ b/gdb/NEWS >> @@ -103,6 +103,12 @@ >> >> * New commands >> >> +maintenance print record-instruction [ N ] >> + Print the recorded information for a given instruction. If N is not given >> + prints how GDB would undo the last instruction executed. If N is negative, >> + prints how GDB would undo the N-th previous instruction, and if N is >> + positive, it prints how GDB will redo the N-th following instruction. >> + >> maintenance set ignore-prologue-end-flag on|off >> maintenance show ignore-prologue-end-flag >> This setting, which is off by default, controls whether GDB ignores the >> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo >> index 5b566669975..807af351e79 100644 >> --- a/gdb/doc/gdb.texinfo >> +++ b/gdb/doc/gdb.texinfo >> @@ -40531,6 +40531,14 @@ that symbol is described. The type chain produced by this command is >> a recursive definition of the data type as stored in @value{GDBN}'s >> data structures, including its flags and contained types. >> >> +@kindex maint print record-instruction >> +@item maint print record-instruction >> +@itemx maint print record-instruction @var{N} >> +@cindex print how GDB recorded a given instruction. If N is not positive >> +number, it prints the values stored by the inferior before the N-th previous >> +instruction was exectued. If N is positive, print the values after the N-th >> +following instruction is executed. If N is not given, 0 is assumed. >> + >> @kindex maint selftest >> @cindex self tests >> @item maint selftest @r{[}-verbose@r{]} @r{[}@var{filter}@r{]} >> diff --git a/gdb/record-full.c b/gdb/record-full.c >> index 48b92281fe6..25e1fd22c6f 100644 >> --- a/gdb/record-full.c >> +++ b/gdb/record-full.c >> @@ -2764,6 +2764,79 @@ set_record_full_insn_max_num (const char *args, int from_tty, >> } >> } >> >> +/* Implement the 'maintenance print record-instruction' command. */ >> + >> +static void >> +maintenance_print_record_instruction (const char *args, int from_tty) >> +{ >> + struct record_full_entry* to_print = record_full_list; >> + >> + if (args != nullptr) >> + { >> + int offset = value_as_long (parse_and_eval (args)); >> + if (offset > 0) >> + { >> + /* Move forward OFFSET instructions. We know we found the >> + end of an instruction when to_print->type is 0. */ > I think the literal 0 in the comment is a left-over from V1, right? > >> + while (to_print->next != nullptr && offset > 0) >> + { >> + to_print = to_print->next; >> + if (to_print->type == record_full_end) >> + offset--; >> + } >> + if (offset != 0) >> + error (_("Not enough recorded history")); >> + } >> + else >> + { >> + while (to_print->prev != nullptr && offset < 0) >> + { >> + to_print = to_print->prev; >> + if (to_print->type == record_full_end) >> + offset++; >> + } >> + if (offset != 0) >> + error (_("Not enough recorded history")); >> + } >> + } >> + gdb_assert (to_print != nullptr); >> + >> + /* Go back to the start of the instruction. */ >> + while (to_print->prev != nullptr && to_print->prev->type != record_full_end) >> + to_print = to_print->prev; >> + >> + while (to_print->type != record_full_end) >> + { >> + switch (to_print->type) >> + { >> + case record_full_reg: >> + { >> + gdb_byte* b = record_full_get_loc (to_print); > ^^ > > The space comes before the * here. > >> + gdb_printf ("Register %%%s changed:", > The '%' prefix for register names is specific to the att assembler > syntax. Do we want this here? I think in most places GDB uses the > plain register name without such prefix. > >> + gdbarch_register_name (target_gdbarch (), >> + to_print->u.reg.num)); >> + for (int i = 0; i < to_print->u.reg.len; i++) >> + gdb_printf (" %02x",b[i]); > ^ > Space after the ",". > >> + gdb_printf ("\n"); > Did you consider printing the register value instead of the bytes > composing the value? I think something like this could do: > > auto mark = value_mark (); > type *regtype = gdbarch_register_type (target_gdbarch (), > to_print->u.reg.num); > value *val > = value_from_contents (regtype, record_full_get_loc (to_print)); > > gdb_printf ("Register %s changed: %s\n", > gdbarch_register_name (target_gdbarch (), > to_print->u.reg.num), > hex_string (value_as_long (val))); > value_free_to_mark (mark); > > This would however not work for vector registers (anything which does > not fit in a long long). You might want to use something like > `value_print` to handle all cases, unless its output is too fancy: > > struct value_print_options opts; > get_user_print_options (&opts); > auto mark = value_mark (); > type *regtype = gdbarch_register_type (target_gdbarch (), > to_print->u.reg.num); > value *val > = value_from_contents (regtype, record_full_get_loc (to_print)); > > gdb_printf ("Register %s changed: %s\n", > gdbarch_register_name (target_gdbarch (), > to_print->u.reg.num)); > value_print (val, gdb_stdout, &opts); > gdb_printf ("\n"); > value_free_to_mark (mark); > > Not sure if there is a cleaner way to achieve this, but it should do the > trick. Hi Lancelot, Thanks for the review, I've fixed all the style nits. I wasn't aware of how to do this, thanks for explaining! I was a bit reticent of using the value_as_long option specifically because I wanted to handle all types of registers, but if I can make value_print work it will definitely be better. However, when I tried this I got the following output: (gdb) maint print record-instruction 8 bytes of memory at address 0x00007fffffffde48 changed from: e0 de ff ff ff 7f 00 00 (gdb) Register rip changed: (void (*)()) 0x40113e <main+8> I see a few issues here: * The casting at the front is pretty confusing. I want the printing to be raw so the user can see what is going on * I'm not necessary fond of the <main+8> at the end, mostly because I am worried that it might be misplaced in other instances * it is being printed after the gdb prompt I'm saying this mostly because it will probably take me a while to make a new version, but I really appreciate your feedback! -- Cheers, Bruno > >> + break; >> + } >> + case record_full_mem: >> + { >> + gdb_byte* b = record_full_get_loc (to_print); > Same here, the space shoud be before the "*". > >> + gdb_printf ("%d bytes of memory at address %s changed from:", >> + to_print->u.mem.len, >> + print_core_address (target_gdbarch (), >> + to_print->u.mem.addr)); >> + for (int i = 0; i < to_print->u.mem.len; i++) >> + gdb_printf (" %02x",b[i]); > Space after the ",". > > Best, > Lancelot. > >> + gdb_printf ("\n"); >> + break; >> + } >> + } >> + to_print = to_print->next; >> + } >> +} >> + >> void _initialize_record_full (); >> void >> _initialize_record_full () >> @@ -2868,4 +2941,12 @@ When ON, query if PREC cannot record memory change of next instruction."), >> c = add_alias_cmd ("memory-query", record_full_memory_query_cmds.show, >> no_class, 1,&show_record_cmdlist); >> deprecate_cmd (c, "show record full memory-query"); >> + >> + add_cmd ("record-instruction", class_maintenance, >> + maintenance_print_record_instruction, >> + _("\ >> +Print a recorded instruction.\nIf no argument is provided, print the last \ >> +instruction recorded.\nIf a negative argument is given, prints how the nth \ >> +previous instruction will be undone.\nIf a positive argument is given, prints \ >> +how the nth following instruction will be redone."), &maintenanceprintlist); >> } >> -- >> 2.38.1 >> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] gdb: add 'maintenance print record-instruction' command 2022-12-12 10:44 [PATCH v2] gdb: add 'maintenance print record-instruction' command Bruno Larsen 2022-12-12 13:54 ` Eli Zaretskii 2022-12-14 0:46 ` Lancelot SIX @ 2022-12-16 13:25 ` Pedro Alves 2 siblings, 0 replies; 7+ messages in thread From: Pedro Alves @ 2022-12-16 13:25 UTC (permalink / raw) To: Bruno Larsen, gdb-patches On 2022-12-12 10:44 a.m., Bruno Larsen via Gdb-patches wrote: > While chasing some reverse debugging bugs, I found myself wondering what > was recorded by GDB to undo and redo a certain instruction. This commit > implements a simple way of printing that information. Please include an example of this working in the commit log. > --- > gdb/NEWS | 6 ++++ > gdb/doc/gdb.texinfo | 8 +++++ > gdb/record-full.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 95 insertions(+) > > diff --git a/gdb/NEWS b/gdb/NEWS > index c4ccfcc9e32..d6ce6bf86a0 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -103,6 +103,12 @@ > > * New commands > > +maintenance print record-instruction [ N ] > + Print the recorded information for a given instruction. If N is not given > + prints how GDB would undo the last instruction executed. If N is negative, > + prints how GDB would undo the N-th previous instruction, and if N is > + positive, it prints how GDB will redo the N-th following instruction. I noticed missing double space after period in the sentences above. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-12-16 13:25 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-12-12 10:44 [PATCH v2] gdb: add 'maintenance print record-instruction' command Bruno Larsen 2022-12-12 13:54 ` Eli Zaretskii 2022-12-14 0:46 ` Lancelot SIX 2022-12-14 10:04 ` Lancelot SIX 2022-12-14 16:30 ` Tom Tromey 2022-12-16 10:03 ` Bruno Larsen 2022-12-16 13:25 ` Pedro Alves
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).