Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Diagnostics / Stacktrace.cs / 1 / Stacktrace.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
namespace System.Diagnostics {
using System.Text;
using System.Threading;
using System;
using System.Security;
using System.Security.Permissions;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Globalization;
using System.Runtime.Serialization;
// READ ME:
// Modifying the order or fields of this object may require other changes
// to the unmanaged definition of the StackFrameHelper class, in
// VM\DebugDebugger.h. The binder will catch some of these layout problems.
[Serializable]
internal class StackFrameHelper
{
[NonSerialized]
private Thread targetThread;
private int[] rgiOffset;
private int[] rgiILOffset;
// this field is here only for backwards compatibility of serialization format
private MethodBase[] rgMethodBase;
#pragma warning disable 414 // Field is not used from managed.
// dynamicMethods is an array of System.Resolver objects, used to keep
// DynamicMethodDescs alive for the lifetime of StackFrameHelper.
private Object dynamicMethods;
#pragma warning restore 414
[NonSerialized]
private RuntimeMethodHandle[] rgMethodHandle;
private String[] rgFilename;
private int[] rgiLineNumber;
private int[] rgiColumnNumber;
private int iFrameCount;
private bool fNeedFileInfo;
public StackFrameHelper(bool fNeedFileLineColInfo, Thread target)
{
targetThread = target;
rgMethodBase = null;
rgMethodHandle = null;
rgiOffset = null;
rgiILOffset = null;
rgFilename = null;
rgiLineNumber = null;
rgiColumnNumber = null;
dynamicMethods = null;
iFrameCount = 512; //read by the internal to EE method: this is the
// number of requested frames
fNeedFileInfo = fNeedFileLineColInfo;
}
public virtual MethodBase GetMethodBase (int i)
{
// There may be a better way to do this.
// we got RuntimeMethodHandles here and we need to go to MethodBase
// but we don't know whether the reflection info has been initialized
// or not. So we call GetMethods and GetConstructors on the type
// and then we fetch the proper MethodBase!!
RuntimeMethodHandle mh = rgMethodHandle [i];
if (mh.IsNullHandle())
return null;
mh = mh.GetTypicalMethodDefinition();
return RuntimeType.GetMethodBase(mh);
}
public virtual int GetOffset (int i) { return rgiOffset [i];}
public virtual int GetILOffset (int i) { return rgiILOffset [i];}
public virtual String GetFilename (int i) { return rgFilename [i];}
public virtual int GetLineNumber (int i) { return rgiLineNumber [i];}
public virtual int GetColumnNumber (int i) { return rgiColumnNumber [i];}
public virtual int GetNumberOfFrames () { return iFrameCount;}
public virtual void SetNumberOfFrames (int i) { iFrameCount = i;}
//
// serialization implementation
//
[OnSerializing]
void OnSerializing(StreamingContext context)
{
// this is called in the process of serializing this object.
// For compatibility with Everett we need to assign the rgMethodBase field as that is the field
// that will be serialized
rgMethodBase = (rgMethodHandle == null) ? null : new MethodBase[rgMethodHandle.Length];
if (rgMethodHandle != null)
{
for (int i = 0; i < rgMethodHandle.Length; i++)
{
if (!rgMethodHandle[i].IsNullHandle())
rgMethodBase[i] = RuntimeType.GetMethodBase(rgMethodHandle[i]);
}
}
}
[OnSerialized]
void OnSerialized(StreamingContext context)
{
// after we are done serializing null the rgMethodBase field
rgMethodBase = null;
}
[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
// after we are done deserializing we need to transform the rgMethodBase in rgMethodHandle
rgMethodHandle = (rgMethodBase == null) ? null : new RuntimeMethodHandle[rgMethodBase.Length];
if (rgMethodBase != null)
{
for (int i = 0; i < rgMethodBase.Length; i++)
{
if (rgMethodBase[i] != null)
rgMethodHandle[i] = rgMethodBase[i].MethodHandle;
}
}
rgMethodBase = null;
}
}
// Class which represents a description of a stack trace
// There is no good reason for the methods of this class to be virtual.
// In order to ensure trusted code can trust the data it gets from a
// StackTrace, we use an InheritanceDemand to prevent partially-trusted
// subclasses.
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
[Serializable()]
[System.Runtime.InteropServices.ComVisible(true)]
public class StackTrace
{
private StackFrame[] frames;
private int m_iNumOfFrames;
public const int METHODS_TO_SKIP = 0;
private int m_iMethodsToSkip;
// Constructs a stack trace from the current location.
public StackTrace()
{
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (METHODS_TO_SKIP, false, null, null);
}
// Constructs a stack trace from the current location.
//
public StackTrace(bool fNeedFileInfo)
{
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (METHODS_TO_SKIP, fNeedFileInfo, null, null);
}
// Constructs a stack trace from the current location, in a caller's
// frame
//
public StackTrace(int skipFrames)
{
if (skipFrames < 0)
throw new ArgumentOutOfRangeException ("skipFrames",
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (skipFrames+METHODS_TO_SKIP, false, null, null);
}
// Constructs a stack trace from the current location, in a caller's
// frame
//
public StackTrace(int skipFrames, bool fNeedFileInfo)
{
if (skipFrames < 0)
throw new ArgumentOutOfRangeException ("skipFrames",
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (skipFrames+METHODS_TO_SKIP, fNeedFileInfo, null, null);
}
// Constructs a stack trace from the current location.
public StackTrace(Exception e)
{
if (e == null)
throw new ArgumentNullException("e");
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (METHODS_TO_SKIP, false, null, e);
}
// Constructs a stack trace from the current location.
//
public StackTrace(Exception e, bool fNeedFileInfo)
{
if (e == null)
throw new ArgumentNullException("e");
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (METHODS_TO_SKIP, fNeedFileInfo, null, e);
}
// Constructs a stack trace from the current location, in a caller's
// frame
//
public StackTrace(Exception e, int skipFrames)
{
if (e == null)
throw new ArgumentNullException("e");
if (skipFrames < 0)
throw new ArgumentOutOfRangeException ("skipFrames",
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (skipFrames+METHODS_TO_SKIP, false, null, e);
}
// Constructs a stack trace from the current location, in a caller's
// frame
//
public StackTrace(Exception e, int skipFrames, bool fNeedFileInfo)
{
if (e == null)
throw new ArgumentNullException("e");
if (skipFrames < 0)
throw new ArgumentOutOfRangeException ("skipFrames",
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (skipFrames+METHODS_TO_SKIP, fNeedFileInfo, null, e);
}
// Constructs a "fake" stack trace, just containing a single frame.
// Does not have the overhead of a full stack trace.
//
public StackTrace(StackFrame frame)
{
frames = new StackFrame[1];
frames[0] = frame;
m_iMethodsToSkip = 0;
m_iNumOfFrames = 1;
}
// Constructs a stack trace for the given thread
//
public StackTrace(Thread targetThread, bool needFileInfo)
{
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
CaptureStackTrace (METHODS_TO_SKIP, needFileInfo, targetThread, null);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void GetStackFramesInternal(StackFrameHelper sfh, int iSkip, Exception e);
internal static int CalculateFramesToSkip (StackFrameHelper StackF, int iNumFrames)
{
int iRetVal = 0;
String PackageName = "System.Diagnostics";
// Check if this method is part of the System.Diagnostics
// package. If so, increment counter keeping track of
// System.Diagnostics functions
for (int i=0; i m_iNumOfFrames)
m_iMethodsToSkip = m_iNumOfFrames;
if (m_iNumOfFrames != 0)
{
frames = new StackFrame [m_iNumOfFrames];
for (int i=0; i= 0))
return frames [index+m_iMethodsToSkip];
return null;
}
// Returns an array of all stack frames for this stacktrace.
// The array is ordered and sized such that GetFrames()[i] == GetFrame(i)
// The nth element of this array is the same as GetFrame(n).
// The length of the array is the same as FrameCount.
//
[ComVisible(false)]
public virtual StackFrame [] GetFrames()
{
if (frames == null || m_iNumOfFrames <= 0)
return null;
// We have to return a subset of the array. Unfortunately this
// means we have to allocate a new array and copy over.
StackFrame [] array = new StackFrame[m_iNumOfFrames];
Array.Copy(frames, m_iMethodsToSkip, array, 0, m_iNumOfFrames);
return array;
}
// Builds a readable representation of the stack trace
//
public override String ToString()
{
// Include a trailing newline for backwards compatibility
return ToString( TraceFormat.TrailingNewLine );
}
// TraceFormat is Used to specify options for how the
// string-representation of a StackTrace should be generated.
internal enum TraceFormat
{
Normal,
TrailingNewLine, // include a trailing new line character
NoResourceLookup // to prevent infinite resource recusion
}
// Builds a readable representation of the stack trace, specifying
// the format for backwards compatibility.
internal String ToString( TraceFormat traceFormat )
{
String word_At = "at";
String inFileLineNum = "in {0}:line {1}";
if( traceFormat != TraceFormat.NoResourceLookup )
{
word_At = Environment.GetResourceString("Word_At");
inFileLineNum = Environment.GetResourceString("StackTrace_InFileLineNumber");
}
bool fFirstFrame = true;
StringBuilder sb = new StringBuilder(255);
for (int iFrameIndex=0; iFrameIndex < m_iNumOfFrames; iFrameIndex++)
{
StackFrame sf = GetFrame(iFrameIndex);
MethodBase mb = sf.GetMethod();
if (mb != null)
{
// We want a newline at the end of every line except for the last
if (fFirstFrame)
fFirstFrame = false;
else
sb.Append( Environment.NewLine );
sb.AppendFormat(CultureInfo.InvariantCulture, " {0} ", word_At);
Type t = mb.DeclaringType;
// if there is a type (non global method) print it
if (t != null)
{
sb.Append (t.FullName.Replace('+', '.'));
sb.Append (".");
}
sb.Append (mb.Name);
// deal with the generic portion of the method
if (mb is MethodInfo && ((MethodInfo)mb).IsGenericMethod)
{
Type[] typars = ((MethodInfo)mb).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 ("]");
}
// arguments printing
sb.Append ("(");
ParameterInfo[] pi = mb.GetParameters();
bool fFirstParam = true;
for( int j=0; j < pi.Length; j++ )
{
if (fFirstParam == false)
sb.Append (", ");
else
fFirstParam = false;
String typeName = "";
if (pi[j].ParameterType != null)
typeName = pi[j].ParameterType.Name;
sb.Append (typeName + " " + pi[j].Name);
}
sb.Append (")");
// source location printing
if (sf.GetILOffset() != -1)
{
// It's possible we have a debug version of an executable but no PDB. In
// this case, the file name will be null.
String fileName = null;
try
{
fileName = sf.GetFileName();
}
catch (SecurityException)
{
}
if (fileName != null) {
// tack on " in c:\tmp\MyFile.cs:line 5"
sb.Append(' ');
sb.AppendFormat(CultureInfo.InvariantCulture, inFileLineNum, fileName, sf.GetFileLineNumber());
}
}
}
}
if( traceFormat == TraceFormat.TrailingNewLine )
sb.Append( Environment.NewLine );
return sb.ToString();
}
// This helper is called from within the EE to construct a string representation
// of the current stack trace.
private static String GetManagedStackTraceStringHelper(bool fNeedFileInfo)
{
// Note all the frames in System.Diagnostics will be skipped when capturing
// a normal stack trace (not from an exception) so we don't need to explicitly
// skip the GetManagedStackTraceStringHelper frame.
StackTrace st = new StackTrace(0, fNeedFileInfo);
return st.ToString();
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MetadataCacheItem.cs
- ListControlBoundActionList.cs
- TextChangedEventArgs.cs
- SmiEventSink.cs
- XmlElementCollection.cs
- BindingsCollection.cs
- OleDbPermission.cs
- HasCopySemanticsAttribute.cs
- CommandValueSerializer.cs
- SmtpCommands.cs
- JapaneseCalendar.cs
- WebPartChrome.cs
- ValidationErrorCollection.cs
- TableItemStyle.cs
- ValueTable.cs
- KeySplineConverter.cs
- TraceXPathNavigator.cs
- WorkflowRuntimeElement.cs
- Model3DGroup.cs
- ConfigurationStrings.cs
- SystemUnicastIPAddressInformation.cs
- OSFeature.cs
- ConcurrentDictionary.cs
- ComplexObject.cs
- LayoutEngine.cs
- StorageAssociationSetMapping.cs
- Encoding.cs
- FormViewUpdatedEventArgs.cs
- unitconverter.cs
- HtmlListAdapter.cs
- BitmapEffectRenderDataResource.cs
- TextEditorTables.cs
- RegexRunnerFactory.cs
- TabControlCancelEvent.cs
- SoapUnknownHeader.cs
- TextParagraphCache.cs
- DESCryptoServiceProvider.cs
- DataGridViewComboBoxCell.cs
- DataServiceKeyAttribute.cs
- OdbcErrorCollection.cs
- MouseButtonEventArgs.cs
- exports.cs
- FixedPageStructure.cs
- SoapFault.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- OdbcCommand.cs
- EdmRelationshipRoleAttribute.cs
- SHA384.cs
- RenderCapability.cs
- XPathDocumentBuilder.cs
- DateTimeStorage.cs
- DataGridViewCellStyleChangedEventArgs.cs
- SettingsPropertyWrongTypeException.cs
- CodeMemberField.cs
- FrameworkContentElement.cs
- DocumentSignatureManager.cs
- PtsCache.cs
- DeploymentExceptionMapper.cs
- SizeChangedInfo.cs
- PluralizationService.cs
- BuildDependencySet.cs
- CustomLineCap.cs
- QueryCursorEventArgs.cs
- DBCommand.cs
- util.cs
- ActivatableWorkflowsQueryResult.cs
- RequestQueue.cs
- ExpressionBinding.cs
- SpeechAudioFormatInfo.cs
- METAHEADER.cs
- ExecutionScope.cs
- RelatedCurrencyManager.cs
- Figure.cs
- Win32Exception.cs
- SimpleModelProvider.cs
- HealthMonitoringSectionHelper.cs
- DataRowCollection.cs
- Image.cs
- NumberSubstitution.cs
- SafeEventLogReadHandle.cs
- StreamGeometry.cs
- UriTemplateMatchException.cs
- RenderCapability.cs
- ValueOfAction.cs
- RegexStringValidatorAttribute.cs
- BitmapFrame.cs
- SqlServices.cs
- WizardStepBase.cs
- MSHTMLHostUtil.cs
- SessionStateModule.cs
- CubicEase.cs
- TextDecorationCollectionConverter.cs
- MLangCodePageEncoding.cs
- ServiceDocumentFormatter.cs
- relpropertyhelper.cs
- ResponseStream.cs
- GestureRecognitionResult.cs
- StaticResourceExtension.cs
- WindowsToolbarAsMenu.cs
- ClientSettingsStore.cs