Showing the changes to src/exec/debugger.cpp (1 of 8 files). Show all
Unified · Split
| @@ -11,7 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <string> | 11 | #include <string> |
| 12 | #include <algorithm> | 12 | #include <algorithm> |
| 13 | #include <map> | 13 | #include <map> |
| 14 | #include <unordered_set> | 14 | #include <set> |
| 15 | #include <utils.h> | 15 | #include <utils.h> |
| 16 | #include <vm_memory.h> | 16 | #include <vm_memory.h> |
| 17 | #include <vm_asm.h> | 17 | #include <vm_asm.h> |
| @@ -91,28 +91,31 @@ namespace · 73 unmodified lines | |||
| 91 | { | 91 | { |
| 92 | static std::string last_successful_cmd_option; | 92 | static std::string last_successful_cmd_option; |
| 93 | 93 | ||
| 94 | dbg_cmd_cxt_t(debugger &d, const vm_registers_t &r) | 94 | dbg_cmd_cxt_t(debugger &d, vm_registers_t &r, bool transient_context = false) |
| 95 | : dbg{ d } | 95 | : dbg{ d } |
| 96 | , exit_break{ false } | 96 | , exit_break{ false } |
| 97 | , current_register{ &r } | ||
| 97 | , initial_register{ r } | 98 | , initial_register{ r } |
| 99 | , transient_context{ transient_context } | ||
| 98 | , vm{ d.controller->get_vm_instance() } | 100 | , vm{ d.controller->get_vm_instance() } |
| 99 | { | 101 | { |
| 100 | current_register = &initial_register; | ||
| 101 | last_successful_cmd = dbg.get_option(last_successful_cmd_option); | 102 | last_successful_cmd = dbg.get_option(last_successful_cmd_option); |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | ~dbg_cmd_cxt_t() | 105 | ~dbg_cmd_cxt_t() |
| 105 | { | 106 | { |
| 106 | dbg.set_option(last_successful_cmd_option, std::move(last_successful_cmd)); | 107 | if (!transient_context) |
| 108 | dbg.set_option(last_successful_cmd_option, std::move(last_successful_cmd)); | ||
| 107 | } | 109 | } |
| 108 | 110 | ||
| 111 | const bool transient_context; | ||
| 109 | bool exit_break; | 112 | bool exit_break; |
| 110 | std::string last_successful_cmd; | 113 | std::string last_successful_cmd; |
| 111 | 114 | ||
| 112 | debugger &dbg; | 115 | debugger &dbg; |
| 113 | const vm_t &vm; | 116 | const vm_t &vm; |
| 114 | const vm_registers_t *current_register; | 117 | const vm_registers_t *current_register; |
| 115 | const vm_registers_t &initial_register; | 118 | vm_registers_t &initial_register; |
| 116 | }; | 119 | }; |
| 117 | 120 | ||
| 118 | std::string dbg_cmd_cxt_t::last_successful_cmd_option = "last_successful_cmd"; | 121 | std::string dbg_cmd_cxt_t::last_successful_cmd_option = "last_successful_cmd"; |
| @@ -168,7 +171,7 @@ namespace · 49 unmodified lines | |||
| 168 | 171 | ||
| 169 | if (!r.module_ref->is_builtin_module()) | 172 | if (!r.module_ref->is_builtin_module()) |
| 170 | { | 173 | { |
| 171 | assert(r.pc < static_cast<word_t>(r.module_ref->code_section.size())); | 174 | assert(static_cast<std::size_t>(r.pc) < r.module_ref->code_section.size()); |
| 172 | const auto &op = r.module_ref->code_section[r.pc].op; | 175 | const auto &op = r.module_ref->code_section[r.pc].op; |
| 173 | register_string | 176 | register_string |
| 174 | << "\n Src: " << op.source | 177 | << "\n Src: " << op.source |
| @@ -332,6 +335,12 @@ namespace · 157 unmodified lines | |||
| 332 | cxt.exit_break = true; | 335 | cxt.exit_break = true; |
| 333 | } | 336 | } |
| 334 | 337 | ||
| 338 | void cmd_step(const std::vector<std::string> &, dbg_cmd_cxt_t &cxt) | ||
| 339 | { | ||
| 340 | cxt.dbg.controller->set_thread_trap_flag(*cxt.current_register, vm_trap_flags_t::instruction); | ||
| 341 | cxt.exit_break = true; | ||
| 342 | } | ||
| 343 | |||
| 335 | void cmd_term(const std::vector<std::string> &, dbg_cmd_cxt_t &) | 344 | void cmd_term(const std::vector<std::string> &, dbg_cmd_cxt_t &) |
| 336 | { | 345 | { |
| 337 | throw vm_term_request{}; | 346 | throw vm_term_request{}; |
| @@ -347,7 +356,7 @@ namespace · 9 unmodified lines | |||
| 347 | { | 356 | { |
| 348 | auto msg = std::stringstream{}; | 357 | auto msg = std::stringstream{}; |
| 349 | for (auto t : cxt.vm.get_scheduler_control().get_all_threads()) | 358 | for (auto t : cxt.vm.get_scheduler_control().get_all_threads()) |
| 350 | msg << " " << std::setw(5) << t->get_thread_id() << " - " << t->get_state() << "\n"; | 359 | msg << " " << std::setw(5) << t->get_thread_id() << " - " << t->get_registers().current_thread_state << "\n"; |
| 351 | 360 | ||
| 352 | debug_print_info(msg.str()); | 361 | debug_print_info(msg.str()); |
| 353 | } | 362 | } |
| @@ -843,9 +852,10 @@ namespace · 489 unmodified lines | |||
| 843 | << console_modifiers::reset_all; | 852 | << console_modifiers::reset_all; |
| 844 | } | 853 | } |
| 845 | 854 | ||
| 846 | std::unordered_set<std::string> dbg_options = | 855 | std::set<std::string> dbg_options = |
| 847 | { | 856 | { |
| 848 | { "bp-cmd" } | 857 | { "bp-cmd" }, |
| 858 | { "step-cmd" } | ||
| 849 | }; | 859 | }; |
| 850 | 860 | ||
| 851 | void set_value_cmd(const std::vector<std::string> &args, dbg_cmd_cxt_t &cxt) | 861 | void set_value_cmd(const std::vector<std::string> &args, dbg_cmd_cxt_t &cxt) |
| @@ -889,6 +899,7 @@ namespace · 37 unmodified lines | |||
| 889 | const dbg_cmd_t cmds[] = | 899 | const dbg_cmd_t cmds[] = |
| 890 | { | 900 | { |
| 891 | { "c", "Continue", nullptr, nullptr, cmd_continue }, | 901 | { "c", "Continue", nullptr, nullptr, cmd_continue }, |
| 902 | { "s", "Step over", nullptr, nullptr, cmd_step }, | ||
| 892 | { "term", "Terminate the VM instance", nullptr, nullptr, cmd_term }, | 903 | { "term", "Terminate the VM instance", nullptr, nullptr, cmd_term }, |
| 893 | 904 | ||
| 894 | { "r", "Print registers", nullptr, nullptr, cmd_print_registers }, | 905 | { "r", "Print registers", nullptr, nullptr, cmd_print_registers }, |
| @@ -969,15 +980,19 @@ namespace · 74 unmodified lines | |||
| 969 | } | 980 | } |
| 970 | } | 981 | } |
| 971 | 982 | ||
| 972 | void prompt(debugger &debugger, const vm_registers_t &r) | 983 | void prompt(debugger &debugger, vm_registers_t &r) |
| 973 | { | 984 | { |
| 974 | debugger.controller->suspend_all_threads(); | 985 | debugger.controller->suspend_all_threads(); |
| 975 | 986 | ||
| 976 | std::cout | 987 | if (debugger.first_break) |
| 977 | << console_modifiers::green_font | 988 | { |
| 978 | << console_modifiers::bold | 989 | debugger.first_break = false; |
| 979 | << "'?' for help\n" | 990 | std::cout |
| 980 | << console_modifiers::reset_all; | 991 | << console_modifiers::green_font |
| 992 | << console_modifiers::bold | ||
| 993 | << "'?' for help\n" | ||
| 994 | << console_modifiers::reset_all; | ||
| 995 | } | ||
| 981 | 996 | ||
| 982 | std::string cmd; | 997 | std::string cmd; |
| 983 | 998 | ||
| @@ -1018,6 +1033,7 @@ debugger::debugger(const debugger_options opt) · 34 unmodified lines | |||
| 1018 | : _options{ opt } | 1033 | : _options{ opt } |
| 1019 | , _tool_id{ 0 } | 1034 | , _tool_id{ 0 } |
| 1020 | , controller{ nullptr } | 1035 | , controller{ nullptr } |
| 1036 | , first_break{ true } | ||
| 1021 | { } | 1037 | { } |
| 1022 | 1038 | ||
| 1023 | std::vector<std::string> debugger::resolve_to_function_source_line( | 1039 | std::vector<std::string> debugger::resolve_to_function_source_line( |
| @@ -1203,11 +1219,23 @@ void debugger::on_load(vm_tool_controller_t &controller_, std::size_t tool_id) · 179 unmodified lines | |||
| 1203 | 1219 | ||
| 1204 | debug_print_info(ss.str()); | 1220 | debug_print_info(ss.str()); |
| 1205 | 1221 | ||
| 1206 | auto bp_cmd = get_option({ "bp-cmd" }); | 1222 | auto cmd = get_option({ "bp-cmd" }); |
| 1207 | if (!bp_cmd.empty()) | 1223 | if (!cmd.empty()) |
| 1224 | { | ||
| 1225 | dbg_cmd_cxt_t dbg_cxt{ *this, *cxt.value1.registers, true }; | ||
| 1226 | execute_single_command(dbg_cxt, std::move(cmd)); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | prompt(*this, *cxt.value1.registers); | ||
| 1230 | })); | ||
| 1231 | |||
| 1232 | _event_cookies.emplace(controller->subscribe_event(vm_event_t::trap, [&](vm_event_t, vm_event_context_t &cxt) | ||
| 1233 | { | ||
| 1234 | auto cmd = get_option({ "step-cmd" }); | ||
| 1235 | if (!cmd.empty()) | ||
| 1208 | { | 1236 | { |
| 1209 | dbg_cmd_cxt_t dbg_cxt{ *this, *cxt.value1.registers }; | 1237 | dbg_cmd_cxt_t dbg_cxt{ *this, *cxt.value1.registers, true }; |
| 1210 | execute_single_command(dbg_cxt, std::move(bp_cmd)); | 1238 | execute_single_command(dbg_cxt, std::move(cmd)); |
| 1211 | } | 1239 | } |
| 1212 | 1240 | ||
| 1213 | prompt(*this, *cxt.value1.registers); | 1241 | prompt(*this, *cxt.value1.registers); |