Logo AND Algorithmique Numérique Distribuée

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