Skip to content

Commit 4ef215d

Browse files
authored
Merge branch 'main' into robust-crossJumpVictim
2 parents 74d0856 + f1e9e36 commit 4ef215d

711 files changed

Lines changed: 28199 additions & 16687 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-failure-fix.lock.yml

Lines changed: 1588 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/ci-failure-fix.md

Lines changed: 396 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/ci-failure-scan-feedback.lock.yml

Lines changed: 22 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/ci-failure-scan-feedback.md

Lines changed: 110 additions & 45 deletions
Large diffs are not rendered by default.

.github/workflows/ci-failure-scan.lock.yml

Lines changed: 23 additions & 112 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/workflows/ci-failure-scan.md

Lines changed: 35 additions & 130 deletions
Large diffs are not rendered by default.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Area → skill directory
2+
3+
A single source of truth mapping a `dotnet/runtime` area / pipeline to the
4+
Copilot skill that carries the domain knowledge for it. Agents and skills that
5+
need to route a failure, a review, or a change to the right area knowledge
6+
should reference this table instead of re-declaring their own copy, so the
7+
mapping stays consistent as skills are added or renamed.
8+
9+
Skill paths in the table below are relative to `.github/skills/`, so
10+
`mobile-platforms/SKILL.md` means `.github/skills/mobile-platforms/SKILL.md`.
11+
The one non-skill entry (NativeAOT) is given as a repo-root-relative path and is
12+
called out as such. Area-owner handles are **not** listed here; resolve owners
13+
from [`docs/area-owners.md`](../../../docs/area-owners.md) by the issue's
14+
`area-*` label.
15+
16+
<a id="area-skill-table"></a>
17+
18+
## Area → skill table
19+
20+
Skill paths are relative to `.github/skills/`.
21+
22+
| Area / pipeline | Skill(s) | What the skill covers |
23+
|---|---|---|
24+
| Mobile (ios / tvos / maccatalyst / android / wasm / wasi) | `mobile-platforms/SKILL.md` | Mobile/wasm test, csproj, and platform-condition knowledge. |
25+
| JIT / GC / PGO stress (codegen) | `jit-regression-test/SKILL.md`; `ci-pipeline-monitor/SKILL.md` | JIT codegen, assertion triage, regression-test extraction. |
26+
| `System.Net.*` | `system-net-review/SKILL.md` | Networking stack review and conventions. |
27+
| `Microsoft.Extensions.*` | `extensions-review/SKILL.md` | Extensions (DI, config, logging, hosting, caching) review. |
28+
| NativeAOT outer loop | repo-root `eng/testing/tests.*aot*.targets` + the test `.csproj` | NativeAOT test wiring (no dedicated skill; read the targets). |
29+
| Generic / unmapped | `ci-pipeline-monitor/SKILL.md` | Cross-cutting CI pipeline monitoring and triage. |
30+
31+
When more than one skill is listed, load them in order; the first carries the
32+
primary domain knowledge and the rest add CI/triage context.
33+
34+
<a id="area-mention-conventions"></a>
35+
36+
## Area-owner mention conventions
37+
38+
When an agent loops a human in (a PR body or an issue comment) based on an
39+
`area-*` label, apply these rules so notifications stay proportionate:
40+
41+
- Resolve owners from [`docs/area-owners.md`](../../../docs/area-owners.md) by the
42+
`area-*` label.
43+
- Live-mention **at most one or two** individual owners.
44+
- **Never live-mention a GitHub team.** Render a team handle (`@dotnet/<team>`)
45+
as inline code `` `@dotnet/<team>` `` so it does not notify the whole team.
46+
- Never mention bots (`dotnet-maestro`, `github-actions`, codeflow accounts).
47+
- Put contacts under a non-accusatory heading framed as "loop-in for triage",
48+
not blame.

.github/workflows/shared/create-kbe.instructions.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,20 @@ never match because there is no test name. Add:
141141
Each candidate body must be fetched and read; do not match on title alone. On
142142
hit, record `existing-PR #<n>`.
143143

