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
128 if (!func_maybe.empty())128 if (!func_maybe.empty())
129 {129 {
130 assert(func_maybe.size() == 1);130 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] << " ";
132 }132 }
133 else133 else
134 {134 {
@@ -136,10 +136,10 @@ namespace · 1 unmodified line
136 if (module_ref.module->module_name != nullptr)136 if (module_ref.module->module_name != nullptr)
137 module_name = module_ref.module->module_name->str();137 module_name = module_ref.module->module_name->str();
138 138
139 msg << module_name << "@" << pc;139 msg << module_name;
140 }140 }
141 141
142 msg << "\n";142 msg << "@" << pc << "\n";
143 return true;143 return true;
144 });144 });
145 145
@@ -200,33 +200,28 @@ namespace · 54 unmodified lines
200 }200 }
201 }201 }
202 202
203 ss << "string\n"203 ss << escaped_string.str() << " length: " << s->get_length() << " string";
204 << "\tlength: " << s->get_length() << "\n"
205 << "\tvalue: \"" << escaped_string.str() << "\"\n";
206 204
207 return ss;205 return ss;
208 }206 }
209 207
210 std::ostream& operator<<(std::ostream &ss, const vm_array_t *a)208 std::ostream& operator<<(std::ostream &ss, const vm_array_t *a)
211 {209 {
212 ss << "array\n"210 ss << "length: " << a->get_length() << " array";
213 << "\tlength: " << a->get_length() << "\n";
214 211
215 return ss;212 return ss;
216 }213 }
217 214
218 std::ostream& operator<<(std::ostream &ss, const vm_list_t *l)215 std::ostream& operator<<(std::ostream &ss, const vm_list_t *l)
219 {216 {
220 ss << "list\n"217 ss << "length: " << l->get_length() << " list";
221 << "\tlength: " << l->get_length() << "\n";
222 218
223 return ss;219 return ss;
224 }220 }
225 221
226 std::ostream& operator<<(std::ostream &ss, const vm_channel_t *c)222 std::ostream& operator<<(std::ostream &ss, const vm_channel_t *c)
227 {223 {
228 ss << "channel\n"224 ss << "buffer size: " << c->get_buffer_size() << " channel";
229 << "\tbuffer size: " << c->get_buffer_size() << "\n";
230 225
231 return ss;226 return ss;
232 }227 }
@@ -255,11 +250,11 @@ namespace · 22 unmodified lines
255 }250 }
256 else251 else
257 {252 {
258 ss << "alloc - size: " << alloc->alloc_type->size_in_bytes << "\n";253 ss << "size: " << alloc->alloc_type->size_in_bytes << " alloc";
259 254
260 enum_pointer_fields(*alloc->alloc_type, alloc->get_allocation(), [&ss](pointer_t p, std::size_t o)255 enum_pointer_fields(*alloc->alloc_type, alloc->get_allocation(), [&ss](pointer_t p, std::size_t o)
261 {256 {
262 ss << " [" << o << "] " << vm_alloc_t::from_allocation(p);257 ss << "\n [" << o << "] " << vm_alloc_t::from_allocation(p);
263 });258 });
264 }259 }
265 260
@@ -384,7 +379,7 @@ namespace · 118 unmodified lines
384 379
385 auto msg = std::stringstream{};380 auto msg = std::stringstream{};
386 auto module_funcs = cxt.dbg.get_module_functions(vm_id, name_to_match);381 auto module_funcs = cxt.dbg.get_module_functions(vm_id, name_to_match);
387 msg << "Function name [PC range]";382 msg << "[PC range] Function";
388 for (auto &f : module_funcs)383 for (auto &f : module_funcs)
389 msg << "\n " << f;384 msg << "\n " << f;
390 385
@@ -501,14 +496,10 @@ namespace · 110 unmodified lines
501 if (!func_maybe.empty())496 if (!func_maybe.empty())
502 {497 {
503 assert(func_maybe.size() == 1);498 assert(func_maybe.size() == 1);
504 msg << "!" << func_maybe[0];499 msg << "!" << func_maybe[0] << " ";
505 }
506 else
507 {
508 msg << "@" << details.pc;
509 }500 }
510 501
511 msg << "\n";502 msg << "@" << details.pc << "\n";
512 }503 }
513 504
514 debug_print_info(msg.str());505 debug_print_info(msg.str());
@@ -603,12 +594,20 @@ namespace · 88 unmodified lines
603 594
604 void cmd_disassemble(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)595 void cmd_disassemble(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)
605 {596 {
597 auto absolute_pc = false;
606 auto disassemble_length = int{ 4 };598 auto disassemble_length = int{ 4 };
607 if (a.size() > 1)599 if (a.size() > 1)
608 {600 {
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
609 try608 try
610 {609 {
611 disassemble_length = std::stoi(a[1]);610 disassemble_length = std::stoi(disassemble_length_maybe);
612 }611 }
613 catch (...)612 catch (...)
614 {613 {
@@ -620,26 +619,36 @@ namespace · 5 unmodified lines
620 const auto &r = *cxt.current_register;619 const auto &r = *cxt.current_register;
621 const auto &code_section = r.module_ref->code_section;620 const auto &code_section = r.module_ref->code_section;
622 621
623 auto begin_pc = static_cast<std::size_t>(r.pc);622 // The current PC is actually the next PC to execute.
624 auto end_pc = static_cast<std::size_t>(r.pc);623 auto begin_pc = r.pc == 0 ? r.pc : r.pc - 1;
625 if (disassemble_length < 0)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)
626 {635 {
627 const auto begin_maybe = r.pc - (-disassemble_length) + 1;636 const auto begin_maybe = begin_pc - (-disassemble_length);
628 begin_pc = static_cast<std::size_t>(std::max(begin_maybe, 0));637 begin_pc = std::max(begin_maybe, 0);
629 }638 }
630 else639 else
631 {640 {
632 const auto end_maybe = static_cast<std::size_t>(r.pc + disassemble_length);641 const auto end_maybe = begin_pc + disassemble_length;
633 end_pc = std::min(end_maybe, code_section.size() - 1);642 end_pc = std::min(end_maybe, static_cast<int32_t>(code_section.size() - 1));
634 }643 }
635 644
636 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);645 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);
637 assert(resolved_pc.empty() || resolved_pc.size() == (end_pc - begin_pc + 1) && "Resolved PCs should have failed or match the PC count");646 assert(resolved_pc.empty() || resolved_pc.size() == (end_pc - begin_pc + 1) && "Resolved PCs should have failed or match the PC count");
638 647
639 auto msg = std::stringstream{};648 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)
641 {650 {
642 auto op = code_section[i].op;651 auto op = code_section[curr_pc].op;
643 652
644 auto op_prefix = " ";653 auto op_prefix = " ";
645 654
@@ -650,7 +659,7 @@ namespace · 4 unmodified lines
650 for (auto bp_cookie : dbg.breakpoint_cookies)659 for (auto bp_cookie : dbg.breakpoint_cookies)
651 {660 {
652 const auto details = dbg.controller->get_breakpoint_details(bp_cookie);661 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)
654 {663 {
655 op.opcode = details.original_opcode;664 op.opcode = details.original_opcode;
656 op_prefix = " b";665 op_prefix = " b";
@@ -662,12 +671,12 @@ namespace · 5 unmodified lines
662 // Print source location if resolved671 // Print source location if resolved
663 if (!resolved_pc.empty())672 if (!resolved_pc.empty())
664 {673 {
665 const auto &rpc = resolved_pc[i - begin_pc];674 const auto &rpc = resolved_pc[curr_pc - begin_pc];
666 if (!rpc.empty())675 if (!rpc.empty())
667 msg << rpc << "\n";676 msg << rpc << "\n";
668 }677 }
669 678
670 msg << op_prefix << std::setw(5) << i << ": " << op << "\n";679 msg << op_prefix << std::setw(5) << curr_pc << ": " << op << "\n";
671 }680 }
672 681
673 debug_print_info(msg.str());682 debug_print_info(msg.str());
@@ -723,9 +732,9 @@ namespace · 49 unmodified lines
723 732
724 auto msg = std::stringstream{};733 auto msg = std::stringstream{};
725 if (byte_offset2 != -1)734 if (byte_offset2 != -1)
726 msg << " " << byte_offset2 << "(" << byte_offset1 << "(" << a[1] << ")):\n";735 msg << byte_offset2 << "(" << byte_offset1 << "(" << a[1] << ")):\n";
727 else736 else
728 msg << " " << byte_offset1 << "(" << a[1] << "):\n";737 msg << byte_offset1 << "(" << a[1] << "):\n";
729 738
730 auto value_is_pointer = bool{ false };739 auto value_is_pointer = bool{ false };
731 const auto pointer_offset1 = byte_offset1 / pointer_size;740 const auto pointer_offset1 = byte_offset1 / pointer_size;
@@ -872,7 +881,7 @@ namespace · 140 unmodified lines
872 881
873 { "sw", "Stack walk for the current or supplied thread", "sw ([0-9]+|\\*)?", "sw, sw 34, sw *", cmd_stackwalk },882 { "sw", "Stack walk for the current or supplied thread", "sw ([0-9]+|\\*)?", "sw, sw 34, sw *", cmd_stackwalk },
874 { "~", "Switch to thread", "~ [0-9]+", "~ 42", cmd_switchthread },883 { "~", "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 },
876 { "x", "Examine memory", "x [mp|fp] [0-9]+ ([0-9]+)?", "x mp 3, x fp 20 6", cmd_examine },885 { "x", "Examine memory", "x [mp|fp] [0-9]+ ([0-9]+)?", "x mp 3, x fp 20 6", cmd_examine },
877 886
878 { "set" , "Set a debug option", "set [ _a-zA-Z0-9]*", "'set' for available options", set_value_cmd },887 { "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
882 { "tlk~*", nullptr, nullptr, nullptr, cmd_tlk_tilde_star }891 { "tlk~*", nullptr, nullptr, nullptr, cmd_tlk_tilde_star }
883 };892 };
884 893
894 const auto cmds_length = sizeof(cmds) / sizeof(cmds[0]);
895
885 dbg_cmd_exec_t find_cmd(const std::string &cmd_maybe)896 dbg_cmd_exec_t find_cmd(const std::string &cmd_maybe)
886 {897 {
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)
888 {899 {
889 if (cmd_maybe.compare(cmds[i].cmd) == 0)900 if (cmd_maybe.compare(cmds[i].cmd) == 0)
890 return cmds[i].exec;901 return cmds[i].exec;
@@ -898,7 +909,7 @@ namespace · 7 unmodified lines
898 {909 {
899 auto msg = std::stringstream{};910 auto msg = std::stringstream{};
900 msg << "Commands:\n";911 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)
902 {913 {
903 auto &c = cmds[i];914 auto &c = cmds[i];
904 915
@@ -906,13 +917,13 @@ namespace · 1 unmodified line
906 if (c.description == nullptr)917 if (c.description == nullptr)
907 continue;918 continue;
908 919
909 msg << " " << c.cmd << "\t" << c.description << "\n";920 msg << " " << c.cmd << " " << c.description << "\n";
910 921
911 if (c.syntax != nullptr)922 if (c.syntax != nullptr)
912 msg << "\t Syntax: " << c.syntax << "\n";923 msg << " Syntax: " << c.syntax << "\n";
913 924
914 if (c.example != nullptr)925 if (c.example != nullptr)
915 msg << "\t Example(s): " << c.example << "\n";926 msg << " Example(s): " << c.example << "\n";
916 }927 }
917 928
918 debug_print_info(msg.str());929 debug_print_info(msg.str());
@@ -959,7 +970,7 @@ namespace · 40 unmodified lines
959 970
960 std::getline(std::cin, cmd);971 std::getline(std::cin, cmd);
961 972
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");
963 execute_single_command(cxt, cmd);974 execute_single_command(cxt, cmd);
964 if (cxt.exit_break)975 if (cxt.exit_break)
965 break;976 break;
@@ -1038,12 +1049,12 @@ std::vector<std::string> debugger::get_module_functions(disvm::runtime::module_i · 72 unmodified lines
1038 continue;1049 continue;
1039 1050
1040 std::stringstream ss;1051 std::stringstream ss;
1041 ss << fi.name1052 ss << "["
1042 << " ["1053 << std::setw(5) << fi.entry_pc
1043 << fi.entry_pc1054 << ","
1044 << ", "1055 << std::setw(5) << fi.limit_pc
1045 << fi.limit_pc1056 << "] "
1046 << "]";1057 << fi.name;
1047 1058
1048 funcs.push_back(ss.str());1059 funcs.push_back(ss.str());
1049 }1060 }
@@ -1084,7 +1095,7 @@ void debugger::on_load(vm_tool_controller_t &controller_, std::size_t tool_id) · 34 unmodified lines
1084 << t->get_thread_id()1095 << t->get_thread_id()
1085 << " started in "1096 << " started in "
1086 << t->get_registers().module_ref->module->module_name->str()1097 << t->get_registers().module_ref->module->module_name->str()
1087 << " @ "1098 << " @"
1088 << t->get_registers().pc;1099 << t->get_registers().pc;
1089 1100
1090 debug_print_info(ss.str());1101 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
1151 // Reset the break on enter flag and set a breakpoint1162 // Reset the break on enter flag and set a breakpoint
1152 // on the entry PC for the module - 'break on enter'1163 // on the entry PC for the module - 'break on enter'
1153 _options ^= debugger_options::break_on_enter;1164 _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));
1155 }1166 }
1156 1167
1157 if (util::has_flag(_options, debugger_options::break_on_module_load))1168 if (util::has_flag(_options, debugger_options::break_on_module_load))