diff options
author | Tomas Rylek <trylek@microsoft.com> | 2017-07-14 12:57:22 +0300 |
---|---|---|
committer | Tomas Rylek <trylek@microsoft.com> | 2017-07-14 12:57:22 +0300 |
commit | 97072c9c8de8d2ac7e4f21ba82a9602422ee4bda (patch) | |
tree | 18a3a5d33454f561cd50603dd0a02d5c75fc86da /src/System.Private.StackTraceGenerator | |
parent | d0fedcd6f1dc55fa77b47c731e75640a35dad7a2 (diff) |
Initial implementation of .NETStandard 2.0 StackTrace / StackFrame API
This change supplies initial functional implementations of the .NET Standard 2.0 API's in StackTrace, StackFrame and StackFrameExtensions; it also includes runtime provisions for optional retrieval of IL offset and MethodBase when available in the AOT runtime.
[tfs-changeset: 1666008]
Diffstat (limited to 'src/System.Private.StackTraceGenerator')
3 files changed, 74 insertions, 5 deletions
diff --git a/src/System.Private.StackTraceGenerator/src/Internal/Dia/DiaInterfaces.cs b/src/System.Private.StackTraceGenerator/src/Internal/Dia/DiaInterfaces.cs index d64921df8..017395cae 100644 --- a/src/System.Private.StackTraceGenerator/src/Internal/Dia/DiaInterfaces.cs +++ b/src/System.Private.StackTraceGenerator/src/Internal/Dia/DiaInterfaces.cs @@ -92,6 +92,18 @@ namespace Internal.StackGenerator.Dia enumLineNumbers = new IDiaEnumLineNumbers(_enumLineNumbers); return hr; } + + public int FindILOffsetsByRVA(int rva, int length, out IDiaEnumLineNumbers enumLineNumbers) + { + enumLineNumbers = null; + IntPtr _enumLineNumbers; + int hr = S.StdCall<int>(GetVTableMember(46), Punk, rva, length, out _enumLineNumbers); + GC.KeepAlive(this); + if (hr != S_OK) + return hr; + enumLineNumbers = new IDiaEnumLineNumbers(_enumLineNumbers); + return hr; + } } internal sealed class IDiaEnumSymbols : ComInterface diff --git a/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Unix.cs b/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Unix.cs index ba5d6c32d..6fb2c5c23 100644 --- a/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Unix.cs +++ b/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Unix.cs @@ -27,5 +27,14 @@ namespace Internal.StackTraceGenerator lineNumber = 0; columnNumber = 0; } + + /// <summary> + /// Makes reasonable effort to locate the IL offset within the current method. + /// </summary> + public static void TryGetILOffsetWithinMethod(IntPtr ip, out int ilOffset) + { + // CORERT-TODO: Implement StackTraceGenerator on Unix + ilOffset = StackFrame.OFFSET_UNKNOWN; + } } } diff --git a/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Windows.cs b/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Windows.cs index 0e7110707..c686b811c 100644 --- a/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Windows.cs +++ b/src/System.Private.StackTraceGenerator/src/Internal/StackTraceGenerator/StackTraceGenerator.Windows.cs @@ -5,6 +5,7 @@ using System; using System.Text; using System.Diagnostics; +using System.Reflection; using System.Runtime.InteropServices; using Internal.Runtime.Augments; using Internal.StackGenerator.Dia; @@ -78,11 +79,33 @@ namespace Internal.StackTraceGenerator fileName = null; lineNumber = 0; columnNumber = 0; - int rva; - IDiaSession session = GetDiaSession(ip, out rva); - if (session == null) - return; - TryGetSourceLineInfo(session, rva, out fileName, out lineNumber, out columnNumber); + if (!IsDiaStackTraceResolutionDisabled()) + { + int rva; + IDiaSession session = GetDiaSession(ip, out rva); + if (session != null) + { + TryGetSourceLineInfo(session, rva, out fileName, out lineNumber, out columnNumber); + } + } + } + + /// <summary> + /// Makes reasonable effort to find the IL offset corresponding to the given address within a method. + /// Returns StackFrame.OFFSET_UNKNOWN if not available. + /// </summary> + public static void TryGetILOffsetWithinMethod(IntPtr ip, out int ilOffset) + { + ilOffset = StackFrame.OFFSET_UNKNOWN; + if (!IsDiaStackTraceResolutionDisabled()) + { + int rva; + IDiaSession session = GetDiaSession(ip, out rva); + if (session != null) + { + TryGetILOffsetInfo(session, rva, out ilOffset); + } + } } // @@ -213,6 +236,31 @@ namespace Internal.StackTraceGenerator } } + private static void TryGetILOffsetInfo(IDiaSession session, int rva, out int ilOffset) + { + IDiaEnumLineNumbers lineNumbers; + int hr = session.FindILOffsetsByRVA(rva, 1, out lineNumbers); + if (hr == S_OK) + { + int numLineNumbers; + hr = lineNumbers.Count(out numLineNumbers); + if (hr == S_OK && numLineNumbers > 0) + { + IDiaLineNumber ln; + hr = lineNumbers.Item(0, out ln); + if (hr == S_OK) + { + hr = ln.LineNumber(out ilOffset); + if (hr == S_OK) + { + return; + } + } + } + } + ilOffset = StackFrame.OFFSET_UNKNOWN; + } + // // Generate the " in <filename>:line <line#>" section. // |