144+
### Integrity-filtered PR candidate
145+
146+
If any PR search above returns a `[Filtered]` marker for a candidate whose
147+
title, source symbol, or assertion slice overlaps the failing signature, do
148+
**not** assume no fix exists and file a fresh KBE. The filter hides a real PR
149+
you are not permitted to read, and it may already handle this failure. Record
150+
`skipped: integrity-filtered candidate, needs human review` and stop for this
151+
signature. A human can confirm whether the hidden PR fixes the failure; filing a
152+
duplicate KBE that is immediately closed as "fixed by" the hidden PR is a
153+
scanner-quality miss the feedback workflow will penalize.
154+
144155
### Merged fix PR (last 14 days)
145156

146-
Only when an existing KBE or area-team tracker was recorded:
157+
When an existing KBE or area-team tracker was recorded:
147158

148159
- `is:pr is:merged "<test-name>" merged:>=<14-days-ago>`
149160
- `is:pr is:merged "<test-file-path>" merged:>=<14-days-ago>`
@@ -152,6 +163,29 @@ Only when an existing KBE or area-team tracker was recorded:
152163
On match, record `skipped: fix recently merged in #<n>` and do not file a
153164
test-disable PR.
154165

166+
#### Always run this for assertion / native / build-level signatures
167+
168+
For a JIT, runtime, or build-level signature (assert in `coreclr!*`, `clrjit!*`,
169+
a native crash, or a compiler diagnostic), run the merged-PR search
170+
**unconditionally** — even when no existing KBE was found. These signatures
171+
recur and their KBEs are frequently closed-as-fixed, so an open-only dedup will
172+
not see the closed predecessor and the failure gets re-filed from a stale build.
173+
Search:
174+
175+
- `is:pr is:merged "<assertion-text>" merged:>=<14-days-ago>` using a 6-12 word
176+
literal slice of the assert / diagnostic message.
177+
- `is:pr is:merged "<source-symbol>" merged:>=<14-days-ago>` for each of the 2-3
178+
most unique C / C++ identifiers in the stack frame or assertion text.
179+
180+
For every merged PR hit, compare its `mergedAt` against the failing build's
181+
`finishTime` (the AzDO build that produced this failure; read it from the build
182+
metadata, not the queue time). If the fix merged **after** the build finished,
183+
the failure is stale and already addressed: record
184+
`skipped: fix already merged after source build` (cite the PR `#<n>`) and do not
185+
file. Only file a new KBE when the same assertion still reproduces in a build
186+
that finished **after** the fix merged (a genuine post-fix recurrence), and say
187+
so explicitly in the KBE body with both the fix PR `#<n>` and the post-fix build.
188+
155189
<a id="verify-embedded-issues"></a>
156190

157191
## Verify every embedded issue number exists

docs/design/datacontracts/DebugInfo.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ public readonly struct DebugVarInfo
343343
public int StackOffset { get; init; }
344344
public uint BaseRegister2 { get; init; }
345345
public int StackOffset2 { get; init; }
346+
public uint CallReturnValueILOffset { get; init; }
346347
}
347348

