//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #endregion //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugProgram3 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int ExecuteOnThread (IDebugThread2 pThread) { // // Executes the debugger program. The thread is returned to give the debugger information on which thread the user is viewing when executing the program. // LoggingUtils.PrintFunction (); try { uint threadId; CLangDebuggeeThread thread = pThread as CLangDebuggeeThread; LoggingUtils.RequireOk (thread.GetThreadId (out threadId)); string command = "-thread-select " + threadId; MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand (command); MiResultRecord.RequireOk (resultRecord, command); CurrentThreadId = threadId; LoggingUtils.RequireOk (Execute ()); return Constants.S_OK; } catch (Exception e) { LoggingUtils.HandleException (e); return Constants.E_FAIL; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int Step(IDebugThread2 pThread, enum_STEPKIND sk, enum_STEPUNIT Step) { // // Performs a step. // LoggingUtils.PrintFunction(); try { CLangDebuggeeThread thread = pThread as CLangDebuggeeThread; LoggingUtils.RequireOk(thread.GetThreadId(out uint threadId)); GdbClient.StepType stepType = (GdbClient.StepType)Step; switch (sk) { case enum_STEPKIND.STEP_INTO: { m_debugger.GdbClient.StepInto(threadId, stepType, false); break; } case enum_STEPKIND.STEP_OVER: { m_debugger.GdbClient.StepOver(threadId, stepType, false); break; } case enum_STEPKIND.STEP_OUT: { m_debugger.GdbClient.StepOut(threadId, stepType, false); break; } case enum_STEPKIND.STEP_BACKWARDS: { throw new NotImplementedException(); } } return(Constants.S_OK); } catch (NotImplementedException e) { LoggingUtils.HandleException(e); return(Constants.E_NOTIMPL); } catch (Exception e) { LoggingUtils.HandleException(e); return(Constants.E_FAIL); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void RefreshThread(uint tid) { LoggingUtils.PrintFunction(); try { m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger) { string command = string.Format("-thread-info {0}", (tid == 0) ? "" : tid.ToString()); MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(command); MiResultRecord.RequireOk(resultRecord, command); if (!resultRecord.HasField("threads")) { throw new InvalidOperationException("-thread-info result missing 'threads' field"); } MiResultValueList threadsValueList = (MiResultValueList)resultRecord ["threads"] [0]; List <MiResultValue> threadsData = threadsValueList.List; bool refreshedProcesses = false; for (int i = threadsData.Count - 1; i >= 0; --i) // reported threads are in descending order. { uint id = threadsData [i] ["id"] [0].GetUnsignedInt(); CLangDebuggeeThread thread = GetThread(id) ?? AddThread(id); if (thread.RequiresRefresh) { MiResultValue threadData = threadsData [i]; if (!refreshedProcesses) { AndroidDevice hostDevice = DebugProgram.DebugProcess.NativeProcess.HostDevice; hostDevice.RefreshProcesses(DebugProgram.DebugProcess.NativeProcess.Pid); refreshedProcesses = true; } thread.Refresh(ref threadData); } } if (resultRecord.HasField("current-thread-id")) { CurrentThreadId = resultRecord ["current-thread-id"] [0].GetUnsignedInt(); } }); } catch (Exception e) { LoggingUtils.HandleException(e); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeStackFrame(CLangDebugger debugger, CLangDebuggeeThread thread, MiResultValueTuple frameTuple, string frameName) : base(debugger.Engine, thread as DebuggeeThread, frameName) { m_debugger = debugger; m_queriedRegisters = false; m_queriedArgumentsAndLocals = false; GetInfoFromCurrentLevel(frameTuple); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeStackFrame (CLangDebugger debugger, CLangDebuggeeThread thread, MiResultValueTuple frameTuple, string frameName) : base (debugger.Engine, thread as DebuggeeThread, frameName) { m_debugger = debugger; if (frameTuple == null) { throw new ArgumentNullException ("frameTuple"); } m_queriedRegisters = false; m_queriedArgumentsAndLocals = false; GetInfoFromCurrentLevel (frameTuple); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeThread AddThread (uint threadId) { LoggingUtils.PrintFunction (); DebuggeeThread thread = null; lock (m_debugThreads) { if (!m_debugThreads.TryGetValue (threadId, out thread)) { thread = new CLangDebuggeeThread (m_debugger, this, threadId); m_debugThreads.Add (threadId, thread); } } if (thread != null) { m_debugger.Engine.Broadcast (new DebugEngineEvent.ThreadCreate (), DebugProgram, thread); } return (CLangDebuggeeThread) thread; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int EnumCodePaths (string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety) { // // Enumerates the code paths of this program. // LoggingUtils.PrintFunction (); try { // // Get the entire call-stack for the current thread, and enumerate. // CLangDebuggeeStackFrame stackFrame = pFrame as CLangDebuggeeStackFrame; IDebugThread2 thread; LoggingUtils.RequireOk (stackFrame.GetThread (out thread)); CLangDebuggeeThread stackFrameThread = thread as CLangDebuggeeThread; List<DebuggeeStackFrame> threadCallStack = stackFrameThread.StackTrace (uint.MaxValue); List <CODE_PATH> threadCodePaths = new List <CODE_PATH> (); for (int i = 0; i < threadCallStack.Count; ++i) { string frameName; IDebugCodeContext2 codeContext; DebuggeeStackFrame frame = threadCallStack [i] as DebuggeeStackFrame; LoggingUtils.RequireOk (frame.GetName (out frameName)); LoggingUtils.RequireOk (frame.GetCodeContext (out codeContext)); if (codeContext != null) { CODE_PATH codePath = new CODE_PATH (); codePath.bstrName = frameName; codePath.pCode = codeContext; threadCodePaths.Add (codePath); } } ppEnum = new DebuggeeProgram.EnumeratorCodePaths (threadCodePaths); ppSafety = null; return Constants.S_OK; } catch (Exception e) { LoggingUtils.HandleException (e); ppEnum = null; ppSafety = null; return Constants.E_FAIL; } }