From: Maryam Ariyan Date: Tue, 29 May 2018 23:13:13 +0000 (-0700) Subject: Moving common logic of StackFrame into shared (dotnet/coreclr#18134) X-Git-Tag: submit/tizen/20210909.063632~11030^2~4748 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8931b644c1aadf5b8851d8167bd116dfda768cf9;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Moving common logic of StackFrame into shared (dotnet/coreclr#18134) Related to: dotnet/coreclr#9474 Commit migrated from https://github.com/dotnet/coreclr/commit/98c22a44ceab4f54607df65ef200e7bf7acb6145 --- diff --git a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj index a555265..1932ebc1 100644 --- a/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/coreclr/src/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -509,7 +509,7 @@ - + diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs new file mode 100644 index 0000000..a08496a --- /dev/null +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/StackFrame.CoreCLR.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text; +using System; +using System.IO; +using System.Reflection; + +namespace System.Diagnostics +{ + /// + /// There is no good reason for the methods of this class to be virtual. + /// + public partial class StackFrame + { + /// + /// Called from the class "StackTrace" + /// + internal StackFrame(bool DummyFlag1, bool DummyFlag2) + { + InitMembers(); + } + + private void BuildStackFrame(int skipFrames, bool needFileInfo) + { + StackFrameHelper StackF = new StackFrameHelper(null); + + StackF.InitializeSourceInfo(0, needFileInfo, null); + + int iNumOfFrames = StackF.GetNumberOfFrames(); + + skipFrames += StackTrace.CalculateFramesToSkip(StackF, iNumOfFrames); + + if ((iNumOfFrames - skipFrames) > 0) + { + _method = StackF.GetMethodBase(skipFrames); + _nativeOffset = StackF.GetOffset(skipFrames); + _ilOffset = StackF.GetILOffset(skipFrames); + if (needFileInfo) + { + _fileName = StackF.GetFilename(skipFrames); + _lineNumber = StackF.GetLineNumber(skipFrames); + _columnNumber = StackF.GetColumnNumber(skipFrames); + } + } + } + + private bool AppendStackFrameWithoutMethodBase(StringBuilder sb) => false; + } +} diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Stackframe.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Stackframe.cs deleted file mode 100644 index 884188d..0000000 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Diagnostics/Stackframe.cs +++ /dev/null @@ -1,285 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - - -using System.Text; -using System; -using System.IO; -using System.Reflection; - -namespace System.Diagnostics -{ - // There is no good reason for the methods of this class to be virtual. - public class StackFrame - { - private MethodBase method; - private int offset; - private int ILOffset; - private String strFileName; - private int iLineNumber; - private int iColumnNumber; - - [System.Runtime.Serialization.OptionalField] - private bool fIsLastFrameFromForeignExceptionStackTrace; - - internal void InitMembers() - { - method = null; - offset = OFFSET_UNKNOWN; - ILOffset = OFFSET_UNKNOWN; - strFileName = null; - iLineNumber = 0; - iColumnNumber = 0; - fIsLastFrameFromForeignExceptionStackTrace = false; - } - - // Constructs a StackFrame corresponding to the active stack frame. - public StackFrame() - { - InitMembers(); - BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, false);// iSkipFrames=0 - } - - // Constructs a StackFrame corresponding to the active stack frame. - public StackFrame(bool fNeedFileInfo) - { - InitMembers(); - BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, fNeedFileInfo);// iSkipFrames=0 - } - - // Constructs a StackFrame corresponding to a calling stack frame. - // - public StackFrame(int skipFrames) - { - InitMembers(); - BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, false); - } - - // Constructs a StackFrame corresponding to a calling stack frame. - // - public StackFrame(int skipFrames, bool fNeedFileInfo) - { - InitMembers(); - BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, fNeedFileInfo); - } - - - // Called from the class "StackTrace" - // - internal StackFrame(bool DummyFlag1, bool DummyFlag2) - { - InitMembers(); - } - - // Constructs a "fake" stack frame, just containing the given file - // name and line number. Use when you don't want to use the - // debugger's line mapping logic. - // - public StackFrame(String fileName, int lineNumber) - { - InitMembers(); - BuildStackFrame(StackTrace.METHODS_TO_SKIP, false); - strFileName = fileName; - iLineNumber = lineNumber; - iColumnNumber = 0; - } - - - // Constructs a "fake" stack frame, just containing the given file - // name, line number and column number. Use when you don't want to - // use the debugger's line mapping logic. - // - public StackFrame(String fileName, int lineNumber, int colNumber) - { - InitMembers(); - BuildStackFrame(StackTrace.METHODS_TO_SKIP, false); - strFileName = fileName; - iLineNumber = lineNumber; - iColumnNumber = colNumber; - } - - - // Constant returned when the native or IL offset is unknown - public const int OFFSET_UNKNOWN = -1; - - - internal virtual void SetMethodBase(MethodBase mb) - { - method = mb; - } - - internal virtual void SetOffset(int iOffset) - { - offset = iOffset; - } - - internal virtual void SetILOffset(int iOffset) - { - ILOffset = iOffset; - } - - internal virtual void SetFileName(String strFName) - { - strFileName = strFName; - } - - internal virtual void SetLineNumber(int iLine) - { - iLineNumber = iLine; - } - - internal virtual void SetColumnNumber(int iCol) - { - iColumnNumber = iCol; - } - - internal virtual void SetIsLastFrameFromForeignExceptionStackTrace(bool fIsLastFrame) - { - fIsLastFrameFromForeignExceptionStackTrace = fIsLastFrame; - } - - internal virtual bool GetIsLastFrameFromForeignExceptionStackTrace() - { - return fIsLastFrameFromForeignExceptionStackTrace; - } - - // Returns the method the frame is executing - // - public virtual MethodBase GetMethod() - { - return method; - } - - // Returns the offset from the start of the native (jitted) code for the - // method being executed - // - public virtual int GetNativeOffset() - { - return offset; - } - - - // Returns the offset from the start of the IL code for the - // method being executed. This offset may be approximate depending - // on whether the jitter is generating debuggable code or not. - // - public virtual int GetILOffset() - { - return ILOffset; - } - - // Returns the file name containing the code being executed. This - // information is normally extracted from the debugging symbols - // for the executable. - // - public virtual String GetFileName() - { - return strFileName; - } - - // Returns the line number in the file containing the code being executed. - // This information is normally extracted from the debugging symbols - // for the executable. - // - public virtual int GetFileLineNumber() - { - return iLineNumber; - } - - // Returns the column number in the line containing the code being executed. - // This information is normally extracted from the debugging symbols - // for the executable. - // - public virtual int GetFileColumnNumber() - { - return iColumnNumber; - } - - - // Builds a readable representation of the stack frame - // - public override String ToString() - { - StringBuilder sb = new StringBuilder(255); - - if (method != null) - { - sb.Append(method.Name); - - // deal with the generic portion of the method - if (method is MethodInfo && ((MethodInfo)method).IsGenericMethod) - { - Type[] typars = ((MethodInfo)method).GetGenericArguments(); - - sb.Append('<'); - int k = 0; - bool fFirstTyParam = true; - while (k < typars.Length) - { - if (fFirstTyParam == false) - sb.Append(','); - else - fFirstTyParam = false; - - sb.Append(typars[k].Name); - k++; - } - - sb.Append('>'); - } - - sb.Append(" at offset "); - if (offset == OFFSET_UNKNOWN) - sb.Append(""); - else - sb.Append(offset); - - sb.Append(" in file:line:column "); - - bool useFileName = (strFileName != null); - - if (!useFileName) - sb.Append(""); - else - sb.Append(strFileName); - sb.Append(':'); - sb.Append(iLineNumber); - sb.Append(':'); - sb.Append(iColumnNumber); - } - else - { - sb.Append(""); - } - sb.Append(Environment.NewLine); - - return sb.ToString(); - } - - - private void BuildStackFrame(int skipFrames, bool fNeedFileInfo) - { - StackFrameHelper StackF = new StackFrameHelper(null); - - StackF.InitializeSourceInfo(0, fNeedFileInfo, null); - - int iNumOfFrames = StackF.GetNumberOfFrames(); - - skipFrames += StackTrace.CalculateFramesToSkip(StackF, iNumOfFrames); - - if ((iNumOfFrames - skipFrames) > 0) - { - method = StackF.GetMethodBase(skipFrames); - offset = StackF.GetOffset(skipFrames); - ILOffset = StackF.GetILOffset(skipFrames); - if (fNeedFileInfo) - { - strFileName = StackF.GetFilename(skipFrames); - iLineNumber = StackF.GetLineNumber(skipFrames); - iColumnNumber = StackF.GetColumnNumber(skipFrames); - } - } - } - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index e292908..8c7464f 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -127,6 +127,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs new file mode 100644 index 0000000..22c9b83 --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackFrame.cs @@ -0,0 +1,302 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text; +using System; +using System.IO; +using System.Reflection; + +namespace System.Diagnostics +{ + /// + /// There is no good reason for the methods of this class to be virtual. + /// + public partial class StackFrame + { + /// + /// Reflection information for the method if available, null otherwise. + /// + private MethodBase _method; + + /// + /// Native offset of the current instruction within the current method if available, + /// OFFSET_UNKNOWN otherwise. + /// + private int _nativeOffset; + + /// + /// IL offset of the current instruction within the current method if available, + /// OFFSET_UNKNOWN otherwise. + /// + private int _ilOffset; + + /// + /// Source file name representing the current code location if available, null otherwise. + /// + private string _fileName; + + /// + /// Line number representing the current code location if available, 0 otherwise. + /// + private int _lineNumber; + + /// + /// Column number representing the current code location if available, 0 otherwise. + /// + private int _columnNumber; + + /// + /// This flag is set to true when the frame represents a rethrow marker. + /// + private bool _isLastFrameFromForeignExceptionStackTrace; + + private void InitMembers() + { + _method = null; + _nativeOffset = OFFSET_UNKNOWN; + _ilOffset = OFFSET_UNKNOWN; + _fileName = null; + _lineNumber = 0; + _columnNumber = 0; + _isLastFrameFromForeignExceptionStackTrace = false; + } + + /// + /// Constructs a StackFrame corresponding to the active stack frame. + /// + public StackFrame() + { + InitMembers(); + BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, false); + } + + /// + /// Constructs a StackFrame corresponding to the active stack frame. + /// + public StackFrame(bool needFileInfo) + { + InitMembers(); + BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, needFileInfo); + } + + /// + /// Constructs a StackFrame corresponding to a calling stack frame. + /// + public StackFrame(int skipFrames) + { + InitMembers(); + BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, false); + } + + /// + /// Constructs a StackFrame corresponding to a calling stack frame. + /// + public StackFrame(int skipFrames, bool needFileInfo) + { + InitMembers(); + BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, needFileInfo); + } + + /// + /// Constructs a "fake" stack frame, just containing the given file + /// name and line number. Use when you don't want to use the + /// debugger's line mapping logic. + /// + public StackFrame(string fileName, int lineNumber) + { + InitMembers(); + BuildStackFrame(StackTrace.METHODS_TO_SKIP, false); + _fileName = fileName; + _lineNumber = lineNumber; + _columnNumber = 0; + } + + /// + /// Constructs a "fake" stack frame, just containing the given file + /// name, line number and column number. Use when you don't want to + /// use the debugger's line mapping logic. + /// + public StackFrame(string fileName, int lineNumber, int colNumber) + { + InitMembers(); + BuildStackFrame(StackTrace.METHODS_TO_SKIP, false); + _fileName = fileName; + _lineNumber = lineNumber; + _columnNumber = colNumber; + } + + /// + /// Constant returned when the native or IL offset is unknown + /// + public const int OFFSET_UNKNOWN = -1; + + internal virtual void SetMethodBase(MethodBase mb) + { + _method = mb; + } + + internal virtual void SetOffset(int iOffset) + { + _nativeOffset = iOffset; + } + + internal virtual void SetILOffset(int iOffset) + { + _ilOffset = iOffset; + } + + internal virtual void SetFileName(string strFName) + { + _fileName = strFName; + } + + internal virtual void SetLineNumber(int iLine) + { + _lineNumber = iLine; + } + + internal virtual void SetColumnNumber(int iCol) + { + _columnNumber = iCol; + } + + internal virtual void SetIsLastFrameFromForeignExceptionStackTrace(bool fIsLastFrame) + { + _isLastFrameFromForeignExceptionStackTrace = fIsLastFrame; + } + + internal virtual bool GetIsLastFrameFromForeignExceptionStackTrace() + { + return _isLastFrameFromForeignExceptionStackTrace; + } + + /// + /// Returns the method the frame is executing + /// + public virtual MethodBase GetMethod() + { + return _method; + } + + /// + /// Returns the offset from the start of the native (jitted) code for the + /// method being executed + /// + public virtual int GetNativeOffset() + { + return _nativeOffset; + } + + + /// + /// Returns the offset from the start of the IL code for the + /// method being executed. This offset may be approximate depending + /// on whether the jitter is generating debuggable code or not. + /// + public virtual int GetILOffset() + { + return _ilOffset; + } + + /// + /// Returns the file name containing the code being executed. This + /// information is normally extracted from the debugging symbols + /// for the executable. + /// + public virtual string GetFileName() + { + return _fileName; + } + + /// + /// Returns the line number in the file containing the code being executed. + /// This information is normally extracted from the debugging symbols + /// for the executable. + /// + public virtual int GetFileLineNumber() + { + return _lineNumber; + } + + /// + /// Returns the column number in the line containing the code being executed. + /// This information is normally extracted from the debugging symbols + /// for the executable. + /// + public virtual int GetFileColumnNumber() + { + return _columnNumber; + } + + /// + /// Builds a readable representation of the stack frame + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder(255); + bool includeFileInfoIfAvailable; + + if (_method != null) + { + sb.Append(_method.Name); + + // deal with the generic portion of the method + if (_method is MethodInfo methodInfo && methodInfo.IsGenericMethod) + { + Type[] typars = methodInfo.GetGenericArguments(); + + sb.Append('<'); + int k = 0; + bool fFirstTyParam = true; + while (k < typars.Length) + { + if (fFirstTyParam == false) + sb.Append(','); + else + fFirstTyParam = false; + + sb.Append(typars[k].Name); + k++; + } + + sb.Append('>'); + } + includeFileInfoIfAvailable = true; + } + else + { + includeFileInfoIfAvailable = AppendStackFrameWithoutMethodBase(sb); + } + + if (includeFileInfoIfAvailable) + { + sb.Append(" at offset "); + if (_nativeOffset == OFFSET_UNKNOWN) + sb.Append(""); + else + sb.Append(_nativeOffset); + + sb.Append(" in file:line:column "); + + bool useFileName = (_fileName != null); + + if (!useFileName) + sb.Append(""); + else + sb.Append(_fileName); + sb.Append(':'); + sb.Append(_lineNumber); + sb.Append(':'); + sb.Append(_columnNumber); + } + else + { + sb.Append(""); + } + sb.Append(Environment.NewLine); + + return sb.ToString(); + } + } +}