/// <summary> /// Attach the debug engine to a program. (http://msdn.microsoft.com/en-us/library/bb145136.aspx) /// </summary> /// <param name="rgpPrograms"> Represent programs to be attached to. These are port programs. </param> /// <param name="rgpProgramNodes"> Represent program nodes, one for each program. The program nodes in this array represent /// the same programs as in pProgram. The program nodes are given so that the DE can identify the programs to attach to. </param> /// <param name="aCeltPrograms"> Number of programs and/or program nodes in the pProgram and rgpProgramNodes arrays. </param> /// <param name="ad7Callback"> The IDebugEventCallback2 object to be used to send debug events to the SDM. </param> /// <param name="dwReason"> A value from the ATTACH_REASON enumeration that specifies the reason for attaching these programs. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason) { if (aCeltPrograms != 1) { System.Diagnostics.Debug.Fail("VSNDK Debugger only supports one debug target at a time."); throw new ArgumentException(); } try { EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out m_programGUID)); m_program = rgpPrograms[0]; // It is NULL when the user attached the debugger to a running process (by using Attach to Process UI). When that // happens, some objects must be instantiated, as well as GDB must be launched. Those ones are instantiated/launched // by LaunchSuspended and ResumeProcess methods when debugging an open project. if (this.m_engineCallback == null) { VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = true; m_engineCallback = new EngineCallback(this, ad7Callback); AD7ProgramNodeAttach pnt = (AD7ProgramNodeAttach)m_program; m_process = pnt.m_process; AD7Port port = pnt.m_process._portAttach; string publicKeyPath = Environment.GetEnvironmentVariable("AppData") + @"\BlackBerry\bbt_id_rsa.pub"; string progName = pnt.m_programName.Substring(pnt.m_programName.LastIndexOf('/') + 1); string exePath = ""; string processesPaths = ""; System.IO.StreamReader readProcessesPathsFile = null; // Read the file ProcessesPath.txt to try to get the file location of the executable file. try { readProcessesPathsFile = new System.IO.StreamReader(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Research In Motion\ProcessesPath.txt"); processesPaths = readProcessesPathsFile.ReadToEnd(); readProcessesPathsFile.Close(); } catch (Exception e) { processesPaths = ""; } string searchProgName = progName + "_" + port.m_isSimulator; int begin = processesPaths.IndexOf(searchProgName + ":>"); if (begin != -1) { begin += searchProgName.Length + 2; int end = processesPaths.IndexOf("\r\n", begin); exePath = processesPaths.Substring(begin, end - begin) + progName; } else { exePath = "CannotAttachToRunningProcess"; } exePath = exePath.Replace("\\", "\\\\\\\\"); if (GDBParser.LaunchProcess(pnt.m_programID, exePath, port.m_IP, port.m_isSimulator, port.m_toolsPath, publicKeyPath, port.m_password)) { if (exePath == "CannotAttachToRunningProcess") { MessageBox.Show(progName + " is attached to the debugger. However, to be able to debug your application, you must build and deploy it from this computer first.", "No executable file with symbols found.", MessageBoxButtons.OK, MessageBoxIcon.Warning); } m_eventDispatcher = new EventDispatcher(this); m_module = new AD7Module(); m_progNode = new AD7ProgramNode(m_process._processGUID, m_process._processID, exePath, new Guid(AD7Engine.Id)); AddThreadsToProgram(); } else { GDBParser.exitGDB(); VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = false; return VSConstants.E_FAIL; } } AD7EngineCreateEvent.Send(this); AD7ProgramCreateEvent.Send(this); AD7ModuleLoadEvent.Send(this, m_module, true); AD7LoadCompleteEvent.Send(this, currentThread()); // If the reason for attaching is ATTACH_REASON_LAUNCH, the DE needs to send the IDebugEntryPointEvent2 event. // See http://msdn.microsoft.com/en-us/library/bb145136%28v=vs.100%29.aspx if (dwReason == enum_ATTACH_REASON.ATTACH_REASON_LAUNCH) { AD7EntryPointEvent ad7Event = new AD7EntryPointEvent(); Guid riidEvent = new Guid(AD7EntryPointEvent.IID); uint attributes = (uint)enum_EVENTATTRIBUTES.EVENT_STOPPING | (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS; int rc = ad7Callback.Event(this, null, m_program, currentThread(), ad7Event, ref riidEvent, attributes); Debug.Assert(rc == VSConstants.S_OK); } } catch (Exception e) { return EngineUtils.UnexpectedException(e); } return VSConstants.S_OK; }
/// <summary> /// Called by the SDM to indicate that a synchronous debug event, previously sent by the DE to the SDM, /// was received and processed. The only event the VSNDK Debug Engine sends in this fashion is Program Destroy. /// It responds to that event by shutting down the engine. (http://msdn.microsoft.com/en-us/library/bb160915.aspx) /// </summary> /// <param name="eventObject"> Represents the previously sent synchronous event from which the debugger should now continue. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 eventObject) { try { if (eventObject is AD7ProgramDestroyEvent) { resetStackFrames(); m_process.Detach(); m_process = null; m_program.Detach(); m_program = null; m_engineCallback = null; m_breakpointManager = null; m_docContext = null; m_eventDispatcher = null; m_module = null; m_progNode = null; m_programGUID = Guid.Empty; m_threads = null; GC.Collect(); } else { Debug.Fail("Unknown synchronous event"); } } catch (Exception e) { return EngineUtils.UnexpectedException(e); } if (m_eventDispatcher != null) m_eventDispatcher.continueExecution(); return VSConstants.S_OK; }
/// <summary> /// Constructor. /// </summary> /// <param name="exp"> The expression to be evaluated. </param> /// <param name="frame"> Current stack frame. </param> /// <param name="dispatcher"> Represents the class that manages debug events for the debug engine. </param> public AD7Expression(string exp, AD7StackFrame frame, EventDispatcher dispatcher) { this.exp = exp; this.m_eventDispatcher = dispatcher; this.m_frame = frame; }
/// <summary> /// Launches a process by means of the debug engine. (http://msdn.microsoft.com/en-us/library/bb146223.aspx) /// </summary> /// <param name="pszServer"> The name of the machine in which to launch the process. Use a null value to specify the local /// machine. Or it should be the name of the server? </param> /// <param name="port"> The IDebugPort2 interface representing the port that the program will run in. </param> /// <param name="exe"> The name of the executable to be launched. </param> /// <param name="args"> The arguments to pass to the executable. May be a null value if there are no arguments. </param> /// <param name="dir"> The name of the working directory used by the executable. May be a null value if no working directory is /// required. </param> /// <param name="env"> Environment block of NULL-terminated strings, followed by an additional NULL terminator. </param> /// <param name="options"> The options for the executable. </param> /// <param name="launchFlags"> Specifies the LAUNCH_FLAGS for a session. </param> /// <param name="hStdInput"> Handle to an alternate input stream. May be 0 if redirection is not required. </param> /// <param name="hStdOutput"> Handle to an alternate output stream. May be 0 if redirection is not required. </param> /// <param name="hStdError"> Handle to an alternate error output stream. May be 0 if redirection is not required. </param> /// <param name="ad7Callback"> The IDebugEventCallback2 object that receives debugger events. </param> /// <param name="process"> Returns the resulting IDebugProcess2 object that represents the launched process. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process) { Debug.Assert(m_programGUID == Guid.Empty); process = null; try { VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = true; m_engineCallback = new EngineCallback(this, ad7Callback); // Read arguments back from the args string var nvc = new NameValueCollection(); NameValueCollectionHelper.LoadFromString(nvc, args); string pid = nvc.GetValues("pid")[0]; string exePath = exe; string targetIP = nvc.GetValues("targetIP")[0]; bool isSimulator = Convert.ToBoolean(nvc.GetValues("isSimulator")[0]); string toolsPath = nvc.GetValues("ToolsPath")[0]; string publicKeyPath = nvc.GetValues("PublicKeyPath")[0]; string password = null; string[] passwordArray = nvc.GetValues("Password"); if (passwordArray != null) password = passwordArray[0]; if (GDBParser.LaunchProcess(pid, exePath, targetIP, isSimulator, toolsPath, publicKeyPath, password)) { process = m_process = new AD7Process(this, port); m_eventDispatcher = new EventDispatcher(this); m_programGUID = m_process._processGUID; m_module = new AD7Module(); // m_progNode = new AD7ProgramNode(m_process.PhysID, pid, exePath, new Guid(AD7Engine.Id)); m_progNode = new AD7ProgramNode(m_process._processGUID, pid, exePath, new Guid(AD7Engine.Id)); AddThreadsToProgram(); AD7EngineCreateEvent.Send(this); return VSConstants.S_OK; } else { GDBParser.exitGDB(); VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = false; return VSConstants.E_FAIL; } } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
public static VariableInfo create(string name, string type, string value, EventDispatcher dispatcher) { VariableInfo newVar = new VariableInfo(name, type, "", value, dispatcher, null, null); return newVar; }
public static VariableInfo get(string name, EventDispatcher m_eventDispatcher, AD7StackFrame m_frame) { VariableInfo vi = null; string search = ""; string separator = ""; bool isArray = false; bool isRoot = true; do { int dot = name.IndexOf("."); int squareBracket = name.IndexOf("["); int pos = name.IndexOf("->"); if (dot == -1) dot = name.Length; if (squareBracket == -1) squareBracket = name.Length; if (pos == -1) pos = name.Length; int stop = dot < squareBracket ? dot : squareBracket; stop = stop < pos ? stop : pos; search = search + separator + name.Substring(0, stop); separator = ""; if (stop < name.Length) { separator = name.Substring(stop, 1); if (separator == "-") { separator = "->"; name = name.Substring(stop + 2, name.Length - (stop + 2)); } else if (separator == "[") { int aux = name.IndexOf("]"); isArray = true; separator = name.Substring(stop, (aux - stop) + 1); name = name.Substring(aux + 1, name.Length - (aux + 1)); } else name = name.Substring(stop + 1, name.Length - (stop + 1)); } else name = ""; if (vi == null) { if (m_frame._locals != null) { foreach (VariableInfo var in m_frame._locals) { if (var._name == search) { vi = var; break; } } } if (vi == null) { if (m_frame._arguments != null) { foreach (VariableInfo var in m_frame._arguments) { if (var._name == search) { vi = var; break; } } } } } else { isRoot = false; VariableInfo vi_child = null; if (vi._children != null) { foreach (VariableInfo var in vi._children) { if (var._name == search) { vi_child = var; break; } } } vi = vi_child; } } while ((vi != null) && ((isArray) || (name != ""))); if (name != "") // variable not found probably because it is in an expression, so return to the original name to evaluate it. search = search + separator + name; string result = ""; bool valid; if (vi == null) valid = evaluateExpression(search, ref result, null); else valid = evaluateExpression(search, ref result, vi._GDBName); if (vi != null) { if ((vi._value != result) || (!isRoot)) // if is not root means that it can be expanded... { vi._value = result; if (vi._value == null || (vi._type.Contains("*") && (vi._value != "0x0"))) { // This is an array, struct, union, or pointer. // Create a variable object so we can list this variable's children. ArrayList GDBNames = new ArrayList(); ArrayList VSNames = new ArrayList(); bool hasVsNdK_ = false; m_eventDispatcher.createVar(vi._name, ref hasVsNdK_); if (hasVsNdK_) { GDBNames.Add("VsNdK_" + vi._name); VSNames.Add(vi._name); } vi._children = new ArrayList(); if (vi._type.Contains("struct")) if (vi._type[vi._type.Length - 1] == '*') vi.listChildren(m_eventDispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else if (vi._type.Contains("[")) vi.listChildren(m_eventDispatcher, "struct[]", GDBNames, VSNames, hasVsNdK_, null); else vi.listChildren(m_eventDispatcher, "struct", GDBNames, VSNames, hasVsNdK_, null); else if (vi._type.Contains("[")) vi.listChildren(m_eventDispatcher, "[]", GDBNames, VSNames, hasVsNdK_, null); else if (vi._type.Contains("*")) vi.listChildren(m_eventDispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else vi.listChildren(m_eventDispatcher, "", GDBNames, VSNames, hasVsNdK_, null); m_eventDispatcher.deleteVar(vi._name, hasVsNdK_); } } } else { if (!valid) vi = new VariableInfo(search, "", result); else { string aux_exp = search.Replace(" ", ""); string datatype; string firstDatatype = GDBParser.parseCommand("whatis " + aux_exp, 3); string baseDatatype = GDBParser.parseCommand("ptype " + aux_exp, 4); if ((baseDatatype[baseDatatype.Length - 1] == '{') && (baseDatatype[baseDatatype.Length - 2] == ' ')) baseDatatype = baseDatatype.Remove(baseDatatype.Length - 2); if (baseDatatype.Length < firstDatatype.Length) { if (firstDatatype.Contains(baseDatatype)) { baseDatatype = firstDatatype; } } if ((baseDatatype == firstDatatype) || ((baseDatatype.Contains("::")) && (!baseDatatype.Contains("union")))) { baseDatatype = ""; datatype = firstDatatype; } else { datatype = baseDatatype; } if (datatype[datatype.Length - 1] == '*') if (result == "0x0") { vi = new VariableInfo(search, firstDatatype, result); } else { vi = new VariableInfo(search, firstDatatype, baseDatatype, result, m_eventDispatcher, null, null); } else if ((datatype.Contains("struct")) || (datatype.Contains("["))) { vi = new VariableInfo(search, firstDatatype, baseDatatype, null, m_eventDispatcher, null, null); } else { vi = new VariableInfo(search, firstDatatype, result); } } } return vi; }
public AD7StackFrame(AD7Engine engine, AD7Thread thread, string[] frameInfo) { m_engine = engine; m_thread = thread; m_dispatcher = m_engine.eDispatcher; uint level = Convert.ToUInt32(frameInfo[0]); string address = frameInfo[1]; m_addressString = address; m_functionName = frameInfo[2]; m_documentName = frameInfo[3]; try { m_lineNum = Convert.ToUInt32(frameInfo[4]); } catch (Exception e) { m_lineNum = 0; } _locals = new ArrayList(); _arguments = new ArrayList(); m_hasSource = (m_lineNum == 0) ? false : true; ArrayList evaluatedVars = new ArrayList(); // Add the variable filter list to the evaluatedVars list. // Causes named variables to be ignored. evaluatedVars.AddRange(m_variableFilter); if (address.StartsWith("0x")) address = address.Remove(0, 2); m_address = uint.Parse(address, System.Globalization.NumberStyles.AllowHexSpecifier); // Query GDB for parameters and locals. string variablesResponse = m_engine.eDispatcher.getVariablesForFrame(level, m_thread._id).Replace("#;;;", ""); if (variablesResponse == null || variablesResponse == "ERROR" || variablesResponse == "") return; variablesResponse = variablesResponse.Substring(3); string[] variableStrings = variablesResponse.Split('#'); foreach (string variableString in variableStrings) { string name = null; bool arg = false; string type = null; string value = null; string[] variableProperties = variableString.Split(';'); if (variableProperties[0] != "") { if (!evaluatedVars.Contains(variableProperties[0])) { name = variableProperties[0]; evaluatedVars.Add(variableProperties[0]); if (variableProperties[1] != "") arg = true; if (variableProperties[2] != "") type = variableProperties[2]; if (variableProperties[3] != "") value = variableProperties[3]; if (arg) _arguments.Add(VariableInfo.create(name, type, value, m_engine.eDispatcher)); else _locals.Add(VariableInfo.create(name, type, value, m_engine.eDispatcher)); } } } }
/// <summary> /// Constructor for Variable Info Object /// </summary> /// <param name="name">The name of the variable</param> /// <param name="type">The data type of the variable</param> /// <param name="baseType">The base type of the variable.</param> /// <param name="value">The value of the variable</param> /// <param name="dispatcher">The event dispatcher</param> /// <param name="GDBNames">The GDBNames of the children</param> /// <param name="VSNames">The VS Names of the children</param> /// <param name="level">The currrent evaluation level</param> public VariableInfo(string name, string type, string baseType, string value, EventDispatcher dispatcher, ArrayList GDBNames, ArrayList VSNames) { /// numChildren - The result of the createvar returns ERROR or a number 0-n where n is the number of children of the variable. string numChildren = ""; _name = name; _exp = null; _type = type; _value = value; _children = null; _GDBName = null; if (baseType != "") type = baseType; if (GDBNames == null) { GDBNames = new ArrayList(); VSNames = new ArrayList(); } if (value == null || (type.Contains("*") && (value != "0x0"))) { // This is an array, struct, union, or pointer. // Create a variable object so we can list this variable's children. bool hasVsNdK_ = false; numChildren = dispatcher.createVar(_name, ref hasVsNdK_); if (hasVsNdK_) { _GDBName = "VsNdK_" + _name; GDBNames.Add("VsNdK_" + _name); VSNames.Add(_name); } try // Catch non-numerical data { if (Convert.ToInt32(numChildren) > 0) // If the variable has children evaluate { _children = new ArrayList(); if (type.Contains("struct")) if (type[type.Length - 1] == '*') this.listChildren(dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else if (type.Contains("[")) this.listChildren(dispatcher, "struct[]", GDBNames, VSNames, hasVsNdK_, null); else this.listChildren(dispatcher, "struct", GDBNames, VSNames, hasVsNdK_, null); else if (type.Contains("[")) this.listChildren(dispatcher, "[]", GDBNames, VSNames, hasVsNdK_, null); else if (type.Contains("*")) this.listChildren(dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else this.listChildren(dispatcher, "", GDBNames, VSNames, hasVsNdK_, null); } } catch (FormatException e) { } dispatcher.deleteVar(_name, hasVsNdK_); } if (value == null) evaluateExpression(name, ref _value, null); }
public HandleBreakpoints(EventDispatcher ed) { m_eventDispatcher = ed; }
public void listChildren(EventDispatcher dispatcher, string parentType, ArrayList GDBNames, ArrayList VSNames, bool hasVsNdK_, string GDBName) { string childListResponse; if (GDBName == null) { if (hasVsNdK_) { childListResponse = dispatcher.listChildren(_GDBName); } else { childListResponse = dispatcher.listChildren(_name); if ((childListResponse == "ERROR") && (_GDBName != null)) { childListResponse = dispatcher.listChildren(_GDBName); } } } else childListResponse = dispatcher.listChildren(GDBName); if (childListResponse != "ERROR") { childListResponse = (childListResponse.Substring(3)).Replace("#;;;", ""); string[] childList = childListResponse.Split('#'); foreach (string childString in childList) { // bool complex = false; string name = null; string type = null; string value = null; string exp = null; int numChildren = 0; bool valid = true; string[] childProperties = childString.Split(';'); if (childProperties[0] == "") continue; name = childProperties[0]; if (name.Contains("::")) { continue; } GDBName = name; // string old = name; int end = name.Length; if (name[end - 1] == '"') end--; if (((name.Length > 8) && (name.Substring(end - 8, 8) == ".private")) || ((name.Length > 7) && (name.Substring(end - 7, 7) == ".public")) || ((name.Length > 10) && (name.Substring(end - 10, 10) == ".protected")) || ((name.Length > 9) && (name.Substring(end - 9, 9) == ".private.")) || ((name.Length > 8) && (name.Substring(end - 8, 8) == ".public.")) || ((name.Length > 11) && (name.Substring(end - 11, 11) == ".protected."))) { int index = VSNames.IndexOf(_name); if (index != -1) GDBNames[index] = GDBName; else { GDBNames.Add(GDBName); VSNames.Add(_name); } this.listChildren(dispatcher, parentType, GDBNames, VSNames, hasVsNdK_, GDBName); continue; } else { int dot = name.LastIndexOf("."); if (dot != -1) { int index = GDBNames.IndexOf(name.Substring(0, dot)); if (index != -1) { name = VSNames[index].ToString() + name.Substring(dot); } } name = name.Replace(".private", ""); name = name.Replace(".public", ""); name = name.Replace(".protected", ""); name = name.Replace("..", "."); dot = name.LastIndexOf(".*"); if (dot != -1) { name = "*(" + name.Remove(dot) + ")"; } if (parentType == "*") { dot = name.LastIndexOf('.'); if (dot != -1) { name = name.Substring(0, dot) + "->" + name.Substring(dot + 1, name.Length - (dot + 1)); } } else if (parentType == "[]") { dot = name.LastIndexOf('.'); name = name.Substring(0, dot) + "[" + name.Substring(dot + 1, name.Length - (dot + 1)); name = name + "]"; } GDBNames.Add(GDBName); VSNames.Add(name); } if (childProperties[1] != "") numChildren = Convert.ToInt32(childProperties[1]); value = childProperties[2]; if ((value == "") || (value.Contains("{...}")) || ((value.Length >= 2) && (value[0] == '[') && (value[value.Length - 1] == ']'))) valid = evaluateExpression(name, ref value, GDBName); type = childProperties[3]; VariableInfo child = new VariableInfo(name, exp, type, value, GDBName); if ((valid) && (numChildren > 0 && value != "0x0")) { child._children = new ArrayList(); } if (VSNames.Contains(name)) { int index = VSNames.IndexOf(name); VSNames.RemoveAt(index); GDBNames.RemoveAt(index); } _children.Add(child); // } } } else { // ??? What to do in case of error??? } }
public GDBOutput(EventDispatcher ed) { m_eventDispatcher = ed; _running = true; }
// HandleBreakpoints calls this too, so it needs to be public and static public static void onStepCompleted(EventDispatcher eventDispatcher, string file, uint line) { if (eventDispatcher.engine.m_state == AD7Engine.DE_STATE.STEP_MODE) { eventDispatcher.engine.m_state = AD7Engine.DE_STATE.BREAK_MODE; // Visual Studio shows the line position one more than it actually is eventDispatcher.engine.m_docContext = eventDispatcher.getDocumentContext(file, line - 1); AD7StepCompletedEvent.Send(eventDispatcher.engine); // EvaluatedExp.reset(); // VariableInfo.reset(); // eventDispatcher.engine.resetStackFrames(); } }
private int m_threadId = -1; // when threadId is 0, it means all threads. #endregion Fields #region Constructors public HandleProcessExecution(EventDispatcher ed) { m_eventDispatcher = ed; }
public HandleOutputs(EventDispatcher ed) { m_eventDispatcher = ed; }
/// <summary> /// Constructor for Variable Info Object inquiring for the variable's children /// </summary> /// <param name="name"> The name of the variable. </param> /// <param name="type"> The data type of the variable. </param> /// <param name="baseType"> The base type of the variable. </param> /// <param name="value"> The value of the variable. </param> /// <param name="dispatcher"> The event dispatcher. </param> /// <param name="GDBNames"> The names of the variables used by GDB. </param> /// <param name="VSNames"> The Names of the variables used by VS. </param> public VariableInfo(string name, string type, string baseType, string value, EventDispatcher dispatcher, ArrayList GDBNames, ArrayList VSNames) { /// numChildren - The result of the createvar returns ERROR or a number from 0 to "n" where "n" is the number of children /// of the variable. string numChildren = ""; _name = name; _type = type; _value = value; _children = null; _GDBName = null; if (baseType != "") type = baseType; if (GDBNames == null) { GDBNames = new ArrayList(); VSNames = new ArrayList(); } if (value == null || (type.Contains("*") && (value != "0x0"))) { // This is an array, struct, union, or pointer. // Create a variable object so we can list this variable's children. /// Some VS variable names cannot be used by GDB. When that happens, it is added the prefix VsNdK_ to the GDB variable /// name and it is stored in the GDBNames array. At the same time, the VS name is stored in the VSNames array using the /// same index position. This bool variable just indicate if this prefix is used or not. bool hasVsNdK_ = false; numChildren = dispatcher.createVar(_name, ref hasVsNdK_); if (hasVsNdK_) { _GDBName = "VsNdK_" + _name; GDBNames.Add("VsNdK_" + _name); VSNames.Add(_name); } try // Catch non-numerical data { if (Convert.ToInt32(numChildren) > 0) // If the variable has children, evaluate them. { _children = new ArrayList(); if (type.Contains("struct")) if (type[type.Length - 1] == '*') this.listChildren(dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else if (type.Contains("[")) this.listChildren(dispatcher, "struct[]", GDBNames, VSNames, hasVsNdK_, null); else this.listChildren(dispatcher, "struct", GDBNames, VSNames, hasVsNdK_, null); else if (type.Contains("[")) this.listChildren(dispatcher, "[]", GDBNames, VSNames, hasVsNdK_, null); else if (type.Contains("*")) this.listChildren(dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else this.listChildren(dispatcher, "", GDBNames, VSNames, hasVsNdK_, null); } } catch (FormatException e) { } dispatcher.deleteVar(_name, hasVsNdK_); } if (value == null) evaluateExpression(name, ref _value, null); }