//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty(CLangDebugger debugger, CLangDebuggeeStackFrame stackFrame, string expression, string value) : base(debugger.Engine, stackFrame, expression, value) { m_debugger = debugger; m_gdbVariable = null; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty(CLangDebugger debugger, CLangDebuggeeStackFrame stackFrame, MiVariable gdbVariable) : base(debugger.Engine, stackFrame, gdbVariable.Expression, string.Empty) { m_debugger = debugger; m_gdbVariable = gdbVariable; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int EvaluateSync(enum_EVALFLAGS evaluateFlags, uint timeout, IDebugEventCallback2 eventCallback, out IDebugProperty2 result) { // // Evaluate the expression synchronously. // LoggingUtils.PrintFunction(); try { CLangDebuggeeStackFrame stackFrame = m_stackFrame as CLangDebuggeeStackFrame; result = stackFrame.EvaluateCustomExpression(evaluateFlags, m_expression, m_radix); if (result == null) { return(Constants.E_FAIL); } return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); result = null; return(Constants.E_FAIL); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty CreatePropertyFromVariable(CLangDebuggeeStackFrame stackFrame, MiVariable variable) { LoggingUtils.PrintFunction(); try { if (stackFrame == null) { throw new ArgumentNullException("stackFrame"); } if (variable == null) { throw new ArgumentNullException("variable"); } /*CLangDebuggeeProperty [] childProperties = GetChildProperties (stackFrame, parentProperty); * * parentProperty.AddChildren (childProperties);*/ return(new CLangDebuggeeProperty(m_debugger, stackFrame, variable));; } catch (Exception e) { LoggingUtils.HandleException(e); return(null); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public MiVariable CreateVariableFromExpression(CLangDebuggeeStackFrame stackFrame, string expression) { LoggingUtils.PrintFunction(); try { LoggingUtils.RequireOk(stackFrame.GetThread(out IDebugThread2 stackThread)); LoggingUtils.RequireOk(stackThread.GetThreadId(out uint stackThreadId)); string command = string.Format("-var-create --thread {0} --frame {1} - * \"{2}\"", stackThreadId, stackFrame.StackLevel, expression); MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(command); MiResultRecord.RequireOk(resultRecord, command); return(new MiVariable(expression, resultRecord.Results)); } catch (Exception e) { LoggingUtils.HandleException(e); return(null); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty (CLangDebugger debugger, CLangDebuggeeStackFrame stackFrame, MiVariable gdbVariable) : base (debugger.Engine, stackFrame, gdbVariable.Expression, string.Empty) { m_debugger = debugger; m_gdbVariable = gdbVariable; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty [] GetChildProperties(CLangDebuggeeStackFrame stackFrame, CLangDebuggeeProperty parentProperty) { LoggingUtils.PrintFunction(); MiVariable parentVariable = parentProperty.GdbVariable; List <CLangDebuggeeProperty> childProperties = new List <CLangDebuggeeProperty> (); if (parentVariable.HasChildren && (parentVariable.Children.Count > 0)) { foreach (MiVariable childVariable in parentVariable.Children.Values) { CLangDebuggeeProperty childProperty = new CLangDebuggeeProperty(m_debugger, stackFrame, childVariable); if (childVariable.IsPseudoChild) { CLangDebuggeeProperty [] childSubProperties = GetChildProperties(stackFrame, childProperty); childProperties.AddRange(childSubProperties); } else { childProperties.Add(childProperty); } } } return(childProperties.ToArray()); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty (CLangDebugger debugger, CLangDebuggeeStackFrame stackFrame, string expression, string value) : base (debugger.Engine, stackFrame, expression, value) { m_debugger = debugger; m_gdbVariable = null; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty [] GetChildProperties (CLangDebuggeeStackFrame stackFrame, CLangDebuggeeProperty parentProperty) { LoggingUtils.PrintFunction (); MiVariable parentVariable = parentProperty.GdbVariable; List<CLangDebuggeeProperty> childProperties = new List<CLangDebuggeeProperty> (); if (parentVariable.HasChildren && (parentVariable.Children.Count > 0)) { foreach (MiVariable childVariable in parentVariable.Children.Values) { CLangDebuggeeProperty childProperty = new CLangDebuggeeProperty (m_debugger, stackFrame, childVariable); if (childVariable.IsPseudoChild) { CLangDebuggeeProperty [] childSubProperties = GetChildProperties (stackFrame, childProperty); childProperties.AddRange (childSubProperties); } else { childProperties.Add (childProperty); } } } return childProperties.ToArray (); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty CreatePropertyFromVariable (CLangDebuggeeStackFrame stackFrame, MiVariable variable) { LoggingUtils.PrintFunction (); try { if (stackFrame == null) { throw new ArgumentNullException ("stackFrame"); } if (variable == null) { throw new ArgumentNullException ("variable"); } /*CLangDebuggeeProperty [] childProperties = GetChildProperties (stackFrame, parentProperty); parentProperty.AddChildren (childProperties);*/ return new CLangDebuggeeProperty (m_debugger, stackFrame, variable);; } catch (Exception e) { LoggingUtils.HandleException (e); return null; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void Refresh(ref MiResultValue threadData) { LoggingUtils.PrintFunction(); if (threadData.HasField("name")) { m_threadDisplayName = threadData ["name"] [0].GetString(); // user-specified name } else if (threadData.HasField("target-id")) { uint threadPid; m_threadDisplayName = threadData ["target-id"] [0].GetString(); // usually the raw name, i.e. 'Thread 18771' if (m_threadDisplayName.StartsWith("Thread ") && uint.TryParse(m_threadDisplayName.Substring("Thread ".Length), out threadPid)) { AndroidDevice hostDevice = NativeProgram.DebugProgram.DebugProcess.NativeProcess.HostDevice; AndroidProcess threadProcess = hostDevice.GetProcessFromPid(threadPid); if (threadProcess != null) { m_threadDisplayName = threadProcess.Name; } } } if (threadData.HasField("frame")) { MiResultValueTuple frameTuple = threadData ["frame"] [0] as MiResultValueTuple; uint stackLevel = frameTuple ["level"] [0].GetUnsignedInt(); string stackFrameId = m_threadName + "#" + stackLevel; CLangDebuggeeStackFrame stackFrame = new CLangDebuggeeStackFrame(m_debugger, this, frameTuple, stackFrameId); lock (m_threadStackFrames) { m_threadStackFrames.Add(stackFrame); } } RequiresRefresh = false; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override List<DebuggeeStackFrame> StackTrace (uint depth) { // // Each thread maintains an internal cache of the last reported stack-trace. This is only cleared when threads are resumed via 'SetRunning(true)'. // LoggingUtils.PrintFunction (); try { if (m_threadStackFrames.Count < depth) { uint threadId; LoggingUtils.RequireOk (GetThreadId (out threadId)); m_debugProgram.AttachedEngine.NativeDebugger.RunInterruptOperation (delegate (CLangDebugger debugger) { // // Determine the maximum available stack depth. // string command; MiResultRecord resultRecord; if (depth == uint.MaxValue) { command = string.Format ("-stack-info-depth --thread {0}", threadId); resultRecord = debugger.GdbClient.SendSyncCommand (command); MiResultRecord.RequireOk (resultRecord, command); depth = resultRecord ["depth"] [0].GetUnsignedInt (); } // // Acquire stack frame information for any levels which we're missing. // if (m_threadStackFrames.Count < depth) { command = string.Format ("-stack-list-frames --thread {0} {1} {2}", threadId, m_threadStackFrames.Count, depth - 1); resultRecord = debugger.GdbClient.SendSyncCommand (command); MiResultRecord.RequireOk (resultRecord, command); if (resultRecord.HasField ("stack")) { MiResultValueList stackRecord = resultRecord ["stack"] [0] as MiResultValueList; for (int i = 0; i < stackRecord.Values.Count; ++i) { MiResultValueTuple frameTuple = stackRecord [i] as MiResultValueTuple; uint stackLevel = frameTuple ["level"] [0].GetUnsignedInt (); string stackFrameId = m_threadName + "#" + stackLevel; CLangDebuggeeStackFrame stackFrame = new CLangDebuggeeStackFrame (debugger, this, frameTuple, stackFrameId); lock (m_threadStackFrames) { m_threadStackFrames.Add (stackFrame); } } } } }); } return m_threadStackFrames; } catch (Exception e) { LoggingUtils.HandleException (e); throw; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public CLangDebuggeeProperty CreatePropertyFromVariable(CLangDebuggeeStackFrame stackFrame, MiVariable variable) { return(new CLangDebuggeeProperty(m_debugger, stackFrame, variable)); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public override List <DebuggeeStackFrame> StackTrace(uint depth) { // // Each thread maintains an internal cache of the last reported stack-trace. This is only cleared when threads are resumed via 'SetRunning(true)'. // LoggingUtils.PrintFunction(); try { if (m_threadStackFrames.Count < depth) { LoggingUtils.RequireOk(GetThreadId(out uint threadId)); m_debugProgram.AttachedEngine.NativeDebugger.RunInterruptOperation(delegate(CLangDebugger debugger) { // // Determine the maximum available stack depth. // string command; MiResultRecord resultRecord; if (depth == uint.MaxValue) { command = string.Format("-stack-info-depth --thread {0}", threadId); resultRecord = debugger.GdbClient.SendSyncCommand(command); MiResultRecord.RequireOk(resultRecord, command); depth = resultRecord ["depth"] [0].GetUnsignedInt(); } // // Acquire stack frame information for any levels which we're missing. // if (m_threadStackFrames.Count < depth) { command = string.Format("-stack-list-frames --thread {0} {1} {2}", threadId, m_threadStackFrames.Count, depth - 1); resultRecord = debugger.GdbClient.SendSyncCommand(command); MiResultRecord.RequireOk(resultRecord, command); if (resultRecord.HasField("stack")) { MiResultValueList stackRecord = resultRecord ["stack"] [0] as MiResultValueList; for (int i = 0; i < stackRecord.Values.Count; ++i) { MiResultValueTuple frameTuple = stackRecord [i] as MiResultValueTuple; uint stackLevel = frameTuple ["level"] [0].GetUnsignedInt(); string stackFrameId = m_threadName + "#" + stackLevel; CLangDebuggeeStackFrame stackFrame = new CLangDebuggeeStackFrame(debugger, this, frameTuple, stackFrameId); lock (m_threadStackFrames) { m_threadStackFrames.Add(stackFrame); } } } } }); } return(m_threadStackFrames); } catch (Exception e) { LoggingUtils.HandleException(e); throw; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void Refresh (ref MiResultValue threadData) { LoggingUtils.PrintFunction (); if (threadData.HasField ("name")) { m_threadDisplayName = threadData ["name"] [0].GetString (); // user-specified name } else if (threadData.HasField ("target-id")) { uint threadPid; m_threadDisplayName = threadData ["target-id"] [0].GetString (); // usually the raw name, i.e. 'Thread 18771' if (m_threadDisplayName.StartsWith ("Thread ") && uint.TryParse (m_threadDisplayName.Substring ("Thread ".Length), out threadPid)) { AndroidDevice hostDevice = NativeProgram.DebugProgram.DebugProcess.NativeProcess.HostDevice; AndroidProcess threadProcess = hostDevice.GetProcessFromPid (threadPid); if (threadProcess != null) { m_threadDisplayName = threadProcess.Name; } } } if (threadData.HasField ("frame")) { MiResultValueTuple frameTuple = threadData ["frame"] [0] as MiResultValueTuple; uint stackLevel = frameTuple ["level"] [0].GetUnsignedInt (); string stackFrameId = m_threadName + "#" + stackLevel; CLangDebuggeeStackFrame stackFrame = new CLangDebuggeeStackFrame (m_debugger, this, frameTuple, stackFrameId); lock (m_threadStackFrames) { m_threadStackFrames.Add (stackFrame); } } RequiresRefresh = false; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public MiVariable CreateVariableFromExpression (CLangDebuggeeStackFrame stackFrame, string expression) { LoggingUtils.PrintFunction (); try { IDebugThread2 stackThread; uint stackThreadId; LoggingUtils.RequireOk (stackFrame.GetThread (out stackThread)); LoggingUtils.RequireOk (stackThread.GetThreadId (out stackThreadId)); string command = string.Format ("-var-create --thread {0} --frame {1} - * \"{2}\"", stackThreadId, stackFrame.StackLevel, expression); MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand (command); MiResultRecord.RequireOk (resultRecord, command); return new MiVariable (expression, resultRecord.Results); } catch (Exception e) { LoggingUtils.HandleException (e); return null; } }