SCI: cleanup of execstack, output of backtrace slightly modified, is now also displaying local calls and exports
svn-id: r50445
This commit is contained in:
parent
9b4406fd35
commit
6402d64419
3 changed files with 35 additions and 30 deletions
|
@ -2320,8 +2320,6 @@ bool Console::cmdScriptSteps(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Console::cmdBacktrace(int argc, const char **argv) {
|
bool Console::cmdBacktrace(int argc, const char **argv) {
|
||||||
DebugPrintf("Dumping the send/self/super/call/calle/callb stack:\n");
|
|
||||||
|
|
||||||
DebugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);
|
DebugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);
|
||||||
Common::List<ExecStack>::iterator iter;
|
Common::List<ExecStack>::iterator iter;
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
|
@ -2333,19 +2331,25 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
|
||||||
int paramc, totalparamc;
|
int paramc, totalparamc;
|
||||||
|
|
||||||
switch (call.type) {
|
switch (call.type) {
|
||||||
|
|
||||||
case EXEC_STACK_TYPE_CALL: // Normal function
|
case EXEC_STACK_TYPE_CALL: // Normal function
|
||||||
DebugPrintf(" %x:[%x] %s::%s(", i, call.origin, objname, (call.selector == -1) ? "<call[be]?>" :
|
if (call.type == EXEC_STACK_TYPE_CALL)
|
||||||
_engine->getKernel()->getSelectorName(call.selector).c_str());
|
DebugPrintf(" %x: script %d - ", i, (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.segment]).getScriptNumber());
|
||||||
|
if (call.debugSelector != -1) {
|
||||||
|
DebugPrintf("%s::%s(", objname, _engine->getKernel()->getSelectorName(call.debugSelector).c_str());
|
||||||
|
} else if (call.debugExportId != -1) {
|
||||||
|
DebugPrintf("export %d (", call.debugExportId);
|
||||||
|
} else if (call.debugLocalCallOffset != -1) {
|
||||||
|
DebugPrintf("call %x (", call.debugLocalCallOffset);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXEC_STACK_TYPE_KERNEL: // Kernel function
|
case EXEC_STACK_TYPE_KERNEL: // Kernel function
|
||||||
DebugPrintf(" %x:[%x] k%s(", i, call.origin, _engine->getKernel()->getKernelName(call.selector).c_str());
|
DebugPrintf(" %x:[%x] k%s(", i, call.debugOrigin, _engine->getKernel()->getKernelName(call.debugSelector).c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXEC_STACK_TYPE_VARSELECTOR:
|
case EXEC_STACK_TYPE_VARSELECTOR:
|
||||||
DebugPrintf(" %x:[%x] vs%s %s::%s (", i, call.origin, (call.argc) ? "write" : "read",
|
DebugPrintf(" %x:[%x] vs%s %s::%s (", i, call.debugOrigin, (call.argc) ? "write" : "read",
|
||||||
objname, _engine->getKernel()->getSelectorName(call.selector).c_str());
|
objname, _engine->getKernel()->getSelectorName(call.debugSelector).c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2364,7 +2368,10 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
|
||||||
if (call.argc > 16)
|
if (call.argc > 16)
|
||||||
DebugPrintf("...");
|
DebugPrintf("...");
|
||||||
|
|
||||||
DebugPrintf(")\n obj@%04x:%04x", PRINT_REG(call.objp));
|
DebugPrintf(")\n ");
|
||||||
|
if (call.debugOrigin != -1)
|
||||||
|
DebugPrintf("by %x ", call.debugOrigin);
|
||||||
|
DebugPrintf("obj@%04x:%04x", PRINT_REG(call.objp));
|
||||||
if (call.type == EXEC_STACK_TYPE_CALL) {
|
if (call.type == EXEC_STACK_TYPE_CALL) {
|
||||||
DebugPrintf(" pc=%04x:%04x", PRINT_REG(call.addr.pc));
|
DebugPrintf(" pc=%04x:%04x", PRINT_REG(call.addr.pc));
|
||||||
if (call.sp == CALL_SP_CARRY)
|
if (call.sp == CALL_SP_CARRY)
|
||||||
|
@ -2377,8 +2384,6 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
|
||||||
DebugPrintf(" pc:none");
|
DebugPrintf(" pc:none");
|
||||||
|
|
||||||
DebugPrintf(" argp:ST:%04x", (unsigned)(call.variables_argp - _engine->_gamestate->stack_base));
|
DebugPrintf(" argp:ST:%04x", (unsigned)(call.variables_argp - _engine->_gamestate->stack_base));
|
||||||
if (call.type == EXEC_STACK_TYPE_CALL)
|
|
||||||
DebugPrintf(" script: %d", (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.segment]).getScriptNumber());
|
|
||||||
DebugPrintf("\n");
|
DebugPrintf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,15 +301,15 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i
|
||||||
Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment);
|
Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment);
|
||||||
int curScriptNr = local_script->getScriptNumber();
|
int curScriptNr = local_script->getScriptNumber();
|
||||||
|
|
||||||
if (lastCall->localCallOffset != -1) {
|
if (lastCall->debugLocalCallOffset != -1) {
|
||||||
// if lastcall was actually a local call search back for a real call
|
// if lastcall was actually a local call search back for a real call
|
||||||
Common::List<ExecStack>::iterator callIterator = state->_executionStack.end();
|
Common::List<ExecStack>::iterator callIterator = state->_executionStack.end();
|
||||||
while (callIterator != state->_executionStack.begin()) {
|
while (callIterator != state->_executionStack.begin()) {
|
||||||
callIterator--;
|
callIterator--;
|
||||||
ExecStack loopCall = *callIterator;
|
ExecStack loopCall = *callIterator;
|
||||||
if ((loopCall.selector != -1) || (loopCall.exportId != -1)) {
|
if ((loopCall.debugSelector != -1) || (loopCall.debugExportId != -1)) {
|
||||||
lastCall->selector = loopCall.selector;
|
lastCall->debugSelector = loopCall.debugSelector;
|
||||||
lastCall->exportId = loopCall.exportId;
|
lastCall->debugExportId = loopCall.debugExportId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,11 +320,11 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i
|
||||||
const SciGameId gameId = g_sci->getGameId();
|
const SciGameId gameId = g_sci->getGameId();
|
||||||
|
|
||||||
if (lastCall->type == EXEC_STACK_TYPE_CALL) {
|
if (lastCall->type == EXEC_STACK_TYPE_CALL) {
|
||||||
if (lastCall->selector != -1) {
|
if (lastCall->debugSelector != -1) {
|
||||||
curMethodName = g_sci->getKernel()->getSelectorName(lastCall->selector);
|
curMethodName = g_sci->getKernel()->getSelectorName(lastCall->debugSelector);
|
||||||
} else if (lastCall->exportId != -1) {
|
} else if (lastCall->debugExportId != -1) {
|
||||||
curObjectName = "";
|
curObjectName = "";
|
||||||
curMethodName = curMethodName.printf("export %d", lastCall->exportId);
|
curMethodName = curMethodName.printf("export %d", lastCall->debugExportId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i
|
||||||
workaround = uninitializedReadWorkarounds;
|
workaround = uninitializedReadWorkarounds;
|
||||||
while (workaround->objectName) {
|
while (workaround->objectName) {
|
||||||
if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr && (workaround->objectName == searchObjectName)
|
if (workaround->gameId == gameId && workaround->scriptNr == curScriptNr && (workaround->objectName == searchObjectName)
|
||||||
&& workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->localCallOffset && workaround->index == index) {
|
&& workaround->methodName == curMethodName && workaround->localCallOffset == lastCall->debugLocalCallOffset && workaround->index == index) {
|
||||||
// Workaround found
|
// Workaround found
|
||||||
r[index] = make_reg(0, workaround->newValue);
|
r[index] = make_reg(0, workaround->newValue);
|
||||||
return r[index];
|
return r[index];
|
||||||
|
@ -348,7 +348,7 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i
|
||||||
if (!searchObject.isNull())
|
if (!searchObject.isNull())
|
||||||
searchObjectName = state->_segMan->getObjectName(searchObject);
|
searchObjectName = state->_segMan->getObjectName(searchObject);
|
||||||
} while (!searchObject.isNull()); // no parent left?
|
} while (!searchObject.isNull()); // no parent left?
|
||||||
error("Uninitialized read for temp %d from method %s::%s (script %d, localCall %x)", index, curObjectName.c_str(), curMethodName.c_str(), curScriptNr, lastCall->localCallOffset);
|
error("Uninitialized read for temp %d from method %s::%s (script %d, localCall %x)", index, curObjectName.c_str(), curMethodName.c_str(), curScriptNr, lastCall->debugLocalCallOffset);
|
||||||
}
|
}
|
||||||
return r[index];
|
return r[index];
|
||||||
} else
|
} else
|
||||||
|
@ -718,10 +718,10 @@ static ExecStack *add_exec_stack_entry(Common::List<ExecStack> &execStack, reg_t
|
||||||
*argp = make_reg(0, argc); // SCI code relies on the zeroeth argument to equal argc
|
*argp = make_reg(0, argc); // SCI code relies on the zeroeth argument to equal argc
|
||||||
|
|
||||||
// Additional debug information
|
// Additional debug information
|
||||||
xstack.selector = selector;
|
xstack.debugSelector = selector;
|
||||||
xstack.exportId = exportId;
|
xstack.debugExportId = exportId;
|
||||||
xstack.localCallOffset = localCallOffset;
|
xstack.debugLocalCallOffset = localCallOffset;
|
||||||
xstack.origin = origin;
|
xstack.debugOrigin = origin;
|
||||||
|
|
||||||
xstack.type = EXEC_STACK_TYPE_CALL; // Normal call
|
xstack.type = EXEC_STACK_TYPE_CALL; // Normal call
|
||||||
|
|
||||||
|
@ -777,7 +777,7 @@ static void callKernelFunc(EngineState *s, int kernelFuncNr, int argc) {
|
||||||
ExecStack *xstack;
|
ExecStack *xstack;
|
||||||
xstack = add_exec_stack_entry(s->_executionStack, NULL_REG, NULL, NULL_REG, argc, argv - 1, 0, -1, -1, NULL_REG,
|
xstack = add_exec_stack_entry(s->_executionStack, NULL_REG, NULL, NULL_REG, argc, argv - 1, 0, -1, -1, NULL_REG,
|
||||||
s->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS);
|
s->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS);
|
||||||
xstack->selector = kernelFuncNr;
|
xstack->debugSelector = kernelFuncNr;
|
||||||
xstack->type = EXEC_STACK_TYPE_KERNEL;
|
xstack->type = EXEC_STACK_TYPE_KERNEL;
|
||||||
|
|
||||||
// Call kernel function
|
// Call kernel function
|
||||||
|
|
|
@ -97,10 +97,10 @@ struct ExecStack {
|
||||||
StackPtr variables_argp; // Argument pointer
|
StackPtr variables_argp; // Argument pointer
|
||||||
SegmentId local_segment; // local variables etc
|
SegmentId local_segment; // local variables etc
|
||||||
|
|
||||||
Selector selector; // The selector which was used to call or -1 if not applicable
|
Selector debugSelector; // The selector which was used to call or -1 if not applicable
|
||||||
int exportId; // The exportId which was called or -1 if not applicable
|
int debugExportId; // The exportId which was called or -1 if not applicable
|
||||||
int localCallOffset; // Local call offset or -1 if not applicable
|
int debugLocalCallOffset; // Local call offset or -1 if not applicable
|
||||||
int origin; // The stack frame position the call was made from, or -1 if it was the initial call
|
int debugOrigin; // The stack frame position the call was made from, or -1 if it was the initial call
|
||||||
ExecStackType type;
|
ExecStackType type;
|
||||||
|
|
||||||
reg_t* getVarPointer(SegManager *segMan) const;
|
reg_t* getVarPointer(SegManager *segMan) const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue