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

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

unix.superglobalmegacorp.com

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