Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Diagnostics/StackFrame.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/StackFrame.cs302
1 files changed, 302 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/StackFrame.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/StackFrame.cs
new file mode 100644
index 000000000..22c9b8399
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/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
+{
+ /// <summary>
+ /// There is no good reason for the methods of this class to be virtual.
+ /// </summary>
+ public partial class StackFrame
+ {
+ /// <summary>
+ /// Reflection information for the method if available, null otherwise.
+ /// </summary>
+ private MethodBase _method;
+
+ /// <summary>
+ /// Native offset of the current instruction within the current method if available,
+ /// OFFSET_UNKNOWN otherwise.
+ /// </summary>
+ private int _nativeOffset;
+
+ /// <summary>
+ /// IL offset of the current instruction within the current method if available,
+ /// OFFSET_UNKNOWN otherwise.
+ /// </summary>
+ private int _ilOffset;
+
+ /// <summary>
+ /// Source file name representing the current code location if available, null otherwise.
+ /// </summary>
+ private string _fileName;
+
+ /// <summary>
+ /// Line number representing the current code location if available, 0 otherwise.
+ /// </summary>
+ private int _lineNumber;
+
+ /// <summary>
+ /// Column number representing the current code location if available, 0 otherwise.
+ /// </summary>
+ private int _columnNumber;
+
+ /// <summary>
+ /// This flag is set to true when the frame represents a rethrow marker.
+ /// </summary>
+ private bool _isLastFrameFromForeignExceptionStackTrace;
+
+ private void InitMembers()
+ {
+ _method = null;
+ _nativeOffset = OFFSET_UNKNOWN;
+ _ilOffset = OFFSET_UNKNOWN;
+ _fileName = null;
+ _lineNumber = 0;
+ _columnNumber = 0;
+ _isLastFrameFromForeignExceptionStackTrace = false;
+ }
+
+ /// <summary>
+ /// Constructs a StackFrame corresponding to the active stack frame.
+ /// </summary>
+ public StackFrame()
+ {
+ InitMembers();
+ BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, false);
+ }
+
+ /// <summary>
+ /// Constructs a StackFrame corresponding to the active stack frame.
+ /// </summary>
+ public StackFrame(bool needFileInfo)
+ {
+ InitMembers();
+ BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, needFileInfo);
+ }
+
+ /// <summary>
+ /// Constructs a StackFrame corresponding to a calling stack frame.
+ /// </summary>
+ public StackFrame(int skipFrames)
+ {
+ InitMembers();
+ BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, false);
+ }
+
+ /// <summary>
+ /// Constructs a StackFrame corresponding to a calling stack frame.
+ /// </summary>
+ public StackFrame(int skipFrames, bool needFileInfo)
+ {
+ InitMembers();
+ BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, needFileInfo);
+ }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ public StackFrame(string fileName, int lineNumber)
+ {
+ InitMembers();
+ BuildStackFrame(StackTrace.METHODS_TO_SKIP, false);
+ _fileName = fileName;
+ _lineNumber = lineNumber;
+ _columnNumber = 0;
+ }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ public StackFrame(string fileName, int lineNumber, int colNumber)
+ {
+ InitMembers();
+ BuildStackFrame(StackTrace.METHODS_TO_SKIP, false);
+ _fileName = fileName;
+ _lineNumber = lineNumber;
+ _columnNumber = colNumber;
+ }
+
+ /// <summary>
+ /// Constant returned when the native or IL offset is unknown
+ /// </summary>
+ 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;
+ }
+
+ /// <summary>
+ /// Returns the method the frame is executing
+ /// </summary>
+ public virtual MethodBase GetMethod()
+ {
+ return _method;
+ }
+
+ /// <summary>
+ /// Returns the offset from the start of the native (jitted) code for the
+ /// method being executed
+ /// </summary>
+ public virtual int GetNativeOffset()
+ {
+ return _nativeOffset;
+ }
+
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ public virtual int GetILOffset()
+ {
+ return _ilOffset;
+ }
+
+ /// <summary>
+ /// Returns the file name containing the code being executed. This
+ /// information is normally extracted from the debugging symbols
+ /// for the executable.
+ /// </summary>
+ public virtual string GetFileName()
+ {
+ return _fileName;
+ }
+
+ /// <summary>
+ /// Returns the line number in the file containing the code being executed.
+ /// This information is normally extracted from the debugging symbols
+ /// for the executable.
+ /// </summary>
+ public virtual int GetFileLineNumber()
+ {
+ return _lineNumber;
+ }
+
+ /// <summary>
+ /// Returns the column number in the line containing the code being executed.
+ /// This information is normally extracted from the debugging symbols
+ /// for the executable.
+ /// </summary>
+ public virtual int GetFileColumnNumber()
+ {
+ return _columnNumber;
+ }
+
+ /// <summary>
+ /// Builds a readable representation of the stack frame
+ /// </summary>
+ 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("<offset unknown>");
+ else
+ sb.Append(_nativeOffset);
+
+ sb.Append(" in file:line:column ");
+
+ bool useFileName = (_fileName != null);
+
+ if (!useFileName)
+ sb.Append("<filename unknown>");
+ else
+ sb.Append(_fileName);
+ sb.Append(':');
+ sb.Append(_lineNumber);
+ sb.Append(':');
+ sb.Append(_columnNumber);
+ }
+ else
+ {
+ sb.Append("<null>");
+ }
+ sb.Append(Environment.NewLine);
+
+ return sb.ToString();
+ }
+ }
+}