public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, int index, out FRAMEINFO frameInfo) { frameInfo = new FRAMEINFO(); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { string funcName = m_thread.StackFrames[index].GetFunc(); if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { string rawSource = m_thread.StackFrames[index].GetSource(); var secs = rawSource.Split(' '); string fileName = secs[secs.Length - 1]; fileName = fileName.Replace("\"", ""); funcName += " in " + Path.GetFileNameWithoutExtension(fileName); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE; } frameInfo.m_bstrFuncName = funcName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { frameInfo.m_bstrFuncName = funcName + " line " + m_thread.StackFrames[index].GetLine(); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES; } } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { frameInfo.m_bstrLanguage = "Lua"; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame have symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = 1; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } }
int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { string moduleName = StackFrame.FileName; if (moduleName != null) { try { moduleName = Path.GetFileName(moduleName); } catch (ArgumentException) { } } else if (!StackFrame.IsGlobal) { moduleName = "<unknown>"; } var fi = new FRAMEINFO(); if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_LANGUAGE)) { fi.m_bstrLanguage = RContentTypeDefinition.LanguageName; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO)) { fi.m_fHasDebugInfo = 1; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_STALECODE)) { fi.m_fStaleCode = 0; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FRAME)) { fi.m_pFrame = this; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_MODULE) && moduleName != null) { fi.m_bstrModule = moduleName; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME)) { fi.m_bstrFuncName = StackFrame.CallingFrame?.Call ?? (StackFrame.IsGlobal ? "<global>" : "<unknown>"); fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) && moduleName != null) { fi.m_bstrFuncName += " in " + moduleName; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) && StackFrame.LineNumber != null) { fi.m_bstrFuncName += " line " + StackFrame.LineNumber; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES; } } pFrameInfo[0] = fi; return VSConstants.S_OK; }
public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { List<SimpleVariableInformation> parameters = null; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0 && !this.Engine.DebuggedProcess.MICommandFactory.SupportsFrameFormatting) { Engine.DebuggedProcess.WorkerThread.RunOperation(async () => { parameters = await Engine.DebuggedProcess.GetParameterInfoOnly(Thread, ThreadContext); }); } SetFrameInfo(dwFieldSpec, out frameInfo, parameters); }
int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 ppEnum) { ThrowIfDisposed(); var fi = new FRAMEINFO[1]; var fis = _stackFrames.Value.Select(f => { var frame = (IDebugStackFrame2)new AD7StackFrame(Engine, f); Marshal.ThrowExceptionForHR(frame.GetInfo(dwFieldSpec, nRadix, fi)); return fi[0]; }).ToArray(); ppEnum = new AD7FrameInfoEnum(fis); return VSConstants.S_OK; }
/// <summary> /// Construct a FRAMEINFO for this stack frame with the requested information. /// </summary> internal void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO info) { info = new FRAMEINFO(); info.m_pFrame = this; info.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; info.m_bstrModule = Thread.Program.MainModule.Name; info.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME)) { info.m_bstrFuncName = GetDocumentContext().DocumentLocation.Description; info.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } }
// Retrieves a list of the stack frames for this thread. // We currently call into the process and get the frames. We might want to cache the frame info. int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 enumObject) { var stackFrames = _debuggedThread.Frames; if (stackFrames == null) { enumObject = null; return VSConstants.E_FAIL; } int numStackFrames = stackFrames.Count; var frameInfoArray = new FRAMEINFO[numStackFrames]; for (int i = 0; i < numStackFrames; i++) { var frame = new AD7StackFrame(_engine, this, stackFrames[i]); frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]); } enumObject = new AD7FrameInfoEnum(frameInfoArray); return VSConstants.S_OK; }
// Retrieves a list of the stack frames for this thread. // For the sample engine, enumerating the stack frames requires walking the callstack in the debuggee for this thread // and coverting that to an implementation of IEnumDebugFrameInfo2. // Real engines will most likely want to cache this information to avoid recomputing it each time it is asked for, // and or construct it on demand instead of walking the entire stack. int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS aFieldSpec, uint aRadix, out IEnumDebugFrameInfo2 oEnumObject) { // Check mStackFrame, not address because it is possible for 2 sequential breaks to be on the same address // but in that case we would need a new stack frame. // // EnumFrameInfo is called several times on each break becuase "different callers can call with different flags". // We ignore flags through and always return full, but EnumFrameInfo gets called half a dozen times which is slow // if we refresh each and every time. So we cache our info. if (mProcess.mStackFrame == null || true) { // Ask the lower-level to perform a stack walk on this thread //m_engine.DebuggedProcess.DoStackWalk(this.m_debuggedThread); oEnumObject = null; try { //System.Collections.Generic.List<X86ThreadContext> stackFrames = this.m_debuggedThread.StackFrames; //int numStackFrames = stackFrames.Count; FRAMEINFO[] xFrameInfoArray; //if (numStackFrames == 0) { // failed to walk any frames. Only return the top frame. xFrameInfoArray = new FRAMEINFO[1]; var xFrame = new AD7StackFrame(mEngine, this, mProcess); xFrame.SetFrameInfo((enum_FRAMEINFO_FLAGS)aFieldSpec, out xFrameInfoArray[0]); //} else { //frameInfoArray = new FRAMEINFO[numStackFrames]; //for (int i = 0; i < numStackFrames; i++) { //AD7StackFrame frame = new AD7StackFrame(m_engine, this, stackFrames[i]); //frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]); //} //} mProcess.mStackFrame = new AD7FrameInfoEnum(xFrameInfoArray); } catch (Exception e) { //catch (ComponentException e) { // return e.HResult; //} return EngineUtils.UnexpectedException(e); } } oEnumObject = mProcess.mStackFrame; return VSConstants.S_OK; }
public int EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 ppEnum) { FRAMEINFO[] frameInfoArray = new FRAMEINFO[FrameCount]; // Only top frame if(FrameCount == 1) { AD7StackFrame frame = new AD7StackFrame(m_engine, this); frame.SetFrameInfo(dwFieldSpec, 0, out frameInfoArray[0]); } else { for(int i =0; i<FrameCount;i++) { AD7StackFrame frame = new AD7StackFrame(m_engine, this); // stackframe[] frame.SetFrameInfo(dwFieldSpec, i, out frameInfoArray[i]); } } ppEnum = new AD7FrameInfoEnum(frameInfoArray); return VSConstants.S_OK; }
/// <summary> /// Retrieves a list of the stack frames for this thread. (http://msdn.microsoft.com/en-ca/library/bb145138.aspx) /// </summary> /// <param name="dwFieldSpec"> A combination of flags from the FRAMEINFO_FLAGS enumeration that specifies which fields of the /// FRAMEINFO structures are to be filled out. </param> /// <param name="nRadix"> Radix used in formatting numerical information in the enumerator. </param> /// <param name="ppEnum"> Returns an IEnumDebugFrameInfo2 object that contains a list of FRAMEINFO structures describing the /// stack frame. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 ppEnum) { if (this._id == "") { ppEnum = null; return(Constants.S_FALSE); } if (this._engine.evaluatedTheseFlags(this._id, dwFieldSpec)) { ppEnum = new AD7FrameInfoEnum(previousFrameInfoArray); return(Constants.S_OK); } // Ask for general stack information. if ((this._id != "") && (this._id != this._engine.currentThread()._id)) { _engine.eDispatcher.selectThread(this._id); } string stackResponse = _engine.eDispatcher.getStackFrames().Replace("#;;;;", ""); if (stackResponse == "") { ppEnum = null; return(Constants.S_FALSE); } string[] frameStrings = stackResponse.Split('#'); // Query the stack depth without inquiring GDB. int numStackFrames = frameStrings.Length; if (numStackFrames > 30) // limiting the amount of stackFrames to avoid VS crashing. { numStackFrames = 30; } ppEnum = null; try { bool created = false; FRAMEINFO[] frameInfoArray = new FRAMEINFO[numStackFrames]; for (int i = 0; i < numStackFrames; i++) { string[] frameInfo = frameStrings[i].Split(';'); if (frameInfo.Length >= 3) { if (frameInfo[3].Contains("~")) { // Need to lengthen the path used by Visual Studio. StringBuilder longPathName = new StringBuilder(1024); GetLongPathName(frameInfo[3], longPathName, longPathName.Capacity); frameInfo[3] = longPathName.ToString(); } AD7StackFrame frame = AD7StackFrame.create(_engine, this, frameInfo, ref created); frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]); } } if ((previousFrameInfoArray.Length != frameInfoArray.Length) || (created == true)) { previousFrameInfoArray = frameInfoArray; ppEnum = new AD7FrameInfoEnum(frameInfoArray); } else { bool isEqual = true; for (int i = 0; i < frameInfoArray.Length; i++) { if (frameInfoArray[i].m_bstrFuncName != previousFrameInfoArray[i].m_bstrFuncName) { isEqual = false; break; } if (frameInfoArray[i].m_dwValidFields != previousFrameInfoArray[i].m_dwValidFields) { isEqual = false; break; } if (frameInfoArray[i].m_bstrLanguage != previousFrameInfoArray[i].m_bstrLanguage) { isEqual = false; break; } } if (!isEqual) { previousFrameInfoArray = frameInfoArray; ppEnum = new AD7FrameInfoEnum(frameInfoArray); } else { ppEnum = new AD7FrameInfoEnum(previousFrameInfoArray); } } if ((this._id != "") && (this._id != this._engine.currentThread()._id)) { _engine.eDispatcher.selectThread(this._engine.currentThread()._id); } return(Constants.S_OK); } catch (ComponentException e) { if ((this._id != "") && (this._id != this._engine.currentThread()._id)) { _engine.eDispatcher.selectThread(this._engine.currentThread()._id); } return(e.HResult); } catch (Exception e) { if ((this._id != "") && (this._id != this._engine.currentThread()._id)) { _engine.eDispatcher.selectThread(this._engine.currentThread()._id); } return(EngineUtils.UnexpectedException(e)); } }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { frameInfo = new FRAMEINFO(); // AD7Module module = m_engine.m_module; // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { // If there is source information, construct a string that contains the module name, function name, and optionally argument names and values. if (m_hasSource) { frameInfo.m_bstrFuncName = ""; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { // Do we support modules? Would this just be the name of the program? // frameInfo.m_bstrFuncName = System.IO.Path.GetFileName(module.Name) + "!"; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_RETURNTYPE) != 0) { // Adds the return type to the m_bstrFuncName field. // TODO: Can we determine the value of this field? //frameInfo.m_bstrFuncName += _returnType; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LANGUAGE) != 0) { // Adds the language to the m_bstrFuncName field. if (m_documentName.EndsWith(".c")) frameInfo.m_bstrFuncName += "(C) "; else if (m_documentName.EndsWith(".cpp") || m_documentName.EndsWith(".c++")) frameInfo.m_bstrFuncName += "(C++) "; } frameInfo.m_bstrFuncName += m_functionName; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0) { // Add the arguments to the m_bstrFuncName field. frameInfo.m_bstrFuncName += "("; bool all = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_ALL) != 0; int i = 0; foreach (VariableInfo arg in _arguments) { if (all || (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0) { frameInfo.m_bstrFuncName += arg._type + " "; } if (all || (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0) { frameInfo.m_bstrFuncName += arg._name; } if (all || (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { frameInfo.m_bstrFuncName += "=" + arg._value; } if (i < _arguments.Count - 1) { frameInfo.m_bstrFuncName += ", "; } i++; } frameInfo.m_bstrFuncName += ")"; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { frameInfo.m_bstrFuncName += " Line: " + m_lineNum.ToString(); } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_OFFSET) != 0) { // TODO: // Adds to the m_bstrFuncName field the offset in bytes from the start of the line if FIF_FUNCNAME_LINES is specified. // If FIF_FUNCNAME_LINES is not specified, or if line numbers are not available, adds the offset in bytes from the start of the function. } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_FORMAT) != 0) { // TODO: // Formats the function name. The result is returned in the m_bstrFuncName field and no other fields are filled out. // According to http://msdn.microsoft.com/en-us/library/bb145138.aspx, this flag "Specify the FIF_FUNCNAME_FORMAT // flag to format the function name into a single string". This method already works on this way. } } else { frameInfo.m_bstrFuncName = "[External Code]"; // No source information, so only return the module name and the instruction pointer. /* if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { frameInfo.m_bstrFuncName = EngineUtils.GetAddressDescription(module, ip); } else { frameInfo.m_bstrFuncName = EngineUtils.GetAddressDescription(null, ip); } */ } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { frameInfo.m_bstrModule = ""; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_RETURNTYPE) != 0) { // TODO: // Initialize/use the m_bstrReturnType field. frameInfo.m_bstrReturnType = ""; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_RETURNTYPE; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS) != 0) { // Initialize/use the m_bstrArgs field. frameInfo.m_bstrArgs = ""; bool all = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_ALL) != 0; int i = 0; foreach (VariableInfo arg in _arguments) { if (all || (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_TYPES) != 0) { frameInfo.m_bstrArgs += arg._type + " "; } if (all || (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NAMES) != 0) { frameInfo.m_bstrArgs += arg._name; } if (all || (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_VALUES) != 0) { frameInfo.m_bstrArgs += "=" + arg._value; } if (i < _arguments.Count - 1) { frameInfo.m_bstrArgs += ", "; } i++; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NO_TOSTRING) != 0) { // TODO: // Do not allow ToString() function evaluation or formatting when returning function arguments. } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NO_FUNC_EVAL) != 0) { // TODO: // Specifies that function (property) evaluation should not be used when retrieving argument values. } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NOFORMAT) != 0) { // TODO: // Specifies that the arguments are not be formatted (for example, do not add opening and closing parentheses around // the argument list nor add a separator between arguments). } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_ARGS; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { // Initialize/use the m_bstrLanguage field. if (m_documentName != null) { if (m_documentName.EndsWith(".c")) frameInfo.m_bstrLanguage = "C"; else if (m_documentName.EndsWith(".cpp") || m_documentName.EndsWith(".c++")) frameInfo.m_bstrLanguage = "C++"; else frameInfo.m_bstrLanguage = ""; } else frameInfo.m_bstrLanguage = ""; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { frameInfo.m_pModule = m_engine.m_module; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; } // The debugger is requesting the range of memory addresses for this frame. // For the sample engine, this is the contents of the frame pointer. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STACKRANGE) != 0) { // TODO: // Initialize/use the m_addrMin and m_addrMax (stack range) fields. //frameInfo.m_addrMin = m_threadContext.ebp; //frameInfo.m_addrMax = m_threadContext.ebp; frameInfo.m_addrMin = 0; frameInfo.m_addrMax = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STACKRANGE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = m_hasSource ? 1 : 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debug engine is to filter non-user code frames so they are not included. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FILTER_NON_USER_CODE ) != 0) { } // Frame information should be gotten from the hosted app-domain rather than the hosting process. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DESIGN_TIME_EXPR_EVAL) != 0) { } }
public int GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { pFrameInfo[0] = GetFrameInfo(dwFieldSpec); return VSConstants.S_OK; }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { frameInfo = new FRAMEINFO(); var frame = _frame(); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { // If there is source information, construct a string that contains the module name, function name, and optionally argument names and values. if (_hasSource) { frameInfo.m_bstrFuncName = ""; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { frameInfo.m_bstrFuncName = Path.GetFileName(frame.FullModuleName) + "!"; } frameInfo.m_bstrFuncName += _functionName; if (((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0) && (_parameters.Length > 0)) { frameInfo.m_bstrFuncName += "("; for (var i = 0; i < _parameters.Length; i++) { if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0) { frameInfo.m_bstrFuncName += _parameters[i].TypeName + " "; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0) { frameInfo.m_bstrFuncName += _parameters[i].Name; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { frameInfo.m_bstrFuncName += "=" + _parameters[i].Value; } if (i < _parameters.Length - 1) { frameInfo.m_bstrFuncName += ", "; } } frameInfo.m_bstrFuncName += ")"; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { frameInfo.m_bstrFuncName += " Line:" + (uint)LineNumber; } } else { // No source information, so only return the module name and the instruction pointer. frameInfo.m_bstrFuncName = frame.AddressSpace; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { frameInfo.m_bstrModule = frame.FullModuleName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the range of memory addresses for this frame. // For the sample engine, this is the contents of the frame pointer. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STACKRANGE) != 0) { frameInfo.m_addrMin = (ulong)frame.Address; frameInfo.m_addrMax = (ulong)frame.Address; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STACKRANGE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = _hasSource ? 1 : 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { // if (module != null) // { // AD7Module ad7Module = (AD7Module)module.Client; // Debug.Assert(ad7Module != null); // frameInfo.m_pModule = ad7Module; // frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; // } } }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { System.Diagnostics.Debug.WriteLine("In AD7StackFrame.SetFrameInfo"); System.Diagnostics.Debug.WriteLine("\tdwFieldSpec = " + dwFieldSpec.ToString()); frameInfo = new FRAMEINFO(); //uint ip = m_threadContext.eip; //DebuggedModule module = null;// m_engine.DebuggedProcess.ResolveAddress(ip); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME)) { // If there is source information, construct a string that contains the module name, function name, and optionally argument names and values. if (mHasSource) { frameInfo.m_bstrFuncName = ""; if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE)) { // m_ //frameInfo.m_bstrFuncName = System.IO.Path.GetFileName(module.Name) + "!"; frameInfo.m_bstrFuncName = "module!"; } frameInfo.m_bstrFuncName += mFunctionName; if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) && mArgumentInfos.Length > 0) { frameInfo.m_bstrFuncName += "("; for (int i = 0; i < mParams.Length; i++) { if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0) { //frameInfo.m_bstrFuncName += m_parameters[i]. + " "; frameInfo.m_bstrFuncName += "ParamType "; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0) { frameInfo.m_bstrFuncName += mParams[i].Name; } // if ((dwFieldSpec & (uint)enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { // frameInfo.m_bstrFuncName += "=" + m_parameters[i].m_value; // } if (i < mParams.Length - 1) { frameInfo.m_bstrFuncName += ", "; } } frameInfo.m_bstrFuncName += ")"; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES)) { frameInfo.m_bstrFuncName += " Line:" + mLineNum.ToString(); } } else { // No source information, so only return the module name and the instruction pointer. if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE)) { //frameInfo.m_bstrFuncName = EngineUtils.GetAddressDescription(module, ip); } else { //frameInfo.m_bstrFuncName = EngineUtils.GetAddressDescription(null, ip); } } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } // The debugger is requesting the name of the module for this stack frame. if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_MODULE)) { frameInfo.m_bstrModule = "module"; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the range of memory addresses for this frame. // For the sample engine, this is the contents of the frame pointer. if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_STACKRANGE)) { //frameInfo.m_addrMin = m_threadContext.ebp; //frameInfo.m_addrMax = m_threadContext.ebp; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STACKRANGE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FRAME)) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO)) { frameInfo.m_fHasDebugInfo = mHasSource ? 1 : 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_STALECODE)) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP)) { if (mEngine.mModule != null) { frameInfo.m_pModule = mEngine.mModule; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; } } }
// Construct a FRAMEINFO for this stack frame with the requested information. public FRAMEINFO CreateFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec) { FRAMEINFO frameInfo = new FRAMEINFO(); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { // If there is source information, construct a string that contains the module name, function name, and optionally argument names and values. frameInfo.m_bstrFuncName = ""; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { frameInfo.m_bstrFuncName = _stackFrame.FullModuleName + "!"; } frameInfo.m_bstrFuncName += _stackFrame.SourceLocation.MethodName; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0 && _parameters.Length > 0) { frameInfo.m_bstrFuncName += "("; for (int i = 0; i < _parameters.Length; i++) { if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0) { frameInfo.m_bstrFuncName += _parameters[i].TypeName + " "; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0) { frameInfo.m_bstrFuncName += _parameters[i].Name; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { frameInfo.m_bstrFuncName += "=" + _parameters[i].Value; } if (i < _parameters.Length - 1) { frameInfo.m_bstrFuncName += ", "; } } frameInfo.m_bstrFuncName += ")"; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { frameInfo.m_bstrFuncName += " Line:" + _stackFrame.SourceLocation.Line.ToString(); } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { frameInfo.m_bstrModule = _stackFrame.FullModuleName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the range of memory addresses for this frame. // For the sample engine, this is the contents of the frame pointer. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STACKRANGE) != 0) { /*frameInfo.m_addrMin = m_threadContext.ebp; * frameInfo.m_addrMax = m_threadContext.ebp; * frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STACKRANGE;*/ } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = _stackFrame.HasDebugInfo ? 1 : 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. /*if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) * { * if (module != null) * { * XamarinModule XamarinModule = (XamarinModule)module.Client; * Debug.Assert(XamarinModule != null); * frameInfo.m_pModule = XamarinModule; * frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; * } * }*/ return(frameInfo); }
public AsStackFrame(FRAMEINFO frameInfo) { frameInfo_ = frameInfo; }
// Gets a description of the stack frame. int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { SetFrameInfo(dwFieldSpec, out pFrameInfo[0]); return VSConstants.S_OK; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public virtual int SetFrameInfo(enum_FRAMEINFO_FLAGS requestedFlags, uint radix, ref FRAMEINFO frameInfo) { LoggingUtils.PrintFunction(); try { throw new NotImplementedException(); } catch (NotImplementedException e) { LoggingUtils.HandleException(e); return(Constants.E_NOTIMPL); } }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { frameInfo = new FRAMEINFO(); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { string funcName = _stackFrame.FunctionName; if (funcName == "<module>") { if (_stackFrame.FileName.IndexOfAny(Path.GetInvalidPathChars()) == -1) { funcName = Path.GetFileName(_stackFrame.FileName) + " module"; } else if (_stackFrame.FileName.EndsWith("<string>", StringComparison.Ordinal)) { funcName = "<exec or eval>"; } else { funcName = _stackFrame.FileName + " unknown code"; } } else { if (_stackFrame.FileName != "<unknown>") { funcName = string.Format(CultureInfo.InvariantCulture, "{0} [{1}]", funcName, Path.GetFileName(_stackFrame.FileName)); } else { funcName = funcName + " in <unknown>"; } } frameInfo.m_bstrFuncName = string.Format(CultureInfo.InvariantCulture, "{0} Line {1}", funcName, _stackFrame.Line + 1); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { Guid dummy; AD7Engine.MapLanguageInfo(_stackFrame.FileName, out frameInfo.m_bstrLanguage, out dummy); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { if (_stackFrame.FileName.IndexOfAny(Path.GetInvalidPathChars()) == -1) { frameInfo.m_bstrModule = Path.GetFileName(_stackFrame.FileName); } else if (_stackFrame.FileName.EndsWith("<string>", StringComparison.Ordinal)) { frameInfo.m_bstrModule = "<exec/eval>"; } else { frameInfo.m_bstrModule = "<unknown>"; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = 1; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { // TODO: Module /* * if (module != null) * { * AD7Module ad7Module = (AD7Module)module.Client; * Debug.Assert(ad7Module != null); * frameInfo.m_pModule = ad7Module; * frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; * }*/ } }
public static bool IsAnnotatedFrame(ref FRAMEINFO frameInfo) { enum_FRAMEINFO_FLAGS_VALUES flags = unchecked ((enum_FRAMEINFO_FLAGS_VALUES)frameInfo.m_dwFlags); return(flags.HasFlag(enum_FRAMEINFO_FLAGS_VALUES.FIFV_ANNOTATEDFRAME)); }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo, List <SimpleVariableInformation> parameters) { frameInfo = new FRAMEINFO(); DebuggedModule module = ThreadContext.FindModule(Engine.DebuggedProcess); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { // If there is source information, construct a string that contains the module name, function name, and optionally argument names and values. if (_textPosition != null) { frameInfo.m_bstrFuncName = ""; if (module != null && (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { frameInfo.m_bstrFuncName = System.IO.Path.GetFileName(module.Name) + "!"; } frameInfo.m_bstrFuncName += _functionName; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0 && !Engine.DebuggedProcess.MICommandFactory.SupportsFrameFormatting) { frameInfo.m_bstrFuncName += "("; if (parameters != null && parameters.Count > 0) { for (int i = 0; i < parameters.Count; i++) { if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0) { frameInfo.m_bstrFuncName += parameters[i].TypeName + " "; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0) { frameInfo.m_bstrFuncName += parameters[i].Name; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0 && (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { frameInfo.m_bstrFuncName += "="; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { frameInfo.m_bstrFuncName += parameters[i].Value; } if (i < parameters.Count - 1) { frameInfo.m_bstrFuncName += ", "; } } } frameInfo.m_bstrFuncName += ")"; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { frameInfo.m_bstrFuncName += string.Format(CultureInfo.CurrentCulture, " Line {0}", _textPosition.BeginPosition.dwLine + 1); } } else { // No source information, so only return the module name and the instruction pointer. if (_functionName != null) { if (module != null) { frameInfo.m_bstrFuncName = System.IO.Path.GetFileName(module.Name) + '!' + _functionName; } else { frameInfo.m_bstrFuncName = _functionName; } } else if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0 && module != null) { frameInfo.m_bstrFuncName = module.Name + '!' + EngineUtils.GetAddressDescription(Engine.DebuggedProcess, ThreadContext.pc.Value); } else { frameInfo.m_bstrFuncName = EngineUtils.GetAddressDescription(Engine.DebuggedProcess, ThreadContext.pc.Value); } } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { if (module != null) { frameInfo.m_bstrModule = module.Name; } else { frameInfo.m_bstrModule = ""; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the range of memory addresses for this frame. // For the sample engine, this is the contents of the frame pointer. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STACKRANGE) != 0) { frameInfo.m_addrMin = ThreadContext.sp; frameInfo.m_addrMax = ThreadContext.sp; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STACKRANGE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = _textPosition != null ? 1 : 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { if (module != null) { AD7Module ad7Module = (AD7Module)module.Client; Debug.Assert(ad7Module != null); frameInfo.m_pModule = ad7Module; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; } } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FLAGS) != 0) { if (_codeCxt == null && _documentCxt == null) { frameInfo.m_dwFlags |= (uint)enum_FRAMEINFO_FLAGS_VALUES.FIFV_ANNOTATEDFRAME; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FLAGS; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { Guid unused = Guid.Empty; if (GetLanguageInfo(ref frameInfo.m_bstrLanguage, ref unused) == 0) { frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } } }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { frameInfo = new FRAMEINFO(); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { string funcName = _stackFrame.FileName; if (funcName.Length > 0) { funcName += "!"; } funcName += _stackFrame.FunctionName; /* * if (funcName == "<module>") { * if (CommonUtils.IsValidPath(_stackFrame.FileName)) { * funcName = Path.GetFileNameWithoutExtension(_stackFrame.FileName) + " module"; * } else if (_stackFrame.FileName.EndsWith("<string>")) { * funcName = "<exec or eval>"; * } else { * funcName = _stackFrame.FileName + " unknown code"; * } * } else if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { * if (CommonUtils.IsValidPath(_stackFrame.FileName)) { * funcName += " in " + Path.GetFileNameWithoutExtension(_stackFrame.FileName); * } else { * funcName += " in " + _stackFrame.FileName; * } * frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE; * } */ frameInfo.m_bstrFuncName = funcName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { if (_stackFrame.LineNo >= 0) { frameInfo.m_bstrFuncName = funcName + " Line " + _stackFrame.LineNo; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES; } } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { switch (_stackFrame.Kind) { case FrameKind.Lua: frameInfo.m_bstrLanguage = "Lua"; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; break; case FrameKind.Django: frameInfo.m_bstrLanguage = "Django Templates"; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; break; } } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { if (CommonUtils.IsValidPath(_stackFrame.FileName)) { frameInfo.m_bstrModule = Path.GetFileNameWithoutExtension(this._stackFrame.FileName); } else if (_stackFrame.FileName.EndsWith("<string>")) { frameInfo.m_bstrModule = "<exec/eval>"; } else { frameInfo.m_bstrModule = "<unknown>"; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = 1; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { // TODO: Module /* * if (module != null) * { * AD7Module ad7Module = (AD7Module)module.Client; * Debug.Assert(ad7Module != null); * frameInfo.m_pModule = ad7Module; * frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; * }*/ } }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { frameInfo = new FRAMEINFO(); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { string funcName = _stackFrame.GetQualifiedFunctionName(); if (funcName == "<module>") { if (PathUtils.IsValidPath(_stackFrame.FileName)) { funcName = Strings.DebugFileModule.FormatUI(Path.GetFileNameWithoutExtension(_stackFrame.FileName)); } else if (_stackFrame.FileName.EndsWithOrdinal("<string>")) { funcName = Strings.DebugExecEvalFunctionName; } else if (_stackFrame.FileName.EndsWithOrdinal("<stdin>")) { funcName = Strings.DebugReplInputFunctionName; } else { funcName = Strings.DebugFileUnknownCode.FormatUI(_stackFrame.FileName); } } else if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { funcName = Strings.DebugStackFrameInfoFunctionNameInFileName.FormatUI( funcName, PathUtils.IsValidPath(_stackFrame.FileName) ? Path.GetFileNameWithoutExtension(_stackFrame.FileName) : _stackFrame.FileName ); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE; } frameInfo.m_bstrFuncName = funcName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { frameInfo.m_bstrFuncName = Strings.DebugStackFrameFunctionWithLine.FormatUI(funcName, _stackFrame.LineNo); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES; } } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { switch (_stackFrame.Kind) { case FrameKind.Python: frameInfo.m_bstrLanguage = DebuggerLanguageNames.Python; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; break; case FrameKind.Django: frameInfo.m_bstrLanguage = DebuggerLanguageNames.DjangoTemplates; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; break; } } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { if (PathUtils.IsValidPath(_stackFrame.FileName)) { frameInfo.m_bstrModule = Path.GetFileNameWithoutExtension(this._stackFrame.FileName); } else if (_stackFrame.FileName.EndsWithOrdinal("<string>")) { frameInfo.m_bstrModule = Strings.DebugExecEvalModuleName; } else if (_stackFrame.FileName.EndsWithOrdinal("<stdin>")) { frameInfo.m_bstrModule = Strings.DebugReplModuleName; } else { frameInfo.m_bstrModule = Strings.DebugUnknownModuleName; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = 1; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { // TODO: Module /* * if (module != null) * { * AD7Module ad7Module = (AD7Module)module.Client; * Debug.Assert(ad7Module != null); * frameInfo.m_pModule = ad7Module; * frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; * }*/ } }
/// <summary> /// Gets a description of the stack frame. /// </summary> /// <param name="dwFieldSpec">A combination of flags from the FRAMEINFO_FLAGS enumeration that specifies which fields of the pFrameInfo parameter are to be filled in.</param> /// <param name="nRadix">The radix to be used in formatting any numerical information.</param> /// <param name="pFrameInfo">A FRAMEINFO structure that is filled in with the description of the stack frame.</param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> public virtual int GetInfo( enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo ) { Logger.Debug( string.Empty ); return VSConstants.E_NOTIMPL; }
/// <summary> /// Gets a description of the stack frame. (http://msdn.microsoft.com/en-us/library/bb145146.aspx) /// </summary> /// <param name="dwFieldSpec"> A combination of flags from the FRAMEINFO_FLAGS enumeration that specifies which fields of the /// pFrameInfo parameter are to be filled in. </param> /// <param name="nRadix"> The radix to be used in formatting any numerical information. </param> /// <param name="pFrameInfo"> A FRAMEINFO structure that is filled in with the description of the stack frame. </param> /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns> int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { try { SetFrameInfo(dwFieldSpec, out pFrameInfo[0]); int frame = 0; if (this.m_thread.__stackFrames != null) { foreach (AD7StackFrame sf in this.m_thread.__stackFrames) { if (sf.m_functionName == this.m_functionName) break; frame++; } } if (this.m_thread._id != this.m_engine.currentThread()._id) this.m_engine.eDispatcher.selectThread(this.m_thread._id); // Waits for the parsed response for the GDB/MI command that changes the selected frame. // (http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Stack-Manipulation.html) GDBParser.parseCommand("-stack-select-frame " + frame, 5); if (this.m_thread._id != this.m_engine.currentThread()._id) this.m_engine.eDispatcher.selectThread(this.m_engine.currentThread()._id); this.m_engine.cleanEvaluatedThreads(); return VSConstants.S_OK; } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
// Retrieves a list of the stack frames for this thread. // For the sample engine, enumerating the stack frames requires walking the callstack in the debuggee for this thread // and coverting that to an implementation of IEnumDebugFrameInfo2. // Real engines will most likely want to cache this information to avoid recomputing it each time it is asked for, // and or construct it on demand instead of walking the entire stack. int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 enumObject) { // Ask the lower-level to perform a stack walk on this thread m_engine.DebuggedProcess.DoStackWalk(this.m_debuggedThread); enumObject = null; try { System.Collections.Generic.List<X86ThreadContext> stackFrames = this.m_debuggedThread.StackFrames; int numStackFrames = stackFrames.Count; FRAMEINFO[] frameInfoArray; if (numStackFrames == 0) { // failed to walk any frames. Only return the top frame. frameInfoArray = new FRAMEINFO[1]; AD7StackFrame frame = new AD7StackFrame(m_engine, this, GetThreadContext()); frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[0]); } else { frameInfoArray = new FRAMEINFO[numStackFrames]; for (int i = 0; i < numStackFrames; i++) { AD7StackFrame frame = new AD7StackFrame(m_engine, this, stackFrames[i]); frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]); } } enumObject = new AD7FrameInfoEnum(frameInfoArray); return Constants.S_OK; } catch (ComponentException e) { return e.HResult; } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
private FRAMEINFO[] GetCallStackInternal() { int hr = VSConstants.S_OK; IDebugThread2 thread = debuggerServiceInternal_.CurrentThread; if (thread == null) { throw new Exception("AsDebugger : Could not get CurrentThread"); } IEnumDebugFrameInfo2 enumDebugFrameInfo2; hr = thread.EnumFrameInfo( enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO | enum_FRAMEINFO_FLAGS.FIF_MODULE | enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FUNCNAME, 0, out enumDebugFrameInfo2); if (hr != VSConstants.S_OK) { throw new Exception("AsDebugger : Could not enumerate stack frames."); } enumDebugFrameInfo2.Reset(); uint pcelt = 0; enumDebugFrameInfo2.GetCount(out pcelt); FRAMEINFO[] frameInfo = new FRAMEINFO[pcelt]; uint fetched = 0; hr = enumDebugFrameInfo2.Next(pcelt, frameInfo, ref fetched); if (hr != VSConstants.S_OK) { throw new Exception("AsDebugger : Could not get FRAMEINFO"); } return frameInfo; }
public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo) { frameInfo = new FRAMEINFO(); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { string funcName = _stackFrame.FunctionName; if (funcName == "<module>") { if (_stackFrame.FileName.IndexOfAny(Path.GetInvalidPathChars()) == -1) { funcName = Path.GetFileNameWithoutExtension(_stackFrame.FileName) + " module"; } else if (_stackFrame.FileName.EndsWith("<string>")) { funcName = "<exec or eval>"; } else { funcName = _stackFrame.FileName + " unknown code"; } } else if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { funcName += " in " + Path.GetFileName(_stackFrame.FileName); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { funcName += " Line " + _stackFrame.Line; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES; } frameInfo.m_bstrFuncName = funcName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { frameInfo.m_bstrLanguage = NodeConstants.LanguageName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { if (_stackFrame.FileName.IndexOfAny(Path.GetInvalidPathChars()) == -1) { frameInfo.m_bstrModule = Path.GetFileNameWithoutExtension(_stackFrame.FileName); } else if (_stackFrame.FileName.EndsWith("<string>")) { frameInfo.m_bstrModule = "<exec/eval>"; } else { frameInfo.m_bstrModule = "<unknown>"; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = 1; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { // TODO: Module /* if (module != null) { AD7Module ad7Module = (AD7Module)module.Client; Debug.Assert(ad7Module != null); frameInfo.m_pModule = ad7Module; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; }*/ } }
private string InterpolateToken(string token, IDebugThread2 pThread, IDebugStackFrame2 topFrame, uint radix, string processName, int processId) { switch (token) { case "$FUNCTION": { int hr = topFrame.GetCodeContext(out IDebugCodeContext2 pCodeContext); if (hr >= 0) { CONTEXT_INFO[] pInfo = new CONTEXT_INFO[1]; hr = pCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, pInfo); if (hr >= 0) { return(pInfo[0].bstrFunction); } } return(string.Format(CultureInfo.InvariantCulture, "<No Function Found>")); } case "$ADDRESS": { int hr = topFrame.GetCodeContext(out IDebugCodeContext2 pCodeContext); if (hr >= 0) { CONTEXT_INFO[] pInfo = new CONTEXT_INFO[1]; hr = pCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, pInfo); if (hr >= 0) { return(pInfo[0].bstrAddress); } } return(string.Format(CultureInfo.InvariantCulture, "<No Address Found>")); } case "$FILEPOS": { int hr = topFrame.GetDocumentContext(out IDebugDocumentContext2 pDocumentContext); if (hr >= 0) { hr = pDocumentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out string fileName); if (hr >= 0) { TEXT_POSITION[] textPosBeg = new TEXT_POSITION[1]; TEXT_POSITION[] textPosEnd = new TEXT_POSITION[1]; hr = pDocumentContext.GetStatementRange(textPosBeg, textPosEnd); if (hr >= 0) { return(string.Format(CultureInfo.InvariantCulture, "{0}({1})", fileName, textPosBeg[0].dwLine + 1)); } } } return(string.Format(CultureInfo.InvariantCulture, "<No File Position>")); } case "$CALLER": { IEnumDebugFrameInfo2 frameInfoEnum; int hr = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FLAGS, Constants.EvaluationRadix, out frameInfoEnum); if (hr >= 0) { FRAMEINFO[] frames = new FRAMEINFO[2]; uint fetched = 0; hr = frameInfoEnum.Next(2, frames, ref fetched); if (hr < 0 && fetched == 2) { return(frames[1].m_bstrFuncName); } } return(string.Format(CultureInfo.InvariantCulture, "<No Caller Avaliable>")); } case "$TID": { int hr = pThread.GetThreadId(out uint threadId); if (hr == 0) { if (radix == 16) { return(string.Format(CultureInfo.InvariantCulture, "{0:X}", threadId)); } else { return(string.Format(CultureInfo.InvariantCulture, "{0}", threadId)); } } return(string.Format(CultureInfo.InvariantCulture, "<No Thread Id>")); } case "$TNAME": { int hr = pThread.GetName(out string name); if (hr == 0) { return(name); } return(string.Format(CultureInfo.InvariantCulture, "<No Thread Name>")); } case "$PID": { if (processId != Constants.InvalidProcessId) { return(processId.ToString(CultureInfo.InvariantCulture)); } return(string.Format(CultureInfo.InvariantCulture, "<Unknown PID>", token)); } case "$PNAME": { return(processName); } case "$CALLSTACK": { IEnumDebugFrameInfo2 frameInfoEnum; int hr = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FLAGS, Constants.EvaluationRadix, out frameInfoEnum); int count = 0; StringBuilder sb = new StringBuilder(); while (count < Constants.DefaultTracepointCallstackDepth) { FRAMEINFO[] frames = new FRAMEINFO[1]; uint fetched = 0; hr = frameInfoEnum.Next(1, frames, ref fetched); if (fetched == 1) { // TODO: Do we want function arguments? frames[0].m_pFrame.GetName(out string name); sb.AppendLine(name); } count++; } return(sb.ToString()); } case "$TICK": return(string.Format(CultureInfo.InvariantCulture, "{0}", Environment.TickCount)); default: return(string.Format(CultureInfo.InvariantCulture, "<Unknown Token: ${0}>", token)); } }
public static ExceptionStackInformation PrintFrames(IDebugThread2 pThread) { int hr = 0; uint threadID = 0; ExceptionStackInformation exceptionStackInfo = null; hr = pThread.GetThreadId(out threadID); IEnumDebugFrameInfo2 enumDebugFrameInfo2; hr = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME, 0, out enumDebugFrameInfo2); if (hr == 0) { FRAMEINFO[] frameInfo = new FRAMEINFO[1]; uint fetched = 0; hr = enumDebugFrameInfo2.Reset(); exceptionStackInfo = new ExceptionStackInformation(); while (enumDebugFrameInfo2.Next(1, frameInfo, ref fetched) == VSConstants.S_OK) { IDebugStackFrame3 stackFrame = frameInfo[0].m_pFrame as IDebugStackFrame3; //IDebugThread2 debugThread; IDebugThread2 debugThread; hr = stackFrame.GetThread(out debugThread); uint sfThreadID = 0; hr = debugThread.GetThreadId(out sfThreadID); if (sfThreadID == threadID) { System.Diagnostics.Debug.WriteLine("We got the right stackframe!!!"); if (stackFrame != null) { StackFrameInformation stackFrameInfo = new StackFrameInformation(); IDebugDocumentContext2 docContext; hr = stackFrame.GetDocumentContext(out docContext); TEXT_POSITION[] startPos = new TEXT_POSITION[1]; TEXT_POSITION[] endPos = new TEXT_POSITION[1]; if (docContext == null) continue; hr = docContext.GetStatementRange(startPos, endPos); var advancedThread = pThread as IDebugThread3; if (advancedThread != null && advancedThread.IsCurrentException() == 0) { var message = ExtractExceptionMessage(stackFrame); if (message != null) { System.Diagnostics.Debug.WriteLine("EXCEPTION: " + message); exceptionStackInfo.ExceptionMessage = message; } var type = ExtractExceptionType(stackFrame); if (type != null) { System.Diagnostics.Debug.WriteLine("EXCEPTION TYPE: " + type); type = type.Replace("\"", ""); exceptionStackInfo.ExceptionKind = type; } } // not for cs...debugging js //IDebugDocument2 document; //docContext.GetDocument(out document); //IDebugDocumentText2 documentText = document as IDebugDocumentText2; //var line = GetDocumentText(documentText, startPos[0]); var line = GetTextLine(docContext, startPos[0], endPos[0]); System.Diagnostics.Debug.WriteLine(string.Format("Line {0}", line )); string fileName = ""; stackFrame.GetName(out fileName); System.Diagnostics.Debug.WriteLine(string.Format("File {0} Function {1}", fileName, frameInfo[0].m_bstrFuncName)); string t = string.Format("start: line({0}) col({1})", startPos[0].dwLine.ToString(), startPos[0].dwColumn.ToString()); System.Diagnostics.Debug.WriteLine(t); t = string.Format("end: line({0}) col({1})", endPos[0].dwLine.ToString(), endPos[0].dwColumn.ToString()); System.Diagnostics.Debug.WriteLine(t); stackFrameInfo.File = fileName; stackFrameInfo.LineNumber = (int)startPos[0].dwLine; stackFrameInfo.ColumnNumber = (int)startPos[0].dwColumn; stackFrameInfo.FramePath = frameInfo[0].m_bstrFuncName; stackFrameInfo.Line = line; exceptionStackInfo.Frames.Add(stackFrameInfo); } } } } return exceptionStackInfo; }
public int GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { DLog.Debug(DContext.VSDebuggerComCall, "DebugStackFrame.GetInfo"); SetFrameInfo(dwFieldSpec, out pFrameInfo[0]); return VSConstants.S_OK; }
internal FRAMEINFO GetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec) { var frameInfo = new FRAMEINFO(); frameInfo.m_bstrFuncName = frame.Location.Method.Name; frameInfo.m_bstrModule = frame.FileName; frameInfo.m_pFrame = this; frameInfo.m_fHasDebugInfo = 1; frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; return frameInfo; }
// Gets a description of the stack frame. int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { try { SetFrameInfo(dwFieldSpec, out pFrameInfo[0]); return Constants.S_OK; } catch (MIException e) { return e.HResult; } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
public int EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 ppEnum) { ppEnum = null; List<FRAMEINFO> frames = new List<FRAMEINFO>(); #if !HIDE_THREADS ReadOnlyCollection<IStackFrame> stackFrames = _thread.GetFrames(); FRAMEINFO[] frameInfo = new FRAMEINFO[1]; foreach (var stackFrame in stackFrames) { JavaDebugStackFrame javaStackFrame = new JavaDebugStackFrame(this, stackFrame); int result = javaStackFrame.GetInfo(dwFieldSpec, nRadix, frameInfo); if (!ErrorHandler.Succeeded(result)) return result; frames.Add(frameInfo[0]); } #endif ppEnum = new EnumDebugFrameInfo(frames); return VSConstants.S_OK; }
private int GetInterpolatedLogMessage(string logMessage, IDebugThread2 pThread, uint radix, string processName, int processId, out string message) { int hr = HRConstants.S_OK; if (pThread == null) { message = AD7Resources.Error_InterpolateMissingThread; return(HRConstants.E_FAIL); } // Get topFrame IEnumDebugFrameInfo2 frameInfoEnum; hr = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FLAGS, Constants.EvaluationRadix, out frameInfoEnum); if (hr < 0) { message = AD7Resources.Error_InterpolateMissingFrames; return(hr); } FRAMEINFO[] topFrame = new FRAMEINFO[1]; uint fetched = 0; hr = frameInfoEnum.Next(1, topFrame, ref fetched); if (hr < 0 || fetched != 1 || topFrame[0].m_pFrame == null) { message = AD7Resources.Error_InterpolateMissingTopFrame; return(hr); } Dictionary <string, string> seenExpressions = new Dictionary <string, string>(); StringBuilder sb = new StringBuilder(); int currIndex = 0; foreach (KeyValuePair <int, string> keyValuePair in m_indexToExpressions) { // Add all characters between current index to the insertion index. sb.Append(LogMessage.Substring(currIndex, keyValuePair.Key - currIndex)); // Move current index to end of replaced string. currIndex = keyValuePair.Key + keyValuePair.Value.Length; if (!seenExpressions.TryGetValue(keyValuePair.Value, out string value)) { if (keyValuePair.Value[0] == '$') { value = InterpolateToken(keyValuePair.Value, pThread, topFrame[0].m_pFrame, radix, processName, processId); } else { string toInterpolate = keyValuePair.Value; if (InterpolateVariable(toInterpolate.Substring(1, toInterpolate.Length - 2), topFrame[0].m_pFrame, radix, out value) < 0) { hr = HRConstants.E_FAIL; DebuggerTelemetry.ReportError(DebuggerTelemetry.TelemetryTracepointEventName, value); // Re-write error message value = string.Format(CultureInfo.CurrentCulture, "<Failed to interpolate {0}: \"{1}\">", toInterpolate, value); } } // Cache expression seenExpressions[keyValuePair.Value] = value; } sb.Append(value); } // Append the rest of LogMessage sb.Append(LogMessage.Substring(currIndex, LogMessage.Length - currIndex)); message = sb.ToString(); return(hr); }
int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 ppEnum) { // Query the stack depth inquiring GDB. // int numStackFrames = _engine.eDispatcher.getStackDepth(); if (this._id == "") { ppEnum = null; return Constants.S_FALSE; } if (this._engine.evaluatedTheseFlags(this._id, dwFieldSpec)) { ppEnum = new AD7FrameInfoEnum(previousFrameInfoArray); return Constants.S_OK; } // Ask for general stack information. if ((this._id != "") && (this._id != this._engine.currentThread()._id)) _engine.eDispatcher.selectThread(this._id); string stackResponse = _engine.eDispatcher.getStackFrames().Replace("#;;;;", ""); if (stackResponse == "") { ppEnum = null; return Constants.S_FALSE; } string[] frameStrings = stackResponse.Split('#'); // Query the stack depth without inquiring GDB. int numStackFrames = frameStrings.Length; if (numStackFrames > 30) // limiting the amount of stackFrames to avoid VS crashing. numStackFrames = 30; ppEnum = null; try { bool created = false; FRAMEINFO[] frameInfoArray = new FRAMEINFO[numStackFrames]; for (int i = 0; i < numStackFrames; i++) { string[] frameInfo = frameStrings[i].Split(';'); if (frameInfo.Length >= 3) { if (frameInfo[3].Contains("~")) { // Need to lengthen the path used by Visual Studio. StringBuilder longPathName = new StringBuilder(1024); GetLongPathName(frameInfo[3], longPathName, longPathName.Capacity); frameInfo[3] = longPathName.ToString(); } AD7StackFrame frame = AD7StackFrame.create(_engine, this, frameInfo, ref created); if (frame.m_thread.__stackFrames == null) // that's weird, but sometimes VS is not initializing __stackFrames, so I added this loop to avoid other problems. { while (frame.m_thread.__stackFrames == null) frame.m_thread.__stackFrames = new ArrayList() { frame }; // frame.m_thread.__stackFrames.Add(frame); } // if ((_filename != "") || (created == true)) frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]); } } // Ignoring when _filename is null to avoid duplicate entries in Call Stack Window. // if ((_filename == "") && (created == false)) // { // ppEnum = null; // if (this._id != "") // _engine.eDispatcher.selectThread(this._engine.currentThread()._id); // return Constants.S_FALSE; // } if ((previousFrameInfoArray.Length != frameInfoArray.Length) || (created == true)) { previousFrameInfoArray = frameInfoArray; ppEnum = new AD7FrameInfoEnum(frameInfoArray); } else { bool isEqual = true; for (int i = 0; i < frameInfoArray.Length; i++) { if (frameInfoArray[i].m_bstrFuncName != previousFrameInfoArray[i].m_bstrFuncName) { isEqual = false; break; } if (frameInfoArray[i].m_dwValidFields != previousFrameInfoArray[i].m_dwValidFields) { isEqual = false; break; } if (frameInfoArray[i].m_bstrLanguage != previousFrameInfoArray[i].m_bstrLanguage) { isEqual = false; break; } } if (!isEqual) { previousFrameInfoArray = frameInfoArray; ppEnum = new AD7FrameInfoEnum(frameInfoArray); } else { ppEnum = new AD7FrameInfoEnum(previousFrameInfoArray); } } // GDBParser.parseCommand("-stack-select-frame 0", 17); if ((this._id != "") && (this._id != this._engine.currentThread()._id)) _engine.eDispatcher.selectThread(this._engine.currentThread()._id); return Constants.S_OK; } catch (ComponentException e) { if ((this._id != "") && (this._id != this._engine.currentThread()._id)) _engine.eDispatcher.selectThread(this._engine.currentThread()._id); return e.HResult; } catch (Exception e) { if ((this._id != "") && (this._id != this._engine.currentThread()._id)) _engine.eDispatcher.selectThread(this._engine.currentThread()._id); return EngineUtils.UnexpectedException(e); } }
private bool TryGetLocation(out string location) { #if !HIDE_THREADS int frameCount = _thread.GetFrameCount(); for (int i = 0; i < frameCount; i++) { IStackFrame frame = _thread.GetFrame(i); IMethod method = frame.GetLocation().GetMethod(); if (method.GetIsNative()) continue; JavaDebugStackFrame stackFrame = new JavaDebugStackFrame(this, frame); FRAMEINFO[] frameInfo = new FRAMEINFO[1]; int result = stackFrame.GetInfo( enum_FRAMEINFO_FLAGS.FIF_FUNCNAME | enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS | enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES | enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES | enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_OFFSET | enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES, 10, frameInfo); if (ErrorHandler.Failed(result)) break; location = frameInfo[0].m_bstrFuncName; return true; } #endif location = null; return false; }
// Retrieves a list of the stack frames for this thread. // For the sample engine, enumerating the stack frames requires walking the callstack in the debuggee for this thread // and coverting that to an implementation of IEnumDebugFrameInfo2. // Real engines will most likely want to cache this information to avoid recomputing it each time it is asked for, // and or construct it on demand instead of walking the entire stack. int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 enumObject) { enumObject = null; try { // get the thread's stack frames System.Collections.Generic.List<ThreadContext> stackFrames = null; _engine.DebuggedProcess.WorkerThread.RunOperation(async () => stackFrames = await _engine.DebuggedProcess.ThreadCache.StackFrames(_debuggedThread)); int numStackFrames = stackFrames != null ? stackFrames.Count : 0; FRAMEINFO[] frameInfoArray; if (numStackFrames == 0) { // failed to walk any frames. Return an empty stack. frameInfoArray = new FRAMEINFO[0]; } else { uint low = stackFrames[0].Level; uint high = stackFrames[stackFrames.Count - 1].Level; FilterUnknownFrames(stackFrames); numStackFrames = stackFrames.Count; frameInfoArray = new FRAMEINFO[numStackFrames]; List<ArgumentList> parameters = null; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0) { _engine.DebuggedProcess.WorkerThread.RunOperation(async () => parameters = await _engine.DebuggedProcess.GetParameterInfoOnly(this, (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0, (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0, low, high)); } for (int i = 0; i < numStackFrames; i++) { var p = parameters != null ? parameters.Find((ArgumentList t) => t.Item1 == stackFrames[i].Level) : null; AD7StackFrame frame = new AD7StackFrame(_engine, this, stackFrames[i]); frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i], p != null ? p.Item2 : null); } } enumObject = new AD7FrameInfoEnum(frameInfoArray); return Constants.S_OK; } catch (MIException e) { return e.HResult; } catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
// Construct a FRAMEINFO for this stack frame with the requested information. public FRAMEINFO GetFrameInfo(FIF dwFieldSpec) { var frameInfo = new FRAMEINFO(); // TODO: were called: // Modules.Add(mod); // Callback.OnModuleLoad(mod); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if (dwFieldSpec.HasFlag(FIF.FIF_FUNCNAME)) { // If there is source information, construct a string that contains the module name, function name, and optionally argument names and values. if (m_hasSource) { var funcName = new StringBuilder(); if (dwFieldSpec.HasFlag(FIF.FIF_FUNCNAME_MODULE)) funcName.Append(System.IO.Path.GetFileName(m_threadContext.script.Name) + "!"); funcName.Append(m_functionName); if (dwFieldSpec.HasFlag(FIF.FIF_FUNCNAME_ARGS)) { funcName.Append("("); var format = GetArgumentFormat(dwFieldSpec); funcName.Append(string.Join(", ", m_parameters .Select(p => string.Format(format, p.m_typeName, string.IsNullOrEmpty(p.m_name) ? "?" : p.m_name, p.m_value)) )); funcName.Append(")"); } if (dwFieldSpec.HasFlag(FIF.FIF_FUNCNAME_LINES)) funcName.AppendFormat(" Line {0}", m_lineNum); frameInfo.m_bstrFuncName = funcName.ToString(); } else { throw new NotImplementedException(); } frameInfo.m_dwValidFields |= FIF.FIF_FUNCNAME; } // The debugger is requesting the name of the module for this stack frame. if (dwFieldSpec.HasFlag(FIF.FIF_MODULE)) { frameInfo.m_bstrModule = m_threadContext.script.Name; frameInfo.m_dwValidFields |= FIF.FIF_MODULE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if (dwFieldSpec.HasFlag(FIF.FIF_FRAME)) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= FIF.FIF_FRAME; } // Does this stack frame of symbols loaded? if (dwFieldSpec.HasFlag(FIF.FIF_DEBUGINFO)) { frameInfo.m_fHasDebugInfo = m_hasSource ? 1 : 0; frameInfo.m_dwValidFields |= FIF.FIF_DEBUGINFO; } // Is this frame stale? if (dwFieldSpec.HasFlag(FIF.FIF_STALECODE)) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= FIF.FIF_STALECODE; } return frameInfo; }
public int GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { // evaluation restrictions bool suppressFuncEval = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NO_FUNC_EVAL) != 0; bool filterNonUserCode = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FILTER_NON_USER_CODE) != 0; bool suppressToString = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NO_TOSTRING) != 0; // basic info items bool getFunctionName = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0; bool getReturnType = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_RETURNTYPE) != 0; bool getArguments = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS) != 0; bool getLanguage = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0; bool getModuleName = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0; bool getStackRange = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STACKRANGE) != 0; bool getFrame = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0; bool getDebugInfo = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0; bool getStaleCode = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0; //bool getAnnotatedFrame = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ANNOTATEDFRAME) != 0; bool getModule = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0; // additional flags for the arguments bool argsArgumentTypes = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_TYPES) != 0; bool argsArgumentNames = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NAMES) != 0; bool argsArgumentValues = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_VALUES) != 0; bool argsUnformatted = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_ARGS_NOFORMAT) != 0; // additional flags for the function name bool funcNameReturnType = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_RETURNTYPE) != 0; bool funcNameArguments = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0; bool funcNameArgumentTypes = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0; bool funcNameArgumentNames = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0; bool funcNameArgumentValues = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0; bool funcNameLanguage = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LANGUAGE) != 0; bool funcNameOffset = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_OFFSET) != 0; bool funcNameOffsetFromLineStart = (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0; FRAMEINFO frameInfo = new FRAMEINFO(); ILocation location = null; IMethod method = null; int? lineNumber = null; if (getFunctionName || getReturnType || (!_nativeMethod && getDebugInfo)) { location = _stackFrame.GetLocation(); try { if (!_nativeMethod) lineNumber = location.GetLineNumber(); } catch (MissingInformationException) { } if (getFunctionName || getReturnType) method = location.GetMethod(); } if (getFunctionName) { frameInfo.m_bstrFuncName = method.GetName(); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; string typeName = method.GetDeclaringType().GetName(); string methodName = method.GetName(); frameInfo.m_bstrFuncName = typeName + "." + methodName; if (funcNameReturnType) { frameInfo.m_bstrFuncName = method.GetReturnTypeName() + " " + frameInfo.m_bstrFuncName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_RETURNTYPE; } if (funcNameArguments) { frameInfo.m_bstrFuncName += "("; ReadOnlyCollection<string> argumentTypeNames = method.GetArgumentTypeNames(); ReadOnlyCollection<ILocalVariable> arguments = null; if (funcNameArgumentNames && !_nativeMethod && method.GetHasVariableInfo()) { arguments = method.GetArguments(); } for (int i = 0; i < argumentTypeNames.Count; i++) { List<string> argumentParts = new List<string>(); if (funcNameArgumentTypes) { string argumentType = argumentTypeNames[i]; if (argumentType.Substring(0, argumentType.LastIndexOf('.') + 1) == "java.lang.") argumentType = argumentType.Substring("java.lang.".Length); argumentParts.Add(argumentType); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES; } if (funcNameArgumentNames && arguments != null) { argumentParts.Add(arguments[i].GetName()); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_ARGS_NAMES; } if (i > 0) frameInfo.m_bstrFuncName += ", "; frameInfo.m_bstrFuncName += string.Join(" ", argumentParts); } frameInfo.m_bstrFuncName += ")"; } if (funcNameOffset && !_nativeMethod) { if (funcNameOffsetFromLineStart && lineNumber.HasValue) frameInfo.m_bstrFuncName += string.Format(" Line {0}", lineNumber); else frameInfo.m_bstrFuncName += string.Format(" + 0x{0:x2} bytes", _stackFrame.GetLocation().GetCodeIndex()); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_OFFSET; } if (funcNameArguments) frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS; if (funcNameArgumentTypes) frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES; //if (funcNameArgumentNames) // frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES; //if (funcNameArgumentValues) // frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES; } if (getArguments) { frameInfo.m_bstrArgs = string.Join(", ", method.GetArgumentTypeNames()); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_ARGS | enum_FRAMEINFO_FLAGS.FIF_ARGS_TYPES; } if (getReturnType) { frameInfo.m_bstrReturnType = method.GetReturnTypeName(); frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_RETURNTYPE; } if (getLanguage && !_nativeMethod) { frameInfo.m_bstrLanguage = Constants.JavaLanguageName; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } if (getModule) { } if (getModuleName) { } if (getStackRange) { } if (getFrame) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } if (getDebugInfo) { frameInfo.m_fHasDebugInfo = lineNumber.HasValue ? 1 : 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } if (getStaleCode) { } pFrameInfo[0] = frameInfo; return VSConstants.S_OK; }
// Gets a description of the stack frame. int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { try { SetFrameInfo(dwFieldSpec, out pFrameInfo[0]); int frame = 0; if (this.m_thread.__stackFrames != null) { foreach (AD7StackFrame sf in this.m_thread.__stackFrames) { if (sf.m_functionName == this.m_functionName) break; frame++; } } if (this.m_thread._id != this.m_engine.currentThread()._id) this.m_engine.eDispatcher.selectThread(this.m_thread._id); GDBParser.parseCommand("-stack-select-frame " + frame, 5); if (this.m_thread._id != this.m_engine.currentThread()._id) this.m_engine.eDispatcher.selectThread(this.m_engine.currentThread()._id); this.m_engine.cleanEvaluatedThreads(); return VSConstants.S_OK; } /*catch (ComponentException e) { return e.HResult; }*/ catch (Exception e) { return EngineUtils.UnexpectedException(e); } }
// Construct a FRAMEINFO for this stack frame with the requested information. public void SetFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, out FRAMEINFO frameInfo, List<SimpleVariableInformation> parameters) { frameInfo = new FRAMEINFO(); DebuggedModule module = ThreadContext.FindModule(Engine.DebuggedProcess); // The debugger is asking for the formatted name of the function which is displayed in the callstack window. // There are several optional parts to this name including the module, argument types and values, and line numbers. // The optional information is requested by setting flags in the dwFieldSpec parameter. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0) { // If there is source information, construct a string that contains the module name, function name, and optionally argument names and values. if (_textPosition != null) { frameInfo.m_bstrFuncName = ""; if (module != null && (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) { frameInfo.m_bstrFuncName = System.IO.Path.GetFileName(module.Name) + "!"; } frameInfo.m_bstrFuncName += _functionName; if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0) { frameInfo.m_bstrFuncName += "("; if (parameters != null && parameters.Count > 0) { for (int i = 0; i < parameters.Count; i++) { if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_TYPES) != 0) { frameInfo.m_bstrFuncName += parameters[i].TypeName + " "; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0) { frameInfo.m_bstrFuncName += parameters[i].Name; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_NAMES) != 0 && (dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { frameInfo.m_bstrFuncName += "="; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS_VALUES) != 0) { frameInfo.m_bstrFuncName += parameters[i].Value; } if (i < parameters.Count - 1) { frameInfo.m_bstrFuncName += ", "; } } } frameInfo.m_bstrFuncName += ")"; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0) { frameInfo.m_bstrFuncName += string.Format(CultureInfo.CurrentCulture, " Line {0}", _textPosition.BeginPosition.dwLine + 1); } } else { // No source information, so only return the module name and the instruction pointer. if (_functionName != null) { if (module != null) { frameInfo.m_bstrFuncName = System.IO.Path.GetFileName(module.Name) + '!' + _functionName; } else { frameInfo.m_bstrFuncName = _functionName; } } else if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0 && module != null) { frameInfo.m_bstrFuncName = module.Name + '!' + EngineUtils.GetAddressDescription(Engine.DebuggedProcess, ThreadContext.pc.Value); } else { frameInfo.m_bstrFuncName = EngineUtils.GetAddressDescription(Engine.DebuggedProcess, ThreadContext.pc.Value); } } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; } // The debugger is requesting the name of the module for this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0) { if (module != null) { frameInfo.m_bstrModule = module.Name; } else { frameInfo.m_bstrModule = ""; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } // The debugger is requesting the range of memory addresses for this frame. // For the sample engine, this is the contents of the frame pointer. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STACKRANGE) != 0) { frameInfo.m_addrMin = ThreadContext.sp; frameInfo.m_addrMax = ThreadContext.sp; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STACKRANGE; } // The debugger is requesting the IDebugStackFrame2 value for this frame info. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0) { frameInfo.m_pFrame = this; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } // Does this stack frame of symbols loaded? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0) { frameInfo.m_fHasDebugInfo = _textPosition != null ? 1 : 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } // Is this frame stale? if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0) { frameInfo.m_fStaleCode = 0; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } // The debugger would like a pointer to the IDebugModule2 that contains this stack frame. if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0) { if (module != null) { AD7Module ad7Module = (AD7Module)module.Client; Debug.Assert(ad7Module != null); frameInfo.m_pModule = ad7Module; frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP; } } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_FLAGS) != 0) { if (_codeCxt == null) { frameInfo.m_dwFlags |= (uint)enum_FRAMEINFO_FLAGS_VALUES.FIFV_ANNOTATEDFRAME; } frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FLAGS; } if ((dwFieldSpec & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0) { Guid unused = Guid.Empty; if (GetLanguageInfo(ref frameInfo.m_bstrLanguage, ref unused) == 0) { frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } } }
int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo) { string moduleName = StackFrame.FileName; if (moduleName != null) { try { moduleName = Path.GetFileName(moduleName); } catch (ArgumentException) { } } else if (!StackFrame.IsGlobal) { moduleName = "<unknown>"; } var fi = new FRAMEINFO(); if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_LANGUAGE)) { fi.m_bstrLanguage = RContentTypeDefinition.LanguageName; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO)) { fi.m_fHasDebugInfo = 1; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_STALECODE)) { fi.m_fStaleCode = 0; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FRAME)) { fi.m_pFrame = this; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_MODULE) && moduleName != null) { fi.m_bstrModule = moduleName; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME)) { fi.m_bstrFuncName = StackFrame.EnvironmentName ?? StackFrame.CallingFrame?.Call ?? "<unknown>"; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME; if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) && moduleName != null) { fi.m_bstrFuncName += " in " + moduleName; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE; } if (dwFieldSpec.HasFlag(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) && StackFrame.LineNumber != null) { fi.m_bstrFuncName += " line " + StackFrame.LineNumber; fi.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES; } } pFrameInfo[0] = fi; return(VSConstants.S_OK); }