History

Expose the loaded path of a module from the VM. Display path for the loaded module in the debugger.

arr committed 10 years ago

Commit 42194721 parent 836214e4 files · +47 −57Browse files

Unified · Split

4 files
  1. src/exec/debugger.cpp +10 −3
  2. src/include/disvm.h +19 −22
  3. src/vm/vm.cpp +13 −30
  4. src/vm/vm_memory.cpp +5 −2
src/exec/debugger.cpp+10−3
@@ -322,8 +322,15 @@ namespace · 321 unmodified lines
322 {322 {
323 auto msg = std::stringstream{};323 auto msg = std::stringstream{};
324 msg << "Modules:\n";324 msg << "Modules:\n";
325 for (auto m : cxt.vm.get_loaded_modules())325
326 msg << " " << m->module_name->str() << "\n";326 cxt.vm.enum_loaded_modules([&msg](const loaded_vm_module_t &m)
327 {
328 auto module_instance = m.module.lock();
329 if (module_instance == nullptr)
330 return;
331
332 msg << std::setw(24) << module_instance->module_name->str() << std::setw(0) << " " << m.origin->str() << "\n";
333 });
327 334
328 debug_print_info(msg.str());335 debug_print_info(msg.str());
329 }336 }
@@ -625,7 +632,7 @@ namespace · 295 unmodified lines
625 { "r", "Print registers", nullptr, nullptr, cmd_print_registers },632 { "r", "Print registers", nullptr, nullptr, cmd_print_registers },
626 { "t", "Print all threads", nullptr, nullptr, cmd_print_threads },633 { "t", "Print all threads", nullptr, nullptr, cmd_print_threads },
627 { "m", "Print all loaded modules", nullptr, nullptr, cmd_print_modules },634 { "m", "Print all loaded modules", nullptr, nullptr, cmd_print_modules },
628 { "sw", "Stack walk/back trace", "bt ([0-9]+|\\*)?", "bt, bt 34, bt *", cmd_stacktrace },635 { "bt", "Stack walk/back trace for the current or supplied thread", "bt ([0-9]+|\\*)?", "bt, bt 34, bt *", cmd_stacktrace },
629 { "st", "Switch to thread", "st [0-9]+", "st 42", cmd_switchthread },636 { "st", "Switch to thread", "st [0-9]+", "st 42", cmd_switchthread },
630 { "d", "Disassemble the next/previous N instructions", "d (-?[0-9]+)?", "d, d -4, d 5", cmd_disassemble },637 { "d", "Disassemble the next/previous N instructions", "d (-?[0-9]+)?", "d, d -4, d 5", cmd_disassemble },
631 { "x", "Examine memory", "x [mp|fp] [0-9]+ ([0-9]+)?", "x mp 3, x fp 20 6", cmd_examine },638 { "x", "Examine memory", "x [mp|fp] [0-9]+ ([0-9]+)?", "x mp 3, x fp 20 6", cmd_examine },
src/include/disvm.h+19−22
@@ -35,6 +35,19 @@ namespace disvm · 34 unmodified lines
35 const char * const label; // Optional35 const char * const label; // Optional
36 };36 };
37 37
38 // Loaded module reference
39 class loaded_vm_module_t final
40 {
41 public:
42 // Origin of module
43 std::unique_ptr<runtime::vm_string_t> origin;
44
45 // Weak reference to a loaded module
46 std::weak_ptr<runtime::vm_module_t> module;
47 };
48
49 using loaded_vm_module_callback_t = std::function<void(const loaded_vm_module_t&)>;
50
38 // Virtual machine51 // Virtual machine
39 class vm_t final52 class vm_t final
40 {53 {
@@ -71,9 +84,11 @@ namespace disvm · 30 unmodified lines
71 // Load the module at the supplied path into the virtual machine84 // Load the module at the supplied path into the virtual machine
72 std::shared_ptr<runtime::vm_module_t> load_module(const char *path);85 std::shared_ptr<runtime::vm_module_t> load_module(const char *path);
73 86
74 // Get a collection of all currently loaded modules.87 // Enumerate all loaded modules - this can include references to modules that
75 // Note this will only include modules that have been loaded by a call to vm_t::load_module.88 // have been unloaded due to no longer being used. If the module instance is null, the
76 std::vector<std::shared_ptr<runtime::vm_module_t>> get_loaded_modules() const;89 // module is no longer loaded.
90 // Note this will only enumerate modules that have been loaded by a call to vm_t::load_module.
91 void enum_loaded_modules(loaded_vm_module_callback_t callback) const;
77 92
78 // Access the scheduler control for this VM.93 // Access the scheduler control for this VM.
79 runtime::vm_scheduler_control_t &get_scheduler_control() const;94 runtime::vm_scheduler_control_t &get_scheduler_control() const;
@@ -94,25 +109,7 @@ namespace disvm · 14 unmodified lines
94 private:109 private:
95 const runtime::vm_thread_t &schedule_thread(std::unique_ptr<runtime::vm_thread_t> thread);110 const runtime::vm_thread_t &schedule_thread(std::unique_ptr<runtime::vm_thread_t> thread);
96 111
97 // Loaded module reference112 using loaded_modules_t = std::forward_list<loaded_vm_module_t>;
98 class loaded_module_t final
99 {
100 public:
101 loaded_module_t(std::unique_ptr<runtime::vm_string_t> origin, std::shared_ptr<runtime::vm_module_t> module);
102 loaded_module_t(const loaded_module_t &) = delete;
103 loaded_module_t &operator=(const loaded_module_t &) = delete;
104
105 loaded_module_t(loaded_module_t &&);
106 ~loaded_module_t();
107
108 // Origin of module
109 std::unique_ptr<runtime::vm_string_t> origin;
110
111 // Weak reference to a loaded module
112 std::weak_ptr<runtime::vm_module_t> module;
113 };
114
115 using loaded_modules_t = std::forward_list<loaded_module_t>;
116 mutable std::mutex _modules_lock;113 mutable std::mutex _modules_lock;
117 loaded_modules_t _modules;114 loaded_modules_t _modules;
118 115
src/vm/vm.cpp+13−30
@@ -20,25 +20,6 @@ · 19 unmodified lines
20using namespace disvm;20using namespace disvm;
21using namespace disvm::runtime;21using namespace disvm::runtime;
22 22
23vm_t::loaded_module_t::loaded_module_t(std::unique_ptr<runtime::vm_string_t> origin, std::shared_ptr<runtime::vm_module_t> module)
24 : origin{ std::move(origin) }
25 , module{ module }
26{
27 assert(this->origin != nullptr);
28}
29
30vm_t::loaded_module_t::loaded_module_t(loaded_module_t &&other)
31 : origin{ std::move(other.origin) }
32 , module{ std::move(other.module) }
33{
34}
35
36vm_t::loaded_module_t::~loaded_module_t()
37{
38 if (origin != nullptr)
39 origin->release();
40}
41
42vm_t::vm_t(23vm_t::vm_t(
43 create_vm_interface_callback_t<runtime::vm_scheduler_t> create_scheduler,24 create_vm_interface_callback_t<runtime::vm_scheduler_t> create_scheduler,
44 create_vm_interface_callback_t<runtime::vm_garbage_collector_t> create_gc)25 create_vm_interface_callback_t<runtime::vm_garbage_collector_t> create_gc)
@@ -80,6 +61,13 @@ vm_t::~vm_t() · 35 unmodified lines
80 // Release the scheduler first since it could be using the gc instance.61 // Release the scheduler first since it could be using the gc instance.
81 _scheduler.reset();62 _scheduler.reset();
82 _gc.reset();63 _gc.reset();
64
65 std::lock_guard<std::mutex> lock{ _modules_lock };
66 for (auto &m : _modules)
67 {
68 if (m.origin != nullptr)
69 m.origin->release();
70 }
83}71}
84 72
85vm_version_t vm_t::get_version() const73vm_version_t vm_t::get_version() const
@@ -139,7 +127,7 @@ std::shared_ptr<runtime::vm_module_t> vm_t::load_module(const char *path) · 53 unmodified lines
139 throw vm_user_exception{ "Invalid module path" };127 throw vm_user_exception{ "Invalid module path" };
140 128
141 std::lock_guard<std::mutex> lock{ _modules_lock };129 std::lock_guard<std::mutex> lock{ _modules_lock };
142 130
143 // Check if the module is already loaded.131 // Check if the module is already loaded.
144 auto iter = std::begin(_modules);132 auto iter = std::begin(_modules);
145 while (iter != std::end(_modules))133 while (iter != std::end(_modules))
@@ -182,26 +170,21 @@ std::shared_ptr<runtime::vm_module_t> vm_t::load_module(const char *path) · 36 unmodified lines
182 _tool_dispatch->on_module_load(new_module, *path_local);170 _tool_dispatch->on_module_load(new_module, *path_local);
183 }171 }
184 172
185 _modules.push_front(std::move(loaded_module_t{ std::move(path_local), new_module }));173 _modules.push_front(std::move(loaded_vm_module_t{ std::move(path_local), new_module }));
186 174
187 debug::log_msg(debug::component_trace_t::module, debug::log_level_t::debug, "load: vm module: >>%s<<\n", path);175 debug::log_msg(debug::component_trace_t::module, debug::log_level_t::debug, "load: vm module: >>%s<<\n", path);
188 176
189 return new_module;177 return new_module;
190}178}
191 179
192std::vector<std::shared_ptr<runtime::vm_module_t>> vm_t::get_loaded_modules() const180void vm_t::enum_loaded_modules(loaded_vm_module_callback_t callback) const
193{181{
194 auto result = std::vector<std::shared_ptr<runtime::vm_module_t>>{};182 if (callback == nullptr)
183 throw vm_system_exception{ "Callback should not be null" };
195 184
196 std::lock_guard<std::mutex> lock{ _modules_lock };185 std::lock_guard<std::mutex> lock{ _modules_lock };
197 for (auto &m : _modules)186 for (auto &m : _modules)
198 {187 callback(m);
199 auto loaded_module_maybe = m.module.lock();
200 if (loaded_module_maybe != nullptr)
201 result.push_back(loaded_module_maybe);
202 }
203
204 return result;
205}188}
206 189
207runtime::vm_scheduler_control_t &vm_t::get_scheduler_control() const190runtime::vm_scheduler_control_t &vm_t::get_scheduler_control() const
src/vm/vm_memory.cpp+5−2
@@ -422,7 +422,9 @@ std::shared_ptr<const type_descriptor_t> type_descriptor_t::create( · 421 unmodified lines
422 free_memory(const_cast<byte_t *>(td->pointer_map));422 free_memory(const_cast<byte_t *>(td->pointer_map));
423 debug::assign_debug_pointer(const_cast<byte_t **>(&td->pointer_map));423 debug::assign_debug_pointer(const_cast<byte_t **>(&td->pointer_map));
424 424
425 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: type descriptor\n");425 if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
426 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: type descriptor\n");
427
426 free_memory(td);428 free_memory(td);
427 }429 }
428 } deleter;430 } deleter;
@@ -451,5 +453,6 @@ type_descriptor_t::type_descriptor_t( · 22 unmodified lines
451 , pointer_map{ pointer_map }453 , pointer_map{ pointer_map }
452 , finalizer{ finalizer }454 , finalizer{ finalizer }
453{455{
454 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: type descriptor\n");456 if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>())
457 debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "init: type descriptor\n");
455}458}