-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[cdac] Implement ISOSDacInterface2::GetObjectExceptionData #104343
Changes from 7 commits
a8c8caf
ca65ff1
26c7632
1e55328
4514056
86875ba
e11102d
1952438
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,28 +1,56 @@ | ||||||
# Contract Thread | ||||||
# Contract Exception | ||||||
|
||||||
This contract is for getting information about exceptions in the process. | ||||||
|
||||||
## APIs of contract | ||||||
|
||||||
```csharp | ||||||
record struct ManagedExceptionData( | ||||||
TargetPointer Message, | ||||||
TargetPointer InnerException, | ||||||
TargetPointer StackTrace, | ||||||
TargetPointer WatsonBuckets, | ||||||
TargetPointer StackTraceString, | ||||||
TargetPointer RemoteStackTraceString, | ||||||
int HResult, | ||||||
int XCode); | ||||||
``` | ||||||
|
||||||
``` csharp | ||||||
TargetPointer GetExceptionInfo(TargetPointer exception, out TargetPointer nextNestedException); | ||||||
ManagedExceptionData GetManagedExceptionData(TargetPointer managedException) | ||||||
``` | ||||||
|
||||||
## Version 1 | ||||||
|
||||||
Data descriptors used: | ||||||
- `ExceptionInfo` | ||||||
- `ExceptionObject` | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we have a consistent naming scheme for data descriptors of managed types? The names of the unmanaged mirrors of managed types are not very consistent. Here are some examples of managed types that may need data descriptor at some point.
One possible naming scheme is to replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or omit Or abbreviate the name space: Or drop the namespace completely (I think I like this the most): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I like the non-abbreviated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The name collisions have been a problem a few times as we are rewriting more of the native runtime in C#. If the name collisions are the only problem, I would say rename the internal types to avoid them. The ultimate picture can be that nearly all types have managed views, and subset of types have unmanaged mirrors. The name collisions between managed and unmanaged code are also a source of confusion. Trivia question - when you see There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
? |
||||||
``` csharp | ||||||
TargetPointer GetExceptionInfo(TargetPointer exception, out TargetPointer nextNestedException) | ||||||
{ | ||||||
if (exception == TargetPointer.Null) | ||||||
throw new InvalidArgumentException(); | ||||||
|
||||||
nextNestedException = target.ReadPointer(address + /* ExceptionInfo::PreviousNestedInfo offset*/); | ||||||
TargetPointer thrownObjHandle = target.ReadPointer(address + /* ExceptionInfo::ThrownObject offset */); | ||||||
nextNestedException = target.ReadPointer(exception + /* ExceptionInfo::PreviousNestedInfo offset*/); | ||||||
TargetPointer thrownObjHandle = target.ReadPointer(exception + /* ExceptionInfo::ThrownObject offset */); | ||||||
return = thrownObjHandle != TargetPointer.Null | ||||||
? target.ReadPointer(thrownObjHandle) | ||||||
: TargetPointer.Null; | ||||||
} | ||||||
|
||||||
ManagedExceptionData GetManagedExceptionData(TargetPointer managedException) | ||||||
{ | ||||||
return new ManagedExceptionData( | ||||||
target.ReadPointer(objectAddress + /* Exception::Message offset */), | ||||||
target.ReadPointer(objectAddress + /* Exception::InnerException offset */), | ||||||
target.ReadPointer(objectAddress + /* Exception::StackTrace offset */), | ||||||
target.ReadPointer(objectAddress + /* Exception::WatsonBuckets offset */), | ||||||
target.ReadPointer(objectAddress + /* Exception::StackTraceString offset */), | ||||||
target.ReadPointer(objectAddress + /* Exception::RemoteStackTraceString offset */), | ||||||
target.Read<int>(objectAddress + /* Exception::HResult offset */), | ||||||
target.Read<int>(objectAddress + /* Exception::XCode offset */), | ||||||
); | ||||||
} | ||||||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace Microsoft.Diagnostics.DataContractReader.Data; | ||
|
||
internal sealed class Exception : IData<Exception> | ||
{ | ||
static Exception IData<Exception>.Create(Target target, TargetPointer address) | ||
=> new Exception(target, address); | ||
|
||
public Exception(Target target, TargetPointer address) | ||
{ | ||
Target.TypeInfo type = target.GetTypeInfo(DataType.Exception); | ||
|
||
Message = target.ReadPointer(address + (ulong)type.Fields["_message"].Offset); | ||
InnerException = target.ReadPointer(address + (ulong)type.Fields["_innerException"].Offset); | ||
StackTrace = target.ReadPointer(address + (ulong)type.Fields["_stackTrace"].Offset); | ||
WatsonBuckets = target.ReadPointer(address + (ulong)type.Fields["_watsonBuckets"].Offset); | ||
StackTraceString = target.ReadPointer(address + (ulong)type.Fields["_stackTraceString"].Offset); | ||
RemoteStackTraceString = target.ReadPointer(address + (ulong)type.Fields["_remoteStackTraceString"].Offset); | ||
HResult = target.Read<int>(address + (ulong)type.Fields["_HResult"].Offset); | ||
XCode = target.Read<int>(address + (ulong)type.Fields["_xcode"].Offset); | ||
} | ||
|
||
public TargetPointer Message { get; init; } | ||
public TargetPointer InnerException { get; init; } | ||
public TargetPointer StackTrace { get; init; } | ||
public TargetPointer WatsonBuckets { get; init; } | ||
public TargetPointer StackTraceString { get; init; } | ||
public TargetPointer RemoteStackTraceString { get; init; } | ||
public int HResult { get; init; } | ||
public int XCode { get; init; } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we call this just
ExceptionData
?I think it would be best to avoid
Managed
prefix in the contract definitions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is something explicitly unmanaged (like
EXCEPTION_INFORMATION
- that is unmanaged equivalent of managed exception), I would use a special prefix for that if necessary.