Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update copyright lines.
[simgrid.git] / src / mc / inspect / mc_unw.hpp
1 /* Copyright (c) 2015-2021. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef SIMGRID_MC_UNW_HPP
7 #define SIMGRID_MC_UNW_HPP
8
9 /** @file
10  *  Libunwind implementation for the model-checker
11  *
12  *  Libunwind provides a pluggable stack unwinding API: the way the current
13  *  registers and memory is accessed, the way unwinding information is found
14  *  is pluggable.
15  *
16  *  This component implements the libunwind API for he model-checker:
17  *
18  *    * reading memory from a simgrid::mc::AddressSpace*;
19  *
20  *    * reading stack registers from a saved snapshot (context).
21  *
22  *  Parts of the libunwind information fetching is currently handled by the
23  *  standard `libunwind` implementations (either the local one or the ptrace one)
24  *  because parsing `.eh_frame` section is not fun and `libdw` does not help
25  *  much here.
26  */
27
28 #include "src/mc/mc_forward.hpp"
29 #include "xbt/base.h"
30
31 #include <cstdio>
32 #include <libunwind.h>
33
34 namespace simgrid {
35 namespace unw {
36
37 XBT_PRIVATE unw_addr_space_t create_addr_space();
38 XBT_PRIVATE void* create_context(unw_addr_space_t as, pid_t pid);
39 } // namespace unw
40 } // namespace simgrid
41
42 namespace simgrid {
43 namespace mc {
44
45 class UnwindContext {
46   simgrid::mc::AddressSpace* address_space_ = nullptr;
47   simgrid::mc::RemoteSimulation* process_   = nullptr;
48   unw_context_t unwind_context_             = {};
49
50 public:
51   void initialize(simgrid::mc::RemoteSimulation* process, unw_context_t* c);
52   unw_cursor_t cursor();
53
54 private: // Methods and virtual table for libunwind
55   static int find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t* pip, int need_unwind_info,
56                             void* arg) noexcept;
57   static void put_unwind_info(unw_addr_space_t as, unw_proc_info_t* pip, void* arg) noexcept;
58   static int get_dyn_info_list_addr(unw_addr_space_t as, unw_word_t* dilap, void* arg) noexcept;
59   static int access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t* valp, int write, void* arg) noexcept;
60   static void* get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept;
61   static int access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t* valp, int write, void* arg) noexcept;
62   static int get_proc_name(unw_addr_space_t as, unw_word_t addr, char* bufp, size_t buf_len, unw_word_t* offp,
63                            void* arg) noexcept;
64   static unw_accessors_t accessors;
65
66 public:
67   // Create a libunwind address space:
68   static unw_addr_space_t createUnwindAddressSpace();
69 };
70
71 void dumpStack(FILE* file, unw_cursor_t* cursor);
72 } // namespace mc
73 } // namespace simgrid
74
75 #endif