#ifndef SIMGRID_MC_UNW_H
#define SIMGRID_MC_UNW_H
-/** \file
+/** @file
* Libunwind implementation for the model-checker
*
* Libunwind provides an pluggable stack unwinding API: the way the current
* much here.
*/
-#include <xbt/base.h>
-
-#include "mc_process.h"
-
-SG_BEGIN_DECL()
-
-// ***** Libunwind namespace
-
-/** Virtual table for our `libunwind-process_vm_readv` implementation.
- *
- * This implementation reuse most the code of `libunwind-ptrace` but
- * does not use ptrace() to read the target process memory by
- * `process_vm_readv()` or `/dev/${pid}/mem` if possible.
- *
- * Does not support any MC-specific behaviour (privatisation, snapshots)
- * and `ucontext_t`.
- *
- * It works with `void*` contexts allocated with `_UPT_create(pid)`.
- */
-extern XBT_PRIVATE unw_accessors_t mc_unw_vmread_accessors;
+#include <sys/types.h>
-/** 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);
+#include <xbt/base.h>
-SG_END_DECL()
+#include <libunwind.h>
+
+#include "src/mc/mc_forward.hpp"
+
+namespace simgrid {
+namespace unw {
+
+XBT_PRIVATE unw_addr_space_t create_addr_space();
+XBT_PRIVATE void* create_context(unw_addr_space_t as, pid_t pid);
+
+}
+}
+
+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();
+};
+
+void MC_dump_stack_unw(FILE* file, unw_cursor_t cursor);
+void dumpStack(FILE* file, unw_cursor_t cursor);
+void dumpStack(FILE* file, pid_t pid);
+
+}
+}
#endif