-
Notifications
You must be signed in to change notification settings - Fork 5.5k
[cDAC] Validate contract presence in interface returning functions #131009
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
4e8abc1
WIP
noahfalk d25c808
cDAC: eager contract validation with classifiable HRESULTs (WIP check…
hoyosjs 4e8da15
Add dbi validation on top of dacdbi entrypoint
hoyosjs 0d02967
React to feedback
hoyosjs cc027fb
Merge branch 'main' into juhoyosa/cdac-policy
hoyosjs cb5c2a5
Enhance contract validation for sub-descriptors and update related tests
hoyosjs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
...native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CdacHResults.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| // 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; | ||
|
|
||
| /// <summary> | ||
| /// cDAC-specific <c>HRESULT</c>s surfaced when creating a data-access interface | ||
| /// for a target fails for a reason this cDAC can describe precisely. This covers two stages of | ||
| /// creation: locating and reading the target's contract descriptor (the <c>DESCRIPTOR</c> codes), | ||
| /// and eager validation that this cDAC can service the contracts the descriptor advertises (the | ||
| /// <c>CONTRACT</c> codes, see | ||
| /// <see cref="Microsoft.Diagnostics.DataContractReader.Contracts.CoreCLRContracts.ValidateForDataAccess"/>). | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// The customer bit (bit 29, <c>0x20000000</c>) is set on every value so these codes can never | ||
| /// collide with system or CLR (corerror.h) <c>HRESULT</c>s. All values are failure codes, so | ||
| /// existing <c>FAILED(hr)</c> checks in native callers continue to behave correctly. Native code | ||
| /// and tooling that wants to distinguish the failure modes (for example, to decide whether to fall | ||
| /// back to the brittle DAC) can compare against the literal values documented here. | ||
| /// </remarks> | ||
| public static class CdacHResults | ||
| { | ||
| /// <summary> | ||
| /// A contract required to service the SOS interface is not advertised by the target's | ||
| /// contract descriptor. The target runtime predates the contract or does not expose it. | ||
| /// </summary> | ||
| public const int CDAC_E_CONTRACT_NOT_ADVERTISED = unchecked((int)0xA0DAC001); | ||
|
|
||
| /// <summary> | ||
| /// The target advertises a required contract at a version this cDAC does not recognize, | ||
| /// typically because the target runtime is newer than this cDAC. | ||
| /// </summary> | ||
| public const int CDAC_E_CONTRACT_UNRECOGNIZED = unchecked((int)0xA0DAC002); | ||
|
|
||
| /// <summary> | ||
| /// The target advertises a required contract at a version this cDAC recognizes but | ||
| /// intentionally does not implement, typically because the target runtime is too old. | ||
| /// </summary> | ||
| public const int CDAC_E_CONTRACT_UNSUPPORTED = unchecked((int)0xA0DAC003); | ||
|
|
||
| /// <summary> | ||
| /// A required contract could not be validated and the cause could not be classified as one of | ||
| /// the more specific CONTRACT codes above. This is the default HRESULT carried by the | ||
| /// <see cref="ContractNotAvailableException"/> base type. | ||
| /// </summary> | ||
| public const int CDAC_E_CONTRACT_UNAVAILABLE = unchecked((int)0xA0DAC004); | ||
|
|
||
| /// <summary> | ||
| /// No usable cDAC contract descriptor could be located for the target: the contract locator | ||
| /// did not produce a descriptor address, the descriptor header could not be read, or the bytes | ||
| /// at the descriptor address are not a contract descriptor (bad magic). This typically means the | ||
| /// target is not a cDAC-capable .NET runtime (for example, a non-.NET target or a runtime that | ||
| /// predates the cDAC contract descriptor), and tooling should fall back to the brittle DAC | ||
| /// rather than treat it as a hard error. | ||
| /// </summary> | ||
| public const int CDAC_E_DESCRIPTOR_NOT_FOUND = unchecked((int)0xA0DAC011); | ||
|
|
||
| /// <summary> | ||
| /// A cDAC contract descriptor was found but could not be consumed: a field could not be read, | ||
| /// the embedded JSON failed to parse, or the descriptor content is internally inconsistent | ||
| /// (for example, duplicate names or an out-of-range pointer-data index). This indicates a | ||
| /// corrupt dump or a descriptor format this cDAC cannot understand, and is distinct from a | ||
| /// recognized-but-unsupported contract version (<see cref="CDAC_E_CONTRACT_UNSUPPORTED"/>). | ||
| /// </summary> | ||
| public const int CDAC_E_DESCRIPTOR_MALFORMED = unchecked((int)0xA0DAC012); | ||
| } |
109 changes: 109 additions & 0 deletions
109
...ac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractNotAvailableException.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System; | ||
|
|
||
| namespace Microsoft.Diagnostics.DataContractReader; | ||
|
|
||
| /// <summary> | ||
| /// Exception for failures to retrieve a data contract from a target. The concrete subclasses | ||
| /// describe the specific cause; this base type is also thrown directly for an unclassified | ||
| /// validation failure. Each concrete subclass sets a distinct <see cref="CdacHResults"/> value on | ||
| /// <see cref="System.Exception.HResult"/> so both the eager validation path | ||
| /// (<see cref="Microsoft.Diagnostics.DataContractReader.Contracts.CoreCLRContracts.ValidateForDataAccess"/>) | ||
| /// and the lazy SOS data-access path surface the same self-describing failure code with no wrapping | ||
| /// or translation. The base defaults to <see cref="CdacHResults.CDAC_E_CONTRACT_UNAVAILABLE"/> so an | ||
| /// unclassified failure still carries a cDAC-specific failure code rather than <c>S_OK</c>. | ||
| /// </summary> | ||
| public class ContractNotAvailableException : Exception | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="ContractNotAvailableException"/> class. | ||
| /// </summary> | ||
| /// <param name="contractName">The name of the requested contract.</param> | ||
| /// <param name="contractVersion">The target-advertised version of the requested contract, or <see langword="null"/> if the target did not advertise the contract.</param> | ||
| /// <param name="message">The exception message.</param> | ||
| public ContractNotAvailableException(string contractName, string? contractVersion, string message) | ||
| : base(message) | ||
| { | ||
| ContractName = contractName; | ||
| ContractVersion = contractVersion; | ||
| HResult = CdacHResults.CDAC_E_CONTRACT_UNAVAILABLE; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets the name of the requested contract. | ||
| /// </summary> | ||
| public string ContractName { get; } | ||
|
|
||
| /// <summary> | ||
| /// Gets the target-advertised version of the requested contract, or <see langword="null"/> if the target did not advertise the contract. | ||
| /// </summary> | ||
| public string? ContractVersion { get; } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Exception thrown when the target's contract descriptor does not advertise the requested contract. | ||
| /// </summary> | ||
| public sealed class ContractMissingException : ContractNotAvailableException | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="ContractMissingException"/> class. | ||
| /// </summary> | ||
| /// <param name="contractName">The name of the requested contract.</param> | ||
| public ContractMissingException(string contractName) | ||
| : base(contractName, null, $"Contract '{contractName}' is not advertised by the target.") | ||
| { | ||
| HResult = CdacHResults.CDAC_E_CONTRACT_NOT_ADVERTISED; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Exception thrown when the target advertises the requested contract, but this cDAC cannot provide an implementation for the advertised version. | ||
| /// </summary> | ||
| public abstract class ContractUnsupportedException : ContractNotAvailableException | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="ContractUnsupportedException"/> class. | ||
| /// </summary> | ||
| /// <param name="contractName">The name of the requested contract.</param> | ||
| /// <param name="contractVersion">The target-advertised version of the requested contract.</param> | ||
| /// <param name="message">The exception message.</param> | ||
| protected ContractUnsupportedException(string contractName, string contractVersion, string message) | ||
| : base(contractName, contractVersion, message) | ||
| { } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Exception thrown when the target advertises a contract version that this cDAC does not recognize, typically because the target runtime is newer than this cDAC. | ||
| /// </summary> | ||
| public sealed class ContractUnrecognizedException : ContractUnsupportedException | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="ContractUnrecognizedException"/> class. | ||
| /// </summary> | ||
| /// <param name="contractName">The name of the requested contract.</param> | ||
| /// <param name="contractVersion">The target-advertised version of the requested contract.</param> | ||
| public ContractUnrecognizedException(string contractName, string contractVersion) | ||
| : base(contractName, contractVersion, $"Contract '{contractName}' version {contractVersion} is advertised by the target but is not recognized by this cDAC.") | ||
| { | ||
| HResult = CdacHResults.CDAC_E_CONTRACT_UNRECOGNIZED; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Exception thrown when the target advertises a contract version that this cDAC recognizes but intentionally does not implement, typically because the target runtime is too old. | ||
| /// </summary> | ||
| public sealed class ContractObsoleteException : ContractUnsupportedException | ||
| { | ||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="ContractObsoleteException"/> class. | ||
| /// </summary> | ||
| /// <param name="contractName">The name of the requested contract.</param> | ||
| /// <param name="contractVersion">The target-advertised version of the requested contract.</param> | ||
| public ContractObsoleteException(string contractName, string contractVersion) | ||
| : base(contractName, contractVersion, $"Contract '{contractName}' version {contractVersion} is advertised by the target and recognized by this cDAC, but is intentionally not implemented.") | ||
| { | ||
| HResult = CdacHResults.CDAC_E_CONTRACT_UNSUPPORTED; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.