Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fix copyright years and other psychotic cleanups
[simgrid.git] / src / mc / mc_unw.h
1 /* Copyright (c) 2015-2017. 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_H
7 #define SIMGRID_MC_UNW_H
8
9 /** @file
10  *  Libunwind implementation for the model-checker
11  *
12  *  Libunwind provides an pluggable stack unwinding API: the way the current
13  *  registers and memory is accessed, the way unwinding informations 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 <sys/types.h>
29
30 #include <xbt/base.h>
31
32 #include <libunwind.h>
33
34 #include "src/mc/mc_forward.hpp"
35
36 namespace simgrid {
37 namespace unw {
38
39 XBT_PRIVATE unw_addr_space_t create_addr_space();
40 XBT_PRIVATE void* create_context(unw_addr_space_t as, pid_t pid);
41
42 }
43 }
44
45 namespace simgrid {
46 namespace mc {
47
48 class UnwindContext {
49   simgrid::mc::AddressSpace* addressSpace_ = nullptr;
50   simgrid::mc::Process*      process_ = nullptr;
51   unw_context_t              unwindContext_;
52 public:
53   UnwindContext() {}
54   ~UnwindContext() { clear(); }
55   void initialize(simgrid::mc::Process* process, unw_context_t* c);
56   void clear();
57   unw_cursor_t cursor();
58
59 private: // Methods and virtual table for libunwind
60   static int find_proc_info(unw_addr_space_t as,
61                 unw_word_t ip, unw_proc_info_t *pip,
62                 int need_unwind_info, void* arg) noexcept;
63   static void put_unwind_info(unw_addr_space_t as,
64                 unw_proc_info_t *pip, void* arg) noexcept;
65   static int get_dyn_info_list_addr(unw_addr_space_t as,
66                 unw_word_t *dilap, void* arg) noexcept;
67   static int access_mem(unw_addr_space_t as,
68                 unw_word_t addr, unw_word_t *valp,
69                 int write, void* arg) noexcept;
70   static void* get_reg(unw_context_t* context, unw_regnum_t regnum) noexcept;
71   static int access_reg(unw_addr_space_t as,
72                 unw_regnum_t regnum, unw_word_t *valp,
73                 int write, void* arg) noexcept;
74   static int access_fpreg(unw_addr_space_t as,
75                 unw_regnum_t regnum, unw_fpreg_t *fpvalp,
76                 int write, void* arg) noexcept;
77   static int resume(unw_addr_space_t as,
78                 unw_cursor_t *cp, void* arg) noexcept;
79   static int get_proc_name(unw_addr_space_t as,
80                 unw_word_t addr, char *bufp,
81                 size_t buf_len, unw_word_t *offp,
82                 void* arg) noexcept;
83   static unw_accessors_t accessors;
84 public:
85   // Create a libunwind address space:
86   static unw_addr_space_t createUnwindAddressSpace();
87 };
88
89 void MC_dump_stack_unw(FILE* file, unw_cursor_t cursor);
90 void dumpStack(FILE* file, unw_cursor_t cursor);
91 void dumpStack(FILE* file, pid_t pid);
92
93 }
94 }
95
96 #endif