Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Debug timeout and cleanup patch.

There are a number of problems we have when launching applications
which have a lot of symbols.  Often times if during that launch
period (since we provide the executable on the command line to gdb
and gdb will slurp up the symbol information automatically) if your
timeout value is too low, then we will throw and exception and kill
the session.  This is bad for a couple of reasons:

1- We should be able to do some sort of intelligent heuristic when
   it comes to scaling these types of things.

This is a prototype of a "general fix" which looks at the executable
size to generate an approximated timeout and then compares the session 
timeout with that size.  If the approximated timeout is greater than
the user defined session timeout it will set the session timeout to
a longer value.

2- Even when things go wrong, we should make sure that we clean up
   properly after ourselves ... and if there is no session created,
   this means cleaning up the gdb process we created.

This fix catches errors in the session creation and kills off the
process before re-throwing the exception.

Thanks,
 Thomas

Index: src/org/eclipse/cdt/debug/mi/core/MIPlugin.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIPlugin.java,v
retrieving revision 1.41
diff -u -r1.41 MIPlugin.java
--- src/org/eclipse/cdt/debug/mi/core/MIPlugin.java	10 Jul 2003 19:25:10 -0000	1.41
+++ src/org/eclipse/cdt/debug/mi/core/MIPlugin.java	22 Sep 2003 14:46:18 -0000
@@ -176,6 +176,7 @@
 		}
 		Process pgdb = ProcessFactory.getFactory().exec(args);
 		MISession session = createMISession(pgdb, null, MISession.CORE);
+		
 		return new Session(session);
 	}
 
@@ -202,27 +203,59 @@
 			args = new String[] {gdb, "--cd="+cwd.getAbsolutePath(), "--command="+gdbinit, "--quiet", "-nw", "-i", "mi1", program.getAbsolutePath()};
 		}
 		Process pgdb = ProcessFactory.getFactory().exec(args);
-		MISession session = createMISession(pgdb, null, MISession.ATTACH);
-		CommandFactory factory = session.getCommandFactory();
-		if (targetParams != null && targetParams.length > 0) {
-			MITargetSelect target = factory.createMITargetSelect(targetParams);
-			session.postCommand(target);
-			MIInfo info = target.getMIInfo();
-			if (info == null) {
-				throw new MIException("No answer");
+		
+		//Allow at least one second per megabyte as a minimum on the timeout
+		//(note one second is an arbitrary choice based on swapping performance).
+		//This is required for loading the symbols from very large programs.
+		Preferences prefs = plugin.getPluginPreferences();
+		int timeout = prefs.getInt(IMIConstants.PREF_REQUEST_TIMEOUT); //milliseconds
+		if(program != null) {
+			long programSize = program.length();
+			int minimumTimeout = (int)(programSize / 1000L);
+
+			if(timeout < minimumTimeout) {
+				//TODO: Remove diagnostic message and replace with some sort of user status
+				System.out.println("Adjusting timeout from " + timeout + "ms to " + minimumTimeout + "ms");
+				timeout = minimumTimeout;			
 			}
 		}
-		if (pid > 0) {
-			MITargetAttach attach = factory.createMITargetAttach(pid);
-			session.postCommand(attach);
-			MIInfo info = attach.getMIInfo();
-			if (info == null) {
-				throw new MIException("No answer");
+
+		//If anything goes wrong during this time we need to destroy the process
+		//since if the session isn't around there isn't anything to reap it.		
+		MISession session = null; 
+		try {
+			session = createMISession(pgdb, null, timeout, MISession.ATTACH);
+		} catch(MIException ex){
+			pgdb.destroy();
+			throw ex;
+		}
+		
+		try {	
+			CommandFactory factory = session.getCommandFactory();
+			if (targetParams != null && targetParams.length > 0) {
+				MITargetSelect target = factory.createMITargetSelect(targetParams);
+				session.postCommand(target);
+				MIInfo info = target.getMIInfo();
+				if (info == null) {
+					throw new MIException("No answer");
+				}
 			}
+			if (pid > 0) {
+				MITargetAttach attach = factory.createMITargetAttach(pid);
+				session.postCommand(attach);
+				MIInfo info = attach.getMIInfo();
+				if (info == null) {
+					throw new MIException("No answer");
+				}
+			}
+			//@@@ We have to manually set the suspended state when we attach
+			session.getMIInferior().setSuspended();
+			session.getMIInferior().update();
+		} catch(MIException ex) {
+			session.terminate();			
+			throw ex;
 		}
-		//@@@ We have to manually set the suspended state when we attach
-		session.getMIInferior().setSuspended();
-		session.getMIInferior().update();
+
 		return new Session(session, true);
 	}
 

Back to the top