Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Fix for GDB sparse register MI format

Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.debug.mi.core/ChangeLog,v
retrieving revision 1.162
diff -u -r1.162 ChangeLog
--- ChangeLog	19 Aug 2003 02:02:13 -0000	1.162
+++ ChangeLog	19 Aug 2003 02:37:14 -0000
@@ -1,5 +1,29 @@
 2003-08-18 Alain Magloire
 
+	Patch from Chris Songer, excerpt from the email.
+	Using the phrase "To ensure consistency between a register name and its
+	number, the output list may include empty register names," the MI protocol
+	appears to allow gdb to return a "sparse" array of registers by giving a 0
+	length name in response to the -data-list-register-names-command. CDT 1.0.1
+	does not handle this especially well and subsequently exposes a bug in GDB
+	5.1.3 and crashes it if the debugger has more than 3  register names of 0
+	length.
+	
+	example:
+
+	8-data-list-register-names
+	(gdb)                                                                                                                          
+	8^done,register-names=["ar0","ar1",... ,"","","","","","","ur0",\
+	"ur1","ur2","ur3","ur4","ur5","ur6","ur7","","" ..]
+	
+
+	* src/org/eclipse/cdt/debug/mi/core/output/MIDataListRegisterNamesInfo.java:
+	New method getNumRealNames().
+	* src/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java:
+	Check if the register name is not empty.
+	
+2003-08-18 Alain Magloire
+
 	From the manual:
 	By default GDB will automatically keep track of objects as they are
 	loaded and unloaded by the dynamic linker.  By using the command `set
Index: src/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java,v
retrieving revision 1.14
diff -u -r1.14 RegisterManager.java
--- src/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java	6 Aug 2003 19:52:27 -0000	1.14
+++ src/org/eclipse/cdt/debug/mi/core/cdi/RegisterManager.java	19 Aug 2003 02:37:14 -0000
@@ -62,11 +62,13 @@
 				throw new CDIException("No answer");
 			}
 			String[] names = info.getRegisterNames();
-			RegisterObject[] regs = new RegisterObject[names.length];
+			List regsList = new ArrayList(names.length);
 			for (int i = 0; i < names.length; i++) {
-				regs[i] = new RegisterObject(session.getCurrentTarget(), names[i], i);
+				if (names[i].length() > 0) {
+					regsList.add(new RegisterObject(session.getCurrentTarget(), names[i], i));
+				}
 			}
-			return regs;
+			return (ICDIRegisterObject[])regsList.toArray(new ICDIRegisterObject[0]);
 		} catch (MIException e) {
 			throw new MI2CDIException(e);
 		}
Index: src/org/eclipse/cdt/debug/mi/core/output/MIDataListRegisterNamesInfo.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/output/MIDataListRegisterNamesInfo.java,v
retrieving revision 1.4
diff -u -r1.4 MIDataListRegisterNamesInfo.java
--- src/org/eclipse/cdt/debug/mi/core/output/MIDataListRegisterNamesInfo.java	28 Aug 2002 01:43:12 -0000	1.4
+++ src/org/eclipse/cdt/debug/mi/core/output/MIDataListRegisterNamesInfo.java	19 Aug 2003 02:37:14 -0000
@@ -14,12 +14,18 @@
 public class MIDataListRegisterNamesInfo extends MIInfo {
 
 	String[] names;
+	protected int realNameCount = 0;
 
 	public MIDataListRegisterNamesInfo(MIOutput rr) {
 		super(rr);
 	}
 
-	public String[] getRegisterNames () {
+	/**
+	 * @return the list of register names. This list can include 0 length
+	 * strings in the case where the underlying GDB has a sparse set of 
+	 * registers. They are returned as 0 length strings 
+	 */
+	public String[] getRegisterNames() {
 		if (names == null) {
 			parse();
 		}
@@ -32,30 +38,47 @@
 			MIOutput out = getMIOutput();
 			MIResultRecord rr = out.getMIResultRecord();
 			if (rr != null) {
-				MIResult[] results =  rr.getMIResults();
+				MIResult[] results = rr.getMIResults();
 				for (int i = 0; i < results.length; i++) {
 					String var = results[i].getVariable();
 					if (var.equals("register-names")) {
 						MIValue value = results[i].getMIValue();
 						if (value instanceof MIList) {
-							parseRegisters((MIList)value, aList);
+							parseRegisters((MIList) value, aList);
 						}
 					}
 				}
 			}
 		}
-		names = (String[])aList.toArray(new String[aList.size()]);
+		names = (String[]) aList.toArray(new String[aList.size()]);
 	}
 
 	void parseRegisters(MIList list, List aList) {
 		MIValue[] values = list.getMIValues();
 		for (int i = 0; i < values.length; i++) {
 			if (values[i] instanceof MIConst) {
-				String str = ((MIConst)values[i]).getCString();
+				String str = ((MIConst) values[i]).getCString();
+
+				/* this cannot filter nulls because index is critical in retreival 
+				 * and index is assigned in the layers above. The MI spec allows 
+				 * empty returns, for some register names. */
 				if (str != null && str.length() > 0) {
+					realNameCount++;
 					aList.add(str);
+				} else {
+					aList.add("");
 				}
 			}
 		}
+	}
+
+	/**
+	 * @return the number of non-null and non-empty names in the 
+	 * register list
+	 */
+	public int getNumRealNames() {
+		if (names == null)
+			parse();
+		return realNameCount;
 	}
 }



Back to the top