Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support gdb_bthread_stack.py in coredump #2624

Open
weixinwei opened this issue Apr 29, 2024 · 1 comment
Open

support gdb_bthread_stack.py in coredump #2624

weixinwei opened this issue Apr 29, 2024 · 1 comment

Comments

@weixinwei
Copy link

Is your feature request related to a problem? (你需要的功能是否与某个问题有关?)
gdb coredump中执行'bthread_frame id'报错

Describe the solution you'd like (描述你期望的解决方法)
简单修改gdb源码,实现在gdb coredump中gdb_bthread_stack.py的功能全部可用

Describe alternatives you've considered (描述你想到的折衷方案)

Additional context/screenshots (更多上下文/截图)
默认gdb
image
修改后gdb
image

@weixinwei
Copy link
Author

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;
 };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant