Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MC: inline a function that is now trivial
[simgrid.git] / src / mc / sosp / mc_snapshot.hpp
1 /* Copyright (c) 2007-2019. 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_SNAPSHOT_HPP
7 #define SIMGRID_MC_SNAPSHOT_HPP
8
9 #include "src/mc/ModelChecker.hpp"
10 #include "src/mc/inspect/mc_unw.hpp"
11 #include "src/mc/remote/RemoteClient.hpp"
12 #include "src/mc/sosp/RegionSnapshot.hpp"
13
14 // ***** Snapshot region
15
16 static XBT_ALWAYS_INLINE void* mc_translate_address_region(uintptr_t addr, simgrid::mc::RegionSnapshot* region)
17 {
18   auto split                = simgrid::mc::mmu::split(addr - region->start().address());
19   auto pageno               = split.first;
20   auto offset               = split.second;
21   const void* snapshot_page = region->get_chunks().page(pageno);
22   return (char*)snapshot_page + offset;
23 }
24
25 // ***** MC Snapshot
26
27 /** Ignored data
28  *
29  *  Some parts of the snapshot are ignored by zeroing them out: the real
30  *  values is stored here.
31  * */
32 struct s_mc_snapshot_ignored_data_t {
33   void* start;
34   std::vector<char> data;
35 };
36
37 /** Information about a given stack frame */
38 struct s_mc_stack_frame_t {
39   /** Instruction pointer */
40   unw_word_t ip;
41   /** Stack pointer */
42   unw_word_t sp;
43   unw_word_t frame_base;
44   simgrid::mc::Frame* frame;
45   std::string frame_name;
46   unw_cursor_t unw_cursor;
47 };
48 typedef s_mc_stack_frame_t* mc_stack_frame_t;
49
50 struct s_local_variable_t {
51   simgrid::mc::Frame* subprogram;
52   unsigned long ip;
53   std::string name;
54   simgrid::mc::Type* type;
55   void* address;
56 };
57 typedef s_local_variable_t* local_variable_t;
58
59 struct XBT_PRIVATE s_mc_snapshot_stack_t {
60   std::vector<s_local_variable_t> local_variables;
61   simgrid::mc::UnwindContext context;
62   std::vector<s_mc_stack_frame_t> stack_frames;
63 };
64 typedef s_mc_snapshot_stack_t* mc_snapshot_stack_t;
65
66 namespace simgrid {
67 namespace mc {
68
69 class XBT_PRIVATE Snapshot final : public AddressSpace {
70 public:
71   Snapshot(int num_state, RemoteClient* process = &mc_model_checker->process());
72   ~Snapshot() = default;
73
74   /* Initialization */
75
76   /* Regular use */
77   const void* read_bytes(void* buffer, std::size_t size, RemotePtr<void> address,
78                          ReadOptions options = ReadOptions::none()) const override;
79   RegionSnapshot* get_region(const void* addr) const;
80   RegionSnapshot* get_region(const void* addr, RegionSnapshot* hinted_region) const;
81   void restore(RemoteClient* process);
82
83   // To be private
84   int num_state_;
85   std::size_t heap_bytes_used_;
86   std::vector<std::unique_ptr<RegionSnapshot>> snapshot_regions_;
87   std::set<pid_t> enabled_processes_;
88   std::vector<std::size_t> stack_sizes_;
89   std::vector<s_mc_snapshot_stack_t> stacks_;
90   std::vector<simgrid::mc::IgnoredHeapRegion> to_ignore_;
91   std::uint64_t hash_ = 0;
92   std::vector<s_mc_snapshot_ignored_data_t> ignored_data_;
93
94 private:
95   void add_region(RegionType type, ObjectInformation* object_info, void* start_addr, std::size_t size);
96   void snapshot_regions(simgrid::mc::RemoteClient* process);
97   void snapshot_stacks(simgrid::mc::RemoteClient* process);
98 };
99 } // namespace mc
100 } // namespace simgrid
101
102 static const void* mc_snapshot_get_heap_end(simgrid::mc::Snapshot* snapshot);
103
104 const void* MC_region_read_fragmented(simgrid::mc::RegionSnapshot* region, void* target, const void* addr,
105                                       std::size_t size);
106
107 int MC_snapshot_region_memcmp(const void* addr1, simgrid::mc::RegionSnapshot* region1, const void* addr2,
108                               simgrid::mc::RegionSnapshot* region2, std::size_t size);
109
110 static XBT_ALWAYS_INLINE const void* mc_snapshot_get_heap_end(simgrid::mc::Snapshot* snapshot)
111 {
112   if (snapshot == nullptr)
113     xbt_die("snapshot is nullptr");
114   return mc_model_checker->process().get_heap()->breakval;
115 }
116
117 /** @brief Read memory from a snapshot region
118  *
119  *  @param addr    Process (non-snapshot) address of the data
120  *  @param region  Snapshot memory region where the data is located
121  *  @param target  Buffer to store the value
122  *  @param size    Size of the data to read in bytes
123  *  @return Pointer where the data is located (target buffer of original location)
124  */
125 static XBT_ALWAYS_INLINE const void* MC_region_read(simgrid::mc::RegionSnapshot* region, void* target, const void* addr,
126                                                     std::size_t size)
127 {
128   xbt_assert(region);
129
130   xbt_assert(region->contain(simgrid::mc::remote(addr)), "Trying to read out of the region boundary.");
131
132       // Last byte of the region:
133       void* end = (char*)addr + size - 1;
134       if (simgrid::mc::mmu::same_chunk((std::uintptr_t)addr, (std::uintptr_t)end)) {
135         // The memory is contained in a single page:
136         return mc_translate_address_region((uintptr_t)addr, region);
137       }
138       // Otherwise, the memory spans several pages:
139       return MC_region_read_fragmented(region, target, addr, size);
140 }
141
142 static XBT_ALWAYS_INLINE void* MC_region_read_pointer(simgrid::mc::RegionSnapshot* region, const void* addr)
143 {
144   void* res;
145   return *(void**)MC_region_read(region, &res, addr, sizeof(void*));
146 }
147
148 #endif