[cDAC] Add data descriptor field type annotations#126163
Conversation
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
6666d12 to
4d008c4
Compare
This comment has been minimized.
This comment has been minimized.
4d008c4 to
0ae4fe8
Compare
This comment has been minimized.
This comment has been minimized.
0ae4fe8 to
e259293
Compare
This comment has been minimized.
This comment has been minimized.
e259293 to
62dcc09
Compare
This comment has been minimized.
This comment has been minimized.
62dcc09 to
d62d46b
Compare
This comment has been minimized.
This comment has been minimized.
d62d46b to
3cfcc06
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
02ddfa0 to
2146118
Compare
This comment has been minimized.
This comment has been minimized.
2146118 to
26a151e
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
c817025 to
cc78c3f
Compare
This comment has been minimized.
This comment has been minimized.
cc78c3f to
11747ec
Compare
This comment has been minimized.
This comment has been minimized.
11747ec to
e0cafde
Compare
This comment has been minimized.
This comment has been minimized.
Remove documentation for CDAC_DATADESCRIPTOR_INC override mechanism that was never implemented in wrappeddatadescriptor.inc. The include always uses 'datadescriptor.inc' resolved via build-configured include directories. Fix comment typo in datadescriptor.cpp: T(GCHandle) -> TYPE(GCHandle). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use individual #ifndef guards for each type annotation define, with a single #ifdef _DEBUG / #else at the top level. This allows callers to override individual type defines without affecting others, matching the pattern used by the CDAC macros below. Update EXTERN_TYPE documentation to clarify it can be used for well-known types that don't have a CDAC_TYPE_BEGIN in the current descriptor, not just cross-descriptor types. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
e0cafde to
e70025e
Compare
…e docs - Change SoftwareExceptionFrame, DebuggerEval, ResumableFrame, and FaultingExceptionFrame TargetContext fields from T_POINTER to EXTERN_TYPE(Context) - Update EXTERN_TYPE docs in cdactypevalidation.inc and README.md to mention well-known types alongside cross-descriptor types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
e70025e to
c979818
Compare
|
Note This review was generated by Copilot. 🤖 Copilot Code Review — PR #126163Holistic AssessmentMotivation: The PR replaces unstructured comment-based type annotations ( Approach: The approach is sound and consistent with the existing macro-heavy data descriptor infrastructure. The type defines are introduced in Summary: ✅ LGTM. The PR is a well-executed infrastructure improvement. All type conversions are consistent with the original comment annotations. The compile-time validation logic is correct. No blocking issues were found. One behavioral observation and one minor suggestion are noted below. Detailed Findings✅ Type Conversion Correctness — All 600+ field/global entries correctly convertedVerified that comment-based types were correctly mapped to macro defines:
✅ Compile-Time Validation —
|
## Summary Add a type system to the cDAC data descriptor infrastructure. Field types in `CDAC_TYPE_FIELD` that were previously specified as C comments (`/*uint32*/`) are now expressed as preprocessor defines (`T_UINT32`, `T_POINTER`, `TYPE(GCHandle)`, etc.). ### Changes **Native-side type defines** (`wrappeddatadescriptor.inc`): - Primitive types: `T_UINT8`, `T_UINT16`, `T_UINT32`, `T_UINT64`, `T_INT8`...`T_INT64`, `T_NUINT`, `T_NINT`, `T_POINTER`, `T_BOOL` - Struct types: `TYPE(name)` for types declared with `CDAC_TYPE_BEGIN` in the same descriptor - Cross-descriptor types: `EXTERN_TYPE(name)` (not validated locally) - Array types: `T_ARRAY(type)` (expands to `pointer` in the blob) - In debug/checked builds, these expand to type name strings in the blob. In release builds, they expand to nothing. **Compile-time validation** (`cdactypevalidation.inc`): - In debug builds, validates that every `TYPE(name)` reference matches a `CDAC_TYPE_BEGIN` declaration via `static_assert`. - Uses two passes: first collects all declared types, then validates references. Handles forward references. ### Descriptor updates - VM `datadescriptor.inc`: All ~200 fields and ~50 globals converted to type defines - GC `datadescriptor.inc`: All fields and globals converted, with `EXTERN_TYPE(GCAllocContext)` for the one cross-descriptor reference > [!NOTE] > This content was generated with the assistance of GitHub Copilot. --------- Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary Add typed field extension methods for the cDAC managed reader and convert all `IData<T>` classes to use them. This builds on the native data descriptor type system (#126163) to add managed-side type validation. ### Changes **`TargetFieldExtensions.cs`** — New extension methods on `Target`: - `ReadField<T>` — reads a primitive field with `Debug.Assert` type validation - `ReadPointerField` / `ReadPointerFieldOrNull` — reads pointer fields (required/optional) - `ReadNUIntField` — reads native unsigned integer fields - `ReadCodePointerField` — reads code pointer fields - `ReadDataField<T>` / `ReadDataFieldPointer<T>` — reads inline/pointer-to Data struct fields - `ReadFieldOrDefault<T>` — reads optional primitive fields with default value When the data descriptor includes type information (debug/checked builds), these methods assert that the declared field type is compatible with the C# read type. **All ~130 `IData<T>` classes converted** to use the new extension methods, replacing direct `target.Read<T>(address + (ulong)type.Fields[...].Offset)` calls. ### Bugs found and fixed The type system caught several pre-existing issues: 1. **DynamicStaticsInfo.GCStatics/NonGCStatics** — descriptor said `uint32`, native type is `TADDR` (pointer) 2. **EEClass.FieldDescList** — used `Read<ulong>` for a pointer field (broken on 32-bit) 3. **ExceptionClause.ClassToken** — read `TypeHandle` (nuint) as `uint` 4. **SimpleComCallWrapper.RefCount** — property was `ulong`, native is `LONGLONG` (signed) 5. **NativeCodeVersionNode.NativeCode** — descriptor was `T_POINTER`, actually `CodePointer` 6. **MethodTable.EEClassOrCanonMT** — descriptor was `T_NUINT`, managed reads as pointer > [!NOTE] > This content was generated with the assistance of GitHub Copilot. --------- Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Add a type system to the cDAC data descriptor infrastructure. Field types in
CDAC_TYPE_FIELDthat were previously specified as C comments (/*uint32*/) are now expressed as preprocessor defines (T_UINT32,T_POINTER,TYPE(GCHandle), etc.).Changes
Native-side type defines (
wrappeddatadescriptor.inc):T_UINT8,T_UINT16,T_UINT32,T_UINT64,T_INT8...T_INT64,T_NUINT,T_NINT,T_POINTER,T_BOOLTYPE(name)for types declared withCDAC_TYPE_BEGINin the same descriptorEXTERN_TYPE(name)(not validated locally)T_ARRAY(type)(expands topointerin the blob)Compile-time validation (
cdactypevalidation.inc):TYPE(name)reference matches aCDAC_TYPE_BEGINdeclaration viastatic_assert.Descriptor updates
datadescriptor.inc: All ~200 fields and ~50 globals converted to type definesdatadescriptor.inc: All fields and globals converted, withEXTERN_TYPE(GCAllocContext)for the one cross-descriptor referenceNote
This content was generated with the assistance of GitHub Copilot.