348349
// Given a code pointer, return the variable location info for the method.
@@ -352,7 +353,8 @@ IEnumerable<DebugVarInfo> GetMethodVarInfo(TargetCodePointer pCode, out uint cod
352353
Additional constants (Version 2):
353354
| Constant Name | Meaning | Value |
354355
| --- | --- | --- |
355-
| `MAX_ILNUM` | Bias for adjusted encoding of variable numbers | `0xfffffffc` (-4) |
356+
| `MAX_ILNUM` | Bias for adjusted encoding of variable numbers | `0xfffffffa` (-6) |
357+
| `CALL_RETURN_ILNUM` | Special variable number identifying a call-return-value entry | `0xfffffffb` (-5) |
356358
| `VLT_REG` | Variable is in a register | `0` |
357359
| `VLT_REG_BYREF` | Address of the variable is in a register | `1` |
358360
| `VLT_REG_FP` | Variable is in an FP register | `2` |
@@ -371,9 +373,11 @@ Additional constants (Version 2):
371373

372374
Each variable entry in the Vars section is nibble-encoded as follows:
373375

374-
1. `startOffset` — encoded unsigned 32-bit integer
375-
2. `endOffset` — encoded as delta from `startOffset` (unsigned)
376-
3. `varNumber` — encoded as adjusted unsigned (`value - MAX_ILNUM`)
376+
1. `varNumber` — encoded as adjusted unsigned (`value - MAX_ILNUM`)
377+
2. `startOffset` — encoded unsigned 32-bit integer
378+
3. The next field depends on `varNumber`:
379+
- If `varNumber == CALL_RETURN_ILNUM`: `callReturnValueILOffset` — encoded unsigned 32-bit integer (IL offset of the call site whose return value this entry describes). `endOffset` is implicit and equals `startOffset + 1`.
380+
- Otherwise: `endOffset` — encoded as delta from `startOffset` (unsigned). `callReturnValueILOffset` is implicit and equals `0`.
377381
4. `VarLocType` — encoded unsigned 32-bit integer
378382
5. Location fields depend on the `VarLocType`:
379383

docs/design/datacontracts/StackWalk.md

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -628,62 +628,24 @@ At each frame yielded by `Filter`, the walk determines whether to scan for GC re
628628

629629
See [GCRefMap Format and Resolution](#gcrefmap-format-and-resolution) for the GCRefMap scanning path and [Signature-Based Scanning](#signature-based-scanning) for the signature decoding path.
630630

631-
### Signature-Based Scanning
631+
### Signature-Based Scanning (currently deferred)
632632

633-
When a transition frame's calling convention is not described by a precomputed GCRefMap (`PrestubMethodFrame`, `CallCountingHelperFrame`, and the fallback path for `StubDispatchFrame`/`ExternalMethodFrame`), the GC reference walk classifies caller-stack arguments by decoding the callee's method signature. This corresponds to native `TransitionFrame::PromoteCallerStack` (`src/coreclr/vm/frames.cpp`).
633+
When a transition frame's calling convention is not described by a precomputed GCRefMap (`PrestubMethodFrame`, `CallCountingHelperFrame`, and the fallback path for `StubDispatchFrame`/`ExternalMethodFrame`), the native runtime classifies caller-stack arguments by decoding the callee's method signature (`TransitionFrame::PromoteCallerStack` in `src/coreclr/vm/frames.cpp`).
634634

635-
#### GcSignatureTypeProvider
636-
637-
`GcSignatureTypeProvider` is an `IRuntimeSignatureTypeProvider<GcTypeKind, GcSignatureContext>` that classifies each parameter type into one of:
635+
The cDAC does **not** currently port this scan. `GcScanner.PromoteCallerStack` is a stub that records the frame as deferred and returns without enumerating any refs:
638636

639637
```csharp
640-
internal enum GcTypeKind
638+
private static void PromoteCallerStack(TargetPointer frameAddress, GcScanContext scanContext)
641639
{
642-
None, // Non-GC primitive that fits in a single slot
643-
Ref, // Object reference (TYPE_GC_REF)
644-
Interior, // Managed pointer / byref (TYPE_GC_BYREF)
645-
Other, // Value type that may contain GC refs, or any type larger than a slot
640+
scanContext.RecordDeferredFrame(frameAddress);
646641
}
647642
```
648643

649-
The provider is scoped to the method's containing module (captured at construction) so that `TypeDef` and `TypeRef` tokens can be resolved to a loaded `MethodTable` via the module's `TypeDefToMethodTable` / `TypeRefToMethodTable` lookup tables. The decoder's generic context is a `GcSignatureContext(TypeHandle classContext, MethodDescHandle methodContext)` carrying the method's class and method instantiations.
650-
651-
The provider classifies primitives directly (`String`/`Object` -> `Ref`, `TypedReference` -> `Other`, others -> `None`). For `TypeDef`/`TypeRef` it resolves the loaded `TypeHandle` and classifies via `RuntimeTypeSystem.GetSignatureCorElementType`, treating enums (`IsEnum`) as their underlying primitive (`None`). When the type cannot be resolved (e.g., not yet loaded), classification falls back to the signature's `rawTypeKind` (`ValueType` -> `Other`, otherwise `Ref`). Arrays are `Ref`, byrefs are `Interior`, raw pointers are `None`. Generic parameters (`!T`, `!!T`) are resolved against the `GcSignatureContext` (via `GetInstantiation` / `GetGenericMethodInstantiation`) and classified by their actual instantiation -- matching native `SigTypeContext`-driven `PeekElemTypeNormalized` behavior. `ELEMENT_TYPE_INTERNAL` resolves the `TypeHandle` via `RuntimeTypeSystem.GetSignatureCorElementType` and maps the `CorElementType` to a `GcTypeKind`.
652-
653-
#### PromoteCallerStack Algorithm
654-
655-
1. Read the `MethodDesc` pointer from the `FramedMethodFrame` and obtain a `MethodDescHandle` from `RuntimeTypeSystem`.
656-
2. Resolve the method's `MetadataReader` via `Loader.GetModuleHandleFromModulePtr` and `EcmaMetadata.GetMetadata`. If metadata is unavailable, no caller-stack refs are reported (matches native fallback behavior).
657-
3. Obtain the method's signature blob, matching native `MethodDesc::GetSig`:
658-
- If `RuntimeTypeSystem.IsStoredSigMethodDesc` is true (dynamic, EEImpl, and array method descs), pin the stored signature span and pass a `BlobReader` over it to `RuntimeSignatureDecoder.DecodeMethodSignature`.
659-
- Otherwise, look up the signature via the metadata token (`mdMethodDef`), skipping methods with a nil token (`0x06000000`).
660-
4. Decode the signature with `RuntimeSignatureDecoder<GcTypeKind, GcSignatureContext>` and a `GcSignatureTypeProvider` constructed for the method's module. The `GcSignatureContext` passes the method's class and method instantiations so that `VAR`/`MVAR` placeholders resolve to their actual types. See [Signature contract](./Signature.md) for the decoder.
661-
5. Skip varargs methods (the caller-stack layout is not described by the callee signature alone).
662-
6. Compute the number of reserved register slots in the `TransitionBlock`:
663-
664-
| Reserved Slot | Condition |
665-
|---|---|
666-
| `this` pointer | `MethodSignature.Header.IsInstance` |
667-
| Return buffer | Return type is `GcTypeKind.Other` |
668-
| Generic instantiation arg | `RuntimeTypeSystem.RequiresInstArg(methodDesc)` |
669-
| Async continuation | `RuntimeTypeSystem.IsAsyncMethod(methodDesc)` |
670-
| ARM64 indirect-result register (`x8`) | Target architecture is ARM64 |
671-
672-
7. If `IsInstance`, report the `this` slot at position `0` (or `1` on ARM64 to skip `x8`). The slot is reported as `GC_CALL_INTERIOR` for value-type `this`, otherwise as a normal reference.
673-
8. Walk `MethodSignature.ParameterTypes` starting at slot index = reserved slot count, advancing one slot per parameter:
674-
- `GcTypeKind.Ref` -> report as a reference.
675-
- `GcTypeKind.Interior` -> report with `GC_CALL_INTERIOR`.
676-
- `GcTypeKind.Other` / `GcTypeKind.None` -> not reported (large value types are reported via the GCRefMap path when one is available; otherwise their interior refs are not visible to this scan).
677-
678-
The slot address is computed using the same formula as the GCRefMap path:
679-
680-
```csharp
681-
slotAddress = transitionBlockPtr + FirstGCRefMapSlot + (position * pointerSize);
682-
```
644+
`RecordDeferredFrame` (on `GcScanContext`) appends a sentinel `StackRefData` entry with `Flags = GcScanFlags.CDAC_DEFERRED_FRAME (0x40000000)` and `Source = frameAddress`. The sentinel has no real GC ref payload; downstream consumers (e.g. the cDAC stress harness in `src/coreclr/vm/cdacstress.cpp`) can detect it and treat the missing refs at that frame as expected gaps rather than cDAC bugs. See [tests/StressTests/known-issues.md](../../../src/native/managed/cdac/tests/StressTests/known-issues.md) for the stress framework's handling and the tracking work to re-enable the scan.
683645

684-
#### Limitations vs. Native
646+
The `GcSignatureTypeProvider` class remains in the tree as the scaffolding the eventual port will use; it has no callers while `PromoteCallerStack` is stubbed.
685647

686-
This signature-based scan has known gaps relative to native see [dotnet/runtime#127765](https://github.com/dotnet/runtime/issues/127765) for tracking.
648+
Tracking work to re-enable the scan: it requires porting `ArgIterator` behind an `ICallingConvention` contract. Once that lands, `PromoteCallerStack` will fan out into the signature-decoding algorithm (reserved-slot computation, signature walk, slot reporting) that mirrors the native version. See also [dotnet/runtime#127765](https://github.com/dotnet/runtime/issues/127765).
687649

688650
### GCRefMap Format and Resolution
689651

0 commit comments

Comments
 (0)