History

Name the entry module in the exec program. Re-write stack walking function for debugger. System exceptions now print out call stack.

arr committed 10 years ago

Commit 794ecfc1 parent 4f6417b5 files · +54 −35Browse files

Unified · Split

5 files
  1. src/exec/main.cpp +3 −0
  2. src/include/runtime.h +8 −9
  3. src/vm/scheduler.cpp +19 −2
  4. src/vm/stack.cpp +0 −21
  5. src/vm/thread.cpp +24 −3
src/exec/main.cpp+3−0
@@ -73,6 +73,9 @@ namespace · 72 unmodified lines
7373 e.header.entry_type = 0;
7474 e.header.runtime_flag = (runtime_flags_t::has_import);
7575
76+ std::array<uint8_t, 8> mod_name = { "_entry_" };
77+ e.module_name = std::make_unique<vm_string_t>(mod_name.size() - 1, mod_name.data());
78+
7679 // Inherit the stack extent from the command module and add the entry frame size.
7780 e.header.stack_extent = command_module->header.stack_extent + sizeof(vm_entry_frame_t);
7881
src/include/runtime.h+8−9
@@ -656,11 +656,6 @@ namespace disvm · 655 unmodified lines
656656 pointer_t fixed_point_register_2() const;
657657 };
658658
659− // Callback for stack walk.
660− // Returning 'false' during the stack walk will terminate the walk.
661− // The second parameter is reserved for internal use by the VM and should not be manipulated.
662− using vm_stack_walk_callback_t = std::function<bool(const vm_frame_t *f, const void *reserved)>;
663−
664659 // VM stack
665660 class vm_stack_t final
666661 {
@@ -680,10 +675,6 @@ namespace disvm · 13 unmodified lines
680675 // Return the current top frame.
681676 vm_frame_t *peek_frame() const;
682677
683− // Walk the stack getting a callback for each frame.
684− // This function is __not__ thread safe.
685− void walk_stack(vm_stack_walk_callback_t callback) const;
686−
687678 private:
688679 std::unique_ptr<vm_alloc_t> _mem;
689680 };
@@ -741,6 +732,14 @@ namespace disvm · 51 unmodified lines
741732 pointer_t dest;
742733 };
743734
735+ // Callback for stack walk.
736+ // Returning 'false' during the stack walk will terminate the walk.
737+ using vm_stack_walk_callback_t = std::function<bool(const pointer_t frame, const vm_pc_t pc, const vm_module_ref_t &module_ref)>;
738+
739+ // Walk the stack getting a callback for each frame.
740+ // This function is __not__ thread safe if the vm thread being walked is not stopped.
741+ void walk_stack(const vm_registers_t &r, vm_stack_walk_callback_t callback);
742+
744743 // VM thread
745744 class vm_thread_t final : public vm_alloc_t
746745 {
src/vm/scheduler.cpp+19−2
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 //
66
77 #include <debug.h>
8+#include <sstream>
89 #include <exceptions.h>
910 #include "scheduler.h"
1011
@@ -45,8 +46,24 @@ void default_scheduler_t::worker_main(default_scheduler_t &instance) · 34 unmodified lines
4546 }
4647 catch (const vm_system_exception &se)
4748 {
48− std::printf("%s\n", se.what());
49+ std::stringstream err_msg;
50+ err_msg << se.what() << "\n";
4951
52+ if (current_thread != nullptr)
53+ {
54+ const auto &r = current_thread->vm_thread->get_registers();
55+ walk_stack(r, [&err_msg](const pointer_t, const vm_pc_t pc, const vm_module_ref_t &module_ref)
56+ {
57+ auto module_name = "<No Name>";
58+ if (module_ref.module->module_name != nullptr)
59+ module_name = module_ref.module->module_name->str();
60+
61+ err_msg << "\t" << module_name << "@" << pc << "\n";
62+ return true;
63+ });
64+ }
65+
66+ std::fprintf(stderr, "%s\n", err_msg.str().c_str());
5067 instance._terminating = true;
5168 instance._worker_event.notify_all();
5269 }
@@ -89,7 +106,7 @@ default_scheduler_t::~default_scheduler_t() · 36 unmodified lines
89106 bool default_scheduler_t::is_idle() const
90107 {
91108 std::lock_guard<std::mutex> lock{ _vm_threads_lock };
92− return _running_vm_thread_count == 0 && _runnable_vm_threads.empty() && _blocked_vm_thread_ids.empty() && !_terminating;
109+ return (_terminating) || (_running_vm_thread_count == 0 && _runnable_vm_threads.empty() && _blocked_vm_thread_ids.empty());
93110 }
94111
95112 vm_scheduler_control_t &default_scheduler_t::get_controller() const
src/vm/stack.cpp+0−21
@@ -295,24 +295,3 @@ vm_frame_t *vm_stack_t::peek_frame() const · 294 unmodified lines
295295 auto layout = dynamic_cast<vm_stack_layout *>(_mem.get());
296296 return layout->top_frame;
297297 }
298−
299−void vm_stack_t::walk_stack(vm_stack_walk_callback_t callback) const
300−{
301− if (callback == nullptr)
302− return;
303−
304− auto layout = dynamic_cast<vm_stack_layout *>(_mem.get());
305− auto current_page = layout->top_page;
306− auto current_frame = layout->top_frame;
307−
308− while (current_page != nullptr && current_frame != nullptr)
309− {
310− if (!callback(current_frame, current_page))
311− break;
312−
313− current_frame = current_frame->prev_frame();
314−
315− if (!current_page->contains_frame(current_frame))
316− current_page = current_page->prev_page;
317− }
318−}
src/vm/thread.cpp+24−3
@@ -153,6 +153,27 @@ vm_registers_t::~vm_registers_t() · 152 unmodified lines
153153 debug::assign_debug_pointer(&module_ref);
154154 }
155155
156+void disvm::runtime::walk_stack(const vm_registers_t &r, vm_stack_walk_callback_t callback)
157+{
158+ assert(callback != nullptr);
159+
160+ auto current_pc = r.pc;
161+ auto current_module = r.module_ref;
162+ auto current_frame = r.stack.peek_frame();
163+ while (current_frame != nullptr)
164+ {
165+ if (!callback(current_frame->base(), current_pc, *current_module))
166+ break;
167+
168+ current_pc = current_frame->prev_pc();
169+ auto prev_module_maybe = current_frame->prev_module_ref();
170+ if (prev_module_maybe != nullptr)
171+ current_module = prev_module_maybe;
172+
173+ current_frame = current_frame->prev_frame();
174+ }
175+}
176+
156177 std::shared_ptr<const type_descriptor_t> vm_thread_t::type_desc()
157178 {
158179 return intrinsic_type_desc::type<vm_thread_t>();
@@ -252,17 +273,17 @@ vm_thread_state_t vm_thread_t::execute(vm_t &virtual_machine, const uint32_t qua · 93 unmodified lines
252273 catch (const unhandled_user_exception &uue)
253274 {
254275 // [TODO] Store the exception
255− std::printf("%s - %s in %s at instruction %d\n", uue.what(), uue.exception_id, uue.module_name, uue.program_counter);
276+ std::fprintf(stderr, "%s - %s in %s at instruction %d\n", uue.what(), uue.exception_id, uue.module_name, uue.program_counter);
256277 _registers.current_thread_state = vm_thread_state_t::broken;
257278 }
258279 catch (const index_out_of_range_memory &ioor)
259280 {
260− std::printf("%s - %d [%d,%d]\n", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max);
281+ std::fprintf(stderr, "%s - %d [%d,%d]\n", ioor.what(), ioor.invalid_value, ioor.valid_min, ioor.valid_max);
261282 _registers.current_thread_state = vm_thread_state_t::broken;
262283 }
263284 catch (const vm_user_exception &ue)
264285 {
265− std::printf("%s\n", ue.what());
286+ std::fprintf(stderr, "%s\n", ue.what());
266287 _registers.current_thread_state = vm_thread_state_t::broken;
267288 }
268289