History

Add support to debugger to have the last successful command be the default command.

arr committed 9 years ago

Commit ad4a6c31 parent 232a6591 file · +22 −7Browse files

Unified · Split

src/exec/debugger.cpp+22−7
@@ -89,6 +89,8 @@ namespace · 88 unmodified lines
89 // Debug command context89 // Debug command context
90 struct dbg_cmd_cxt_t90 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 operation120 // 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 opcode666 // 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);