weixinwei commented on issue #2624: URL: https://github.com/apache/brpc/issues/2624#issuecomment-2082321731
gdb修改思路: core target,增加m_registers寄存器缓存变量,用来接收set $rsp等的临时寄存器值; 同时实现虚函数prepare_to_store和store_registers的override。当store_registers时,m_registers保存当前set的寄存器值。 同时修改fetch_registers,如果m_registers有效,就从直接从m_registers中返回给上层调用者。 Patch如下(基于gdb12.1) ``` diff -uNr gdb-12.1/gdb/corelow.c gdb-new/gdb/corelow.c --- gdb-12.1/gdb/corelow.c 2024-04-28 14:20:44.560135484 +0800 +++ gdb-new/gdb/corelow.c 2024-04-28 14:33:54.505499546 +0800 @@ -122,6 +122,9 @@ /* See definition. */ void info_proc_mappings (struct gdbarch *gdbarch); + void prepare_to_store (struct regcache *) override {} + void store_registers (struct regcache *, int) override; + private: /* per-core data */ /* The core's section table. Note that these target sections are @@ -154,6 +157,18 @@ /* FIXME: kettenis/20031023: Eventually this field should disappear. */ struct gdbarch *m_core_gdbarch = NULL; + +private: + /* register cache for the core file. + which is used to fetch&save the registers from the core file. + so that we call exec 'set $reg = xxx' in the core file. */ + + /* The register buffers. */ + std::unique_ptr<gdb_byte[]> m_registers; + /* Register cache status. */ + std::unique_ptr<register_status[]> m_register_status; + /* current ptid */ + ptid_t current_ptid = null_ptid; }; core_target::core_target () @@ -312,6 +327,9 @@ current_program_space->cbfd.reset (nullptr); } + m_registers.reset(nullptr); + m_register_status.reset(nullptr); + /* Core targets are heap-allocated (see core_target_open), so here we delete ourselves. */ delete this; @@ -739,6 +757,13 @@ return; } + if (m_registers && current_ptid == regcache->ptid ()) + { + memcpy(regcache->m_registers.get(), m_registers.get(), regcache->sizeof_raw_registers); + memcpy(regcache->m_register_status.get(), m_register_status.get(), regcache->num_regs); + return; + } + struct gdbarch *gdbarch = regcache->arch (); get_core_registers_cb_data data = { this, regcache }; gdbarch_iterate_over_regset_sections (gdbarch, @@ -749,6 +774,25 @@ for (int i = 0; i < gdbarch_num_regs (regcache->arch ()); i++) if (regcache->get_register_status (i) == REG_UNKNOWN) regcache->raw_supply (i, NULL); + + if (m_registers == nullptr || current_ptid != regcache->ptid ()) + { + m_registers.reset (new gdb_byte[regcache->sizeof_raw_registers]); + m_register_status.reset (new register_status[regcache->num_regs]); + current_ptid = regcache->ptid (); + + memcpy(m_registers.get(), regcache->m_registers.get(), regcache->sizeof_raw_registers); + memcpy(m_register_status.get(), regcache->m_register_status.get(), regcache->num_regs); + } +} + +void +core_target::store_registers (struct regcache *regcache, int regnum) +{ + memcpy(m_registers.get() + regcache->register_offset[regnum], + regcache->m_registers.get() + regcache->register_offset[regnum], + regcache->sizeof_register[regnum]); + m_register_status[regnum] = REG_VALID; } void diff -uNr gdb-12.1/gdb/regcache.c gdb-new/gdb/regcache.c --- gdb-12.1/gdb/regcache.c 2022-05-02 02:46:31.000000000 +0800 +++ gdb-new/gdb/regcache.c 2024-04-28 14:31:32.225651588 +0800 @@ -198,6 +198,11 @@ m_registers.reset (new gdb_byte[m_descr->sizeof_raw_registers]); m_register_status.reset (new register_status[gdbarch_num_regs (gdbarch)] ()); + + sizeof_raw_registers = m_descr->sizeof_raw_registers; + num_regs = gdbarch_num_regs (gdbarch); + register_offset = m_descr->register_offset; + sizeof_register = m_descr->sizeof_register; } } diff -uNr gdb-12.1/gdb/regcache.h gdb-new/gdb/regcache.h --- gdb-12.1/gdb/regcache.h 2022-03-20 12:59:56.000000000 +0800 +++ gdb-new/gdb/regcache.h 2024-04-28 14:30:54.680636185 +0800 @@ -260,11 +260,19 @@ struct regcache_descr *m_descr; bool m_has_pseudo; + +public: /* The register buffers. */ std::unique_ptr<gdb_byte[]> m_registers; /* Register cache status. */ std::unique_ptr<register_status[]> m_register_status; + // used for corelow.c + long sizeof_raw_registers; + int num_regs; + long *register_offset; + long *sizeof_register; + friend class regcache; friend class detached_regcache; }; ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org For additional commands, e-mail: dev-h...@brpc.apache.org