[Scummvm-cvs-logs] SF.net SVN: scummvm:[52490] scummvm/trunk/engines/sci

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Thu Sep 2 11:05:08 CEST 2010


Revision: 52490
          http://scummvm.svn.sourceforge.net/scummvm/?rev=52490&view=rev
Author:   m_kiewitz
Date:     2010-09-02 09:05:08 +0000 (Thu, 02 Sep 2010)

Log Message:
-----------
SCI: adding "bpr" and "bpw" debug commands

"bpr" breakpoint on reading of selectors
"bpw" breakpoint of writing of selectors
"bpx" is now breakpoint on executing of selectors only

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/console.h
    scummvm/trunk/engines/sci/debug.h
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/sci.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2010-09-02 05:12:07 UTC (rev 52489)
+++ scummvm/trunk/engines/sci/console.cpp	2010-09-02 09:05:08 UTC (rev 52490)
@@ -178,6 +178,10 @@
 	DCmd_Register("bc",					WRAP_METHOD(Console, cmdBreakpointDelete));			// alias
 	DCmd_Register("bp_method",			WRAP_METHOD(Console, cmdBreakpointMethod));
 	DCmd_Register("bpx",				WRAP_METHOD(Console, cmdBreakpointMethod));			// alias
+	DCmd_Register("bp_read",			WRAP_METHOD(Console, cmdBreakpointRead));
+	DCmd_Register("bpr",				WRAP_METHOD(Console, cmdBreakpointRead));			// alias
+	DCmd_Register("bp_write",			WRAP_METHOD(Console, cmdBreakpointWrite));
+	DCmd_Register("bpw",				WRAP_METHOD(Console, cmdBreakpointWrite));			// alias
 	DCmd_Register("bp_kernel",			WRAP_METHOD(Console, cmdBreakpointKernel));
 	DCmd_Register("bpk",				WRAP_METHOD(Console, cmdBreakpointKernel));			// alias
 	DCmd_Register("bp_function",		WRAP_METHOD(Console, cmdBreakpointFunction));
@@ -389,7 +393,9 @@
 	DebugPrintf("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_method / bpx - Sets a breakpoint on the execution or access of a specified method/selector\n");
+	DebugPrintf(" bp_method / bpx - Sets a breakpoint on the execution of a specified method/selector\n");
+	DebugPrintf(" bp_read / bpr - Sets a breakpoint on reading of a specified selector\n");
+	DebugPrintf(" bp_write / bpw - Sets a breakpoint on writing to a specified selector\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");
@@ -2741,9 +2747,15 @@
 	for (; bp != end; ++bp) {
 		DebugPrintf("  #%i: ", i);
 		switch (bp->type) {
-		case BREAK_SELECTOR:
+		case BREAK_SELECTOREXEC:
 			DebugPrintf("Execute %s\n", bp->name.c_str());
 			break;
+		case BREAK_SELECTORREAD:
+			DebugPrintf("Read %s\n", bp->name.c_str());
+			break;
+		case BREAK_SELECTORWRITE:
+			DebugPrintf("Write %s\n", bp->name.c_str());
+			break;
 		case BREAK_EXPORT:
 			bpdata = bp->address;
 			DebugPrintf("Execute script %d, export %d\n", bpdata >> 16, bpdata & 0xFFFF);
@@ -2803,7 +2815,7 @@
 
 bool Console::cmdBreakpointMethod(int argc, const char **argv) {
 	if (argc != 2) {
-		DebugPrintf("Sets a breakpoint on execution/access of a specified method/selector.\n");
+		DebugPrintf("Sets a breakpoint on execution of a specified method/selector.\n");
 		DebugPrintf("Usage: %s <name>\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");
@@ -2815,15 +2827,48 @@
 	   Thus, we can't check whether the command argument is a valid method name.
 	   A breakpoint set on an invalid method name will just never trigger. */
 	Breakpoint bp;
-	bp.type = BREAK_SELECTOR;
+	bp.type = BREAK_SELECTOREXEC;
 	bp.name = argv[1];
 
 	_debugState._breakpoints.push_back(bp);
-	_debugState._activeBreakpointTypes |= BREAK_SELECTOR;
+	_debugState._activeBreakpointTypes |= BREAK_SELECTOREXEC;
+	return true;
+}
 
+bool Console::cmdBreakpointRead(int argc, const char **argv) {
+	if (argc != 2) {
+		DebugPrintf("Sets a breakpoint on reading of a specified selector.\n");
+		DebugPrintf("Usage: %s <name>\n", argv[0]);
+		DebugPrintf("Example: %s ego::view\n", argv[0]);
+		return true;
+	}
+
+	Breakpoint bp;
+	bp.type = BREAK_SELECTORREAD;
+	bp.name = argv[1];
+
+	_debugState._breakpoints.push_back(bp);
+	_debugState._activeBreakpointTypes |= BREAK_SELECTORREAD;
 	return true;
 }
 
+bool Console::cmdBreakpointWrite(int argc, const char **argv) {
+	if (argc != 2) {
+		DebugPrintf("Sets a breakpoint on writing of a specified selector.\n");
+		DebugPrintf("Usage: %s <name>\n", argv[0]);
+		DebugPrintf("Example: %s ego::view\n", argv[0]);
+		return true;
+	}
+
+	Breakpoint bp;
+	bp.type = BREAK_SELECTORWRITE;
+	bp.name = argv[1];
+
+	_debugState._breakpoints.push_back(bp);
+	_debugState._activeBreakpointTypes |= BREAK_SELECTORWRITE;
+	return true;
+}
+
 bool Console::cmdBreakpointKernel(int argc, const char **argv) {
 	if (argc != 2) {
 		DebugPrintf("Sets a breakpoint on execution of a kernel function.\n");

Modified: scummvm/trunk/engines/sci/console.h
===================================================================
--- scummvm/trunk/engines/sci/console.h	2010-09-02 05:12:07 UTC (rev 52489)
+++ scummvm/trunk/engines/sci/console.h	2010-09-02 09:05:08 UTC (rev 52490)
@@ -135,6 +135,8 @@
 	bool cmdBreakpointList(int argc, const char **argv);
 	bool cmdBreakpointDelete(int argc, const char **argv);
 	bool cmdBreakpointMethod(int argc, const char **argv);
+	bool cmdBreakpointRead(int argc, const char **argv);
+	bool cmdBreakpointWrite(int argc, const char **argv);
 	bool cmdBreakpointKernel(int argc, const char **argv);
 	bool cmdBreakpointFunction(int argc, const char **argv);
 	// VM

Modified: scummvm/trunk/engines/sci/debug.h
===================================================================
--- scummvm/trunk/engines/sci/debug.h	2010-09-02 05:12:07 UTC (rev 52489)
+++ scummvm/trunk/engines/sci/debug.h	2010-09-02 09:05:08 UTC (rev 52490)
@@ -37,13 +37,15 @@
 	 * Break when selector is executed. data contains (char *) selector name
 	 * (in the format Object::Method)
 	 */
-	BREAK_SELECTOR = 1,
+	BREAK_SELECTOREXEC = 1 << 0, // break when selector gets executed
+	BREAK_SELECTORREAD = 1 << 1, // break when selector gets executed
+	BREAK_SELECTORWRITE = 1 << 2, // break when selector gets executed
 
 	/**
 	 * Break when an exported function is called. data contains
 	 * script_no << 16 | export_no.
 	 */
-	BREAK_EXPORT = 2
+	BREAK_EXPORT = 1 << 3
 };
 
 struct Breakpoint {

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2010-09-02 05:12:07 UTC (rev 52489)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-09-02 09:05:08 UTC (rev 52490)
@@ -366,27 +366,24 @@
 	int type; /**< Same as ExecStack.type */
 };
 
-bool SciEngine::checkSelectorBreakpoint(reg_t send_obj, int selector) {
-	if (_debugState._activeBreakpointTypes & BREAK_SELECTOR) {
-		char method_name[256];
+bool SciEngine::checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector) {
+	char method_name[256];
 
-		sprintf(method_name, "%s::%s", _gamestate->_segMan->getObjectName(send_obj), getKernel()->getSelectorName(selector).c_str());
+	sprintf(method_name, "%s::%s", _gamestate->_segMan->getObjectName(send_obj), getKernel()->getSelectorName(selector).c_str());
 
-		Common::List<Breakpoint>::const_iterator bp;
-		for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
-			int cmplen = bp->name.size();
-			if (bp->name.lastChar() != ':')
-				cmplen = 256;
+	Common::List<Breakpoint>::const_iterator bp;
+	for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
+		int cmplen = bp->name.size();
+		if (bp->name.lastChar() != ':')
+			cmplen = 256;
 
-			if (bp->type == BREAK_SELECTOR && !strncmp(bp->name.c_str(), method_name, cmplen)) {
-				_console->DebugPrintf("Break on %s (in [%04x:%04x])\n", method_name, PRINT_REG(send_obj));
-				_debugState.debugging = true;
-				_debugState.breakpointWasHit = true;
-				return true;
-			}
+		if (bp->type == breakpointType && !strncmp(bp->name.c_str(), method_name, cmplen)) {
+			_console->DebugPrintf("Break on %s (in [%04x:%04x])\n", method_name, PRINT_REG(send_obj));
+			_debugState.debugging = true;
+			_debugState.breakpointWasHit = true;
+			return true;
 		}
 	}
-
 	return false;
 }
 
@@ -399,12 +396,13 @@
 	int selector;
 	int argc;
 	int origin = s->_executionStack.size()-1; // Origin: Used for debugging
-	bool printSendActions = false;
 	// We return a pointer to the new active ExecStack
 
 	// The selector calls we catch are stored below:
 	Common::Stack<CallsStruct> sendCalls;
 
+	int activeBreakpointTypes = g_sci->_debugState._activeBreakpointTypes;
+
 	while (framesize > 0) {
 		selector = validate_arithmetic(*argp++);
 		argc = validate_arithmetic(*argp);
@@ -413,9 +411,6 @@
 			error("send_selector(): More than 0x800 arguments to function call");
 		}
 
-		// Check if a breakpoint is set on this method
-		printSendActions = g_sci->checkSelectorBreakpoint(send_obj, selector);
-
 #ifdef VM_DEBUG_SEND
 		printf("Send to %04x:%04x (%s), selector %04x (%s):", PRINT_REG(send_obj), 
 			s->_segMan->getObjectName(send_obj), selector, 
@@ -439,20 +434,25 @@
 
 			// argc == 0: read selector
 			// argc != 0: write selector
-			if (printSendActions && !argc) {	// read selector
-				debug("[read selector]\n");
-				printSendActions = false;
+			if (!argc) {
+				// read selector
+				if (activeBreakpointTypes & BREAK_SELECTORREAD) {
+					if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORREAD, send_obj, selector))
+						debug("[read selector]\n");
+				}
+			} else {
+				// write selector
+				if (activeBreakpointTypes & BREAK_SELECTORWRITE) {
+					if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORWRITE, send_obj, selector)) {
+						reg_t oldReg = *varp.getPointer(s->_segMan);
+						reg_t newReg = argp[1];
+						warning("[write to selector (%s:%s): change %04x:%04x to %04x:%04x]\n", 
+							s->_segMan->getObjectName(send_obj), g_sci->getKernel()->getSelectorName(selector).c_str(), 
+							PRINT_REG(oldReg), PRINT_REG(newReg));
+					}
+				}
 			}
 
-			if (printSendActions && argc) {
-				reg_t oldReg = *varp.getPointer(s->_segMan);
-				reg_t newReg = argp[1];
-				warning("[write to selector (%s:%s): change %04x:%04x to %04x:%04x]\n", 
-					s->_segMan->getObjectName(send_obj), g_sci->getKernel()->getSelectorName(selector).c_str(), 
-					PRINT_REG(oldReg), PRINT_REG(newReg));
-				printSendActions = false;
-			}
-
 			if (argc > 1) {
 				// argc can indeed be bigger than 1 in some cases, and it's usually the
 				// result of a script bug. Usually these aren't fatal.
@@ -483,6 +483,8 @@
 		case kSelectorMethod:
 
 #ifdef VM_DEBUG_SEND
+			if (_debugState._activeBreakpointTypes & BREAK_SELECTOREXEC)
+				g_sci->checkSelectorBreakpoint(BREAK_SELECTOREXEC, send_obj, selector);
 			printf("Funcselector(");
 			for (int i = 0; i < argc; i++) {
 				printf("%04x:%04x", PRINT_REG(argp[i+1]));
@@ -491,30 +493,32 @@
 			}
 			printf(") at %04x:%04x\n", PRINT_REG(funcp));
 #endif // VM_DEBUG_SEND
-			if (printSendActions) {
-				printf("[invoke selector]");
 #ifndef VM_DEBUG_SEND
-				int displaySize = 0;
-				for (int argNr = 1; argNr <= argc; argNr++) {
-					if (argNr == 1)
-						printf(" - ");
-					reg_t curParam = argp[argNr];
-					if (curParam.segment) {
-						printf("[%04x:%04x] ", PRINT_REG(curParam));
-						displaySize += 12;
-					} else {
-						printf("[%04x] ", curParam.offset);
-						displaySize += 7;
+			if (activeBreakpointTypes & BREAK_SELECTOREXEC) {
+				if (g_sci->checkSelectorBreakpoint(BREAK_SELECTOREXEC, send_obj, selector)) {
+					printf("[execute selector]");
+
+					int displaySize = 0;
+					for (int argNr = 1; argNr <= argc; argNr++) {
+						if (argNr == 1)
+							printf(" - ");
+						reg_t curParam = argp[argNr];
+						if (curParam.segment) {
+							printf("[%04x:%04x] ", PRINT_REG(curParam));
+							displaySize += 12;
+						} else {
+							printf("[%04x] ", curParam.offset);
+							displaySize += 7;
+						}
+						if (displaySize > 50) {
+							if (argNr < argc)
+								printf("...");
+							break;
+						}
 					}
-					if (displaySize > 50) {
-						if (argNr < argc)
-							printf("...");
-						break;
-					}
 				}
 #endif
 				printf("\n");
-				printSendActions = false;
 			}
 
 			{

Modified: scummvm/trunk/engines/sci/sci.h
===================================================================
--- scummvm/trunk/engines/sci/sci.h	2010-09-02 05:12:07 UTC (rev 52489)
+++ scummvm/trunk/engines/sci/sci.h	2010-09-02 09:05:08 UTC (rev 52490)
@@ -260,7 +260,7 @@
 
 	void scriptDebug();
 	bool checkExportBreakpoint(uint16 script, uint16 pubfunct);
-	bool checkSelectorBreakpoint(reg_t send_obj, int selector);
+	bool checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector);
 
 	void patchGameSaveRestore(SegManager *segMan);
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list