/// <summary> /// Reads the function name and displacement of the specified code address. /// </summary> /// <param name="address">The code address</param> public Tuple <string, ulong> ReadFunctionNameAndDisplacement(ulong address) { Microsoft.Diagnostics.Runtime.ClrMethod method = ClrRuntime.GetMethodByAddress(address); IClrModule clrModule = Provider.FromClrModule(method.Type.Module); return(ClrMdStackFrame.ReadFunctionNameAndDisplacement(clrModule.Module, method, address)); }
/// <summary> /// Reads the function name and displacement. /// </summary> /// <returns></returns> /// <exception cref="System.AggregateException">Couldn't read source file name. Check if symbols are present.</exception> private Tuple <string, ulong> ReadFunctionNameAndDisplacement() { try { ulong displacement; string functionName; Context.SymbolProvider.GetProcessAddressFunctionName(Process, Address, out functionName, out displacement); return(Tuple.Create(functionName, displacement)); } catch (Exception ex) { // Try to find function among CLR ones foreach (Runtime runtime in Process.ClrRuntimes) { try { Microsoft.Diagnostics.Runtime.ClrMethod method = runtime.ClrRuntime.GetMethodByAddress(Address); if (method != null) { return(StackFrame.ReadClrFunctionNameAndDisplacement(Process.ClrModuleCache[method.Type.Module], method, Address)); } } catch { } } throw new AggregateException("Couldn't read function name. Check if symbols are present.", ex); } }
/// <summary> /// Reads the name of the source file, line and displacement of the specified code address. /// </summary> /// <param name="address">The code address</param> public Tuple <string, uint, ulong> ReadSourceFileNameAndLine(ulong address) { Microsoft.Diagnostics.Runtime.ClrMethod method = ClrRuntime.GetMethodByAddress(address); ClrMdModule clrModule = Provider.FromClrModule(method.Type.Module); return(ClrMdStackFrame.ReadSourceFileNameAndLine(clrModule, method, address)); }
/// <summary> /// Finds the IL offset for the specified frame. /// </summary> /// <param name="method">The method.</param> /// <param name="instructionPointer">The instruction pointer.</param> internal static uint FindIlOffset(Microsoft.Diagnostics.Runtime.ClrMethod method, ulong instructionPointer) { ulong ip = instructionPointer; uint last = uint.MaxValue; foreach (var item in method.ILOffsetMap) { if (item.StartAddress > ip) { return(last); } if (ip <= item.EndAddress) { return((uint)item.ILOffset); } last = (uint)item.ILOffset; } return(last); }
/// <summary> /// Reads the CLR source file name, line number and displacement. /// </summary> /// <param name="module">The module.</param> /// <param name="method">The method.</param> /// <param name="address">The address.</param> internal static Tuple <string, uint, ulong> ReadClrSourceFileNameAndLine(Module module, Microsoft.Diagnostics.Runtime.ClrMethod method, ulong address) { Microsoft.Diagnostics.Runtime.Utilities.Pdb.PdbReader pdbReader = module.ClrPdbReader; Microsoft.Diagnostics.Runtime.Utilities.Pdb.PdbFunction function = pdbReader.GetFunctionFromToken(method.MetadataToken); uint ilOffset = StackFrame.FindIlOffset(method, address); ulong distance = ulong.MaxValue; string sourceFileName = ""; uint sourceFileLine = uint.MaxValue; foreach (Microsoft.Diagnostics.Runtime.Utilities.Pdb.PdbSequencePointCollection sequenceCollection in function.SequencePoints) { foreach (Microsoft.Diagnostics.Runtime.Utilities.Pdb.PdbSequencePoint point in sequenceCollection.Lines) { if (point.Offset <= ilOffset) { ulong dist = ilOffset - point.Offset; if (dist < distance) { sourceFileName = sequenceCollection.File.Name; sourceFileLine = point.LineBegin; distance = dist; } } } } return(Tuple.Create(sourceFileName, sourceFileLine, distance)); }
/// <summary> /// Reads the CLR function name and displacement. /// </summary> /// <param name="module">The module.</param> /// <param name="method">The method.</param> /// <param name="address">The address.</param> internal static Tuple <string, ulong> ReadClrFunctionNameAndDisplacement(Module module, Microsoft.Diagnostics.Runtime.ClrMethod method, ulong address) { string moduleName = module?.Name ?? "???"; string functionName = moduleName + "!" + method; ulong displacement = address - method.NativeCode; return(Tuple.Create(functionName, displacement)); }
/// <summary> /// Reads the name of the source file, line and displacement. /// </summary> /// <param name="module">The module.</param> /// <param name="method">The CLR method.</param> /// <param name="address">The address.</param> internal static Tuple <string, uint, ulong> ReadSourceFileNameAndLine(ClrMdModule module, Microsoft.Diagnostics.Runtime.ClrMethod method, ulong address) { IPdbFile pdbReader = module.ClrPdbReader; IPdbFunction function = pdbReader.GetFunctionFromToken((int)method.MetadataToken); uint ilOffset = FindIlOffset(method, address); ulong distance = ulong.MaxValue; string sourceFileName = ""; uint sourceFileLine = uint.MaxValue; foreach (IPdbSequencePoint point in function.SequencePoints) { if (point.Offset <= ilOffset) { ulong dist = (ulong)(ilOffset - point.Offset); if (dist < distance) { sourceFileName = point.Source.Name; sourceFileLine = (uint)point.StartLine; distance = dist; } } } return(Tuple.Create(sourceFileName, sourceFileLine, distance)); }