From: Guinevere Larsen <guinevere@redhat.com>
To: gdb-patches@sourceware.org
Cc: Guinevere Larsen <guinevere@redhat.com>
Subject: [PATCH v2 3/6] gdb/record: c++ify internal structures of record-full.c
Date: Thu, 23 Apr 2026 12:26:01 -0300 [thread overview]
Message-ID: <20260423152604.171356-4-guinevere@redhat.com> (raw)
In-Reply-To: <20260423152604.171356-1-guinevere@redhat.com>
This commit adds a constructor, destructor, and some methods to the
structures record_full_entry, record_full_reg_entry and
record_full_mem_entry. This is a move to disentangle the internal
representation of the data and how record-full manipulates it for
replaying.
Along with this change, record_full_entry is changed to use an
std::variant, since it was basically doing that already, but now we have
the stdlibc++ error checking to make sure we're only accessing elements
we're allowed to.
---
gdb/record-full.c | 553 ++++++++++++++++++++++++----------------------
1 file changed, 289 insertions(+), 264 deletions(-)
diff --git a/gdb/record-full.c b/gdb/record-full.c
index 613dd166881..6e3907325cd 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -48,6 +48,7 @@
#include "cli/cli-style.h"
#include <signal.h>
+#include <variant>
/* This module implements "target record-full", also known as "process
record and replay". This target sits on top of a "normal" target
@@ -90,12 +91,92 @@ struct record_full_mem_entry
int len;
/* Set this flag if target memory for this entry
can no longer be accessed. */
- int mem_entry_not_accessible;
+ bool mem_entry_accessible;
union
{
gdb_byte *ptr;
gdb_byte buf[sizeof (gdb_byte *)];
} u;
+
+ record_full_mem_entry () : addr (0), len (0) { }
+
+ record_full_mem_entry (CORE_ADDR mem_addr, int mem_len)
+ {
+ addr = mem_addr;
+ len = mem_len;
+ if (len > sizeof (u.buf))
+ u.ptr = new gdb_byte[len];
+ mem_entry_accessible = true;
+ }
+
+ gdb_byte *get_loc ()
+ {
+ if (len > sizeof (u.buf))
+ return u.ptr;
+ else
+ return u.buf;
+ }
+
+ bool execute (gdbarch *gdbarch)
+ {
+ /* Nothing to do if the memory is flagged not_accessible. */
+ if (!mem_entry_accessible)
+ return false;
+
+ gdb::byte_vector buf (len);
+
+ if (record_debug > 1)
+ gdb_printf (gdb_stdlog,
+ "Process record: record_full_mem %s to "
+ "inferior addr = %s len = %d.\n",
+ host_address_to_string (this),
+ paddress (gdbarch, addr),
+ len);
+
+ if (record_read_memory (gdbarch, addr, buf.data (), len))
+ mem_entry_accessible = false;
+ else
+ {
+ if (target_write_memory (addr,
+ get_loc (),
+ len))
+ {
+ mem_entry_accessible = false;
+ if (record_debug)
+ warning (_("Process record: error writing memory at "
+ "addr = %s len = %d."),
+ paddress (gdbarch, addr),
+ len);
+ }
+ else
+ {
+ memcpy (get_loc (), buf.data (), len);
+
+ /* We've changed memory --- check if a hardware
+ watchpoint should trap. Note that this
+ presently assumes the target beneath supports
+ continuable watchpoints. On non-continuable
+ watchpoints target, we'll want to check this
+ _before_ actually doing the memory change, and
+ not doing the change at all if the watchpoint
+ traps. */
+ if (hardware_watchpoint_inserted_in_range
+ (current_inferior ()->aspace.get (), addr, len))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /* Cleanup this entry. This would ideally be a destructor for the class,
+ but I kept running into issues with double free, so this is left as a
+ future improvement. */
+
+ void cleanup ()
+ {
+ if (len > sizeof (u.buf))
+ delete u.ptr;
+ }
};
struct record_full_reg_entry
@@ -107,6 +188,51 @@ struct record_full_reg_entry
gdb_byte *ptr;
gdb_byte buf[2 * sizeof (gdb_byte *)];
} u;
+
+ record_full_reg_entry () : num (0), len (0) { }
+
+ record_full_reg_entry (gdbarch *gdbarch, int regnum)
+ {
+ num = regnum;
+ len = register_size (gdbarch, regnum);
+ if (len > sizeof (u.buf))
+ u.ptr = new gdb_byte[len];
+ }
+
+ gdb_byte *get_loc ()
+ {
+ if (len > sizeof (u.buf))
+ return u.ptr;
+ else
+ return u.buf;
+ }
+
+ bool execute (regcache *regcache)
+ {
+ gdb::byte_vector buf (len);
+
+ if (record_debug > 1)
+ gdb_printf (gdb_stdlog,
+ "Process record: record_full_reg %s to "
+ "inferior num = %d.\n",
+ host_address_to_string (this),
+ num);
+
+ regcache->cooked_read (num, buf);
+ regcache->cooked_write (num, get_loc ());
+ memcpy (get_loc (), buf.data (), len);
+ return false;
+ }
+
+ /* Cleanup this entry. This would ideally be a destructor for the class,
+ but I kept running into issues with double free, so this is left as a
+ future improvement. */
+
+ void cleanup ()
+ {
+ if (len > sizeof (u.buf))
+ delete u.ptr;
+ }
};
enum record_full_type
@@ -115,16 +241,96 @@ enum record_full_type
record_full_mem
};
-struct record_full_entry
+class record_full_entry
{
- enum record_full_type type;
- union
+ std::variant<record_full_reg_entry, record_full_mem_entry> entry;
+
+public:
+ record_full_entry () : entry (record_full_reg_entry ()) {}
+
+ /* Constructor for a register entry. Type is here to make it
+ easier to recognize it in the constructor calls, it isn't
+ actually important. */
+ record_full_entry (record_full_type reg_type, gdbarch *gdbarch,
+ int regnum)
+ : entry(record_full_reg_entry (gdbarch, regnum))
{
- /* reg */
- struct record_full_reg_entry reg;
- /* mem */
- struct record_full_mem_entry mem;
- } u;
+ gdb_assert (reg_type == record_full_reg);
+ }
+
+ record_full_entry (record_full_type mem_type, CORE_ADDR addr, int len)
+ : entry(record_full_mem_entry (addr, len))
+ {
+ gdb_assert (mem_type == record_full_mem);
+ }
+
+ record_full_reg_entry& reg ()
+ {
+ gdb_assert (type () == record_full_reg);
+ return std::get<record_full_reg_entry> (entry);
+ }
+
+ record_full_mem_entry& mem ()
+ {
+ gdb_assert (type () == record_full_mem);
+ return std::get<record_full_mem_entry> (entry);
+ }
+
+ record_full_type type ()
+ {
+ switch (entry.index ())
+ {
+ case 0:
+ return record_full_reg;
+ case 1:
+ return record_full_mem;
+ }
+ gdb_assert_not_reached ("Impossible variant index");
+ }
+
+ /* Get the pointer to the data stored by this entry. */
+ gdb_byte *get_loc ()
+ {
+ switch (type ())
+ {
+ case record_full_reg:
+ return reg ().get_loc ();
+ case record_full_mem:
+ return mem ().get_loc ();
+ }
+ gdb_assert_not_reached ("Impossible entry type");
+ }
+
+ /* Execute this entry, swapping the appropriate values from memory or
+ register and the recorded ones. Returns TRUE if the execution was
+ stopped by a watchpoint. */
+
+ bool execute (regcache *regcache)
+ {
+ switch (type ())
+ {
+ case record_full_reg:
+ return reg ().execute (regcache);
+ case record_full_mem:
+ return mem ().execute (regcache->arch ());
+ }
+ return false;
+ }
+
+ /* Free one record entry, any type. */
+
+ void cleanup ()
+ {
+ switch (type ())
+ {
+ case record_full_reg:
+ reg ().cleanup ();
+ break;
+ case record_full_mem:
+ mem ().cleanup ();
+ break;
+ }
+ }
};
/* This is the main structure that comprises the execution log.
@@ -381,79 +587,6 @@ static struct cmd_list_element *record_full_cmdlist;
static void record_full_goto_insn (size_t target_insn,
enum exec_direction_kind dir);
-/* Initialization and cleanup functions for record_full_reg and
- record_full_mem entries. */
-
-/* Init a record_full_reg record entry. */
-
-static inline struct record_full_entry
-record_full_reg_init (struct regcache *regcache, int regnum)
-{
- struct record_full_entry rec;
- struct gdbarch *gdbarch = regcache->arch ();
-
- rec.type = record_full_reg;
- rec.u.reg.num = regnum;
- rec.u.reg.len = register_size (gdbarch, regnum);
- if (rec.u.reg.len > sizeof (rec.u.reg.u.buf))
- rec.u.reg.u.ptr = (gdb_byte *) xmalloc (rec.u.reg.len);
-
- return rec;
-}
-
-/* Cleanup a record_full_reg record entry. */
-
-static inline void
-record_full_reg_cleanup (struct record_full_entry rec)
-{
- gdb_assert (rec.type == record_full_reg);
- if (rec.u.reg.len > sizeof (rec.u.reg.u.buf))
- xfree (rec.u.reg.u.ptr);
-}
-
-/* Init a record_full_mem record entry. */
-
-static inline struct record_full_entry
-record_full_mem_init (CORE_ADDR addr, int len)
-{
- struct record_full_entry rec;
-
- rec.type = record_full_mem;
- rec.u.mem.addr = addr;
- rec.u.mem.len = len;
- if (rec.u.mem.len > sizeof (rec.u.mem.u.buf))
- rec.u.mem.u.ptr = (gdb_byte *) xmalloc (len);
- rec.u.mem.mem_entry_not_accessible = 0;
-
- return rec;
-}
-
-/* Cleanup a record_full_mem record entry. */
-
-static inline void
-record_full_mem_cleanup (struct record_full_entry rec)
-{
- gdb_assert (rec.type == record_full_mem);
- if (rec.u.mem.len > sizeof (rec.u.mem.u.buf))
- xfree (rec.u.mem.u.ptr);
-}
-
-/* Free one record entry, any type. */
-
-static inline void
-record_full_entry_cleanup (struct record_full_entry rec)
-{
-
- switch (rec.type) {
- case record_full_reg:
- record_full_reg_cleanup (rec);
- break;
- case record_full_mem:
- record_full_mem_cleanup (rec);
- break;
- }
-}
-
static void
record_full_reset_history ()
{
@@ -463,7 +596,7 @@ record_full_reset_history ()
for (auto &insn : record_full_list)
{
for (auto &entry : insn.effects)
- record_full_entry_cleanup (entry);
+ entry.cleanup ();
}
record_full_list.clear ();
@@ -475,7 +608,7 @@ record_full_list_release_following (int index)
for (int i = record_full_list.size () - 1; i > index; i--)
{
for (auto &entry : record_full_list[i].effects)
- record_full_entry_cleanup (entry);
+ entry.cleanup ();
record_full_list.pop_back ();
}
/* Set the next instruction to be past the end of the log so we
@@ -503,7 +636,7 @@ record_full_list_release_first (void)
return;
for (auto &entry : record_full_list[0].effects)
- record_full_entry_cleanup (entry);
+ entry.cleanup ();
record_full_list.pop_front ();
--record_full_next_insn;
@@ -517,33 +650,12 @@ record_full_arch_list_add (struct record_full_entry &rec)
record_full_incomplete_instruction.effects.push_back (rec);
}
-/* Return the value storage location of a record entry. */
-static inline gdb_byte *
-record_full_get_loc (struct record_full_entry *rec)
-{
- switch (rec->type) {
- case record_full_mem:
- if (rec->u.mem.len > sizeof (rec->u.mem.u.buf))
- return rec->u.mem.u.ptr;
- else
- return rec->u.mem.u.buf;
- case record_full_reg:
- if (rec->u.reg.len > sizeof (rec->u.reg.u.buf))
- return rec->u.reg.u.ptr;
- else
- return rec->u.reg.u.buf;
- default:
- gdb_assert_not_reached ("unexpected record_full_entry type");
- return NULL;
- }
-}
-
/* Record the value of a register NUM to record_full_arch_list. */
int
record_full_arch_list_add_reg (struct regcache *regcache, int regnum)
{
- struct record_full_entry rec;
+ struct record_full_entry rec (record_full_reg, regcache->arch (), regnum);
if (record_debug > 1)
gdb_printf (gdb_stdlog,
@@ -551,9 +663,7 @@ record_full_arch_list_add_reg (struct regcache *regcache, int regnum)
"record list.\n",
regnum);
- rec = record_full_reg_init (regcache, regnum);
-
- regcache->cooked_read (regnum, record_full_get_loc (&rec));
+ regcache->cooked_read (regnum, rec.get_loc ());
record_full_arch_list_add (rec);
@@ -566,7 +676,7 @@ record_full_arch_list_add_reg (struct regcache *regcache, int regnum)
int
record_full_arch_list_add_mem (CORE_ADDR addr, int len)
{
- struct record_full_entry rec;
+ struct record_full_entry rec (record_full_mem, addr, len);
if (record_debug > 1)
gdb_printf (gdb_stdlog,
@@ -577,12 +687,10 @@ record_full_arch_list_add_mem (CORE_ADDR addr, int len)
if (!addr) /* FIXME: Why? Some arch must permit it... */
return 0;
- rec = record_full_mem_init (addr, len);
-
if (record_read_memory (current_inferior ()->arch (), addr,
- record_full_get_loc (&rec), len))
+ rec.get_loc (), len))
{
- record_full_mem_cleanup (rec);
+ rec.cleanup ();
return -1;
}
@@ -712,98 +820,14 @@ record_full_gdb_operation_disable_set (void)
static enum target_stop_reason record_full_stop_reason
= TARGET_STOPPED_BY_NO_REASON;
-/* Execute one instruction from the record log. Each instruction in
- the log will be represented by an arbitrary sequence of register
- entries and memory entries, followed by an 'end' entry. */
-
-static inline void
-record_full_exec_entry (struct regcache *regcache,
- struct gdbarch *gdbarch,
- struct record_full_entry *entry)
-{
- switch (entry->type)
- {
- case record_full_reg: /* reg */
- {
- gdb::byte_vector reg (entry->u.reg.len);
-
- if (record_debug > 1)
- gdb_printf (gdb_stdlog,
- "Process record: record_full_reg %s to "
- "inferior num = %d.\n",
- host_address_to_string (entry),
- entry->u.reg.num);
-
- regcache->cooked_read (entry->u.reg.num, reg.data ());
- regcache->cooked_write (entry->u.reg.num, record_full_get_loc (entry));
- memcpy (record_full_get_loc (entry), reg.data (), entry->u.reg.len);
- }
- break;
-
- case record_full_mem: /* mem */
- {
- /* Nothing to do if the entry is flagged not_accessible. */
- if (!entry->u.mem.mem_entry_not_accessible)
- {
- gdb::byte_vector mem (entry->u.mem.len);
-
- if (record_debug > 1)
- gdb_printf (gdb_stdlog,
- "Process record: record_full_mem %s to "
- "inferior addr = %s len = %d.\n",
- host_address_to_string (entry),
- paddress (gdbarch, entry->u.mem.addr),
- entry->u.mem.len);
-
- if (record_read_memory (gdbarch,
- entry->u.mem.addr, mem.data (),
- entry->u.mem.len))
- entry->u.mem.mem_entry_not_accessible = 1;
- else
- {
- if (target_write_memory (entry->u.mem.addr,
- record_full_get_loc (entry),
- entry->u.mem.len))
- {
- entry->u.mem.mem_entry_not_accessible = 1;
- if (record_debug)
- warning (_("Process record: error writing memory at "
- "addr = %s len = %d."),
- paddress (gdbarch, entry->u.mem.addr),
- entry->u.mem.len);
- }
- else
- {
- memcpy (record_full_get_loc (entry), mem.data (),
- entry->u.mem.len);
-
- /* We've changed memory --- check if a hardware
- watchpoint should trap. Note that this
- presently assumes the target beneath supports
- continuable watchpoints. On non-continuable
- watchpoints target, we'll want to check this
- _before_ actually doing the memory change, and
- not doing the change at all if the watchpoint
- traps. */
- if (hardware_watchpoint_inserted_in_range
- (current_inferior ()->aspace.get (),
- entry->u.mem.addr, entry->u.mem.len))
- record_full_stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
- }
- }
- }
- }
- break;
- }
-}
-
static inline void
record_full_exec_insn (struct regcache *regcache,
struct gdbarch *gdbarch,
record_full_instruction &insn)
{
for (auto &entry : insn.effects)
- record_full_exec_entry (regcache, gdbarch, &entry);
+ if (entry.execute (regcache))
+ record_full_stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
}
static void record_full_restore (struct bfd &cbfd);
@@ -2175,21 +2199,19 @@ record_full_read_entry_from_bfd (bfd *cbfd, asection *osec, int *bfd_offset)
bfdcore_read (cbfd, osec, ®num, sizeof (regnum), bfd_offset);
regnum = netorder32 (regnum);
- record_full_entry rec;
-
- rec = record_full_reg_init (cache, regnum);
+ record_full_entry rec (record_full_reg, cache->arch (), regnum);
/* Get val. */
- bfdcore_read (cbfd, osec, record_full_get_loc (&rec),
- rec.u.reg.len, bfd_offset);
+ bfdcore_read (cbfd, osec, rec.get_loc (),
+ rec.reg ().len, bfd_offset);
if (record_debug)
gdb_printf (gdb_stdlog,
" Reading register %d (1 "
"plus %lu plus %d bytes)\n",
- rec.u.reg.num,
+ rec.reg ().num,
(unsigned long) sizeof (regnum),
- rec.u.reg.len);
+ rec.reg ().len);
record_full_arch_list_add (rec);
break;
@@ -2206,19 +2228,17 @@ record_full_read_entry_from_bfd (bfd *cbfd, asection *osec, int *bfd_offset)
bfd_offset);
addr = netorder64 (addr);
- record_full_entry rec;
- rec = record_full_mem_init (addr, len);
+ record_full_entry rec (record_full_mem, addr, len);
/* Get val. */
- bfdcore_read (cbfd, osec, record_full_get_loc (&rec), len,
- bfd_offset);
+ bfdcore_read (cbfd, osec, rec.get_loc (), len, bfd_offset);
if (record_debug)
gdb_printf (gdb_stdlog,
" Reading memory %s (1 plus "
"%lu plus %lu plus %d bytes)\n",
paddress (get_current_arch (),
- rec.u.mem.addr),
+ rec.mem ().addr),
(unsigned long) sizeof (addr),
(unsigned long) sizeof (len),
len);
@@ -2370,52 +2390,56 @@ record_full_write_entry_to_bfd (record_full_entry &entry,
uint32_t regnum, len;
uint64_t addr;
- type = entry.type;
+ type = entry.type ();
bfdcore_write (obfd.get (), osec, &type, sizeof (type), bfd_offset);
- switch (entry.type)
+ switch (type)
{
case record_full_reg: /* reg */
- if (record_debug)
- gdb_printf (gdb_stdlog,
- " Writing register %d (1 "
- "plus %lu plus %d bytes)\n",
- entry.u.reg.num,
- (unsigned long) sizeof (regnum),
- entry.u.reg.len);
-
- /* Write regnum. */
- regnum = netorder32 (entry.u.reg.num);
- bfdcore_write (obfd.get (), osec, ®num, sizeof (regnum), bfd_offset);
-
- /* Write regval. */
- bfdcore_write (obfd.get (), osec, record_full_get_loc (&entry),
- entry.u.reg.len, bfd_offset);
- break;
+ {
+ auto reg = entry.reg ();
+ if (record_debug)
+ gdb_printf (gdb_stdlog,
+ " Writing register %d (1 "
+ "plus %lu plus %d bytes)\n",
+ reg.num,
+ (unsigned long) sizeof (regnum),
+ reg.len);
+
+ /* Write regnum. */
+ regnum = netorder32 (reg.num);
+ bfdcore_write (obfd.get (), osec, ®num, sizeof (regnum), bfd_offset);
+
+ /* Write regval. */
+ bfdcore_write (obfd.get (), osec, entry.get_loc (), reg.len, bfd_offset);
+ break;
+ }
case record_full_mem: /* mem */
- if (record_debug)
- gdb_printf (gdb_stdlog,
- " Writing memory %s (1 plus "
- "%lu plus %lu plus %d bytes)\n",
- paddress (gdbarch,
- entry.u.mem.addr),
- (unsigned long) sizeof (addr),
- (unsigned long) sizeof (len),
- entry.u.mem.len);
-
- /* Write memlen. */
- len = netorder32 (entry.u.mem.len);
- bfdcore_write (obfd.get (), osec, &len, sizeof (len), bfd_offset);
-
- /* Write memaddr. */
- addr = netorder64 (entry.u.mem.addr);
- bfdcore_write (obfd.get (), osec, &addr, sizeof (addr), bfd_offset);
-
- /* Write memval. */
- bfdcore_write (obfd.get (), osec, record_full_get_loc (&entry),
- entry.u.mem.len, bfd_offset);
- break;
+ {
+ auto mem = entry.mem ();
+ if (record_debug)
+ gdb_printf (gdb_stdlog,
+ " Writing memory %s (1 plus "
+ "%lu plus %lu plus %d bytes)\n",
+ paddress (gdbarch, mem.addr),
+ (unsigned long) sizeof (addr),
+ (unsigned long) sizeof (len),
+ mem.len);
+
+ /* Write memlen. */
+ len = netorder32 (mem.len);
+ bfdcore_write (obfd.get (), osec, &len, sizeof (len), bfd_offset);
+
+ /* Write memaddr. */
+ addr = netorder64 (mem.addr);
+ bfdcore_write (obfd.get (), osec, &addr, sizeof (addr), bfd_offset);
+
+ /* Write memval. */
+ bfdcore_write (obfd.get (), osec, entry.get_loc (), mem.len,
+ bfd_offset);
+ break;
+ }
}
}
@@ -2463,13 +2487,13 @@ record_full_base_target::save_record (const char *recfilename)
/* Number of effects of an instruction. */
save_size += sizeof (uint32_t) + sizeof (uint8_t) + sizeof (uint32_t);
for (auto &entry : record_full_list[i].effects)
- switch (entry.type)
+ switch (entry.type ())
{
case record_full_reg:
- save_size += 1 + 4 + entry.u.reg.len;
+ save_size += 1 + 4 + entry.reg ().len;
break;
case record_full_mem:
- save_size += 1 + 4 + 8 + entry.u.mem.len;
+ save_size += 1 + 4 + 8 + entry.mem ().len;
break;
}
}
@@ -2604,16 +2628,16 @@ maintenance_print_record_instruction (const char *args, int from_tty)
for (auto entry : to_print->effects)
{
- switch (entry.type)
+ switch (entry.type ())
{
case record_full_reg:
{
- type *regtype = gdbarch_register_type (arch, entry.u.reg.num);
+ type *regtype = gdbarch_register_type (arch, entry.reg ().num);
value *val
= value_from_contents (regtype,
- record_full_get_loc (&entry));
+ entry.get_loc ());
gdb_printf ("Register %s changed: ",
- gdbarch_register_name (arch, entry.u.reg.num));
+ gdbarch_register_name (arch, entry.reg ().num));
struct value_print_options opts;
get_user_print_options (&opts);
opts.raw = true;
@@ -2623,11 +2647,12 @@ maintenance_print_record_instruction (const char *args, int from_tty)
}
case record_full_mem:
{
- gdb_byte *b = record_full_get_loc (&entry);
+ record_full_mem_entry& mem = entry.mem ();
+ gdb_byte *b = entry.get_loc ();
gdb_printf ("%d bytes of memory at address %s changed from:",
- entry.u.mem.len,
- print_core_address (arch, entry.u.mem.addr));
- for (int i = 0; i < entry.u.mem.len; i++)
+ mem.len,
+ print_core_address (arch, mem.addr));
+ for (int i = 0; i < mem.len; i++)
gdb_printf (" %02x", b[i]);
gdb_printf ("\n");
break;
--
2.53.0
next prev parent reply other threads:[~2026-04-23 15:27 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-23 15:25 [PATCH v2 0/6] refactor the internals of record-full Guinevere Larsen
2026-04-23 15:25 ` [PATCH v2 1/6] gdb/record: Refactor record history Guinevere Larsen
2026-04-28 3:28 ` Thiago Jung Bauermann
2026-04-28 19:54 ` Guinevere Larsen
2026-05-06 21:16 ` Schimpe, Christina
2026-05-07 17:38 ` Guinevere Larsen
2026-05-11 15:23 ` Schimpe, Christina
2026-05-12 18:50 ` Guinevere Larsen
2026-05-13 7:54 ` Schimpe, Christina
2026-05-14 15:20 ` Guinevere Larsen
2026-04-23 15:26 ` [PATCH v2 2/6] gdb/record: remove record_full_insn_num Guinevere Larsen
2026-04-23 15:26 ` Guinevere Larsen [this message]
2026-04-28 3:29 ` [PATCH v2 3/6] gdb/record: c++ify internal structures of record-full.c Thiago Jung Bauermann
2026-04-23 15:26 ` [PATCH v2 4/6] gdb/record: make record_full_history more c++-like Guinevere Larsen
2026-04-28 3:29 ` Thiago Jung Bauermann
2026-04-23 15:26 ` [PATCH v2 5/6] gdb/record: extract the PC to record_full_instruction Guinevere Larsen
2026-04-28 3:30 ` Thiago Jung Bauermann
2026-04-23 15:26 ` [PATCH v2 6/6] gdb/record: Define new version of the record-save section Guinevere Larsen
2026-04-23 15:45 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260423152604.171356-4-guinevere@redhat.com \
--to=guinevere@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox