Showing the changes to src/exec/debugger.cpp (1 of 1 file). Show all
Unified · Split
| @@ -89,6 +89,8 @@ namespace · 88 unmodified lines | |||
| 89 | // Debug command context | 89 | // Debug command context |
| 90 | struct dbg_cmd_cxt_t | 90 | struct dbg_cmd_cxt_t |
| 91 | { | 91 | { |
| 92 | static std::string last_successful_cmd_option; | ||
| 93 | |||
| 92 | dbg_cmd_cxt_t(debugger &d, const vm_registers_t &r) | 94 | dbg_cmd_cxt_t(debugger &d, const vm_registers_t &r) |
| 93 | : dbg{ d } | 95 | : dbg{ d } |
| 94 | , exit_break{ false } | 96 | , exit_break{ false } |
| @@ -96,9 +98,16 @@ namespace · 1 unmodified line | |||
| 96 | , vm{ d.controller->get_vm_instance() } | 98 | , vm{ d.controller->get_vm_instance() } |
| 97 | { | 99 | { |
| 98 | current_register = &initial_register; | 100 | current_register = &initial_register; |
| 101 | last_successful_cmd = dbg.get_option(last_successful_cmd_option); | ||
| 102 | } | ||
| 103 | |||
| 104 | ~dbg_cmd_cxt_t() | ||
| 105 | { | ||
| 106 | dbg.set_option(last_successful_cmd_option, std::move(last_successful_cmd)); | ||
| 99 | } | 107 | } |
| 100 | 108 | ||
| 101 | bool exit_break; | 109 | bool exit_break; |
| 110 | std::string last_successful_cmd; | ||
| 102 | 111 | ||
| 103 | debugger &dbg; | 112 | debugger &dbg; |
| 104 | const vm_t &vm; | 113 | const vm_t &vm; |
| @@ -106,6 +115,8 @@ namespace · 1 unmodified line | |||
| 106 | const vm_registers_t &initial_register; | 115 | const vm_registers_t &initial_register; |
| 107 | }; | 116 | }; |
| 108 | 117 | ||
| 118 | std::string dbg_cmd_cxt_t::last_successful_cmd_option = "last_successful_cmd"; | ||
| 119 | |||
| 109 | // Debug command exec operation | 120 | // Debug command exec operation |
| 110 | using dbg_cmd_exec_t = void(*)(const std::vector<std::string> &, dbg_cmd_cxt_t &cxt); | 121 | using dbg_cmd_exec_t = void(*)(const std::vector<std::string> &, dbg_cmd_cxt_t &cxt); |
| 111 | 122 | ||
| @@ -379,7 +390,7 @@ namespace · 267 unmodified lines | |||
| 379 | 390 | ||
| 380 | auto msg = std::stringstream{}; | 391 | auto msg = std::stringstream{}; |
| 381 | auto module_funcs = cxt.dbg.get_module_functions(vm_id, name_to_match); | 392 | auto module_funcs = cxt.dbg.get_module_functions(vm_id, name_to_match); |
| 382 | msg << "[PC range] Function"; | 393 | msg << " [PC range] Function"; |
| 383 | for (auto &f : module_funcs) | 394 | for (auto &f : module_funcs) |
| 384 | msg << "\n " << f; | 395 | msg << "\n " << f; |
| 385 | 396 | ||
| @@ -650,7 +661,7 @@ namespace · 264 unmodified lines | |||
| 650 | { | 661 | { |
| 651 | auto op = code_section[curr_pc].op; | 662 | auto op = code_section[curr_pc].op; |
| 652 | 663 | ||
| 653 | auto op_prefix = " "; | 664 | auto op_prefix = " "; |
| 654 | 665 | ||
| 655 | // If the opcode is a breakpoint then try and replace it with the real opcode | 666 | // If the opcode is a breakpoint then try and replace it with the real opcode |
| 656 | if (op.opcode == opcode_t::brkpt) | 667 | if (op.opcode == opcode_t::brkpt) |
| @@ -662,7 +673,7 @@ namespace · 5 unmodified lines | |||
| 662 | if (details.pc == curr_pc && details.module == r.module_ref->module) | 673 | if (details.pc == curr_pc && details.module == r.module_ref->module) |
| 663 | { | 674 | { |
| 664 | op.opcode = details.original_opcode; | 675 | op.opcode = details.original_opcode; |
| 665 | op_prefix = " b"; | 676 | op_prefix = " b "; |
| 666 | break; | 677 | break; |
| 667 | } | 678 | } |
| 668 | } | 679 | } |
| @@ -929,7 +940,7 @@ namespace · 260 unmodified lines | |||
| 929 | debug_print_info(msg.str()); | 940 | debug_print_info(msg.str()); |
| 930 | } | 941 | } |
| 931 | 942 | ||
| 932 | void execute_single_command(dbg_cmd_cxt_t &cxt, const std::string &cmd) | 943 | void execute_single_command(dbg_cmd_cxt_t &cxt, std::string cmd) |
| 933 | { | 944 | { |
| 934 | const auto cmd_tokens = util::split(cmd); | 945 | const auto cmd_tokens = util::split(cmd); |
| 935 | if (cmd_tokens.empty()) | 946 | if (cmd_tokens.empty()) |
| @@ -939,6 +950,8 @@ namespace · 3 unmodified lines | |||
| 939 | { | 950 | { |
| 940 | auto cmd_exec = find_cmd(cmd_tokens[0]); | 951 | auto cmd_exec = find_cmd(cmd_tokens[0]); |
| 941 | cmd_exec(cmd_tokens, cxt); | 952 | cmd_exec(cmd_tokens, cxt); |
| 953 | |||
| 954 | cxt.last_successful_cmd = std::move(cmd); | ||
| 942 | } | 955 | } |
| 943 | catch (const debug_cmd_error_t &e) | 956 | catch (const debug_cmd_error_t &e) |
| 944 | { | 957 | { |
| @@ -969,9 +982,11 @@ namespace · 24 unmodified lines | |||
| 969 | << console_modifiers::reset_all; | 982 | << console_modifiers::reset_all; |
| 970 | 983 | ||
| 971 | std::getline(std::cin, cmd); | 984 | std::getline(std::cin, cmd); |
| 985 | if (cmd.empty()) | ||
| 986 | cmd = cxt.last_successful_cmd; | ||
| 972 | 987 | ||
| 973 | assert(!cxt.exit_break && "Precondition on exit_break state before execute failed"); | 988 | assert(!cxt.exit_break && "Precondition on exit_break state before execute failed"); |
| 974 | execute_single_command(cxt, cmd); | 989 | execute_single_command(cxt, std::move(cmd)); |
| 975 | if (cxt.exit_break) | 990 | if (cxt.exit_break) |
| 976 | break; | 991 | break; |
| 977 | } | 992 | } |
| @@ -1178,11 +1193,11 @@ void debugger::on_load(vm_tool_controller_t &controller_, std::size_t tool_id) · 200 unmodified lines | |||
| 1178 | 1193 | ||
| 1179 | debug_print_info(ss.str()); | 1194 | debug_print_info(ss.str()); |
| 1180 | 1195 | ||
| 1181 | const auto bp_cmd = get_option({ "bp-cmd" }); | 1196 | auto bp_cmd = get_option({ "bp-cmd" }); |
| 1182 | if (!bp_cmd.empty()) | 1197 | if (!bp_cmd.empty()) |
| 1183 | { | 1198 | { |
| 1184 | dbg_cmd_cxt_t dbg_cxt{ *this, *cxt.value1.registers }; | 1199 | dbg_cmd_cxt_t dbg_cxt{ *this, *cxt.value1.registers }; |
| 1185 | execute_single_command(dbg_cxt, bp_cmd); | 1200 | execute_single_command(dbg_cxt, std::move(bp_cmd)); |
| 1186 | } | 1201 | } |
| 1187 | 1202 | ||
| 1188 | prompt(*this, *cxt.value1.registers); | 1203 | prompt(*this, *cxt.value1.registers); |