singrdk/base/Kernel/System/Exception.cs

180 lines
5.7 KiB
C#

// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*=============================================================================
**
** Class: Exception
**
**
** Purpose: The base class for all exceptional conditions.
**
** Date: March 11, 1998
**
=============================================================================*/
namespace System {
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using System.Text;
using System.Reflection;
#if SINGULARITY_KERNEL
using Microsoft.Singularity;
#elif SINGULARITY_PROCESS
using Microsoft.Singularity.V1.Services;
#endif // SINGULARITY_PROCESS
//| <include path='docs/doc[@for="Exception"]/*' />
[RequiredByBartok]
public class Exception
{
//| <include path='docs/doc[@for="Exception.Exception"]/*' />
public Exception() {
_message = null;
#if SINGULARITY_KERNEL
//DebugStub.Break();
#elif SINGULARITY_PROCESS
//DebugService.Break();
#endif // SINGULARITY_PROCESS
}
//| <include path='docs/doc[@for="Exception.Exception1"]/*' />
public Exception(String message) {
_message = message;
#if SINGULARITY_KERNEL
//DebugStub.Break();
#elif SINGULARITY_PROCESS
//DebugService.Break();
#endif // SINGULARITY_PROCESS
}
// Creates a new Exception. All derived classes should
// provide this constructor.
// Note: the stack trace is not started until the exception
// is thrown
//
//| <include path='docs/doc[@for="Exception.Exception2"]/*' />
public Exception (String message, Exception innerException)
{
// TODO: The innerException will be provided by the runtime
// in the M9 time frame. Until then, we need this method.
_message = message;
_innerException = innerException;
}
//| <include path='docs/doc[@for="Exception.Message"]/*' />
public virtual String Message {
get {
if (_message == null) {
return "Exception_WasThrown";
} else {
return _message;
}
}
}
private String GetClassName() {
return this.vtable.vtableType.FullName;
}
// Retrieves the lowest exception (inner most) for the given Exception.
// This will traverse exceptions using the innerException property.
//
//| <include path='docs/doc[@for="Exception.GetBaseException"]/*' />
public virtual Exception GetBaseException()
{
Exception inner = InnerException;
Exception back = this;
while (inner != null) {
back = inner;
inner = inner.InnerException;
}
return back;
}
// Returns the inner exception contained in this exception
//
//| <include path='docs/doc[@for="Exception.InnerException"]/*' />
public Exception InnerException {
get { return _innerException; }
}
//| <include path='docs/doc[@for="Exception.ToString"]/*' />
public override String ToString() {
String message = Message;
if (_innerException!=null) {
message = message + " ---> " + _innerException.ToString() + "\r\n" + " " + "Exception_EndOfInnerExceptionStack";
}
return message;
}
[AccessedByRuntime("referenced from halasm.asm")]
internal static unsafe bool IsUnlinkStack(UIntPtr throwAddr) {
UIntPtr unlinkBegin;
UIntPtr unlinkLimit;
fixed (byte *begin = &Microsoft.Singularity.Memory.Stacks.UnlinkStackBegin) {
unlinkBegin = (UIntPtr)begin;
}
fixed (byte *limit = &Microsoft.Singularity.Memory.Stacks.UnlinkStackLimit) {
unlinkLimit = (UIntPtr)limit;
}
if(throwAddr >= unlinkBegin && throwAddr <= unlinkLimit) {
return true;
} else {
return false;
}
}
// The following functions are for tryall support.
// This is the function actually called by the internal runtime
[NoLoggingForUndo]
[RequiredByBartok]
private Exception internalCloneForUndo() {
/* this function is not allowed to throw an exception. */
try {
return cloneForUndo();
} catch (Exception ex) {
return ex;
}
}
// This is the function that users can override
// BUGBUG: provide a better default (probably deep copy). The
// current one does not deal with references well, and so, is
// not even a good shallow copy (it should at least null out the
// references).
virtual protected Exception cloneForUndo() {
return (Exception)this.MemberwiseClone();
}
[AccessedByRuntime("referenced from halexn.cpp")]
internal String _message;
private Exception _innerException;
[AccessedByRuntime("referenced from halexn.cpp")]
private UIntPtr _throwAddress;
[AccessedByRuntime("referenced from halexn.cpp")]
private bool _notifiedDebugger; // True if debugger first chance already thrown.
//
public string StackTrace
{
get {
return "<no.stack.trace>";
}
}
}
}