SCI: adding bpk debug command
currently removing or listing such breakpoints is not yet supported svn-id: r51710
This commit is contained in:
parent
449927abcf
commit
fcede4680a
5 changed files with 72 additions and 23 deletions
|
@ -176,10 +176,12 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
|
||||||
DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
|
DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
|
||||||
DCmd_Register("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
|
DCmd_Register("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
|
||||||
DCmd_Register("bc", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
|
DCmd_Register("bc", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
|
||||||
DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod));
|
DCmd_Register("bp_method", WRAP_METHOD(Console, cmdBreakpointMethod));
|
||||||
DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointExecMethod)); // alias
|
DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointMethod)); // alias
|
||||||
DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction));
|
DCmd_Register("bp_kernel", WRAP_METHOD(Console, cmdBreakpointKernel));
|
||||||
DCmd_Register("bpe", WRAP_METHOD(Console, cmdBreakpointExecFunction)); // alias
|
DCmd_Register("bpk", WRAP_METHOD(Console, cmdBreakpointKernel)); // alias
|
||||||
|
DCmd_Register("bp_function", WRAP_METHOD(Console, cmdBreakpointFunction));
|
||||||
|
DCmd_Register("bpe", WRAP_METHOD(Console, cmdBreakpointFunction)); // alias
|
||||||
// VM
|
// VM
|
||||||
DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
|
DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
|
||||||
DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
|
DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
|
||||||
|
@ -384,8 +386,9 @@ bool Console::cmdHelp(int argc, const char **argv) {
|
||||||
DebugPrintf("Breakpoints:\n");
|
DebugPrintf("Breakpoints:\n");
|
||||||
DebugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n");
|
DebugPrintf(" bp_list / bplist / bl - Lists the current breakpoints\n");
|
||||||
DebugPrintf(" bp_del / bpdel / bc - Deletes a breakpoint with the specified index\n");
|
DebugPrintf(" bp_del / bpdel / bc - Deletes a breakpoint with the specified index\n");
|
||||||
DebugPrintf(" bp_exec_method / bpx - Sets a breakpoint on the execution of the specified method\n");
|
DebugPrintf(" bp_method / bpx - Sets a breakpoint on the execution or access of a specified method/selector\n");
|
||||||
DebugPrintf(" bp_exec_function / bpe - Sets a breakpoint on the execution of the specified exported function\n");
|
DebugPrintf(" bp_kernel / bpk - Sets a breakpoint on execution of a kernel function\n");
|
||||||
|
DebugPrintf(" bp_function / bpe - Sets a breakpoint on the execution of the specified exported function\n");
|
||||||
DebugPrintf("\n");
|
DebugPrintf("\n");
|
||||||
DebugPrintf("VM:\n");
|
DebugPrintf("VM:\n");
|
||||||
DebugPrintf(" script_steps - Shows the number of executed SCI operations\n");
|
DebugPrintf(" script_steps - Shows the number of executed SCI operations\n");
|
||||||
|
@ -2716,7 +2719,7 @@ bool Console::cmdLogKernel(int argc, const char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_sci->getKernel()->debugSetFunctionLogging(argv[1], logging))
|
if (g_sci->getKernel()->debugSetFunction(argv[1], logging, -1))
|
||||||
DebugPrintf("Logging %s for k%s\n", logging ? "enabled" : "disabled", argv[1]);
|
DebugPrintf("Logging %s for k%s\n", logging ? "enabled" : "disabled", argv[1]);
|
||||||
else
|
else
|
||||||
DebugPrintf("Unknown kernel function %s\n", argv[1]);
|
DebugPrintf("Unknown kernel function %s\n", argv[1]);
|
||||||
|
@ -2794,10 +2797,10 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Console::cmdBreakpointExecMethod(int argc, const char **argv) {
|
bool Console::cmdBreakpointMethod(int argc, const char **argv) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
DebugPrintf("Sets a breakpoint on the execution of the specified method.\n");
|
DebugPrintf("Sets a breakpoint on execution/access of a specified method/selector.\n");
|
||||||
DebugPrintf("Usage: %s <method name>\n", argv[0]);
|
DebugPrintf("Usage: %s <name>\n", argv[0]);
|
||||||
DebugPrintf("Example: %s ego::doit\n", argv[0]);
|
DebugPrintf("Example: %s ego::doit\n", argv[0]);
|
||||||
DebugPrintf("May also be used to set a breakpoint that applies whenever an object\n");
|
DebugPrintf("May also be used to set a breakpoint that applies whenever an object\n");
|
||||||
DebugPrintf("of a specific type is touched: %s foo::\n", argv[0]);
|
DebugPrintf("of a specific type is touched: %s foo::\n", argv[0]);
|
||||||
|
@ -2817,7 +2820,23 @@ bool Console::cmdBreakpointExecMethod(int argc, const char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Console::cmdBreakpointExecFunction(int argc, const char **argv) {
|
bool Console::cmdBreakpointKernel(int argc, const char **argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
DebugPrintf("Sets a breakpoint on execution of a kernel function.\n");
|
||||||
|
DebugPrintf("Usage: %s <name>\n", argv[0]);
|
||||||
|
DebugPrintf("Example: %s DrawPic\n", argv[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_sci->getKernel()->debugSetFunction(argv[1], -1, true))
|
||||||
|
DebugPrintf("Breakpoint enabled for k%s\n", argv[1]);
|
||||||
|
else
|
||||||
|
DebugPrintf("Unknown kernel function %s\n", argv[1]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Console::cmdBreakpointFunction(int argc, const char **argv) {
|
||||||
// TODO/FIXME: Why does this accept 2 parameters (the high and the low part of the address)?"
|
// TODO/FIXME: Why does this accept 2 parameters (the high and the low part of the address)?"
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
DebugPrintf("Sets a breakpoint on the execution of the specified exported function.\n");
|
DebugPrintf("Sets a breakpoint on the execution of the specified exported function.\n");
|
||||||
|
|
|
@ -134,8 +134,9 @@ private:
|
||||||
// Breakpoints
|
// Breakpoints
|
||||||
bool cmdBreakpointList(int argc, const char **argv);
|
bool cmdBreakpointList(int argc, const char **argv);
|
||||||
bool cmdBreakpointDelete(int argc, const char **argv);
|
bool cmdBreakpointDelete(int argc, const char **argv);
|
||||||
bool cmdBreakpointExecMethod(int argc, const char **argv);
|
bool cmdBreakpointMethod(int argc, const char **argv);
|
||||||
bool cmdBreakpointExecFunction(int argc, const char **argv);
|
bool cmdBreakpointKernel(int argc, const char **argv);
|
||||||
|
bool cmdBreakpointFunction(int argc, const char **argv);
|
||||||
// VM
|
// VM
|
||||||
bool cmdScriptSteps(int argc, const char **argv);
|
bool cmdScriptSteps(int argc, const char **argv);
|
||||||
bool cmdVMVarlist(int argc, const char **argv);
|
bool cmdVMVarlist(int argc, const char **argv);
|
||||||
|
|
|
@ -656,7 +656,7 @@ void Kernel::mapFunctions() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) {
|
bool Kernel::debugSetFunction(const char *kernelName, int logging, int breakpoint) {
|
||||||
if (strcmp(kernelName, "*")) {
|
if (strcmp(kernelName, "*")) {
|
||||||
for (uint id = 0; id < _kernelFuncs.size(); id++) {
|
for (uint id = 0; id < _kernelFuncs.size(); id++) {
|
||||||
if (_kernelFuncs[id].name) {
|
if (_kernelFuncs[id].name) {
|
||||||
|
@ -666,14 +666,21 @@ bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) {
|
||||||
KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions;
|
KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions;
|
||||||
uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount;
|
uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount;
|
||||||
for (uint subId = 0; subId < kernelSubCallCount; subId++) {
|
for (uint subId = 0; subId < kernelSubCallCount; subId++) {
|
||||||
if (kernelSubCall->function)
|
if (kernelSubCall->function) {
|
||||||
kernelSubCall->debugLogging = logging;
|
if (logging != -1)
|
||||||
|
kernelSubCall->debugLogging = logging == 1 ? true : false;
|
||||||
|
if (breakpoint != -1)
|
||||||
|
kernelSubCall->debugBreakpoint = breakpoint == 1 ? true : false;
|
||||||
|
}
|
||||||
kernelSubCall++;
|
kernelSubCall++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// function name matched, set for this one and exit
|
// function name matched, set for this one and exit
|
||||||
_kernelFuncs[id].debugLogging = logging;
|
if (logging != -1)
|
||||||
|
_kernelFuncs[id].debugLogging = logging == 1 ? true : false;
|
||||||
|
if (breakpoint != -1)
|
||||||
|
_kernelFuncs[id].debugBreakpoint = breakpoint == 1 ? true : false;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// main name was not matched
|
// main name was not matched
|
||||||
|
@ -685,7 +692,10 @@ bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) {
|
||||||
if (kernelSubCall->function) {
|
if (kernelSubCall->function) {
|
||||||
if (strcmp(kernelName, kernelSubCall->name) == 0) {
|
if (strcmp(kernelName, kernelSubCall->name) == 0) {
|
||||||
// sub-function name matched, set for this one and exit
|
// sub-function name matched, set for this one and exit
|
||||||
kernelSubCall->debugLogging = logging;
|
if (logging != -1)
|
||||||
|
kernelSubCall->debugLogging = logging == 1 ? true : false;
|
||||||
|
if (breakpoint != -1)
|
||||||
|
kernelSubCall->debugBreakpoint = breakpoint == 1 ? true : false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -702,14 +712,21 @@ bool Kernel::debugSetFunctionLogging(const char *kernelName, bool logging) {
|
||||||
if (_kernelFuncs[id].name) {
|
if (_kernelFuncs[id].name) {
|
||||||
if (!_kernelFuncs[id].subFunctions) {
|
if (!_kernelFuncs[id].subFunctions) {
|
||||||
// No sub-functions, enable actual kernel function
|
// No sub-functions, enable actual kernel function
|
||||||
_kernelFuncs[id].debugLogging = logging;
|
if (logging != -1)
|
||||||
|
_kernelFuncs[id].debugLogging = logging == 1 ? true : false;
|
||||||
|
if (breakpoint != -1)
|
||||||
|
_kernelFuncs[id].debugBreakpoint = breakpoint == 1 ? true : false;
|
||||||
} else {
|
} else {
|
||||||
// Sub-Functions available, enable those too
|
// Sub-Functions available, enable those too
|
||||||
KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions;
|
KernelSubFunction *kernelSubCall = _kernelFuncs[id].subFunctions;
|
||||||
uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount;
|
uint kernelSubCallCount = _kernelFuncs[id].subFunctionCount;
|
||||||
for (uint subId = 0; subId < kernelSubCallCount; subId++) {
|
for (uint subId = 0; subId < kernelSubCallCount; subId++) {
|
||||||
if (kernelSubCall->function)
|
if (kernelSubCall->function) {
|
||||||
kernelSubCall->debugLogging = logging;
|
if (logging != -1)
|
||||||
|
kernelSubCall->debugLogging = logging == 1 ? true : false;
|
||||||
|
if (breakpoint != -1)
|
||||||
|
kernelSubCall->debugBreakpoint = breakpoint == 1 ? true : false;
|
||||||
|
}
|
||||||
kernelSubCall++;
|
kernelSubCall++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ struct KernelSubFunction {
|
||||||
uint16 *signature;
|
uint16 *signature;
|
||||||
const SciWorkaroundEntry *workarounds;
|
const SciWorkaroundEntry *workarounds;
|
||||||
bool debugLogging;
|
bool debugLogging;
|
||||||
|
bool debugBreakpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct KernelFunction {
|
struct KernelFunction {
|
||||||
|
@ -137,6 +138,7 @@ struct KernelFunction {
|
||||||
KernelSubFunction *subFunctions;
|
KernelSubFunction *subFunctions;
|
||||||
uint16 subFunctionCount;
|
uint16 subFunctionCount;
|
||||||
bool debugLogging;
|
bool debugLogging;
|
||||||
|
bool debugBreakpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Kernel {
|
class Kernel {
|
||||||
|
@ -218,9 +220,9 @@ public:
|
||||||
void loadKernelNames(GameFeatures *features);
|
void loadKernelNames(GameFeatures *features);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets debugCalls flag for a kernel function
|
* Sets debug flags for a kernel function
|
||||||
*/
|
*/
|
||||||
bool debugSetFunctionLogging(const char *kernelName, bool debugCalls);
|
bool debugSetFunction(const char *kernelName, int logging, int breakpoint);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -743,6 +743,11 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
|
||||||
|
|
||||||
if (kernelCall.debugLogging)
|
if (kernelCall.debugLogging)
|
||||||
logKernelCall(&kernelCall, NULL, s, argc, argv, s->r_acc);
|
logKernelCall(&kernelCall, NULL, s, argc, argv, s->r_acc);
|
||||||
|
if (kernelCall.debugBreakpoint) {
|
||||||
|
printf("Break on k%s\n", kernelCall.name);
|
||||||
|
g_sci->_debugState.debugging = true;
|
||||||
|
g_sci->_debugState.breakpointWasHit = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Sub-functions available, check signature and call that one directly
|
// Sub-functions available, check signature and call that one directly
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
|
@ -793,6 +798,11 @@ static void callKernelFunc(EngineState *s, int kernelCallNr, int argc) {
|
||||||
|
|
||||||
if (kernelSubCall.debugLogging)
|
if (kernelSubCall.debugLogging)
|
||||||
logKernelCall(&kernelCall, &kernelSubCall, s, argc, argv, s->r_acc);
|
logKernelCall(&kernelCall, &kernelSubCall, s, argc, argv, s->r_acc);
|
||||||
|
if (kernelSubCall.debugBreakpoint) {
|
||||||
|
printf("Break on k%s\n", kernelSubCall.name);
|
||||||
|
g_sci->_debugState.debugging = true;
|
||||||
|
g_sci->_debugState.breakpointWasHit = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove callk stack frame again, if there's still an execution stack
|
// Remove callk stack frame again, if there's still an execution stack
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue