-
Notifications
You must be signed in to change notification settings - Fork 387
Description
The .Net Runtime's internal debugging APIs do not support generics fully. Only the link between the runtime and ICorDebug interfaces has essentially complete-ish support for generics. The downstream effects of this are that it is not currently possible to successfully implement generic support for SOS commands and ClrMD commands in a complete way.
I'm creating this issue as a hub-issue to resolve other requests against and to collect all issues into one place.
The underlying work to make this supported is very large, and we've been able to debug issues successfully for the last 20 years without this working. This may be something we consider in the future, but at the moment there are more important features, issues, and areas that we are investing into. SOS and the underlying APIs it uses are ancient, and not the path forward in the diagnostic space for future work, so investing a lot here has very little payoff in the bigger picture of the ecosystem.
There's no planned work to fix this (as of filing this bug), but that doesn't mean we won't consider this in the future. This bug is just prioritized against other features we could be working on, and in 20 years it simply has never risen high enough on that list to invest that amount of time into SOS for this feature.
SOS Commands
| Command | Status | Problem |
|---|---|---|
!DumpClass |
Broken for generic statics | Passes canonical MT to GetThreadStaticBaseAddress/GetStaticFieldPTR, gets back 0. Thread static and static values never displayed. |
!DumpMT -md |
Partial | Shows canonical MT only. -md shows methods but generic parameters in method signatures incomplete. |
!DumpModule -mt |
Only canonical MTs | TraverseModuleMap(TypeDefToMethodTable) returns only canonical MTs. No closed generics listed. |
!Name2EE |
Cannot find closed generics | Now a managed command, but still can't resolve System.Collections.Generic.List<int> to its MT. |
!PrintException |
Generic args missing | When exception methods have generic type arguments in their signatures, they show as object addresses instead of readable type names. |
!DumpObj |
Mostly works | Objects of closed generic types display fields correctly since the object header contains the closed MT. Static fields of generic types are broken (same root cause). |
!DumpHeap -type |
Mostly works | Can find objects by type name substring, but only because it matches against the MT name. No way to enumerate types with only statics and no heap instances. |
!ClrStack -a |
Mostly works | Shows generic method signatures from the JIT code manager, but complex generic arguments may be incomplete. |
List isn't exhaustive.
ClrMD Classes
| Class / Area | Status | Problem |
|---|---|---|
ClrType |
No generic argument API | EnumerateGenericParameters() returns definition-time params only (e.g. T), not concrete args (e.g. int). No IsOpenGeneric, IsClosedGeneric, or GenericTypeArguments property. |
ClrModule.EnumerateTypes() |
Canonical MTs only | Calls TraverseModuleMap(TypeDefToMethodTable). Cannot discover closed generic instantiations. |
ClrModule.GetTypeByName() |
Broken for closed generics | Cannot find List<int> — only finds canonical List<T>. |
ClrField.Type (on generic types) |
__Canon leakage |
Shared generic reference types expose System.__Canon as field types instead of concrete types. A proper fix needs DAC-level generic argument resolution. |
ClrStaticField / ClrThreadStaticField |
Broken for generics | Can't get the address of statics on generic types because it can't find the closed MTs. |
ClrMethod (generic methods) |
Partial | GetMethodByHandle returns null for reference-type generic instantiations. |
List isn't exhaustive.