History

Update debugger to use exceptions for internal command processing.

arr committed 10 years ago

Commit 8549d341 parent 682a72b1 file · +47 −71Browse files

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

Unified · Split

src/exec/debugger.cpp+47−71
@@ -51,7 +51,14 @@ namespace · 50 unmodified lines
51#undef CSI51#undef CSI
52 }52 }
53 53
54 void debug_print_error(const std::string &str)54 struct debug_cmd_error_t : std::runtime_error
55 {
56 debug_cmd_error_t(const char *message)
57 : std::runtime_error{ message }
58 { }
59 };
60
61 void debug_print_error(const char *str)
55 {62 {
56 std::cout63 std::cout
57 << console_modifiers::red_font64 << console_modifiers::red_font
@@ -62,6 +69,11 @@ namespace · 4 unmodified lines
62 << "\n";69 << "\n";
63 }70 }
64 71
72 void debug_print_error(const std::string &str)
73 {
74 debug_print_error(str.c_str());
75 }
76
65 void debug_print_info(const std::string &str)77 void debug_print_info(const std::string &str)
66 {78 {
67 std::cout79 std::cout
@@ -290,7 +302,7 @@ namespace · 222 unmodified lines
290 cxt.exit_break = true;302 cxt.exit_break = true;
291 }303 }
292 304
293 void cmd_term(const std::vector<std::string> &, dbg_cmd_cxt_t &cxt)305 void cmd_term(const std::vector<std::string> &, dbg_cmd_cxt_t &)
294 {306 {
295 throw vm_user_exception{ "Debugger signaled VM termination" };307 throw vm_user_exception{ "Debugger signaled VM termination" };
296 }308 }
@@ -332,10 +344,7 @@ namespace · 35 unmodified lines
332 void cmd_breakpoint_set(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)344 void cmd_breakpoint_set(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)
333 {345 {
334 if (a.size() < 3)346 if (a.size() < 3)
335 {347 throw debug_cmd_error_t{ "Must supply an IP and module ID" };
336 debug_print_error("Must supply an IP and module ID");
337 return;
338 }
339 348
340 vm_pc_t pc;349 vm_pc_t pc;
341 try350 try
@@ -344,8 +353,7 @@ namespace · 2 unmodified lines
344 }353 }
345 catch (...)354 catch (...)
346 {355 {
347 debug_print_error("Invalid IP format");356 throw debug_cmd_error_t{ "Invalid IP format" };
348 return;
349 }357 }
350 358
351 uint32_t module_id;359 uint32_t module_id;
@@ -355,8 +363,7 @@ namespace · 3 unmodified lines
355 }363 }
356 catch (...)364 catch (...)
357 {365 {
358 debug_print_error("Invalid module ID format");366 throw debug_cmd_error_t{ "Invalid module ID format" };
359 return;
360 }367 }
361 368
362 auto module = std::shared_ptr<vm_module_t>{};369 auto module = std::shared_ptr<vm_module_t>{};
@@ -372,20 +379,15 @@ namespace · 9 unmodified lines
372 379
373 if (module == nullptr)380 if (module == nullptr)
374 {381 {
375 debug_print_error("Invalid module ID");382 throw debug_cmd_error_t{ "Invalid module ID" };
376 return;
377 }383 }
378 else if (util::has_flag(module->header.runtime_flag, runtime_flags_t::builtin))384 else if (util::has_flag(module->header.runtime_flag, runtime_flags_t::builtin))
379 {385 {
380 debug_print_error("Unable to set breakpoint in built-in module");386 throw debug_cmd_error_t{ "Unable to set breakpoint in built-in module" };
381 return;
382 }387 }
383 388
384 if (pc < 0 || module->code_section.size() <= static_cast<std::size_t>(pc))389 if (pc < 0 || module->code_section.size() <= static_cast<std::size_t>(pc))
385 {390 throw debug_cmd_error_t{ "Invalid IP for module" };
386 debug_print_error("Invalid IP for module");
387 return;
388 }
389 391
390 cxt.dbg.breakpoint_cookies.push_back(cxt.dbg.controller->set_breakpoint(module, pc));392 cxt.dbg.breakpoint_cookies.push_back(cxt.dbg.controller->set_breakpoint(module, pc));
391 }393 }
@@ -393,10 +395,7 @@ namespace · 1 unmodified line
393 void cmd_breakpoint_clear(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)395 void cmd_breakpoint_clear(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)
394 {396 {
395 if (a.size() == 1)397 if (a.size() == 1)
396 {398 throw debug_cmd_error_t{ "Must supply a breakpoint ID or wildcard" };
397 debug_print_error("Must supply a breakpoint ID or wildcard");
398 return;
399 }
400 399
401 auto controller = cxt.dbg.controller;400 auto controller = cxt.dbg.controller;
402 if (a[1].compare("*") == 0)401 if (a[1].compare("*") == 0)
@@ -417,8 +416,7 @@ namespace · 14 unmodified lines
417 }416 }
418 catch (...)417 catch (...)
419 {418 {
420 debug_print_error("Invalid breakpoint ID format");419 throw debug_cmd_error_t{ "Invalid breakpoint ID format" };
421 return;
422 }420 }
423 421
424 auto cookie_iter = std::find_if(422 auto cookie_iter = std::find_if(
@@ -426,10 +424,7 @@ namespace · 1 unmodified line
426 std::end(cxt.dbg.breakpoint_cookies),424 std::end(cxt.dbg.breakpoint_cookies),
427 [breakpoint_cookie] (const cookie_t c) { return c == breakpoint_cookie; });425 [breakpoint_cookie] (const cookie_t c) { return c == breakpoint_cookie; });
428 if (cookie_iter == cxt.dbg.breakpoint_cookies.end())426 if (cookie_iter == cxt.dbg.breakpoint_cookies.end())
429 {427 throw debug_cmd_error_t{ "Unknown breakpoint ID" };
430 debug_print_error("Unknown breakpoint ID");
431 return;
432 }
433 428
434 // Clear the breakpoint429 // Clear the breakpoint
435 controller->clear_breakpoint(breakpoint_cookie);430 controller->clear_breakpoint(breakpoint_cookie);
@@ -446,7 +441,7 @@ namespace · 10 unmodified lines
446 const auto details = cxt.dbg.controller->get_breakpoint_details(cookie);441 const auto details = cxt.dbg.controller->get_breakpoint_details(cookie);
447 msg << std::setw(3) << cookie << ": "442 msg << std::setw(3) << cookie << ": "
448 << std::setw(16) << details.module->module_name->str()443 << std::setw(16) << details.module->module_name->str()
449 << std::setw(0) << " @ " << details.pc << "\n";444 << std::setw(0) << "@" << details.pc << "\n";
450 }445 }
451 446
452 debug_print_info(msg.str());447 debug_print_info(msg.str());
@@ -474,8 +469,7 @@ namespace · 21 unmodified lines
474 }469 }
475 catch (...)470 catch (...)
476 {471 {
477 debug_print_error("Invalid thread ID format");472 throw debug_cmd_error_t{ "Invalid thread ID format" };
478 return;
479 }473 }
480 }474 }
481 475
@@ -496,10 +490,7 @@ namespace · 14 unmodified lines
496 }490 }
497 491
498 if (thread_registers.empty())492 if (thread_registers.empty())
499 {493 throw debug_cmd_error_t{ "Unknown thread ID" };
500 debug_print_error("Unknown thread ID");
501 return;
502 }
503 494
504 auto msg = std::stringstream{};495 auto msg = std::stringstream{};
505 for (auto t : thread_registers)496 for (auto t : thread_registers)
@@ -515,10 +506,7 @@ namespace · 9 unmodified lines
515 void cmd_switchthread(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)506 void cmd_switchthread(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)
516 {507 {
517 if (a.size() == 1)508 if (a.size() == 1)
518 {509 throw debug_cmd_error_t{ "Must supply a target thread ID" };
519 debug_print_error("Must supply a target thread ID");
520 return;
521 }
522 510
523 uint32_t thread_id;511 uint32_t thread_id;
524 try512 try
@@ -527,8 +515,7 @@ namespace · 2 unmodified lines
527 }515 }
528 catch (...)516 catch (...)
529 {517 {
530 debug_print_error("Invalid thread ID format");518 throw debug_cmd_error_t{ "Invalid thread ID format" };
531 return;
532 }519 }
533 520
534 auto all_threads = cxt.vm.get_scheduler_control().get_all_threads();521 auto all_threads = cxt.vm.get_scheduler_control().get_all_threads();
@@ -544,7 +531,7 @@ namespace · 9 unmodified lines
544 }531 }
545 }532 }
546 533
547 debug_print_error("Unknown thread ID");534 throw debug_cmd_error_t{ "Unknown thread ID" };
548 }535 }
549 536
550 void cmd_disassemble(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)537 void cmd_disassemble(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)
@@ -558,8 +545,7 @@ namespace · 7 unmodified lines
558 }545 }
559 catch (...)546 catch (...)
560 {547 {
561 debug_print_error("Invalid disassemble count format");548 throw debug_cmd_error_t{ "Invalid disassemble count format" };
562 return;
563 }549 }
564 }550 }
565 551
@@ -589,10 +575,7 @@ namespace · 23 unmodified lines
589 void cmd_examine(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)575 void cmd_examine(const std::vector<std::string> &a, dbg_cmd_cxt_t &cxt)
590 {576 {
591 if (a.size() < 3)577 if (a.size() < 3)
592 {578 throw debug_cmd_error_t{ "Invalid number of arguments" };
593 debug_print_error("Invalid number of arguments");
594 return;
595 }
596 579
597 std::shared_ptr<const type_descriptor_t> base_type;580 std::shared_ptr<const type_descriptor_t> base_type;
598 word_t *base_pointer;581 word_t *base_pointer;
@@ -606,18 +589,14 @@ namespace · 7 unmodified lines
606 {589 {
607 auto frame = cxt.current_register->stack.peek_frame();590 auto frame = cxt.current_register->stack.peek_frame();
608 if (frame == nullptr)591 if (frame == nullptr)
609 {592 throw debug_cmd_error_t{ "Invalid frame pointer " };
610 debug_print_error("Invalid frame pointer ");
611 return;
612 }
613 593
614 base_type = frame->frame_type;594 base_type = frame->frame_type;
615 base_pointer = reinterpret_cast<word_t *>(frame->base());595 base_pointer = reinterpret_cast<word_t *>(frame->base());
616 }596 }
617 else597 else
618 {598 {
619 debug_print_error("Invalid memory base pointer");599 throw debug_cmd_error_t{ "Invalid memory base pointer" };
620 return;
621 }600 }
622 601
623 assert(base_type != nullptr && base_pointer != nullptr);602 assert(base_type != nullptr && base_pointer != nullptr);
@@ -635,15 +614,11 @@ namespace · 11 unmodified lines
635 }614 }
636 catch (...)615 catch (...)
637 {616 {
638 debug_print_error("Invalid memory offset format");617 throw debug_cmd_error_t{ "Invalid memory offset format" };
639 return;
640 }618 }
641 619
642 if (0 > byte_offset1 || byte_offset1 >= base_type->size_in_bytes)620 if (0 > byte_offset1 || byte_offset1 >= base_type->size_in_bytes)
643 {621 throw debug_cmd_error_t{ "First offset out of range" };
644 debug_print_error("First offset out of range");
645 return;
646 }
647 622
648 auto msg = std::stringstream{};623 auto msg = std::stringstream{};
649 if (byte_offset2 != -1)624 if (byte_offset2 != -1)
@@ -661,16 +636,10 @@ namespace · 11 unmodified lines
661 if (byte_offset2 != -1)636 if (byte_offset2 != -1)
662 {637 {
663 if (alloc_to_examine == nullptr)638 if (alloc_to_examine == nullptr)
664 {639 throw debug_cmd_error_t{ "First offset is nil" };
665 debug_print_error("First offset is nil");
666 return;
667 }
668 640
669 if (0 > byte_offset2 || byte_offset2 >= alloc_to_examine->alloc_type->size_in_bytes)641 if (0 > byte_offset2 || byte_offset2 >= alloc_to_examine->alloc_type->size_in_bytes)
670 {642 throw debug_cmd_error_t{ "Second offset out of range" };
671 debug_print_error("Second offset out of range");
672 return;
673 }
674 643
675 // Update data pointer for 2nd indirection644 // Update data pointer for 2nd indirection
676 base_pointer = reinterpret_cast<word_t *>(alloc_to_examine->get_allocation());645 base_pointer = reinterpret_cast<word_t *>(alloc_to_examine->get_allocation());
@@ -862,9 +831,16 @@ namespace · 185 unmodified lines
862 continue;831 continue;
863 }832 }
864 833
865 cmd_exec(cmd_tokens, cxt);834 try
866 if (cxt.exit_break)835 {
867 break;836 cmd_exec(cmd_tokens, cxt);
837 if (cxt.exit_break)
838 break;
839 }
840 catch (const debug_cmd_error_t &e)
841 {
842 debug_print_error(e.what());
843 }
868 }844 }
869 }845 }
870}846}