Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
4bdb15384040818ceaea5bf7c6e4d14c08be1b71
[simgrid.git] / src / mc / sosp / 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/Region.hpp"
13
14 // ***** Snapshot region
15
16 static XBT_ALWAYS_INLINE void* mc_translate_address_region(uintptr_t addr, simgrid::mc::Region* 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   Region* get_region(const void* addr) const;
80   Region* get_region(const void* addr, Region* 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<Region>> 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::Region* region, void* target, const void* addr, std::size_t size);
105
106 int MC_snapshot_region_memcmp(const void* addr1, simgrid::mc::Region* region1, const void* addr2,
107                               simgrid::mc::Region* region2, std::size_t size);
108
109 static XBT_ALWAYS_INLINE const void* mc_snapshot_get_heap_end(simgrid::mc::Snapshot* snapshot)
110 {
111   if (snapshot == nullptr)
112     xbt_die("snapshot is nullptr");
113   return mc_model_checker->process().get_heap()->breakval;
114 }
115
116 /** @brief Read memory from a snapshot region
117  *
118  *  @param addr    Process (non-snapshot) address of the data
119  *  @param region  Snapshot memory region where the data is located
120  *  @param target  Buffer to store the value
121  *  @param size    Size of the data to read in bytes
122  *  @return Pointer where the data is located (target buffer of original location)
123  */
124 static XBT_ALWAYS_INLINE const void* MC_region_read(simgrid::mc::Region* region, void* target, const void* addr,
125                                                     std::size_t size)
126 {
127   xbt_assert(region);
128
129   xbt_assert(region->contain(simgrid::mc::remote(addr)), "Trying to read out of the region boundary.");
130
131   // Last byte of the region:
132   void* end = (char*)addr + size - 1;
133   if (simgrid::mc::mmu::same_chunk((std::uintptr_t)addr, (std::uintptr_t)end)) {
134     // The memory is contained in a single page:
135     return mc_translate_address_region((uintptr_t)addr, region);
136   }
137   // Otherwise, the memory spans several pages:
138   return MC_region_read_fragmented(region, target, addr, size);
139 }
140
141 static XBT_ALWAYS_INLINE void* MC_region_read_pointer(simgrid::mc::Region* region, const void* addr)
142 {
143   void* res;
144   return *(void**)MC_region_read(region, &res, addr, sizeof(void*));
145 }
146
147 #endif