Annotation of hatari/tests/debugger/test-breakcond.c, revision 1.1.1.5

1.1       root        1: /* 
                      2:  * Code to test Hatari conditional breakpoints in src/debug/breakcond.c
1.1.1.2   root        3:  * (both matching and setting CPU and DSP breakpoints)
1.1       root        4:  */
                      5: #include "main.h"
                      6: #include "dsp.h"
                      7: #include "debugcpu.h"
                      8: #include "breakcond.h"
                      9: #include "stMemory.h"
                     10: #include "newcpu.h"
                     11: 
                     12: #define BITMASK(x)      ((1<<(x))-1)
                     13: 
                     14: /* BreakCond_Command() command strings */
                     15: #define CMD_LIST NULL
                     16: #define CMD_REMOVE_ALL "all"
                     17: 
                     18: 
                     19: static bool SetCpuRegister(const char *regname, Uint32 value)
                     20: {
                     21:        Uint32 *addr;
                     22:        
                     23:        switch (DebugCpu_GetRegisterAddress(regname, &addr)) {
                     24:        case 32:
                     25:                *addr = value;
                     26:                break;
                     27:        case 16:
                     28:                *(Uint16*)addr = value;
                     29:                break;
                     30:        default:
                     31:                fprintf(stderr, "SETUP ERROR: Register '%s' to set (to %x) is unrecognized!\n", regname, value);
                     32:                return false;
                     33:        }
                     34:        return true;
                     35: }
                     36: 
                     37: #if 0
                     38: static bool SetDspRegister(const char *regname, Uint32 value)
                     39: {
                     40:        Uint32 *addr, mask;
                     41: 
                     42:        switch (DSP_GetRegisterAddress(regname, &addr, &mask)) {
                     43:        case 32:
                     44:                *addr = value & mask;
                     45:                break;
                     46:        case 16:
                     47:                *(Uint16*)addr = value & mask;
                     48:                break;
                     49:        default:
                     50:                return false;
                     51:        }
                     52:        return true;
                     53: }
                     54: #endif
                     55: 
                     56: int main(int argc, const char *argv[])
                     57: {
                     58:        const char *parser_fail[] = {
                     59:                /* syntax & register name errors */
                     60:                "",
                     61:                " = ",
                     62:                " a0 d0 ",
                     63:                "gggg=a0",
                     64:                "=a=b=",
                     65:                "a0=d0=20",
                     66:                "a0=d || 0=20",
                     67:                "a0=d & 0=20",
                     68:                ".w&3=2",
                     69:                "d0 = %200",
                     70:                "d0 = \"ICE!BAR",
                     71:                "pc > $200 :foobar",
                     72:                "foo().w=bar()",
                     73:                "(a0.w=d0.l)",
                     74:                "(a0&3)=20",
                     75:                "20 = (a0.w)",
                     76:                "()&=d0",
                     77:                "d0=().w",
1.1.1.3   root       78:                "&& pc = 2",
                     79:                "pc = 2 &&",
1.1       root       80:                "255 & 3 = (d0) & && 2 = 2",
                     81:                /* missing options file */
                     82:                "pc>pc :file no-such-file",             
                     83:                /* size and mask mismatches with numbers */
                     84:                "d0.w = $ffff0",
                     85:                "(a0).b & 3 < 100",
                     86:                NULL
                     87:        };
                     88:        const char *parser_pass[] = {
                     89:                /* comparisons with normal numbers + indrect addressing */
                     90:                " ($200).w > 200 ",
                     91:                " ($200).w < 200 ",
                     92:                " (200).w = $200 ",
                     93:                " (200).w ! $200 ",
                     94:                /* indirect addressing with registers */
                     95:                "(a0)=(d0)",
                     96:                "(d0).w=(a0).b",
                     97:                /* sizes + multiple conditions + spacing */
                     98:                "(a0).w&3=(d0)&&d0=1",
                     99:                " ( a 0 ) . w  &  1 = ( d 0 ) & 1 &&  d 0 = 3 ",
                    100:                "a0=1 && (d0)&2=(a0).w && ($00ff00).w&1=1",
                    101:                " ($ff820a).b = 2",
                    102:                /* variables */
                    103:                "hbl > 0 && vbl < 2000 && linecycles = 508",
                    104:                /* options */
                    105:                "($200).w ! ($200).w :trace",
                    106:                "($200).w > ($200).w :4 :lock",
                    107:                "pc>pc :file data/test.ini :once",
                    108:                NULL
                    109:        };
                    110:        /* address breakpoint + expression evalution with register */
                    111:        char addr_pass[] = "pc + ($200*16/2 & 0xffff)";
                    112: 
1.1.1.5 ! root      113:        const char *nonmatching_tests[] = {
1.1       root      114:                "( $200 ) . b > 200", /* byte access to avoid endianess */
                    115:                "pc < $50000 && pc > $60000",
                    116:                "pc > $50000 && pc < $54000",
1.1.1.5 ! root      117:                "d0 = a0",
        !           118:                "a0 = pc :trace",  /* matches, but :trace should hide that */
        !           119:                "a0 = pc :3",      /* matches, but not yet */
        !           120:                NULL
        !           121:        };
        !           122:        const char *matching_tests[] = {
        !           123:                "a0 = pc",         /* tested with all above */
        !           124:                "( $200 ) . b > ( 200 ) . b :once",
1.1       root      125:                "pc > $50000 && pc < $60000",
1.1.1.5 ! root      126:                "d0 = d1 :once :quiet",
        !           127:                "a0 = pc",         /* tested alone */
1.1       root      128:                NULL
                    129:        };
                    130:        const char *test;
1.1.1.5 ! root      131:        int total_tests = 0, total_errors = 0;
        !           132:        int i, errors;
1.1       root      133:        bool use_dsp;
                    134: 
                    135:        /* first automated tests... */
                    136:        use_dsp = false;
                    137:        fprintf(stderr, "\nShould FAIL for CPU:\n");
                    138:        for (i = 0; (test = parser_fail[i]); i++) {
                    139:                fprintf(stderr, "-----------------\n- parsing '%s'\n", test);
                    140:                if (BreakCond_Command(test, use_dsp)) {
                    141:                        fprintf(stderr, "***ERROR***: should have failed\n");
1.1.1.5 ! root      142:                        total_errors++;
1.1       root      143:                }
                    144:        }
1.1.1.5 ! root      145:        total_tests += i;
1.1       root      146:        fprintf(stderr, "-----------------\n\n");
                    147:        BreakCond_Command(CMD_LIST, use_dsp);
                    148:        
                    149:        fprintf(stderr, "\nShould PASS for CPU:\n");
                    150:        for (i = 0; (test = parser_pass[i]); i++) {
                    151:                fprintf(stderr, "-----------------\n- parsing '%s'\n", test);
                    152:                if (!BreakCond_Command(test, use_dsp)) {
                    153:                        fprintf(stderr, "***ERROR***: should have passed\n");
1.1.1.5 ! root      154:                        total_errors++;
1.1       root      155:                }
                    156:        }
1.1.1.5 ! root      157:        total_tests += i;
1.1       root      158:        fprintf(stderr, "\nAddress PASS test for CPU:\n");
                    159:        if (!BreakAddr_Command(addr_pass, use_dsp)) {
                    160:                fprintf(stderr, "***ERROR***: should have passed\n");
1.1.1.5 ! root      161:                total_errors++;
1.1       root      162:        }
1.1.1.5 ! root      163:        total_tests += 1;
1.1       root      164: 
                    165:        fprintf(stderr, "-----------------\n\n");
                    166:        BreakCond_Command(CMD_LIST, use_dsp);
                    167:        fprintf(stderr, "\n");
                    168:        BreakCond_Command(CMD_REMOVE_ALL, use_dsp);
                    169:        BreakCond_Command(CMD_LIST, use_dsp);
                    170:        fprintf(stderr, "-----------------\n");
                    171:        
                    172:        /* set up registers etc */
                    173: 
1.1.1.5 ! root      174:        /* fail indirect equality checks with zeroed regs */
1.1       root      175:        memset(STRam, 0, sizeof(STRam));
1.1.1.4   root      176:        STMemory_WriteByte(0, 1);
1.1.1.5 ! root      177:        /* !match: "( $200 ) . b > 200"
        !           178:         *  match: "( $200 ) . b > ( 200 ) . b"
1.1       root      179:         */
1.1.1.4   root      180:        STMemory_WriteByte(0x200, 100);
                    181:        STMemory_WriteByte(200, 0x20);
1.1       root      182:        /* !match: "pc < $50000  &&  pc > $60000"
                    183:         * !match: "pc < $50000  &&  pc > $54000"
                    184:         *  match: "pc > $50000  &&  pc < $60000"
                    185:         */
                    186:        regs.pc = 0x58000;
1.1.1.5 ! root      187:        /*  match: "d0 = d1"
        !           188:         */
        !           189:        SetCpuRegister("d0", 4);
        !           190:        SetCpuRegister("d1", 4);
1.1       root      191:        /* !match: "d0 = a0"
                    192:         *  match: "pc = a0"
                    193:         */
                    194:        SetCpuRegister("a0", 0x58000);
1.1.1.5 ! root      195: 
        !           196:        /* add conditions */
        !           197:        fprintf(stderr, "\nBreakpoints that should NOT match:\n");
        !           198:        for (errors = i = 0; (test = nonmatching_tests[i]); i++) {
        !           199:                fprintf(stderr, "-----------------\n- parsing '%s'\n", test);
        !           200:                if (!BreakCond_Command(test, use_dsp)) {
        !           201:                        fprintf(stderr, "***ERROR***: should have passed\n");
        !           202:                        total_errors++;
        !           203:                } else {
        !           204:                        /* does it match? */
        !           205:                        if (BreakCond_MatchCpu()) {
        !           206:                                fprintf(stderr, "***ERROR***: should NOT have matched\n");
        !           207:                                errors++;
        !           208:                                /* remove */
        !           209:                                BreakCond_Command("1", use_dsp);
1.1       root      210:                        }
                    211:                }
1.1.1.5 ! root      212:        }
        !           213:        fprintf(stderr, "-----------------\n\n");
        !           214:        BreakCond_Command(CMD_LIST, use_dsp);
        !           215:        if (errors) {
        !           216:                total_errors += errors;
        !           217:                fprintf(stderr, "\nERROR: %d out of %d breakpoints matched!\n",
        !           218:                        errors, i);
        !           219:        }
        !           220:        total_tests += i;
        !           221: 
        !           222:        /* leave non-matching breakpoints, so that first matching
        !           223:         * breakpoint is at after those, and test rest of matching
        !           224:         * breakpoints as single breakpoints
        !           225:         */
        !           226: 
        !           227:        /* add conditions */
        !           228:        fprintf(stderr, "\nBreakpoints that should match:\n");
        !           229:        for (errors = i = 0; (test = matching_tests[i]); i++) {
        !           230:                fprintf(stderr, "-----------------\n- parsing '%s'\n", test);
        !           231:                if (!BreakCond_Command(test, use_dsp)) {
        !           232:                        fprintf(stderr, "***ERROR***: should have passed\n");
        !           233:                        total_errors++;
        !           234:                } else {
        !           235:                        /* does it match? */
        !           236:                        if (!BreakCond_MatchCpu()) {
        !           237:                                fprintf(stderr, "***ERROR***: should have matched\n");
1.1       root      238:                                errors++;
                    239:                        }
1.1.1.5 ! root      240:                        /* remove all */
        !           241:                        BreakCond_Command(CMD_REMOVE_ALL, use_dsp);
1.1       root      242:                }
                    243:        }
1.1.1.5 ! root      244:        fprintf(stderr, "-----------------\n\n");
        !           245:        if (errors) {
        !           246:                total_errors += errors;
        !           247:                fprintf(stderr, "ERROR: %d out of %d breakpoints didn't match!\n\n",
        !           248:                        errors, i);
1.1       root      249:        }
1.1.1.5 ! root      250:        total_tests += i;
1.1       root      251: 
                    252:        /* ...last parse cmd line args as DSP breakpoints */
                    253:        if (argc > 1) {
                    254:                use_dsp = true;
                    255:                fprintf(stderr, "\nCommand line DSP breakpoints:\n");
                    256:                for (argv++; --argc > 0; argv++) {
                    257:                        fprintf(stderr, "-----------------\n- parsing '%s'\n", *argv);
                    258:                        BreakCond_Command(*argv, use_dsp);
                    259:                }
                    260:                fprintf(stderr, "-----------------\n\n");
                    261:                BreakCond_Command("", use_dsp); /* list */
                    262: 
1.1.1.5 ! root      263:                if (BreakCond_MatchDsp()) {
        !           264:                        fprintf(stderr, "There were matching DSP breakpoint(s).\n");
1.1       root      265:                }
                    266: 
                    267:                BreakCond_Command(CMD_REMOVE_ALL, use_dsp);
                    268:                BreakCond_Command(CMD_LIST, use_dsp);
                    269:                fprintf(stderr, "-----------------\n");
                    270:        }
1.1.1.5 ! root      271:        if (total_errors) {
1.1       root      272:                fprintf(stderr, "\n***Detected %d ERRORs in %d automated tests!***\n\n",
1.1.1.5 ! root      273:                        total_errors, total_tests);
1.1       root      274:        } else {
                    275:                fprintf(stderr, "\nFinished without any errors!\n\n");
                    276:        }
1.1.1.5 ! root      277:        return total_errors;
1.1       root      278: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.