Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Move unwinding glue in a UnwindContext class
authorGabriel Corona <gabriel.corona@loria.fr>
Tue, 15 Mar 2016 11:00:44 +0000 (12:00 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Tue, 15 Mar 2016 11:01:02 +0000 (12:01 +0100)
src/mc/Process.cpp
src/mc/Process.hpp
src/mc/mc_checkpoint.cpp
src/mc/mc_snapshot.h
src/mc/mc_unw.cpp
src/mc/mc_unw.h

index 613eec4..184fd06 100644 (file)
@@ -226,7 +226,7 @@ void Process::init()
 
   this->smx_process_infos.clear();
   this->smx_old_process_infos.clear();
-  this->unw_addr_space = unw_create_addr_space(&mc_unw_accessors  , __BYTE_ORDER);
+  this->unw_addr_space = simgrid::mc::UnwindContext::createUnwindAddressSpace();
   this->unw_underlying_addr_space = simgrid::unw::create_addr_space();
   this->unw_underlying_context = simgrid::unw::create_context(
     this->unw_underlying_addr_space, this->pid_);
index 2b53837..fe648f8 100644 (file)
@@ -284,7 +284,7 @@ public: // Libunwind-data
 
   /** Full-featured MC-aware libunwind address space for the process
    *
-   *  This address space is using a mc_unw_context_t
+   *  This address space is using a simgrid::mc::UnwindContext*
    *  (with simgrid::mc::Process* / simgrid::mc::AddressSpace*
    *  and unw_context_t).
    */
index 77d6a73..f4f6cd8 100644 (file)
@@ -335,16 +335,14 @@ static std::vector<s_local_variable> get_local_variables_values(
   return std::move(variables);
 }
 
-static std::vector<s_mc_stack_frame_t> unwind_stack_frames(mc_unw_context_t stack_context)
+static std::vector<s_mc_stack_frame_t> unwind_stack_frames(simgrid::mc::UnwindContext* stack_context)
 {
   simgrid::mc::Process* process = &mc_model_checker->process();
   std::vector<s_mc_stack_frame_t> result;
 
-  unw_cursor_t c;
+  unw_cursor_t c = stack_context->cursor();
 
   // TODO, check condition check (unw_init_local==0 means end of frame)
-  if (mc_unw_init_cursor(&c, stack_context) != 0)
-    xbt_die("Could not initialize stack unwinding");
 
     while (1) {
 
@@ -408,9 +406,7 @@ static std::vector<s_mc_snapshot_stack_t> take_snapshot_stacks(mc_snapshot_t * s
     mc_model_checker->process().read_bytes(
       &context, sizeof(context), remote(stack.context));
 
-    if (mc_unw_init_context(&st.context, &mc_model_checker->process(),
-      &context) < 0)
-      xbt_die("Could not initialise the libunwind context.");
+    st.context.initialize(&mc_model_checker->process(), &context);
 
     st.stack_frames = unwind_stack_frames(&st.context);
     st.local_variables = get_local_variables_values(st.stack_frames, stack.process_index);
index ff3551f..c84a17b 100644 (file)
@@ -123,7 +123,7 @@ typedef struct s_local_variable{
 
 typedef struct XBT_PRIVATE s_mc_snapshot_stack {
   std::vector<s_local_variable> local_variables;
-  s_mc_unw_context_t context;
+  simgrid::mc::UnwindContext context;
   std::vector<s_mc_stack_frame_t> stack_frames;
   int process_index;
 } s_mc_snapshot_stack_t, *mc_snapshot_stack_t;
index b172da9..1a6fa90 100644 (file)
@@ -24,7 +24,8 @@
 
 using simgrid::mc::remote;
 
-extern "C" {
+namespace simgrid {
+namespace mc {
 
 // ***** Implementation
 
@@ -32,14 +33,14 @@ extern "C" {
  *
  *  Delegates to the local/ptrace implementation.
  */
-static int find_proc_info(unw_addr_space_t as,
+int UnwindContext::find_proc_info(unw_addr_space_t as,
               unw_word_t ip, unw_proc_info_t *pip,
-              int need_unwind_info, void* arg)
+              int need_unwind_info, void* arg) noexcept
 {
-  mc_unw_context_t context = (mc_unw_context_t) arg;
-  return unw_get_accessors(context->process->unw_underlying_addr_space)->find_proc_info(
-    context->process->unw_underlying_addr_space, ip, pip,
-    need_unwind_info, context->process->unw_underlying_context
+  simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*) arg;
+  return unw_get_accessors(context->process_->unw_underlying_addr_space)->find_proc_info(
+    context->process_->unw_underlying_addr_space, ip, pip,
+    need_unwind_info, context->process_->unw_underlying_context
   );
 }
 
@@ -47,13 +48,13 @@ static int find_proc_info(unw_addr_space_t as,
  *
  *  Delegates to the local/ptrace implementation.
  */
-static void put_unwind_info(unw_addr_space_t as,
-              unw_proc_info_t *pip, void* arg)
+void UnwindContext::put_unwind_info(unw_addr_space_t as,
+              unw_proc_info_t *pip, void* arg) noexcept
 {
-  mc_unw_context_t context = (mc_unw_context_t) arg;
-  return unw_get_accessors(context->process->unw_underlying_addr_space)->put_unwind_info(
-    context->process->unw_underlying_addr_space, pip,
-    context->process->unw_underlying_context
+  simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*) arg;
+  return unw_get_accessors(context->process_->unw_underlying_addr_space)->put_unwind_info(
+    context->process_->unw_underlying_addr_space, pip,
+    context->process_->unw_underlying_context
   );
 }
 
@@ -61,14 +62,14 @@ static void put_unwind_info(unw_addr_space_t as,
  *
  *  Not implemented.
  */
-static int get_dyn_info_list_addr(unw_addr_space_t as,
-              unw_word_t *dilap, void* arg)
+int UnwindContext::get_dyn_info_list_addr(unw_addr_space_t as,
+              unw_word_t *dilap, void* arg) noexcept
 {
-  mc_unw_context_t context = (mc_unw_context_t) arg;
-  return unw_get_accessors(context->process->unw_underlying_addr_space)->get_dyn_info_list_addr(
-    context->process->unw_underlying_addr_space,
+  simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*) arg;
+  return unw_get_accessors(context->process_->unw_underlying_addr_space)->get_dyn_info_list_addr(
+    context->process_->unw_underlying_addr_space,
     dilap,
-    context->process->unw_underlying_context
+    context->process_->unw_underlying_context
   );
 }
 
@@ -76,18 +77,18 @@ static int get_dyn_info_list_addr(unw_addr_space_t as,
  *
  *  Delegates to the `simgrid::mc::Process*`.
  */
-static int access_mem(unw_addr_space_t as,
+int UnwindContext::access_mem(unw_addr_space_t as,
               unw_word_t addr, unw_word_t *valp,
-              int write, void* arg)
+              int write, void* arg) noexcept
 {
-  mc_unw_context_t context = (mc_unw_context_t) arg;
+  simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*) arg;
   if (write)
     return - UNW_EREADONLYREG;
-  context->address_space->read_bytes(valp, sizeof(unw_word_t), remote(addr));
+  context->addressSpace_->read_bytes(valp, sizeof(unw_word_t), remote(addr));
   return 0;
 }
 
-static void* get_reg(unw_context_t* context, unw_regnum_t regnum)
+void* UnwindContext::get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept
 {
 #ifdef __x86_64
   mcontext_t* mcontext = &context->uc_mcontext;
@@ -118,12 +119,12 @@ static void* get_reg(unw_context_t* context, unw_regnum_t regnum)
 
 /** Read a standard register (libunwind method)
  */
-static int access_reg(unw_addr_space_t as,
+int UnwindContext::access_reg(unw_addr_space_t as,
               unw_regnum_t regnum, unw_word_t *valp,
-              int write, void* arg)
+              int write, void* arg) noexcept
 {
-  mc_unw_context_t as_context = (mc_unw_context_t) arg;
-  unw_context_t* context = &as_context->context;
+  simgrid::mc::UnwindContext* as_context = (simgrid::mc::UnwindContext*) arg;
+  unw_context_t* context = &as_context->unwindContext_;
   if (write)
     return -UNW_EREADONLYREG;
   greg_t* preg = (greg_t*) get_reg(context, regnum);
@@ -139,9 +140,9 @@ static int access_reg(unw_addr_space_t as,
  *  `getcontext()` is not relevant for the caller. It is not really necessary
  *  to save and handle them.
  */
-static int access_fpreg(unw_addr_space_t as,
+int UnwindContext::access_fpreg(unw_addr_space_t as,
               unw_regnum_t regnum, unw_fpreg_t *fpvalp,
-              int write, void* arg)
+              int write, void* arg) noexcept
 {
   return -UNW_EBADREG;
 }
@@ -150,21 +151,21 @@ static int access_fpreg(unw_addr_space_t as,
  *
  * We don't use this.
  */
-static int resume(unw_addr_space_t as,
-              unw_cursor_t *cp, void* arg)
+int UnwindContext::resume(unw_addr_space_t as,
+              unw_cursor_t *cp, void* arg) noexcept
 {
   return -UNW_EUNSPEC;
 }
 
 /** Find informations about a function (libunwind method)
  */
-static int get_proc_name(unw_addr_space_t as,
+int UnwindContext::get_proc_name(unw_addr_space_t as,
               unw_word_t addr, char *bufp,
               size_t buf_len, unw_word_t *offp,
-              void* arg)
+              void* arg) noexcept
 {
-  mc_unw_context_t context = (mc_unw_context_t) arg;
-  simgrid::mc::Frame* frame = context->process->find_function(remote(addr));
+  simgrid::mc::UnwindContext* context = (simgrid::mc::UnwindContext*) arg;
+  simgrid::mc::Frame* frame = context->process_->find_function(remote(addr));
   if (!frame)
     return - UNW_ENOINFO;
   *offp = (unw_word_t) frame->range.begin() - addr;
@@ -180,50 +181,69 @@ static int get_proc_name(unw_addr_space_t as,
 
 // ***** Init
 
-unw_accessors_t mc_unw_accessors =
-  {
-    &find_proc_info,
-    &put_unwind_info,
-    &get_dyn_info_list_addr,
-    &access_mem,
-    &access_reg,
-    &access_fpreg,
-    &resume,
-    &get_proc_name
-  };
-
-// ***** Context management
-
-int mc_unw_init_context(
-  mc_unw_context_t context, simgrid::mc::Process* process, unw_context_t* c)
+/** Virtual table for our `libunwind` implementation
+ *
+ *  Stack unwinding on a `simgrid::mc::Process*` (for memory, unwinding information)
+ *  and `ucontext_t` (for processor registers).
+ *
+ *  It works with the `simgrid::mc::UnwindContext` context.
+ */
+unw_accessors_t UnwindContext::accessors = {
+  &find_proc_info,
+  &put_unwind_info,
+  &get_dyn_info_list_addr,
+  &access_mem,
+  &access_reg,
+  &access_fpreg,
+  &resume,
+  &get_proc_name
+};
+
+unw_addr_space_t UnwindContext::createUnwindAddressSpace()
+{
+  return unw_create_addr_space(&UnwindContext::accessors, __BYTE_ORDER);
+}
+
+void UnwindContext::clear()
 {
-  context->address_space = process;
-  context->process = process;
+  addressSpace_ = nullptr;
+  process_ = nullptr;
+}
+
+void UnwindContext::initialize(simgrid::mc::Process* process, unw_context_t* c)
+{
+  clear();
+
+  this->addressSpace_ = process;
+  this->process_ = process;
 
   // Take a copy of the context for our own purpose:
-  context->context = *c;
+  this->unwindContext_ = *c;
 #if SIMGRID_PROCESSOR_x86_64 || SIMGRID_PROCESSOR_i686
   // On x86_64, ucontext_t contains a pointer to itself for FP registers.
   // We don't really need support for FR registers as they are caller saved
   // and probably never use those fields as libunwind-x86_64 does not read
   // FP registers from the unw_context_t
   // but we fix the pointer in order to avoid dangling pointers:
-  context->context.uc_mcontext.fpregs = &(context->context.__fpregs_mem);
+  // context->context_.uc_mcontext.fpregs = &(context->context.__fpregs_mem);
+
+  // Let's ignore this and see what happens:
+  this->unwindContext_.uc_mcontext.fpregs = nullptr;
 #else
   // Do we need to do any fixup like this?
   #error Target CPU type is not handled.
 #endif
-
-  return 0;
 }
 
-// ***** Cursor management
-
-int mc_unw_init_cursor(unw_cursor_t *cursor, mc_unw_context_t context)
+unw_cursor_t UnwindContext::cursor()
 {
-  if (!context->process || !context->address_space)
-    return -UNW_EUNSPEC;
-  return unw_init_remote(cursor, context->process->unw_addr_space, context);
+  unw_cursor_t cursor;
+  if (process_ == nullptr
+    || addressSpace_ == nullptr
+    || unw_init_remote(&cursor, process_->unw_addr_space, this) != 0)
+    xbt_die("UnwindContext not initialized");
+  return cursor;
 }
 
 }
+}
index d27fbd1..3625d26 100644 (file)
@@ -43,38 +43,51 @@ XBT_PRIVATE void* create_context(unw_addr_space_t as, pid_t pid);
 }
 }
 
-SG_BEGIN_DECL()
-
-// ***** Libunwind namespace
-
-/** Virtual table for our `libunwind` implementation
- *
- *  Stack unwinding on a `simgrid::mc::Process*` (for memory, unwinding information)
- *  and `ucontext_t` (for processor registers).
- *
- *  It works with the `s_mc_unw_context_t` context.
- */
-extern XBT_PRIVATE unw_accessors_t mc_unw_accessors;
-
-// ***** Libunwind context
-
-/** A `libunwind` context
- */
-typedef struct XBT_PRIVATE s_mc_unw_context {
-  simgrid::mc::AddressSpace* address_space;
-  simgrid::mc::Process*       process;
-  unw_context_t      context;
-} s_mc_unw_context_t, *mc_unw_context_t;
-
-/** Initialises an already allocated context */
-XBT_PRIVATE int mc_unw_init_context(
-  mc_unw_context_t context, simgrid::mc::Process* process, unw_context_t* c);
-
-// ***** Libunwind cursor
-
-/** Initialises a `libunwind` cursor */
-XBT_PRIVATE int mc_unw_init_cursor(unw_cursor_t *cursor, mc_unw_context_t context);
+namespace simgrid {
+namespace mc {
+
+class UnwindContext {
+  simgrid::mc::AddressSpace* addressSpace_ = nullptr;
+  simgrid::mc::Process*      process_ = nullptr;
+  unw_context_t              unwindContext_;
+public:
+  UnwindContext() {}
+  ~UnwindContext() { clear(); }
+  void initialize(simgrid::mc::Process* process, unw_context_t* c);
+  void clear();
+  unw_cursor_t cursor();
+
+private: // Methods and virtual table for libunwind
+  static int find_proc_info(unw_addr_space_t as,
+                unw_word_t ip, unw_proc_info_t *pip,
+                int need_unwind_info, void* arg) noexcept;
+  static void put_unwind_info(unw_addr_space_t as,
+                unw_proc_info_t *pip, void* arg) noexcept;
+  static int get_dyn_info_list_addr(unw_addr_space_t as,
+                unw_word_t *dilap, void* arg) noexcept;
+  static int access_mem(unw_addr_space_t as,
+                unw_word_t addr, unw_word_t *valp,
+                int write, void* arg) noexcept;
+  static void* get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept;
+  static int access_reg(unw_addr_space_t as,
+                unw_regnum_t regnum, unw_word_t *valp,
+                int write, void* arg) noexcept;
+  static int access_fpreg(unw_addr_space_t as,
+                unw_regnum_t regnum, unw_fpreg_t *fpvalp,
+                int write, void* arg) noexcept;
+  static int resume(unw_addr_space_t as,
+                unw_cursor_t *cp, void* arg) noexcept;
+  static int get_proc_name(unw_addr_space_t as,
+                unw_word_t addr, char *bufp,
+                size_t buf_len, unw_word_t *offp,
+                void* arg) noexcept;
+  static unw_accessors_t accessors;
+public:
+  // Create a libunwind address space:
+  static unw_addr_space_t createUnwindAddressSpace();
+};
 
-SG_END_DECL()
+}
+}
 
 #endif