int dbg_lua_handle_raise(lua_State* L) { struct dbg_state* state = dbg_lua_extract_state(L, 1); void* ud = dbg_lua_extract_state_ud(L, 1); dbg_lua_handle_hook(state, NULL, bautofree(bfromcstr(luaL_checkstring(L, 2))), luaL_optinteger(L, 3, 0)); return 0; }
void ddbg_step_into() { vm->sleep_cycles = 0; vm_cycle(vm); // Handle custom Lua commands. dbg_lua_handle_hook(&lstate, NULL, bautofree(bfromcstr("step")), 0); }
void ddbg_continue_vm() { vm->halted = false; vm->sleep_cycles = 0; dbg_lua_handle_hook(&lstate, NULL, bautofree(bfromcstr("continue")), 0); vm_execute(vm, NULL); printd(LEVEL_DEFAULT, "\n"); }
void ddbg_step_over() { uint16_t inst, op_a, op_b, offset = 1, bp; inst = INSTRUCTION_GET_OP(vm->ram[vm->pc]); op_a = INSTRUCTION_GET_A(vm->ram[vm->pc]); op_b = INSTRUCTION_GET_B(vm->ram[vm->pc]); vm->sleep_cycles = 0; if (op_a == NXT) offset += 1; if (op_a == NXT_LIT) offset += 1; if (op_b == NXT) offset += 1; if (op_b == NXT_LIT) offset += 1; if (inst == NBOP_RESERVED) { if (op_b == NBOP_JSR) { bp = op_a; } } else { bp = vm->pc + offset; } list_append(&breakpoints, breakpoint_create(bp, true, true)); vm->halted = false; vm_execute(vm, NULL); // Handle custom Lua commands. dbg_lua_handle_hook(&lstate, NULL, bautofree(bfromcstr("next")), 0); }
void ddbg_interrupt_hook(vm_t* vm, uint16_t pos, void* ud) { // Handle custom Lua commands. dbg_lua_handle_hook(&lstate, NULL, bautofree(bfromcstr("interrupt")), pos); }
void ddbg_precycle_hook(vm_t* vm, uint16_t pos, void* ud) { unsigned int i = 0; struct breakpoint* bk; uint16_t op, a, b; // Handle any symbols that are at this cycle. list_t* symbols = ddbg_get_symbols(vm->pc); list_iterator_start(symbols); while (list_iterator_hasnext(symbols)) dbg_lua_handle_hook_symbol(&lstate, NULL, bautofree((bstring)list_iterator_next(symbols))); list_iterator_stop(symbols); list_empty(symbols); free(symbols); // Handle custom Lua commands. dbg_lua_handle_hook(&lstate, NULL, bautofree(bfromcstr("precycle")), pos); // Check to see if Lua halted the VM and return if it did. if (vm->halted) return; // Handle breakpoints. if (!ignore_next_breakpoint) { for (i = 0; i < list_size(&breakpoints); i++) { bk = (struct breakpoint*)list_get_at(&breakpoints, i); if (vm->pc == bk->addr) { vm->halted = true; ignore_next_breakpoint = true; vm_hook_break(vm); // Required for UI to update correctly. if (bk->temporary) list_delete_at(&breakpoints, i--); if (!bk->silent) ddbg_disassemble(max_int32((int32_t)vm->pc - 10, 0x0), min_int32((int32_t)vm->pc + 10, 0x10000) - vm->pc); printd(LEVEL_DEFAULT, "Breakpoint hit at 0x%04X.\n", bk->addr); return; } } } ignore_next_breakpoint = false; // Handle backtrace. op = INSTRUCTION_GET_OP(vm->ram[vm->pc]); a = INSTRUCTION_GET_A(vm->ram[vm->pc]); b = INSTRUCTION_GET_B(vm->ram[vm->pc]); if ((op == OP_SET && b == PC) || (op == OP_NONBASIC && b == NBOP_JSR)) { // FIXME: This doesn't handle every valid value correctly.. if (a == PUSH_POP) list_delete_at(&backtrace, list_size(&backtrace) - 1); else if (a == NXT_LIT) { printd(LEVEL_DEBUG, "jumping literally from 0x%04X to 0x%04X (0x%04X).\n", vm->pc, vm->ram[vm->pc + 1], vm->pc + 1); list_append(&backtrace, backtrace_entry_create(vm->pc, vm->ram[vm->pc + 1])); } else if (a == NXT) { //list_append(&backtrace, backtrace_entry_create(vm->pc, vm->ram[vm->ram[vm->pc+1]])); } else { // Unhandled. printd(LEVEL_DEBUG, "warning: unhandled backtrace jump occurred.\n"); } } }