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