Mercurial > repos > blastem
comparison debug.c @ 830:5a3ac6093ea2
Add support for executing a list of debugger commands when a breakpoint is hit
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 14 Oct 2015 09:12:11 -0700 |
parents | cc05444a4a4e |
children | 079eb395ddd1 |
comparison
equal
deleted
inserted
replaced
829:cc05444a4a4e | 830:5a3ac6093ea2 |
---|---|
523 uint32_t value, after; | 523 uint32_t value, after; |
524 bp_def *new_bp, **this_bp; | 524 bp_def *new_bp, **this_bp; |
525 switch(input_buf[0]) | 525 switch(input_buf[0]) |
526 { | 526 { |
527 case 'c': | 527 case 'c': |
528 printf("%X, %X\n", input_buf[1], input_buf[2]); | 528 if (input_buf[1] == 0 || input_buf[1] == 'o' && input_buf[2] == 'n') |
529 puts("Continuing"); | 529 { |
530 return 0; | 530 printf("%X, %X\n", input_buf[1], input_buf[2]); |
531 puts("Continuing"); | |
532 return 0; | |
533 } else if (input_buf[1] == 'o' && input_buf[2] == 'm') { | |
534 param = find_param(input_buf); | |
535 if (!param) { | |
536 fputs("com command requires a parameter\n", stderr); | |
537 break; | |
538 } | |
539 bp_def **target = find_breakpoint_idx(&breakpoints, atoi(param)); | |
540 if (!target) { | |
541 fprintf(stderr, "Breakpoint %s does not exist!\n", param); | |
542 break; | |
543 } | |
544 printf("Enter commands for breakpoing %d, type end when done\n", atoi(param)); | |
545 char cmd_buf[1024]; | |
546 char *commands = NULL; | |
547 for (;;) | |
548 { | |
549 fputs(">>", stdout); | |
550 fflush(stdout); | |
551 fgets(cmd_buf, sizeof(cmd_buf), stdin); | |
552 if (strcmp(cmd_buf, "end\n")) { | |
553 if (commands) { | |
554 char *tmp = commands; | |
555 commands = alloc_concat(commands, cmd_buf); | |
556 free(tmp); | |
557 } else { | |
558 commands = strdup(cmd_buf); | |
559 } | |
560 } else { | |
561 break; | |
562 } | |
563 } | |
564 (*target)->commands = commands; | |
565 } else { | |
566 } | |
531 case 'b': | 567 case 'b': |
532 if (input_buf[1] == 't') { | 568 if (input_buf[1] == 't') { |
533 uint32_t stack = context->aregs[7]; | 569 uint32_t stack = context->aregs[7]; |
534 if (stack >= 0xE00000) { | 570 if (stack >= 0xE00000) { |
535 stack &= 0xFFFF; | 571 stack &= 0xFFFF; |
610 fprintf(stderr, "Breakpoint %d does not exist\n", value); | 646 fprintf(stderr, "Breakpoint %d does not exist\n", value); |
611 break; | 647 break; |
612 } | 648 } |
613 new_bp = *this_bp; | 649 new_bp = *this_bp; |
614 *this_bp = (*this_bp)->next; | 650 *this_bp = (*this_bp)->next; |
651 if (new_bp->commands) { | |
652 free(new_bp->commands); | |
653 } | |
615 free(new_bp); | 654 free(new_bp); |
616 } | 655 } |
617 break; | 656 break; |
618 case 'p': | 657 case 'p': |
619 format_char = 0; | 658 format_char = 0; |
785 m68k_context * debugger(m68k_context * context, uint32_t address) | 824 m68k_context * debugger(m68k_context * context, uint32_t address) |
786 { | 825 { |
787 static char last_cmd[1024]; | 826 static char last_cmd[1024]; |
788 char input_buf[1024]; | 827 char input_buf[1024]; |
789 m68kinst inst; | 828 m68kinst inst; |
790 | 829 |
791 init_terminal(); | 830 init_terminal(); |
792 | 831 |
793 sync_components(context, 0); | 832 sync_components(context, 0); |
794 //probably not necessary, but let's play it safe | 833 //probably not necessary, but let's play it safe |
795 address &= 0xFFFFFF; | 834 address &= 0xFFFFFF; |
796 if (address == branch_t) { | 835 if (address == branch_t) { |
797 bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f); | 836 bp_def ** f_bp = find_breakpoint(&breakpoints, branch_f); |
804 if (!*t_bp) { | 843 if (!*t_bp) { |
805 remove_breakpoint(context, branch_t); | 844 remove_breakpoint(context, branch_t); |
806 } | 845 } |
807 branch_t = branch_f = 0; | 846 branch_t = branch_f = 0; |
808 } | 847 } |
848 int debugging = 1; | |
809 //Check if this is a user set breakpoint, or just a temporary one | 849 //Check if this is a user set breakpoint, or just a temporary one |
810 bp_def ** this_bp = find_breakpoint(&breakpoints, address); | 850 bp_def ** this_bp = find_breakpoint(&breakpoints, address); |
811 if (*this_bp) { | 851 if (*this_bp) { |
812 printf("68K Breakpoint %d hit\n", (*this_bp)->index); | 852 |
853 if ((*this_bp)->commands) | |
854 { | |
855 char *commands = strdup((*this_bp)->commands); | |
856 char *copy = commands; | |
857 | |
858 while (debugging && *commands) | |
859 { | |
860 char *cmd = commands; | |
861 strip_nl(cmd); | |
862 commands += strlen(cmd) + 1; | |
863 debugging = run_debugger_command(context, cmd); | |
864 } | |
865 free(copy); | |
866 } | |
867 if (debugging) { | |
868 printf("68K Breakpoint %d hit\n", (*this_bp)->index); | |
869 } else { | |
870 return context; | |
871 } | |
813 } else { | 872 } else { |
814 remove_breakpoint(context, address); | 873 remove_breakpoint(context, address); |
815 } | 874 } |
816 for (disp_def * cur = displays; cur; cur = cur->next) { | 875 for (disp_def * cur = displays; cur; cur = cur->next) { |
817 debugger_print(context, cur->format_char, cur->param); | 876 debugger_print(context, cur->format_char, cur->param); |
826 } | 885 } |
827 uint16_t * after_pc = m68k_decode(pc, &inst, address); | 886 uint16_t * after_pc = m68k_decode(pc, &inst, address); |
828 m68k_disasm(&inst, input_buf); | 887 m68k_disasm(&inst, input_buf); |
829 printf("%X: %s\n", address, input_buf); | 888 printf("%X: %s\n", address, input_buf); |
830 uint32_t after = address + (after_pc-pc)*2; | 889 uint32_t after = address + (after_pc-pc)*2; |
831 int debugging = 1; | |
832 #ifdef _WIN32 | 890 #ifdef _WIN32 |
833 #define prompt 1 | 891 #define prompt 1 |
834 #else | 892 #else |
835 int prompt = 1; | 893 int prompt = 1; |
836 fd_set read_fds; | 894 fd_set read_fds; |