Showing the changes to src/exec/debugger.cpp (1 of 8 files). Show all
Unified · Split
| @@ -11,7 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <string> |
| 12 | 12 | #include <algorithm> |
| 13 | 13 | #include <map> |
| 14 | −#include <unordered_set> | |
| 14 | +#include <set> | |
| 15 | 15 | #include <utils.h> |
| 16 | 16 | #include <vm_memory.h> |
| 17 | 17 | #include <vm_asm.h> |
| @@ -91,28 +91,31 @@ namespace · 73 unmodified lines | ||
| 91 | 91 | { |
| 92 | 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 | 95 | : dbg{ d } |
| 96 | 96 | , exit_break{ false } |
| 97 | + , current_register{ &r } | |
| 97 | 98 | , initial_register{ r } |
| 99 | + , transient_context{ transient_context } | |
| 98 | 100 | , vm{ d.controller->get_vm_instance() } |
| 99 | 101 | { |
| 100 | − current_register = &initial_register; | |
| 101 | 102 | last_successful_cmd = dbg.get_option(last_successful_cmd_option); |
| 102 | 103 | } |
| 103 | 104 | |
| 104 | 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 | 112 | bool exit_break; |
| 110 | 113 | std::string last_successful_cmd; |
| 111 | 114 | |
| 112 | 115 | debugger &dbg; |
| 113 | 116 | const vm_t &vm; |
| 114 | 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 | 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 | 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 | 175 | const auto &op = r.module_ref->code_section[r.pc].op; |
| 173 | 176 | register_string |
| 174 | 177 | << "\n Src: " << op.source |
| @@ -332,6 +335,12 @@ namespace · 157 unmodified lines | ||
| 332 | 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 | 344 | void cmd_term(const std::vector<std::string> &, dbg_cmd_cxt_t &) |
| 336 | 345 | { |
| 337 | 346 | throw vm_term_request{}; |
| @@ -347,7 +356,7 @@ namespace · 9 unmodified lines | ||
| 347 | 356 | { |
| 348 | 357 | auto msg = std::stringstream{}; |
| 349 | 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 | 361 | debug_print_info(msg.str()); |
| 353 | 362 | } |
| @@ -843,9 +852,10 @@ namespace · 489 unmodified lines | ||
| 843 | 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 | 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 | 899 | const dbg_cmd_t cmds[] = |
| 890 | 900 | { |
| 891 | 901 | { "c", "Continue", nullptr, nullptr, cmd_continue }, |
| 902 | + { "s", "Step over", nullptr, nullptr, cmd_step }, | |
| 892 | 903 | { "term", "Terminate the VM instance", nullptr, nullptr, cmd_term }, |
| 893 | 904 | |
| 894 | 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 | 985 | debugger.controller->suspend_all_threads(); |
| 975 | 986 | |
| 976 | − std::cout | |
| 977 | − << console_modifiers::green_font | |
| 978 | − << console_modifiers::bold | |
| 979 | − << "'?' for help\n" | |
| 980 | − << console_modifiers::reset_all; | |
| 987 | + if (debugger.first_break) | |
| 988 | + { | |
| 989 | + debugger.first_break = false; | |
| 990 | + std::cout | |
| 991 | + << console_modifiers::green_font | |
| 992 | + << console_modifiers::bold | |
| 993 | + << "'?' for help\n" | |
| 994 | + << console_modifiers::reset_all; | |
| 995 | + } | |
| 981 | 996 | |
| 982 | 997 | std::string cmd; |
| 983 | 998 | |
| @@ -1018,6 +1033,7 @@ debugger::debugger(const debugger_options opt) · 34 unmodified lines | ||
| 1018 | 1033 | : _options{ opt } |
| 1019 | 1034 | , _tool_id{ 0 } |
| 1020 | 1035 | , controller{ nullptr } |
| 1036 | + , first_break{ true } | |
| 1021 | 1037 | { } |
| 1022 | 1038 | |
| 1023 | 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 | 1220 | debug_print_info(ss.str()); |
| 1205 | 1221 | |
| 1206 | − auto bp_cmd = get_option({ "bp-cmd" }); | |
| 1207 | − if (!bp_cmd.empty()) | |
| 1222 | + auto cmd = get_option({ "bp-cmd" }); | |
| 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 }; | |
| 1210 | − execute_single_command(dbg_cxt, std::move(bp_cmd)); | |
| 1237 | + dbg_cmd_cxt_t dbg_cxt{ *this, *cxt.value1.registers, true }; | |
| 1238 | + execute_single_command(dbg_cxt, std::move(cmd)); | |
| 1211 | 1239 | } |
| 1212 | 1240 | |
| 1213 | 1241 | prompt(*this, *cxt.value1.registers); |