public void OnAsyncBreakComplete(AD7Thread thread) { // This will get called when the engine receives the breakpoint event that is created when the user // hits the pause button in vs. // Debug.Assert(GDBParser.CurrentThreadId == m_engine.DebuggedProcess.PollThreadId); AD7AsyncBreakCompleteEvent eventObject = new AD7AsyncBreakCompleteEvent(); Send(eventObject, AD7AsyncBreakCompleteEvent.IID, thread); }
/// <summary> /// Send an event to SDM with the breakpoint that was hit. /// </summary> /// <param name="thread"> The thread running in a program. </param> /// <param name="clients"> List of bound breakpoints. At this moment, this list has only one element. </param> public void OnBreakpoint(AD7Thread thread, IList<IDebugBoundBreakpoint2> clients) { IDebugBoundBreakpoint2[] boundBreakpoints = new IDebugBoundBreakpoint2[clients.Count]; int i = 0; foreach (object objCurrentBreakpoint in clients) { boundBreakpoints[i] = (IDebugBoundBreakpoint2)objCurrentBreakpoint; i++; } AD7BoundBreakpointsEnum boundBreakpointsEnum = new AD7BoundBreakpointsEnum(boundBreakpoints); AD7BreakpointEvent eventObject = new AD7BreakpointEvent(boundBreakpointsEnum); Send(eventObject, AD7BreakpointEvent.IID, thread); }
/// <summary> /// Send an event to SDM with the breakpoint that was hit. /// </summary> /// <param name="thread"> The thread running in a program. </param> /// <param name="clients"> List of bound breakpoints. At this moment, this list has only one element. </param> public void OnBreakpoint(AD7Thread thread, IList <IDebugBoundBreakpoint2> clients) { IDebugBoundBreakpoint2[] boundBreakpoints = new IDebugBoundBreakpoint2[clients.Count]; int i = 0; foreach (object objCurrentBreakpoint in clients) { boundBreakpoints[i] = (IDebugBoundBreakpoint2)objCurrentBreakpoint; i++; } AD7BoundBreakpointsEnum boundBreakpointsEnum = new AD7BoundBreakpointsEnum(boundBreakpoints); AD7BreakpointEvent eventObject = new AD7BreakpointEvent(boundBreakpointsEnum); Send(eventObject, AD7BreakpointEvent.IID, thread); }
/// <summary> /// Sends the event. /// </summary> /// <param name="engine"> The AD7Engine object that represents the DE. </param> /// <param name="exitCode"> The thread's exit code. </param> /// <param name="thread"> The AD7Thread object that represents the thread. </param> internal static void Send(AD7Engine engine, uint exitCode, AD7Thread thread) { var eventObject = new AD7ThreadDestroyEvent(exitCode); if (thread == null) { foreach (AD7Thread t in engine.thread) { engine.Callback.Send(eventObject, IID, t); } engine._currentThreadIndex = -1; } else { engine.Callback.Send(eventObject, IID, thread); } }
/*public void OnThreadStart(DebuggedThread debuggedThread) { // This will get called when the entrypoint breakpoint is fired because the engine sends a thread start event // for the main thread of the application. //if (m_engine.DebuggedProcess != null) //{ // Debug.Assert(GDBParser.CurrentThreadId == m_engine.DebuggedProcess.PollThreadId); //} // AD7Thread ad7Thread = new AD7Thread(m_engine, debuggedThread); // debuggedThread.Client = ad7Thread; AD7ThreadCreateEvent eventObject = new AD7ThreadCreateEvent(); // Send(eventObject, AD7ThreadCreateEvent.IID, ad7Thread); Send(eventObject, AD7ThreadCreateEvent.IID, debuggedThread); }*/ public void OnBreakpoint(AD7Thread thread, IList<IDebugBoundBreakpoint2> clients) { IDebugBoundBreakpoint2[] boundBreakpoints = new IDebugBoundBreakpoint2[clients.Count]; int i = 0; foreach (object objCurrentBreakpoint in clients) { boundBreakpoints[i] = (IDebugBoundBreakpoint2)objCurrentBreakpoint; i++; } // An engine that supports more advanced breakpoint features such as hit counts, conditions and filters // should notify each bound breakpoint that it has been hit and evaluate conditions here. // The sample engine does not support these features. AD7BoundBreakpointsEnum boundBreakpointsEnum = new AD7BoundBreakpointsEnum(boundBreakpoints); AD7BreakpointEvent eventObject = new AD7BreakpointEvent(boundBreakpointsEnum); Send(eventObject, AD7BreakpointEvent.IID, thread); }
/// <summary> /// Sends the event. /// </summary> /// <param name="aEngine"> The AD7Engine object that represents the DE. </param> /// <param name="aThread"> The AD7Thread object that represents the thread. </param> internal static void Send(AD7Engine aEngine, AD7Thread aThread) { var xMessage = new AD7LoadCompleteEvent(); aEngine.Callback.Send(xMessage, IID, aThread); }
/// <summary> /// Get the list of threads being debugged, also returning the index of the current thread (or -1 in case of error) /// </summary> /// <param name="threadObjects"> Returns the current list of threads that are being debugged. </param> /// <returns> Returns the index of the current thread in the list of threads (or -1 in case of error) </returns> public int GetListOfThreads(out AD7Thread[] threadObjects) { // Gets the parsed response for the GDB/MI command that ask for information about all threads. // (http://www.sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Thread-Commands.html) string threadResponse = GDBParser.parseCommand(@"-thread-info", 22); string[] threadStrings = threadResponse.Split('#'); cleanEvaluatedThreads(); // Query the threads depth without inquiring GDB. int numThreads = threadStrings.Length - 1; // the last item in threadStrings is not a thread but the current thread ID. string currentThread = threadStrings[threadStrings.Length - 1]; if (numThreads < 1) { threadObjects = null; return -1; } try { threadObjects = new AD7Thread[numThreads]; int currentThreadIndex = -1; for (int i = 0; i < numThreads; i++) { string[] threadInfo = threadStrings[i].Split(';'); // Setting the current thread index. if (currentThread == threadInfo[0]) { currentThreadIndex = i; } // Each threadInfo has one of these two formats: // with 5 elements: ID; State; targetID; details (not used); name -> this format is normally used for external code. // with 7 elements: ID; State; targetID; details (not used); full short-path filename; line; name if (threadInfo.Length > 5) threadObjects[i] = new AD7Thread(this, threadInfo[0], threadInfo[2], threadInfo[1], "Normal", threadInfo[6], threadInfo[4], threadInfo[5]); else threadObjects[i] = new AD7Thread(this, threadInfo[0], threadInfo[2], threadInfo[1], "Normal", threadInfo[4], "", ""); } return currentThreadIndex; } catch (ComponentException e) { threadObjects = null; return -1; } catch (Exception e) { threadObjects = null; return -1; } }
internal static void Send(AD7Engine engine, uint exitCode, AD7Thread thread) { var eventObject = new AD7ThreadDestroyEvent(exitCode); if (thread == null) { foreach (AD7Thread t in engine.thread) { engine.Callback.Send(eventObject, IID, t); } engine._currentThreadIndex = -1; } else { engine.Callback.Send(eventObject, IID, thread); } // engine.Callback.Send(eventObject, IID, null); }
internal static void Send(AD7Engine aEngine, AD7Thread aThread) { var xMessage = new AD7LoadCompleteEvent(); aEngine.Callback.Send(xMessage, IID, aThread); }
public static AD7StackFrame create(AD7Engine engine, AD7Thread thread, string[] frameInfo, ref bool created) { created = false; if (thread.__stackFrames != null) { foreach (AD7StackFrame frame in thread.__stackFrames) { if (frame.m_documentName != null && frame.m_functionName != null) { if (frame.m_documentName == frameInfo[3] && frame.m_functionName == frameInfo[2])// && frame.m_addressString == frameInfo[1]) // frameInfo[2] = func, frameInfo[3] = file return frame; } } } else thread.__stackFrames = new ArrayList(); AD7StackFrame newFrame = new AD7StackFrame(engine, thread, frameInfo); if (thread.__stackFrames == null) // that's weird, but sometimes VS is not initializing __stackFrames, so I added this loop to avoid other problems. thread.__stackFrames = new ArrayList() { newFrame }; else thread.__stackFrames.Add(newFrame); created = true; return newFrame; }
/// <summary> /// Search the __stackframes cache for the internal representation of the stack frame associated to the GDB frameInfo /// information. If successful, returns the stack frame; otherwise, creates a new one and return it. /// </summary> /// <param name="engine"> The AD7Engine object that represents the DE. </param> /// <param name="thread"> Represents the thread for this stack frame. </param> /// <param name="frameInfo"> Array of strings with the information provided by GDB about this stack frame. </param> /// <param name="created"> Boolean value that indicates if a new object for this stack frame was created or not. </param> /// <returns> Returns the created/found stack frame. </returns> public static AD7StackFrame create(AD7Engine engine, AD7Thread thread, string[] frameInfo, ref bool created) { created = false; if (thread.__stackFrames != null) { foreach (AD7StackFrame frame in thread.__stackFrames) { if (frame.m_documentName != null && frame.m_functionName != null) { if (frame.m_documentName == frameInfo[3] && frame.m_functionName == frameInfo[2]) // frameInfo[2] = func, frameInfo[3] = file return frame; } } } else thread.__stackFrames = new ArrayList(); AD7StackFrame newFrame = new AD7StackFrame(engine, thread, frameInfo); thread.__stackFrames.Add(newFrame); created = true; return newFrame; }
/// <summary> /// This will get called when the engine receives the breakpoint event that is created when the user /// hits the pause button in VS. /// </summary> /// <param name="thread"> The thread running in a program. </param> public void OnAsyncBreakComplete(AD7Thread thread) { AD7AsyncBreakCompleteEvent eventObject = new AD7AsyncBreakCompleteEvent(); Send(eventObject, AD7AsyncBreakCompleteEvent.IID, thread); }
/// <summary> /// Send an event to notify the SDM that this thread was created. /// </summary> /// <param name="debuggedThread"> The new thread running in a program. </param> public void OnThreadStart(AD7Thread debuggedThread) { AD7ThreadCreateEvent eventObject = new AD7ThreadCreateEvent(); Send(eventObject, AD7ThreadCreateEvent.IID, debuggedThread); }
// Get the list of threads being debugged, also returning the index of the current thread (or -1 in case of error) public int GetListOfThreads(out AD7Thread[] threadObjects) { // Ask for general threads information. string threadResponse = GDBParser.parseCommand(@"-thread-info", 22); string[] threadStrings = threadResponse.Split('#'); cleanEvaluatedThreads(); // Query the threads depth without inquiring GDB. int numThreads = threadStrings.Length - 1; string currentThread = threadStrings[threadStrings.Length - 1]; if (numThreads < 1) { threadObjects = null; return -1; } try { List<string[]> threadsList = new List<string[]>(); int currentThreadIndex = -1; for (int i = 0; i < numThreads; i++) { string[] threadInfo = threadStrings[i].Split(';'); threadsList.Add(threadInfo); } // if (threadsList.Count > 1) // there is always one thread, the GDB debugger. // { threadObjects = new AD7Thread[threadsList.Count]; for (int i = 0; i < threadsList.Count; i++) { bool current = false; if (currentThread == threadsList[i][0]) { currentThreadIndex = i; current = true; } if (threadsList[i].Length > 5) threadObjects[i] = new AD7Thread(this, current, threadsList[i][0], threadsList[i][2], threadsList[i][1], "Normal", threadsList[i][6], threadsList[i][4], threadsList[i][5]); else threadObjects[i] = new AD7Thread(this, current, threadsList[i][0], threadsList[i][2], threadsList[i][1], "Normal", threadsList[i][4], "", ""); } // } // else // { // threadObjects = new AD7Thread[1]; // threadObjects[0] = new AD7Thread(this, false, "", "Thread 1", "", "", "", "", "0"); // } return currentThreadIndex; } catch (ComponentException e) { threadObjects = null; return -1; } catch (Exception e) { threadObjects = null; return -1; } }
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)); } } } }
public void OnLoadComplete(AD7Thread thread) { AD7LoadCompleteEvent eventObject = new AD7LoadCompleteEvent(); Send(eventObject, AD7LoadCompleteEvent.IID, thread); }