History

Debugger supports breakpoints (set/clear/list) Clean up usage of final and override on various classes Distinguish tool events for vm loading module and thread loading module

arr committed 10 years ago

Commit e2f8e251 parent d8c9a3314 files · +382 −177Browse files

Showing the changes to src/include (4 of 14 files). Show all

Unified · Split

4 files
  1. src/include/disvm.h +4 −1
  2. src/include/runtime.h +4 −5
  3. src/include/vm_memory.h +13 −11
  4. src/include/vm_tools.h +23 −8
src/include/disvm.h+4−1
@@ -39,6 +39,8 @@ namespace disvm · 38 unmodified lines
39 class loaded_vm_module_t final39 class loaded_vm_module_t final
40 {40 {
41 public:41 public:
42 std::size_t load_id;
43
42 // Origin of module44 // Origin of module
43 std::unique_ptr<runtime::vm_string_t> origin;45 std::unique_ptr<runtime::vm_string_t> origin;
44 46
@@ -46,7 +48,8 @@ namespace disvm · 1 unmodified line
46 std::weak_ptr<runtime::vm_module_t> module;48 std::weak_ptr<runtime::vm_module_t> module;
47 };49 };
48 50
49 using loaded_vm_module_callback_t = std::function<void(const loaded_vm_module_t&)>;51 // Callback for enumerating loaded modules - return 'false' to stop enumeration, otherwise 'true'
52 using loaded_vm_module_callback_t = std::function<bool(const loaded_vm_module_t&)>;
50 53
51 // Virtual machine54 // Virtual machine
52 class vm_t final55 class vm_t final
src/include/runtime.h+4−5
@@ -824,13 +824,12 @@ namespace disvm · 823 unmodified lines
824 virtual void set_tool_dispatch_on_all_threads(vm_tool_dispatch_t *dispatch) = 0;824 virtual void set_tool_dispatch_on_all_threads(vm_tool_dispatch_t *dispatch) = 0;
825 };825 };
826 826
827 // The supplied allocation is guaranteed to be valid for the lifetime of the callback.
828 using vm_alloc_callback_t = std::function<void(const vm_alloc_t *)>;
829
827 // VM garbage collector interface830 // VM garbage collector interface
828 class vm_garbage_collector_t831 class vm_garbage_collector_t
829 {832 {
830 public:
831 // The supplied allocation is guaranteed to be valid for the lifetime of the callback.
832 using vm_alloc_callback_t = std::function<void(const vm_alloc_t *)>;
833
834 public:833 public:
835 virtual ~vm_garbage_collector_t() = 0;834 virtual ~vm_garbage_collector_t() = 0;
836 835
@@ -862,7 +861,7 @@ namespace disvm · 25 unmodified lines
862 virtual ~vm_tool_t() = 0;861 virtual ~vm_tool_t() = 0;
863 862
864 // Called when the tool is loaded into the VM863 // Called when the tool is loaded into the VM
865 virtual void on_load(vm_t &vm, vm_tool_controller_t &controller, std::size_t tool_id) = 0;864 virtual void on_load(vm_tool_controller_t &controller, std::size_t tool_id) = 0;
866 865
867 // Called when the tool is unloaded from the VM.866 // Called when the tool is unloaded from the VM.
868 // Note once the tool has been unloaded the vm and controller references supplied during load867 // Note once the tool has been unloaded the vm and controller references supplied during load
src/include/vm_memory.h+13−11
@@ -70,10 +70,11 @@ namespace disvm · 69 unmodified lines
70 // Increment the ref count of all points in the supplied memory allocation70 // Increment the ref count of all points in the supplied memory allocation
71 void inc_ref_count_in_memory(const type_descriptor_t &type_desc, void *data);71 void inc_ref_count_in_memory(const type_descriptor_t &type_desc, void *data);
72 72
73 // Decrement the ref count and if 0 free the allocation.73 // Decrement the ref count and if 0 free the allocation
74 void dec_ref_count_and_free(vm_alloc_t *alloc);74 void dec_ref_count_and_free(vm_alloc_t *alloc);
75 75
76 using pointer_field_callback_t = std::function<void(pointer_t)>;76 // Callback for a pointer field supplying the pointer and byte offset
77 using pointer_field_callback_t = std::function<void(pointer_t, std::size_t)>;
77 78
78 // The callback will be called on all non-null pointer fields.79 // The callback will be called on all non-null pointer fields.
79 inline void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback)80 inline void enum_pointer_fields(const type_descriptor_t &type_desc, void *data, pointer_field_callback_t callback)
@@ -82,8 +83,9 @@ namespace disvm · 2 unmodified lines
82 if (type_desc.size_in_bytes == 0)83 if (type_desc.size_in_bytes == 0)
83 return;84 return;
84 85
86 auto offset_accum = std::size_t{ 0 };
85 auto memory = reinterpret_cast<word_t *>(data);87 auto memory = reinterpret_cast<word_t *>(data);
86 for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8)88 for (auto i = word_t{ 0 }; i < type_desc.map_in_bytes; ++i, memory += 8, offset_accum += 8)
87 {89 {
88 const auto words8 = type_desc.pointer_map[i];90 const auto words8 = type_desc.pointer_map[i];
89 if (words8 != 0)91 if (words8 != 0)
@@ -91,14 +93,14 @@ namespace disvm · 1 unmodified line
91 const auto flags = std::bitset<sizeof(words8) * 8>{ words8 };93 const auto flags = std::bitset<sizeof(words8) * 8>{ words8 };
92 94
93 // Enumerating the flags in reverse order so memory access is sequential.95 // Enumerating the flags in reverse order so memory access is sequential.
94 if (flags[7] && (memory[0] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[0]));96 if (flags[7] && (memory[0] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[0]), offset_accum);
95 if (flags[6] && (memory[1] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[1]));97 if (flags[6] && (memory[1] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[1]), offset_accum + (1 * sizeof(pointer_t)));
96 if (flags[5] && (memory[2] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[2]));98 if (flags[5] && (memory[2] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[2]), offset_accum + (2 * sizeof(pointer_t)));
97 if (flags[4] && (memory[3] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[3]));99 if (flags[4] && (memory[3] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[3]), offset_accum + (3 * sizeof(pointer_t)));
98 if (flags[3] && (memory[4] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[4]));100 if (flags[3] && (memory[4] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[4]), offset_accum + (4 * sizeof(pointer_t)));
99 if (flags[2] && (memory[5] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[5]));101 if (flags[2] && (memory[5] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[5]), offset_accum + (5 * sizeof(pointer_t)));
100 if (flags[1] && (memory[6] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[6]));102 if (flags[1] && (memory[6] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[6]), offset_accum + (6 * sizeof(pointer_t)));
101 if (flags[0] && (memory[7] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[7]));103 if (flags[0] && (memory[7] != runtime_constants::nil)) callback(reinterpret_cast<pointer_t>(memory[7]), offset_accum + (7 * sizeof(pointer_t)));
102 }104 }
103 }105 }
104 }106 }
src/include/vm_tools.h+23−8
@@ -17,10 +17,12 @@ namespace disvm · 16 unmodified lines
17{17{
18 namespace runtime18 namespace runtime
19 {19 {
20 using cookie_t = std::size_t;
21
20 // Value in event context22 // Value in event context
21 union vm_context_value_t23 union vm_context_value_t
22 {24 {
23 std::size_t i;25 cookie_t cookie;
24 std::shared_ptr<vm_module_t> *module; // Note this is a pointer to std::shared_ptr<>26 std::shared_ptr<vm_module_t> *module; // Note this is a pointer to std::shared_ptr<>
25 vm_registers_t *registers;27 vm_registers_t *registers;
26 const vm_thread_t *thread;28 const vm_thread_t *thread;
@@ -39,8 +41,11 @@ namespace disvm · 12 unmodified lines
39 // List of possible events41 // List of possible events
40 enum class vm_event_t42 enum class vm_event_t
41 {43 {
42 module_load, // value1: std::shared_ptr<vm_module_t>44 module_vm_load, // value1: std::shared_ptr<vm_module_t>
43 // value2: const vm_string_t - path45 // value2: const vm_string_t - path on disk
46
47 module_thread_load, // value1: vm_registers_t
48 // value2: std::shared_ptr<vm_module_t>
44 49
45 thread_begin, // value1: const vm_thread_t50 thread_begin, // value1: const vm_thread_t
46 thread_end, // value1: const vm_thread_t51 thread_end, // value1: const vm_thread_t
@@ -54,22 +59,32 @@ namespace disvm · 7 unmodified lines
54 // value3: const vm_alloc_t - object raised59 // value3: const vm_alloc_t - object raised
55 60
56 breakpoint, // value1: vm_registers_t61 breakpoint, // value1: vm_registers_t
57 // value2: std::size_t - cookie of breakpoint. '0' indicates the breakpoint was inserted by the VM or compiler.62 // value2: cookie_t - cookie of breakpoint. '0' indicates the breakpoint was inserted by the VM or compiler.
58 };63 };
59 64
60 using vm_event_callback_t = std::function<void(vm_event_t, vm_event_context_t &)>;65 using vm_event_callback_t = std::function<void(vm_event_t, vm_event_context_t &)>;
61 66
67 struct breakpoint_details_t final
68 {
69 std::shared_ptr<vm_module_t> module;
70 vm_pc_t pc;
71 };
72
62 // VM tool controller73 // VM tool controller
63 class vm_tool_controller_t74 class vm_tool_controller_t
64 {75 {
65 public:76 public:
77 // The current vm instance
78 virtual vm_t& get_vm_instance() const = 0;
79
66 // Call the supplied callback when the specified event occurs80 // Call the supplied callback when the specified event occurs
67 virtual std::size_t subscribe_event(vm_event_t, vm_event_callback_t) = 0;81 virtual cookie_t subscribe_event(vm_event_t, vm_event_callback_t) = 0;
68 virtual void unsubscribe_event(std::size_t) = 0;82 virtual void unsubscribe_event(cookie_t) = 0;
69 83
70 // Set a breakpoint in the supplied module at the specified PC location84 // Set a breakpoint in the supplied module at the specified PC location
71 virtual std::size_t set_breakpoint(std::shared_ptr<vm_module_t>, vm_pc_t) = 0;85 virtual cookie_t set_breakpoint(std::shared_ptr<vm_module_t>, vm_pc_t) = 0;
72 virtual void clear_breakpoint(std::size_t) = 0;86 virtual breakpoint_details_t get_breakpoint_details(cookie_t) const = 0;
87 virtual void clear_breakpoint(cookie_t) = 0;
73 };88 };
74 }89 }
75}90}