History

Update UX for some scenarios. - PCs should be prefixed with an '@' - Function symbol printing in debugger - Disassemble command can now specify absolute PC to disassemble - Exception printing - md5sum program - prints new lines

arr committed 9 years ago

Commit 55b7ecc1 parent b6c3b7d5 files · +69 −56Browse files

Showing the changes to src/exec/debugger.cpp (1 of 5 files). Show all

Unified · Split

src/exec/debugger.cpp+62−51
@@ -128,7 +128,7 @@ namespace · 127 unmodified lines
128128 if (!func_maybe.empty())
129129 {
130130 assert(func_maybe.size() == 1);
131− msg << module_ref.module->module_name->str() << "!" << func_maybe[0];
131+ msg << module_ref.module->module_name->str() << "!" << func_maybe[0] << " ";
132132 }
133133 else
134134 {
@@ -136,10 +136,10 @@ namespace · 1 unmodified line
136136 if (module_ref.module->module_name != nullptr)
137137 module_name = module_ref.module->module_name->str();
138138
139− msg << module_name << "@" << pc;
139+ msg << module_name;
140140 }
141141
142− msg << "\n";
142+ msg << "@" << pc << "\n";
143143 return true;
144144 });
145145
@@ -200,33 +200,28 @@ namespace · 54 unmodified lines
200200 }
201201 }
202202
203− ss << "string\n"
204− << "\tlength: " << s->get_length() << "\n"
205− << "\tvalue: \"" << escaped_string.str() << "\"\n";
203+ ss << escaped_string.str() << " length: " << s->get_length() << " string";
206204
207205 return ss;
208206 }
209207
210208 std::ostream& operator<<(std::ostream &ss, const vm_array_t *a)
211209 {
212− ss << "array\n"
213− << "\tlength: " << a->get_length() << "\n";
210+ ss << "length: " << a->get_length() << " array";
214211
215212 return ss;
216213 }
217214
218215 std::ostream& operator<<(std::ostream &ss, const vm_list_t *l)
219216 {
220− ss << "list\n"
221− << "\tlength: " << l->get_length() << "\n";
217+ ss << "length: " << l->get_length() << " list";
222218
223219 return ss;
224220 }
225221
226222 std::ostream& operator<<(std::ostream &ss, const vm_channel_t *c)
227223 {
228− ss << "channel\n"
229− << "\tbuffer size: " << c->get_buffer_size() << "\n";
224+ ss << "buffer size: " << c->get_buffer_size() << " channel";
230225
231226 return ss;
232227 }
@@ -255,11 +250,11 @@ namespace · 22 unmodified lines
255250 }
256251 else
257252 {
258− ss << "alloc - size: " << alloc->alloc_type->size_in_bytes << "\n";
253+ ss << "size: " << alloc->alloc_type->size_in_bytes << " alloc";
259254
260255 enum_pointer_fields(*alloc->alloc_type, alloc->get_allocation(), [&ss](pointer_t p, std::size_t o)
261256 {
262− ss << " [" << o << "] " << vm_alloc_t::from_allocation(p);
257+ ss << "\n [" << o << "] " << vm_alloc_t::from_allocation(p);
263258 });
264259 }
265260
@@ -384,7 +379,7 @@ namespace · 118 unmodified lines
384379
385380 auto msg = std::stringstream{};
386381 auto module_funcs = cxt.dbg.get_module_functions(vm_id, name_to_match);
387− msg << "Function name [PC range]";
382+ msg << "[PC range] Function";
388383 for (auto &f : module_funcs)
389384 msg << "\n " << f;
390385
@@ -501,14 +496,10 @@ namespace · 110 unmodified lines
501496 if (!func_maybe.empty())
502497 {
503498 assert(func_maybe.size() == 1);
504− msg << "!" << func_maybe[0];
505− }
506− else
507− {
508− msg << "@" << details.pc;
499+ msg << "!" << func_maybe[0] << " ";
509500 }
510501
511− msg << "\n";
502+ msg << "@" << details.pc << "\n";
512503 }
513504
514505 debug_print_info(msg.str());
@@ -603,12 +594,20 @@ namespace · 88 unmodified lines
603594
604595 void cmd_disassemble(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)
605596 {
597+ auto absolute_pc = false;
606598 auto disassemble_length = int{ 4 };
607599 if (a.size() > 1)
608600 {
601+ auto disassemble_length_maybe = a[1];
602+ if (disassemble_length_maybe[0] == '@')
603+ {
604+ absolute_pc = true;
605+ disassemble_length_maybe.erase(0, 1);
606+ }
607+
609608 try
610609 {
611− disassemble_length = std::stoi(a[1]);
610+ disassemble_length = std::stoi(disassemble_length_maybe);
612611 }
613612 catch (...)
614613 {
@@ -620,26 +619,36 @@ namespace · 5 unmodified lines
620619 const auto &r = *cxt.current_register;
621620 const auto &code_section = r.module_ref->code_section;
622621
623− auto begin_pc = static_cast<std::size_t>(r.pc);
624− auto end_pc = static_cast<std::size_t>(r.pc);
625− if (disassemble_length < 0)
622+ // The current PC is actually the next PC to execute.
623+ auto begin_pc = r.pc == 0 ? r.pc : r.pc - 1;
624+ auto end_pc = begin_pc;
625+ if (absolute_pc)
626+ {
627+ begin_pc = disassemble_length;
628+ end_pc = disassemble_length;
629+ disassemble_length = 0;
630+
631+ if (begin_pc < 0 || static_cast<int32_t>(code_section.size()) <= end_pc)
632+ throw debug_cmd_error_t{ "Invalid absolute pc" };
633+ }
634+ else if (disassemble_length < 0)
626635 {
627− const auto begin_maybe = r.pc - (-disassemble_length) + 1;
628− begin_pc = static_cast<std::size_t>(std::max(begin_maybe, 0));
636+ const auto begin_maybe = begin_pc - (-disassemble_length);
637+ begin_pc = std::max(begin_maybe, 0);
629638 }
630639 else
631640 {
632− const auto end_maybe = static_cast<std::size_t>(r.pc + disassemble_length);
633− end_pc = std::min(end_maybe, code_section.size() - 1);
641+ const auto end_maybe = begin_pc + disassemble_length;
642+ end_pc = std::min(end_maybe, static_cast<int32_t>(code_section.size() - 1));
634643 }
635644
636645 auto resolved_pc = dbg.resolve_to_function_source_line(r.module_ref->module->vm_id, begin_pc, end_pc, symbol::function_name_format_t::name);
637646 assert(resolved_pc.empty() || resolved_pc.size() == (end_pc - begin_pc + 1) && "Resolved PCs should have failed or match the PC count");
638647
639648 auto msg = std::stringstream{};
640− for (auto i = begin_pc; i <= end_pc; ++i)
649+ for (auto curr_pc = begin_pc; curr_pc <= end_pc; ++curr_pc)
641650 {
642− auto op = code_section[i].op;
651+ auto op = code_section[curr_pc].op;
643652
644653 auto op_prefix = " ";
645654
@@ -650,7 +659,7 @@ namespace · 4 unmodified lines
650659 for (auto bp_cookie : dbg.breakpoint_cookies)
651660 {
652661 const auto details = dbg.controller->get_breakpoint_details(bp_cookie);
653− if (details.pc == i && details.module == r.module_ref->module)
662+ if (details.pc == curr_pc && details.module == r.module_ref->module)
654663 {
655664 op.opcode = details.original_opcode;
656665 op_prefix = " b";
@@ -662,12 +671,12 @@ namespace · 5 unmodified lines
662671 // Print source location if resolved
663672 if (!resolved_pc.empty())
664673 {
665− const auto &rpc = resolved_pc[i - begin_pc];
674+ const auto &rpc = resolved_pc[curr_pc - begin_pc];
666675 if (!rpc.empty())
667676 msg << rpc << "\n";
668677 }
669678
670− msg << op_prefix << std::setw(5) << i << ": " << op << "\n";
679+ msg << op_prefix << std::setw(5) << curr_pc << ": " << op << "\n";
671680 }
672681
673682 debug_print_info(msg.str());
@@ -723,9 +732,9 @@ namespace · 49 unmodified lines
723732
724733 auto msg = std::stringstream{};
725734 if (byte_offset2 != -1)
726− msg << " " << byte_offset2 << "(" << byte_offset1 << "(" << a[1] << ")):\n";
735+ msg << byte_offset2 << "(" << byte_offset1 << "(" << a[1] << ")):\n";
727736 else
728− msg << " " << byte_offset1 << "(" << a[1] << "):\n";
737+ msg << byte_offset1 << "(" << a[1] << "):\n";
729738
730739 auto value_is_pointer = bool{ false };
731740 const auto pointer_offset1 = byte_offset1 / pointer_size;
@@ -872,7 +881,7 @@ namespace · 140 unmodified lines
872881
873882 { "sw", "Stack walk for the current or supplied thread", "sw ([0-9]+|\\*)?", "sw, sw 34, sw *", cmd_stackwalk },
874883 { "~", "Switch to thread", "~ [0-9]+", "~ 42", cmd_switchthread },
875− { "d", "Disassemble the next/previous N instructions (default N = 4)", "d (-?[0-9]+)?", "d, d -4, d 5", cmd_disassemble },
884+ { "d", "Disassemble the next/previous N instructions (default N = 4)", "d (@?-?[0-9]+)?", "d, d -4, d 5, d @36", cmd_disassemble },
876885 { "x", "Examine memory", "x [mp|fp] [0-9]+ ([0-9]+)?", "x mp 3, x fp 20 6", cmd_examine },
877886
878887 { "set" , "Set a debug option", "set [ _a-zA-Z0-9]*", "'set' for available options", set_value_cmd },
@@ -882,9 +891,11 @@ namespace · 3 unmodified lines
882891 { "tlk~*", nullptr, nullptr, nullptr, cmd_tlk_tilde_star }
883892 };
884893
894+ const auto cmds_length = sizeof(cmds) / sizeof(cmds[0]);
895+
885896 dbg_cmd_exec_t find_cmd(const std::string &cmd_maybe)
886897 {
887− for (auto i = std::size_t{}; i < sizeof(cmds) / sizeof(cmds[0]); ++i)
898+ for (auto i = std::size_t{}; i < cmds_length; ++i)
888899 {
889900 if (cmd_maybe.compare(cmds[i].cmd) == 0)
890901 return cmds[i].exec;
@@ -898,7 +909,7 @@ namespace · 7 unmodified lines
898909 {
899910 auto msg = std::stringstream{};
900911 msg << "Commands:\n";
901− for (auto i = std::size_t{}; i < sizeof(cmds) / sizeof(cmds[0]); ++i)
912+ for (auto i = std::size_t{}; i < cmds_length; ++i)
902913 {
903914 auto &c = cmds[i];
904915
@@ -906,13 +917,13 @@ namespace · 1 unmodified line
906917 if (c.description == nullptr)
907918 continue;
908919
909− msg << " " << c.cmd << "\t" << c.description << "\n";
920+ msg << " " << c.cmd << " " << c.description << "\n";
910921
911922 if (c.syntax != nullptr)
912− msg << "\t Syntax: " << c.syntax << "\n";
923+ msg << " Syntax: " << c.syntax << "\n";
913924
914925 if (c.example != nullptr)
915− msg << "\t Example(s): " << c.example << "\n";
926+ msg << " Example(s): " << c.example << "\n";
916927 }
917928
918929 debug_print_info(msg.str());
@@ -959,7 +970,7 @@ namespace · 40 unmodified lines
959970
960971 std::getline(std::cin, cmd);
961972
962− assert(!cxt.exit_break && "Pre-condition on exit_break state before execute failed");
973+ assert(!cxt.exit_break && "Precondition on exit_break state before execute failed");
963974 execute_single_command(cxt, cmd);
964975 if (cxt.exit_break)
965976 break;
@@ -1038,12 +1049,12 @@ std::vector<std::string> debugger::get_module_functions(disvm::runtime::module_i · 72 unmodified lines
10381049 continue;
10391050
10401051 std::stringstream ss;
1041− ss << fi.name
1042− << " ["
1043− << fi.entry_pc
1044− << ", "
1045− << fi.limit_pc
1046− << "]";
1052+ ss << "["
1053+ << std::setw(5) << fi.entry_pc
1054+ << ","
1055+ << std::setw(5) << fi.limit_pc
1056+ << "] "
1057+ << fi.name;
10471058
10481059 funcs.push_back(ss.str());
10491060 }
@@ -1084,7 +1095,7 @@ void debugger::on_load(vm_tool_controller_t &controller_, std::size_t tool_id) · 34 unmodified lines
10841095 << t->get_thread_id()
10851096 << " started in "
10861097 << t->get_registers().module_ref->module->module_name->str()
1087− << " @ "
1098+ << " @"
10881099 << t->get_registers().pc;
10891100
10901101 debug_print_info(ss.str());
@@ -1151,7 +1162,7 @@ void debugger::on_load(vm_tool_controller_t &controller_, std::size_t tool_id) · 60 unmodified lines
11511162 // Reset the break on enter flag and set a breakpoint
11521163 // on the entry PC for the module - 'break on enter'
11531164 _options ^= debugger_options::break_on_enter;
1154− controller->set_breakpoint(m, m->header.entry_pc);
1165+ breakpoint_cookies.emplace(controller->set_breakpoint(m, m->header.entry_pc));
11551166 }
11561167
11571168 if (util::has_flag(_options, debugger_options::break_on_module_load))