//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private MiVariable [] GetChildVariables(MiVariable parentVariable, int depth) { LoggingUtils.PrintFunction(); List <MiVariable> childVariables = new List <MiVariable> (); if ((depth > 0) && (parentVariable.HasChildren)) { string command = string.Format("-var-list-children --all-values \"{0}\"", parentVariable.Name); MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(command); MiResultRecord.RequireOk(resultRecord, command); if (resultRecord.HasField("children")) { List <MiResultValue> childrenList = resultRecord ["children"] [0] ["child"]; for (int i = 0; i < childrenList.Count; ++i) { MiResultValueTuple childTuple = childrenList [i] as MiResultValueTuple; string variableName = childTuple ["name"] [0].GetString(); MiVariable childVariable = null; bool isPseudoChild = false; if (childTuple.HasField("exp")) { string variableExpression = childTuple ["exp"] [0].GetString(); if (!string.IsNullOrEmpty(variableExpression)) { childVariable = new MiVariable(variableName, variableExpression); childVariable.Populate(childTuple.Values); isPseudoChild = childVariable.IsPseudoChild; } } if (childVariable == null) { childVariable = new MiVariable(variableName, childTuple.Values); } if (isPseudoChild) { depth += 1; // need an additional level of children. MiVariable [] evaluatedChildren = GetChildVariables(childVariable, depth - 1); foreach (MiVariable child in evaluatedChildren) { childVariable.AddChild(child); } } childVariables.Add(childVariable); } } } return(childVariables.ToArray()); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void GetInfoFromCurrentLevel(MiResultValueTuple frameTuple) { LoggingUtils.PrintFunction(); try { if (frameTuple == null) { throw new ArgumentNullException("frameTuple"); } if (frameTuple.HasField("level")) { m_stackLevel = frameTuple ["level"] [0].GetUnsignedInt(); } // // Discover the function or shared library location. // if (frameTuple.HasField("addr")) { m_locationAddress = new DebuggeeAddress(frameTuple ["addr"] [0].GetString()); } else { m_locationAddress = new DebuggeeAddress("0x0"); } if (frameTuple.HasField("func")) { m_locationFunction = frameTuple ["func"] [0].GetString(); } else { m_locationFunction = "??"; } m_locationIsSymbolicated = !(m_locationFunction.Equals("??")); if (frameTuple.HasField("from")) { m_locationModule = Path.GetFileName(frameTuple ["from"] [0].GetString()); } else { m_locationModule = string.Empty; } // // Generate code and document contexts for this frame location. // if (frameTuple.HasField("fullname") && frameTuple.HasField("line")) { // // If the symbol table isn't yet loaded, we'll need to specify exactly the location of this stack frame. // TEXT_POSITION [] textPositions = new TEXT_POSITION [2]; textPositions [0].dwLine = frameTuple ["line"] [0].GetUnsignedInt() - 1; textPositions [0].dwColumn = 0; textPositions [1].dwLine = textPositions [0].dwLine; textPositions [1].dwColumn = textPositions [0].dwColumn; string filename = PathUtils.ConvertPathCygwinToWindows(frameTuple ["fullname"] [0].GetString()); m_documentContext = new DebuggeeDocumentContext(m_debugger.Engine, filename, textPositions [0], textPositions [1]); m_codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation(m_debugger, m_locationAddress.ToString()); if (m_codeContext == null) { throw new InvalidOperationException(); } } else { m_codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation(m_debugger, m_locationAddress.ToString()); m_documentContext = (m_codeContext != null) ? m_codeContext.DocumentContext : null; } } catch (Exception e) { LoggingUtils.HandleException(e); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; } }