Changeset 439 for EcnlProtoTool/trunk/prototool/src/mrdb.c
- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/prototool/src/mrdb.c
r321 r439 6 6 #include <stdlib.h> 7 7 #include <string.h> 8 9 #include "mruby.h" 10 #include "mruby/dump.h" 11 #include "mruby/debug.h" 12 #include "mruby/class.h" 13 #include "mruby/opcode.h" 14 #include "mruby/variable.h" 8 #include <ctype.h> 9 10 #include <mruby.h> 11 #include <mruby/dump.h> 12 #include <mruby/debug.h> 13 #include <mruby/class.h> 14 #include <mruby/opcode.h> 15 #include <mruby/variable.h> 15 16 16 17 #include "mrdb.h" 17 18 #include "apibreak.h" 19 #include "apilist.h" 18 20 19 21 void mrdb_state_free(mrb_state *); … … 22 24 static mrdb_state *_mrdb_state = NULL; 23 25 24 struct _args 25 { 26 FILE *rfp; 27 char* fname; 28 char* srcpath; 29 int argc; 30 char** argv; 31 mrb_bool mrbfile : 1; 26 struct _args { 27 FILE *rfp; 28 char* fname; 29 char* srcpath; 30 int argc; 31 char** argv; 32 mrb_bool mrbfile : 1; 32 33 }; 33 34 34 typedef struct debug_command 35 { 36 const char *cmd1; 37 const char *cmd2; 38 uint8_t len1; 39 uint8_t len2; 40 uint8_t div; 41 debug_command_id id; 42 debug_command_func func; 35 typedef struct debug_command { 36 const char *cmd1; 37 const char *cmd2; 38 uint8_t len1; 39 uint8_t len2; 40 uint8_t div; 41 debug_command_id id; 42 debug_command_func func; 43 43 } debug_command; 44 44 … … 52 52 {"help", NULL, 1, 0, 1, DBGCMD_HELP, dbgcmd_help}, /* h[elp] */ 53 53 {"info", "breakpoints", 1, 1, 1, DBGCMD_INFO_BREAK, dbgcmd_info_break}, /* i[nfo] b[reakpoints] */ 54 {"info", "locals", 1, 1, 0, DBGCMD_INFO_LOCAL, dbgcmd_info_local}, /* i[nfo] l[ocals] */ 55 {"list", NULL, 1, 0, 1, DBGCMD_LIST, dbgcmd_list}, /* l[ist] */ 54 56 {"print", NULL, 1, 0, 0, DBGCMD_PRINT, dbgcmd_print}, /* p[rint] */ 55 57 {"quit", NULL, 1, 0, 0, DBGCMD_QUIT, dbgcmd_quit}, /* q[uit] */ … … 64 66 usage(const char *name) 65 67 { 66 67 68 69 70 71 72 73 74 75 76 77 78 79 68 static const char *const usage_msg[] = { 69 "switches:", 70 "-b load and execute RiteBinary (mrb) file", 71 "-d specify source directory", 72 "--version print the version", 73 "--copyright print the copyright", 74 NULL 75 }; 76 const char *const *p = usage_msg; 77 78 printf("Usage: %s [switches] programfile\n", name); 79 while (*p) { 80 printf(" %s\n", *p++); 81 } 80 82 } 81 83 … … 83 85 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 84 86 { 85 86 87 88 89 90 for (argc--, argv++; argc > 0; argc--,argv++) {91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 memcpy(args->argv, argv, (argc +1) * sizeof(char*));164 165 166 87 char **origargv = argv; 88 static const struct _args args_zero = { 0 }; 89 90 *args = args_zero; 91 92 for (argc--,argv++; argc > 0; argc--,argv++) { 93 char *item; 94 if (argv[0][0] != '-') break; 95 96 item = argv[0] + 1; 97 switch (*item++) { 98 case 'b': 99 args->mrbfile = TRUE; 100 break; 101 case 'd': 102 if (item[0]) { 103 goto append_srcpath; 104 } 105 else if (argc > 1) { 106 argc--; argv++; 107 item = argv[0]; 108 append_srcpath: 109 if (!args->srcpath) { 110 size_t buflen; 111 char *buf; 112 113 buflen = strlen(item) + 1; 114 buf = (char *)mrb_malloc(mrb, buflen); 115 memcpy(buf, item, buflen); 116 args->srcpath = buf; 117 } 118 else { 119 size_t srcpathlen; 120 size_t itemlen; 121 122 srcpathlen = strlen(args->srcpath); 123 itemlen = strlen(item); 124 args->srcpath = 125 (char *)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2); 126 args->srcpath[srcpathlen] = '\n'; 127 memcpy(args->srcpath + srcpathlen + 1, item, itemlen + 1); 128 } 129 } 130 else { 131 printf("%s: No path specified for -d\n", *origargv); 132 return EXIT_SUCCESS; 133 } 134 break; 135 case '-': 136 if (strcmp((*argv) + 2, "version") == 0) { 137 mrb_show_version(mrb); 138 exit(EXIT_SUCCESS); 139 } 140 else if (strcmp((*argv) + 2, "copyright") == 0) { 141 mrb_show_copyright(mrb); 142 exit(EXIT_SUCCESS); 143 } 144 default: 145 return EXIT_FAILURE; 146 } 147 } 148 149 if (args->rfp == NULL) { 150 if (*argv == NULL) { 151 printf("%s: Program file not specified.\n", *origargv); 152 return EXIT_FAILURE; 153 } 154 else { 155 args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r"); 156 if (args->rfp == NULL) { 157 printf("%s: Cannot open program file. (%s)\n", *origargv, *argv); 158 return EXIT_FAILURE; 159 } 160 args->fname = argv[0]; 161 argc--; argv++; 162 } 163 } 164 args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1)); 165 memcpy(args->argv, argv, (argc+1) * sizeof(char*)); 166 args->argc = argc; 167 168 return EXIT_SUCCESS; 167 169 } 168 170 … … 170 172 cleanup(mrb_state *mrb, struct _args *args) 171 173 { 172 173 174 175 176 177 178 179 174 if (args->rfp) 175 fclose(args->rfp); 176 if (args->srcpath) 177 mrb_free(mrb, args->srcpath); 178 if (args->argv) 179 mrb_free(mrb, args->argv); 180 mrdb_state_free(mrb); 181 mrb_close(mrb); 180 182 } 181 183 … … 183 185 mrb_debug_context_new(mrb_state *mrb) 184 186 { 185 mrb_debug_context *dbg = (mrb_debug_context*)mrb_malloc(mrb, sizeof(mrb_debug_context));186 187 188 189 InterlockedExchange(&dbg->xm, DBG_INIT);190 191 192 193 187 mrb_debug_context *dbg = (mrb_debug_context*)mrb_malloc(mrb, sizeof(mrb_debug_context)); 188 189 memset(dbg, 0, sizeof(mrb_debug_context)); 190 191 dbg->xm = DBG_INIT; 192 dbg->xphase = DBG_PHASE_BEFORE_RUN; 193 dbg->next_bpno = 1; 194 195 return dbg; 194 196 } 195 197 … … 197 199 mrb_debug_context_get(mrb_state *mrb) 198 200 { 199 200 201 202 201 if (!_debug_context) { 202 _debug_context = mrb_debug_context_new(mrb); 203 } 204 return _debug_context; 203 205 } 204 206 … … 206 208 mrb_debug_context_set(mrb_debug_context *dbg) 207 209 { 208 210 _debug_context = dbg; 209 211 } 210 212 … … 212 214 mrb_debug_context_free(mrb_state *mrb) 213 215 { 214 215 216 217 218 216 if (_debug_context) { 217 mrb_debug_delete_break_all(mrb, _debug_context); 218 mrb_free(mrb, _debug_context); 219 _debug_context = NULL; 220 } 219 221 } 220 222 … … 222 224 mrdb_state_new(mrb_state *mrb) 223 225 { 224 mrdb_state *mrdb = (mrdb_state*)mrb_malloc(mrb, sizeof(mrdb_state));225 226 227 228 229 mrdb->command = (char *)mrb_malloc(mrb, MAX_COMMAND_LINE +1);230 231 232 226 mrdb_state *mrdb = (mrdb_state*)mrb_malloc(mrb, sizeof(mrdb_state)); 227 228 memset(mrdb, 0, sizeof(mrdb_state)); 229 230 mrdb->dbg = mrb_debug_context_get(mrb); 231 mrdb->command = (char*)mrb_malloc(mrb, MAX_COMMAND_LINE+1); 232 mrdb->print_no = 1; 233 234 return mrdb; 233 235 } 234 236 … … 236 238 mrdb_state_get(mrb_state *mrb) 237 239 { 238 239 240 241 240 if (!_mrdb_state) { 241 _mrdb_state = mrdb_state_new(mrb); 242 } 243 return _mrdb_state; 242 244 } 243 245 … … 245 247 mrdb_state_set(mrdb_state *mrdb) 246 248 { 247 249 _mrdb_state = mrdb; 248 250 } 249 251 … … 251 253 mrdb_state_free(mrb_state *mrb) 252 254 { 253 254 255 256 257 258 255 mrb_debug_context_free(mrb); 256 if (_mrdb_state) { 257 mrb_free(mrb, _mrdb_state->command); 258 mrb_free(mrb, _mrdb_state); 259 _mrdb_state = NULL; 260 } 259 261 } 260 262 … … 262 264 get_command(mrb_state *mrb, mrdb_state *mrdb) 263 265 { 264 265 266 267 for (i = 0; i <MAX_COMMAND_LINE; i++) {268 if ((c =getchar()) == EOF || c == '\n') break;269 270 271 272 273 274 strlcpy(mrdb->command, "quit", MAX_COMMAND_LINE + 1);275 276 277 278 279 for (; (c = getchar()) != EOF && c != '\n'; i++);280 281 282 283 284 285 286 287 288 266 int i; 267 int c; 268 269 for (i=0; i<MAX_COMMAND_LINE; i++) { 270 if ((c=getchar()) == EOF || c == '\n') break; 271 mrdb->command[i] = c; 272 } 273 274 if (i == 0 && feof(stdin)) { 275 clearerr(stdin); 276 strcpy(mrdb->command, "quit"); 277 i += sizeof("quit") - 1; 278 } 279 280 if (i == MAX_COMMAND_LINE) { 281 for ( ; (c=getchar()) != EOF && c !='\n'; i++) ; 282 } 283 284 if (i > MAX_COMMAND_LINE) { 285 printf("command line too long.\n"); 286 i = 0; /* discard command data */ 287 } 288 mrdb->command[i] = '\0'; 289 290 return mrdb->command; 289 291 } 290 292 … … 292 294 pick_out_word(mrb_state *mrb, char **pp) 293 295 { 294 295 296 for (ps = *pp; ISBLANK(*ps); ps++);297 298 299 300 301 302 *pp = strchr(ps +1, *ps);303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 296 char *ps; 297 298 for (ps=*pp; ISBLANK(*ps); ps++) ; 299 if (*ps == '\0') { 300 return NULL; 301 } 302 303 if (*ps == '\"' || *ps == '\'') { 304 *pp = strchr(ps+1, *ps); 305 if (*pp) (*pp)++; 306 } 307 else { 308 *pp = strpbrk(ps, " \t"); 309 } 310 311 if (!*pp) { 312 *pp = ps + strlen(ps); 313 } 314 315 if (**pp != '\0') { 316 **pp = '\0'; 317 (*pp)++; 318 } 319 320 return ps; 319 321 } 320 322 … … 322 324 parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf) 323 325 { 324 325 326 327 328 329 330 331 332 333 334 335 for (; *p && ISBLANK(*p); p++);336 337 338 339 340 341 for (cmd =(debug_command*)debug_command_list; cmd->cmd1; cmd++) {342 343 344 345 346 347 348 349 350 351 352 353 354 355 for (; *p && ISBLANK(*p); p++);356 357 358 359 360 361 362 363 for (; cmd->cmd1; cmd++) {364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 for (; mrdb->wcnt <MAX_COMMAND_WORD; mrdb->wcnt++) {386 387 388 389 390 391 392 393 326 debug_command *cmd = NULL; 327 char *p = buf; 328 size_t wlen; 329 330 /* get word #1 */ 331 mrdb->words[0] = pick_out_word(mrb, &p); 332 if (!mrdb->words[0]) { 333 return NULL; 334 } 335 mrdb->wcnt = 1; 336 /* set remain parameter */ 337 for ( ; *p && ISBLANK(*p); p++) ; 338 if (*p) { 339 mrdb->words[mrdb->wcnt++] = p; 340 } 341 342 /* check word #1 */ 343 for (cmd=(debug_command*)debug_command_list; cmd->cmd1; cmd++) { 344 wlen = strlen(mrdb->words[0]); 345 if (wlen >= cmd->len1 && 346 strncmp(mrdb->words[0], cmd->cmd1, wlen) == 0) { 347 break; 348 } 349 } 350 351 if (cmd->cmd2) { 352 if (mrdb->wcnt > 1) { 353 /* get word #2 */ 354 mrdb->words[1] = pick_out_word(mrb, &p); 355 if (mrdb->words[1]) { 356 /* update remain parameter */ 357 for ( ; *p && ISBLANK(*p); p++) ; 358 if (*p) { 359 mrdb->words[mrdb->wcnt++] = p; 360 } 361 } 362 } 363 364 /* check word #1,#2 */ 365 for ( ; cmd->cmd1; cmd++) { 366 wlen = strlen(mrdb->words[0]); 367 if (wlen < cmd->len1 || 368 strncmp(mrdb->words[0], cmd->cmd1, wlen)) { 369 continue; 370 } 371 372 if (!cmd->cmd2) break; /* word #1 only */ 373 374 if (mrdb->wcnt == 1) continue; /* word #2 not specified */ 375 376 wlen = strlen(mrdb->words[1]); 377 if (wlen >= cmd->len2 && 378 strncmp(mrdb->words[1], cmd->cmd2, wlen) == 0) { 379 break; /* word #1 and #2 */ 380 } 381 } 382 } 383 384 /* divide remain parameters */ 385 if (cmd->cmd1 && cmd->div) { 386 p = mrdb->words[--mrdb->wcnt]; 387 for ( ; mrdb->wcnt<MAX_COMMAND_WORD; mrdb->wcnt++) { 388 mrdb->words[mrdb->wcnt] = pick_out_word(mrb, &p); 389 if (!mrdb->words[mrdb->wcnt]) { 390 break; 391 } 392 } 393 } 394 395 return cmd->cmd1 ? cmd : NULL; 394 396 } 395 397 … … 397 399 print_info_stopped_break(mrb_state *mrb, mrdb_state *mrdb) 398 400 { 399 400 401 402 403 404 405 406 407 408 switch(bp.type) {409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 401 mrb_debug_breakpoint bp; 402 int32_t ret; 403 uint16_t lineno; 404 const char *file; 405 const char *method_name; 406 const char *class_name; 407 408 ret = mrb_debug_get_break(mrb, mrdb->dbg, mrdb->dbg->stopped_bpno, &bp); 409 if (ret == 0) { 410 switch(bp.type) { 411 case MRB_DEBUG_BPTYPE_LINE: 412 file = bp.point.linepoint.file; 413 lineno = bp.point.linepoint.lineno; 414 printf("Breakpoint %d, at %s:%d\n", bp.bpno, file, lineno); 415 break; 416 case MRB_DEBUG_BPTYPE_METHOD: 417 method_name = bp.point.methodpoint.method_name; 418 class_name = bp.point.methodpoint.class_name; 419 if (class_name == NULL) { 420 printf("Breakpoint %d, %s\n", bp.bpno, method_name); 421 } 422 else { 423 printf("Breakpoint %d, %s:%s\n", bp.bpno, class_name, method_name); 424 } 425 if (mrdb->dbg->isCfunc) { 426 printf("Stopped before calling the C function.\n"); 427 } 428 break; 429 default: 430 break; 431 } 432 } 431 433 } 432 434 … … 434 436 print_info_stopped_step_next(mrb_state *mrb, mrdb_state *mrdb) 435 437 { 436 const char* file = mrdb->dbg->prvfile; 437 uint16_t lineno = mrdb->dbg->prvline; 438 printf("%s:%d\n", file, lineno); 438 const char* file = mrdb->dbg->prvfile; 439 uint16_t lineno = mrdb->dbg->prvline; 440 printf("%s:%d\n", file, lineno); 441 } 442 443 static void 444 print_info_stopped_code(mrb_state *mrb, mrdb_state *mrdb) 445 { 446 char* file = mrb_debug_get_source(mrb, mrdb, mrdb->srcpath, mrdb->dbg->prvfile); 447 uint16_t lineno = mrdb->dbg->prvline; 448 if (file != NULL) { 449 mrb_debug_list(mrb, mrdb->dbg, file, lineno, lineno); 450 mrb_free(mrb, file); 451 } 439 452 } 440 453 … … 442 455 print_info_stopped(mrb_state *mrb, mrdb_state *mrdb) 443 456 { 444 switch (mrdb->dbg->bm) { 445 case BRK_BREAK: 446 print_info_stopped_break(mrb, mrdb); 447 break; 448 case BRK_STEP: 449 case BRK_NEXT: 450 print_info_stopped_step_next(mrb, mrdb); 451 break; 452 default: 453 break; 454 } 457 switch(mrdb->dbg->bm) { 458 case BRK_BREAK: 459 print_info_stopped_break(mrb, mrdb); 460 print_info_stopped_code(mrb, mrdb); 461 break; 462 case BRK_STEP: 463 case BRK_NEXT: 464 print_info_stopped_step_next(mrb, mrdb); 465 print_info_stopped_code(mrb, mrdb); 466 break; 467 default: 468 break; 469 } 455 470 } 456 471 … … 458 473 get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb) 459 474 { 460 461 462 463 464 465 for (p = NULL; !p || *p =='\0'; ) {466 467 468 469 470 471 475 debug_command *cmd = NULL; 476 char *p; 477 int i; 478 479 while (!cmd) { 480 for (p=NULL; !p || *p=='\0'; ) { 481 printf("(%s:%d) ", mrdb->dbg->prvfile, mrdb->dbg->prvline); 482 fflush(stdout); 483 p = get_command(mrb, mrdb); 484 } 485 486 cmd = parse_command(mrb, mrdb, p); 472 487 #ifdef _DBG_MRDB_PARSER_ 473 for (i = 0; i <mrdb->wcnt; i++) {474 475 488 for (i=0; i<mrdb->wcnt; i++) { 489 printf("%d: %s\n", i, mrdb->words[i]); 490 } 476 491 #endif 477 478 479 for (i = 0; i <mrdb->wcnt; i++) {480 if (i >0) {481 482 483 484 485 486 487 488 492 if (!cmd) { 493 printf("invalid command ("); 494 for (i=0; i<mrdb->wcnt; i++) { 495 if (i>0) { 496 printf(" "); 497 } 498 printf("%s", mrdb->words[i]); 499 } 500 puts(")"); 501 } 502 } 503 return cmd; 489 504 } 490 505 491 506 static int32_t 492 check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs) 493 { 494 struct RClass* c = NULL; 495 mrb_sym sym; 496 int32_t bpno; 497 mrb_bool isCfunc; 498 499 mrb_debug_context *dbg = mrb_debug_context_get(mrb); 500 501 isCfunc = FALSE; 502 bpno = dbg->method_bpno; 503 dbg->method_bpno = 0; 504 505 switch (GET_OPCODE(*pc)) { 506 case OP_SEND: 507 case OP_SENDB: 508 c = mrb_class(mrb, regs[GETARG_A(*pc)]); 509 sym = irep->syms[GETARG_B(*pc)]; 510 break; 511 case OP_SUPER: 512 c = mrb->c->ci->target_class->super; 513 sym = mrb->c->ci->mid; 514 break; 515 default: 516 sym = 0; 517 break; 518 } 519 if (sym != 0) { 520 dbg->method_bpno = mrb_debug_check_breakpoint_method(mrb, dbg, c, sym, &isCfunc); 521 if (isCfunc) { 522 bpno = dbg->method_bpno; 523 dbg->method_bpno = 0; 524 } 525 } 526 dbg->isCfunc = isCfunc; 527 return bpno; 507 check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs) 508 { 509 struct RClass* c; 510 mrb_sym sym; 511 int32_t bpno; 512 mrb_bool isCfunc; 513 struct mrb_insn_data insn; 514 515 mrb_debug_context *dbg = mrb_debug_context_get(mrb); 516 517 isCfunc = FALSE; 518 bpno = dbg->method_bpno; 519 dbg->method_bpno = 0; 520 521 insn = mrb_decode_insn(pc); 522 switch(insn.insn) { 523 case OP_SEND: 524 case OP_SENDB: 525 c = mrb_class(mrb, regs[insn.a]); 526 sym = irep->syms[insn.b]; 527 break; 528 case OP_SUPER: 529 c = mrb->c->ci->target_class->super; 530 sym = mrb->c->ci->mid; 531 break; 532 default: 533 sym = 0; 534 break; 535 } 536 if (sym != 0) { 537 dbg->method_bpno = mrb_debug_check_breakpoint_method(mrb, dbg, c, sym, &isCfunc); 538 if (isCfunc) { 539 bpno = dbg->method_bpno; 540 dbg->method_bpno = 0; 541 } 542 } 543 dbg->isCfunc = isCfunc; 544 return bpno; 528 545 } 529 546 530 547 static void 531 mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)532 { 533 534 535 536 537 538 539 540 541 542 dbg->pc= pc;543 544 545 546 547 548 549 550 InterlockedExchange(&dbg->xm, DBG_RUN);551 552 553 554 file = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));555 line = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 548 mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs) 549 { 550 const char *file; 551 int32_t line; 552 int32_t bpno; 553 554 mrb_debug_context *dbg = mrb_debug_context_get(mrb); 555 556 mrb_assert(dbg); 557 558 dbg->irep = irep; 559 dbg->pc = pc; 560 dbg->regs = regs; 561 562 if (dbg->xphase == DBG_PHASE_RESTART) { 563 dbg->root_irep = irep; 564 dbg->prvfile = NULL; 565 dbg->prvline = 0; 566 dbg->prvci = NULL; 567 dbg->xm = DBG_RUN; 568 dbg->xphase = DBG_PHASE_RUNNING; 569 } 570 571 file = mrb_debug_get_filename(mrb, irep, pc - irep->iseq); 572 line = mrb_debug_get_line(mrb, irep, pc - irep->iseq); 573 574 switch (dbg->xm) { 575 case DBG_STEP: 576 if (!file || (dbg->prvfile == file && dbg->prvline == line)) { 577 return; 578 } 579 dbg->method_bpno = 0; 580 dbg->bm = BRK_STEP; 581 break; 582 583 case DBG_NEXT: 584 if (!file || (dbg->prvfile == file && dbg->prvline == line)) { 585 return; 586 } 587 if ((intptr_t)(dbg->prvci) < (intptr_t)(mrb->c->ci)) { 588 return; 589 } 590 dbg->prvci = NULL; 591 dbg->method_bpno = 0; 592 dbg->bm = BRK_NEXT; 593 break; 594 595 case DBG_RUN: 596 bpno = check_method_breakpoint(mrb, irep, pc, regs); 597 if (bpno > 0) { 598 dbg->stopped_bpno = bpno; 599 dbg->bm = BRK_BREAK; 600 break; 601 } 602 if (dbg->prvfile != file || dbg->prvline != line) { 603 bpno = mrb_debug_check_breakpoint_line(mrb, dbg, file, line); 604 if (bpno > 0) { 605 dbg->stopped_bpno = bpno; 606 dbg->bm = BRK_BREAK; 607 break; 608 } 609 } 610 dbg->prvfile = file; 611 dbg->prvline = line; 612 return; 613 case DBG_INIT: 614 dbg->root_irep = irep; 615 dbg->bm = BRK_INIT; 616 if (!file || line < 0) { 617 puts("Cannot get debugging information."); 618 } 619 break; 620 621 default: 622 return; 623 } 624 625 dbg->prvfile = file; 626 dbg->prvline = line; 627 628 if (dbg->bm == BRK_BREAK && --dbg->ccnt > 0) { 629 return; 630 } 631 dbg->break_hook(mrb, dbg); 632 633 dbg->xphase = DBG_PHASE_RUNNING; 617 634 } 618 635 … … 620 637 mrb_debug_break_hook(mrb_state *mrb, mrb_debug_context *dbg) 621 638 { 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 639 debug_command *cmd; 640 dbgcmd_state st = DBGST_CONTINUE; 641 mrdb_state *mrdb = mrdb_state_get(mrb); 642 643 print_info_stopped(mrb, mrdb); 644 645 while (1) { 646 cmd = get_and_parse_command(mrb, mrdb); 647 mrb_assert(cmd); 648 649 st = cmd->func(mrb, mrdb); 650 651 if ((st == DBGST_CONTINUE) || (st == DBGST_RESTART)) break; 652 } 653 return dbg->xm; 637 654 } 638 655 … … 643 660 if (mrdb == NULL) 644 661 return 0; 645 return InterlockedCompareExchange(&mrdb->dbg->xm, DBG_STEP, DBG_RUN) == DBG_RUN; 662 long prev = mrdb->dbg->xm; 663 if (mrdb->dbg->xm == DBG_RUN) 664 mrdb->dbg->xm = DBG_STEP; 665 return prev == DBG_RUN; 646 666 } 647 667 … … 649 669 mrdb_main(int argc, char **argv) 650 670 { 651 652 653 654 655 656 657 658 659 660 l_restart:661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 InterlockedExchange(&mrdb->dbg->xm, DBG_INIT);687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 if (cmd->func(mrb, mrdb) == DBGST_RESTART) goto l_restart;748 749 750 751 752 753 } 671 mrb_state *mrb = mrb_open(); 672 int n = -1; 673 struct _args args; 674 mrb_value v; 675 mrdb_state *mrdb; 676 mrdb_state *mrdb_backup; 677 mrb_debug_context* dbg_backup; 678 debug_command *cmd; 679 680 l_restart: 681 682 if (mrb == NULL) { 683 fputs("Invalid mrb_state, exiting mruby\n", stderr); 684 return EXIT_FAILURE; 685 } 686 687 /* parse command parameters */ 688 n = parse_args(mrb, argc, argv, &args); 689 if (n == EXIT_FAILURE || args.rfp == NULL) { 690 cleanup(mrb, &args); 691 usage(argv[0]); 692 return n; 693 } 694 695 /* initialize debugger information */ 696 mrdb = mrdb_state_get(mrb); 697 mrb_assert(mrdb && mrdb->dbg); 698 mrdb->srcpath = args.srcpath; 699 700 if (mrdb->dbg->xm == DBG_QUIT) { 701 mrdb->dbg->xphase = DBG_PHASE_RESTART; 702 } 703 else { 704 mrdb->dbg->xphase = DBG_PHASE_BEFORE_RUN; 705 } 706 mrdb->dbg->xm = DBG_INIT; 707 mrdb->dbg->ccnt = 1; 708 709 /* setup hook functions */ 710 mrb->code_fetch_hook = mrb_code_fetch_hook; 711 mrdb->dbg->break_hook = mrb_debug_break_hook; 712 713 if (args.mrbfile) { /* .mrb */ 714 v = mrb_load_irep_file(mrb, args.rfp); 715 } 716 else { /* .rb */ 717 mrbc_context *cc = mrbc_context_new(mrb); 718 mrbc_filename(mrb, cc, args.fname); 719 v = mrb_load_file_cxt(mrb, args.rfp, cc); 720 mrbc_context_free(mrb, cc); 721 } 722 if (mrdb->dbg->xm == DBG_QUIT && !mrb_undef_p(v) && mrb->exc) { 723 const char *classname = mrb_obj_classname(mrb, mrb_obj_value(mrb->exc)); 724 if (!strcmp(classname, "DebuggerExit")) { 725 cleanup(mrb, &args); 726 return 0; 727 } 728 if (!strcmp(classname, "DebuggerRestart")) { 729 mrdb_backup = mrdb_state_get(mrb); 730 dbg_backup = mrb_debug_context_get(mrb); 731 732 mrdb_state_set(NULL); 733 mrb_debug_context_set(NULL); 734 735 cleanup(mrb, &args); 736 mrb = mrb_open(); 737 738 mrdb_state_set(mrdb_backup); 739 mrb_debug_context_set(dbg_backup); 740 741 goto l_restart; 742 } 743 } 744 puts("mruby application exited."); 745 mrdb->dbg->xphase = DBG_PHASE_AFTER_RUN; 746 if (!mrb_undef_p(v)) { 747 if (mrb->exc) { 748 mrb_print_error(mrb); 749 } 750 else { 751 printf(" => "); 752 mrb_p(mrb, v); 753 } 754 } 755 756 mrdb->dbg->prvfile = "-"; 757 mrdb->dbg->prvline = 0; 758 759 while (1) { 760 cmd = get_and_parse_command(mrb, mrdb); 761 mrb_assert(cmd); 762 763 if (cmd->id == DBGCMD_QUIT) { 764 break; 765 } 766 767 if ( cmd->func(mrb, mrdb) == DBGST_RESTART ) goto l_restart; 768 } 769 770 cleanup(mrb, &args); 771 772 return 0; 773 }
Note:
See TracChangeset
for help on using the changeset viewer.