Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public sealed unsafe partial class ClrDataExceptionState : IXCLRDataExceptionSta
private readonly Target _target;
private readonly TargetPointer _threadAddress;
private readonly uint _flags;
private readonly TargetPointer _exceptionInfoAddress;
private readonly TargetPointer _thrownObjectHandle;
private readonly TargetPointer _previousExInfoAddress;
private readonly IXCLRDataExceptionState? _legacyImpl;
Expand All @@ -22,13 +23,15 @@ public ClrDataExceptionState(
Target target,
TargetPointer threadAddress,
uint flags,
TargetPointer exceptionInfoAddress,
TargetPointer thrownObjectHandle,
TargetPointer previousExInfoAddress,
IXCLRDataExceptionState? legacyImpl)
{
_target = target;
_threadAddress = threadAddress;
_flags = flags;
_exceptionInfoAddress = exceptionInfoAddress;
_thrownObjectHandle = thrownObjectHandle;
_previousExInfoAddress = previousExInfoAddress;
_legacyImpl = legacyImpl;
Expand Down Expand Up @@ -91,6 +94,7 @@ int IXCLRDataExceptionState.GetPrevious(DacComNullableByRef<IXCLRDataExceptionSt
_target,
_threadAddress,
(uint)CLRDataExceptionStateFlag.CLRDATA_EXCEPTION_DEFAULT,
_previousExInfoAddress,
prevExThrownObjectHandle,
nextNestedException,
legacyPrevious
Expand Down Expand Up @@ -213,9 +217,81 @@ int IXCLRDataExceptionState.Request(uint reqCode, uint inBufferSize, byte* inBuf
}

int IXCLRDataExceptionState.IsSameState(EXCEPTION_RECORD64* exRecord, uint contextSize, byte* cxRecord)
=> LegacyFallbackHelper.CanFallback() && _legacyImpl is not null ? _legacyImpl.IsSameState(exRecord, contextSize, cxRecord) : HResults.E_NOTIMPL;
{
int hr = IsSameState2((uint)CLRDataExceptionSameFlag.CLRDATA_EXSAME_SECOND_CHANCE, exRecord);
#if DEBUG
if (_legacyImpl is not null)
{
int hrLocal = _legacyImpl.IsSameState(exRecord, contextSize, cxRecord);
Debug.ValidateHResult(hr, hrLocal);
}
#endif
return hr;
}

int IXCLRDataExceptionState.IsSameState2(uint flags, EXCEPTION_RECORD64* exRecord, uint contextSize, byte* cxRecord)
=> LegacyFallbackHelper.CanFallback() && _legacyImpl is not null ? _legacyImpl.IsSameState2(flags, exRecord, contextSize, cxRecord) : HResults.E_NOTIMPL;
{
int hr = IsSameState2(flags, exRecord);
#if DEBUG
if (_legacyImpl is not null)
{
int hrLocal = _legacyImpl.IsSameState2(flags, exRecord, contextSize, cxRecord);
Debug.ValidateHResult(hr, hrLocal);
}
#endif
return hr;
}

private int IsSameState2(uint flags, EXCEPTION_RECORD64* exRecord)
{
int hr = HResults.S_FALSE;
try
{
if ((flags & ~(uint)(CLRDataExceptionSameFlag.CLRDATA_EXSAME_SECOND_CHANCE | CLRDataExceptionSameFlag.CLRDATA_EXSAME_FIRST_CHANCE)) != 0)
throw new ArgumentException();

if ((_flags & (uint)CLRDataExceptionStateFlag.CLRDATA_EXCEPTION_PARTIAL) != 0)
{
if ((flags & (uint)CLRDataExceptionSameFlag.CLRDATA_EXSAME_FIRST_CHANCE) != 0)
hr = HResults.S_OK;
}
else
{
if (exRecord is null)
throw new NullReferenceException();

Comment thread
rcj1 marked this conversation as resolved.
TargetPointer exceptionRecord;
if (_exceptionInfoAddress != TargetPointer.Null)
{
Target.TypeInfo exceptionInfoType = _target.GetTypeInfo(DataType.ExceptionInfo);
exceptionRecord = _target.ReadPointer(
_exceptionInfoAddress + (ulong)exceptionInfoType.Fields["ExceptionRecord"].Offset);
}
else
{
ThreadData threadData = _target.Contracts.Thread.GetThreadData(_threadAddress);
exceptionRecord = threadData.OSExceptionRecord;
}

TargetPointer exceptionAddress = _target.ReadPointer(
exceptionRecord + (ulong)(sizeof(uint) * 2 + _target.PointerSize));
TargetPointer requestedAddress = new(
_target.PointerSize == sizeof(ulong)
? exRecord->ExceptionAddress
: (uint)exRecord->ExceptionAddress);

if (exceptionAddress == requestedAddress)
hr = HResults.S_OK;
}
}
catch (System.Exception ex)
{
hr = ex.HResult;
}

return hr;
}

int IXCLRDataExceptionState.GetTask(DacComNullableByRef<IXCLRDataTask> task)
{
int hr = HResults.S_OK, hrLocal = HResults.S_OK;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ int IXCLRDataTask.GetCurrentExceptionState(DacComNullableByRef<IXCLRDataExceptio
else
{
Contracts.ThreadData threadData = _target.Contracts.Thread.GetThreadData(_address);
exception.Interface = new ClrDataExceptionState(_target, _address, (uint)CLRDataExceptionStateFlag.CLRDATA_EXCEPTION_DEFAULT, thrownObjectHandle, threadData.FirstNestedException, legacyExceptionState);
exception.Interface = new ClrDataExceptionState(_target, _address, (uint)CLRDataExceptionStateFlag.CLRDATA_EXCEPTION_DEFAULT, TargetPointer.Null, thrownObjectHandle, threadData.FirstNestedException, legacyExceptionState);
}
}
catch (System.Exception ex)
Expand Down Expand Up @@ -155,7 +155,7 @@ int IXCLRDataTask.GetLastExceptionState(DacComNullableByRef<IXCLRDataExceptionSt
}
else
{
exception.Interface = new ClrDataExceptionState(_target, _address, (uint)CLRDataExceptionStateFlag.CLRDATA_EXCEPTION_PARTIAL, thrownObjectHandle, TargetPointer.Null, legacyExceptionState);
exception.Interface = new ClrDataExceptionState(_target, _address, (uint)CLRDataExceptionStateFlag.CLRDATA_EXCEPTION_PARTIAL, TargetPointer.Null, thrownObjectHandle, TargetPointer.Null, legacyExceptionState);
}
}
catch (System.Exception ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,13 @@ public enum CLRDataExceptionStateFlag : uint
CLRDATA_EXCEPTION_PARTIAL = 0x2,
}

[Flags]
public enum CLRDataExceptionSameFlag : uint
{
CLRDATA_EXSAME_SECOND_CHANCE = 0,
CLRDATA_EXSAME_FIRST_CHANCE = 0x1,
}
Comment thread
rcj1 marked this conversation as resolved.

[GeneratedComInterface]
[Guid("75DA9E4C-BD33-43C8-8F5C-96E8A5241F57")]
public unsafe partial interface IXCLRDataExceptionState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ int IXCLRDataProcess.TranslateExceptionRecordToNotification(EXCEPTION_RECORD64*
_target,
exception.ThreadAddress,
(uint)CLRDataExceptionStateFlag.CLRDATA_EXCEPTION_DEFAULT,
TargetPointer.Null,
thrownObjectHandle,
threadData.FirstNestedException,
null));
Expand Down
Loading