Skip to content

[wasm] Bump chrome for testing - linux: 117.0.5938.132, windows: 117.0.5938.132#1

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
update-chrome-version-6366904082
Open

[wasm] Bump chrome for testing - linux: 117.0.5938.132, windows: 117.0.5938.132#1
github-actions[bot] wants to merge 1 commit into
mainfrom
update-chrome-version-6366904082

Conversation

@github-actions

@github-actions github-actions Bot commented Oct 1, 2023

Copy link
Copy Markdown

No description provided.

maraf pushed a commit that referenced this pull request Dec 14, 2023
Fixes dotnet#95367.

Relevant part of the JitDump:

```
Using `if true` assertions from pred BB02
Assertions in: #1
fgMorphTree BB04, STMT00021 (before)
               [000070] DA---------                         *  STORE_LCL_VAR ubyte  V10 tmp9
               [000057] -----------                         \--*  CAST      int <- ubyte <- int
               [000006] -----------                            \--*  EQ        int
               [000004] -----------                               +--*  LCL_VAR   ref    V02 tmp1          (last use)
               [000055] H----------                               \--*  CNS_INT(h) ref     'Frozen EmptyPartition`1<Int32> object'

Assertion prop for index #1 in BB04:
               [000006] -----------                         *  EQ        int
GenTreeNode creates assertion:
               [000070] DA---+-----                         *  STORE_LCL_VAR ubyte  V10 tmp9
In BB04 New Local Constant Assertion: V10 == [0000000000000001], index = #2

fgMorphTree BB04, STMT00021 (after)
               [000070] DA---+-----                         *  STORE_LCL_VAR ubyte  V10 tmp9
               [000055] H----+-----                         \--*  CNS_INT(h) int
```

The JitDump is unfinished because the compiler crashes when trying to dump the last line. Clearly, the `CNS_INT` is no longer a handle at that point because we just bashed it to a constant 1.
maraf pushed a commit that referenced this pull request Mar 18, 2024
CodeQL flagged various places where we're dereferencing pointers that could be NULL, this PR systematically cleans some of them up via g_assert.
* g_assert result of g_build_path calls
* Allocation failure handling
* mono_class_inflate_generic_class_checked can return NULL
maraf pushed a commit that referenced this pull request May 27, 2024
…#102133)

This generalizes the indir reordering optimization (that currently only
triggers for loads) to kick in for GT_STOREIND nodes.

The main complication with doing this is the fact that the data node of
the second indirection needs its own reordering with the previous
indirection. The existing logic works by reordering all nodes between
the first and second indirection that are unrelated to the second
indirection's computation to happen after it. Once that is done we know
that there are no uses of the first indirection's result between it and
the second indirection, so after doing the necessary interference checks
we can safely move the previous indirection to happen after the data
node of the second indirection.

Example:
```csharp
class Body { public double x, y, z, vx, vy, vz, mass; }

static void Advance(double dt, Body[] bodies)
{
    foreach (Body b in bodies)
    {
        b.x += dt * b.vx;
        b.y += dt * b.vy;
        b.z += dt * b.vz;
    }
}
```

Diff:
```diff
@@ -1,18 +1,17 @@
-G_M55007_IG04:  ;; offset=0x001C
+G_M55007_IG04:  ;; offset=0x0020
             ldr     x3, [x0, w1, UXTW #3]
             ldp     d16, d17, [x3, #0x08]
             ldp     d18, d19, [x3, #0x20]
             fmul    d18, d0, d18
             fadd    d16, d16, d18
-            str     d16, [x3, #0x08]
-            fmul    d16, d0, d19
-            fadd    d16, d17, d16
-            str     d16, [x3, #0x10]
+            fmul    d18, d0, d19
+            fadd    d17, d17, d18
+            stp     d16, d17, [x3, #0x08]
             ldr     d16, [x3, #0x18]
             ldr     d17, [x3, #0x30]
             fmul    d17, d0, d17
             fadd    d16, d16, d17
             str     d16, [x3, #0x18]
             add     w1, w1, #1
             cmp     w2, w1
             bgt     G_M55007_IG04
```
maraf pushed a commit that referenced this pull request Sep 24, 2024
* bug #1: don't allow for values out of the SerializationRecordType enum range

* bug #2: throw SerializationException rather than KeyNotFoundException when the referenced record is missing or it points to a record of different type

* bug #3: throw SerializationException rather than FormatException when it's being thrown by BinaryReader (or sth else that we use)

* bug #4: document the fact that IOException can be thrown

* bug #5: throw SerializationException rather than OverflowException when parsing the decimal fails

* bug #6: 0 and 17 are illegal values for PrimitiveType enum

* bug #7: throw SerializationException when a surrogate character is read (so far an ArgumentException was thrown)
maraf pushed a commit that referenced this pull request Oct 9, 2024
* [NRBF] Don't use Unsafe.As when decoding DateTime(s) (dotnet#105749)

* Add NrbfDecoder Fuzzer (dotnet#107385)

* [NRBF] Fix bugs discovered by the fuzzer (dotnet#107368)

* bug #1: don't allow for values out of the SerializationRecordType enum range

* bug #2: throw SerializationException rather than KeyNotFoundException when the referenced record is missing or it points to a record of different type

* bug #3: throw SerializationException rather than FormatException when it's being thrown by BinaryReader (or sth else that we use)

* bug #4: document the fact that IOException can be thrown

* bug #5: throw SerializationException rather than OverflowException when parsing the decimal fails

* bug #6: 0 and 17 are illegal values for PrimitiveType enum

* bug #7: throw SerializationException when a surrogate character is read (so far an ArgumentException was thrown)
# Conflicts:
#	src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/NrbfDecoder.cs

* [NRBF] throw SerializationException when a surrogate character is read (dotnet#107532)

 (so far an ArgumentException was thrown)

* [NRBF] Fuzzing non-seekable stream input (dotnet#107605)

* [NRBF] More bug fixes (dotnet#107682)

- Don't use `Debug.Fail` not followed by an exception (it may cause problems for apps deployed in Debug)
- avoid Int32 overflow
- throw for unexpected enum values just in case parsing has not rejected them
- validate the number of chars read by BinaryReader.ReadChars
- pass serialization record id to ex message
- return false rather than throw EndOfStreamException when provided Stream has not enough data
- don't restore the position in finally 
- limit max SZ and MD array length to Array.MaxLength, stop using LinkedList<T> as List<T> will be able to hold all elements now
- remove internal enum values that were always illegal, but needed to be handled everywhere
- Fix DebuggerDisplay

* [NRBF] Comments and bug fixes from internal code review (dotnet#107735)

* copy comments and asserts from Levis internal code review

* apply Levis suggestion: don't store Array.MaxLength as a const, as it may change in the future

* add missing and fix some of the existing comments

* first bug fix: SerializationRecord.TypeNameMatches should throw ArgumentNullException for null Type argument

* second bug fix: SerializationRecord.TypeNameMatches should know the difference between SZArray and single-dimension, non-zero offset arrays (example: int[] and int[*])

* third bug fix: don't cast bytes to booleans

* fourth bug fix: don't cast bytes to DateTimes

* add one test case that I've forgot in previous PR
# Conflicts:
#	src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/SerializationRecord.cs

* [NRBF] Address issues discovered by Threat Model  (dotnet#106629)

* introduce ArrayRecord.FlattenedLength

* do not include invalid Type or Assembly names in the exception messages, as it's most likely corrupted/tampered/malicious data and could be used as a vector of attack.

* It is possible to have binary array records have an element type of array without being marked as jagged

---------

Co-authored-by: Buyaa Namnan <bunamnan@microsoft.com>
maraf pushed a commit that referenced this pull request Mar 11, 2025
* JIT: Introduce `LclVarDsc::lvIsMultiRegDest`

With recent work to expand returned promoted locals into `FIELD_LIST`
the only "whole references" of promoted locals we should see is when
stored from a multi-reg node. This is the only knowledge the backend
should need for correctness purposes, so introduce a bit to track this
property, and switch the backend to check this instead.

The existing `lvIsMultiRegRet` is essentially this + whether the local
is returned. We should be able to remove this, but it is currently used
for some heuristics in old promotion, so keep it around for now.

* JIT: Add some more constant folding in lowering

Add folding for shifts and certain binops that are now getting produced
late due to returned `FIELD_LIST` nodes.

win-arm64 example:
```csharp
[MethodImpl(MethodImplOptions.NoInlining)]
static ValueTask<byte> Foo()
{
    return new ValueTask<byte>(123);
}
```

```diff
 G_M17084_IG02:  ;; offset=0x0008
             mov     x0, xzr
-            mov     w1, #1
-            mov     w2, wzr
-            mov     w3, dotnet#123
-            orr     w2, w2, w3,  LSL dotnet#16
-            orr     w1, w2, w1,  LSL dotnet#24
-						;; size=24 bbWeight=1 PerfScore 4.00
+            mov     w1, #0x17B0000
+						;; size=8 bbWeight=1 PerfScore 1.00
```

* Feedback
maraf pushed a commit that referenced this pull request Sep 30, 2025
maraf pushed a commit that referenced this pull request Sep 30, 2025
…ds from dotnet#27912 (Flow System.Text.Rune through more APIs)) (dotnet#120145)

* Fix tests from dotnet#117168

* Add `SyncTextWriter` overloads as well

* Add missing overloads to BroadcastingTextWriter

* Reapply "Add methods from dotnet#27912 (Flow System.Text.Rune through more APIs) (#1…" (dotnet#120138)

This reverts commit be80737.

* Override the TextWrite Rune overloads in IndentedTextWriter

---------

Co-authored-by: Tarek Mahmoud Sayed <tarekms@microsoft.com>
maraf pushed a commit that referenced this pull request Feb 17, 2026
…er (dotnet#123735)

From discussion, opting into enabling the crash chaining is more
correct.

<s>The previously registered signal action/handler aren't guaranteed to
return, so we lose out on notifying shutdown and creating a dump in
those cases. Specifically, PROCCreateCrashDumpIfEnabled would be the
last chance to provide the managed context for the thread that crashed.

e.g. On Android CoreCLR, it seems that, by default, signal handlers are
already registered by Android's runtime
(/apex/com.android.runtime/bin/linker64 +
/system/lib64/libandroid_runtime.so). Whenever an unhandled synchronous
fault occurs, the previously registered handler will not return back to
invoke_previous_action and aborts the thread itself, so
PROCCreateCrashDumpIfEnabled will not be hit.</s>

## Sigsegv behavior Android CoreCLR vs other platforms

### Android CoreCLR
When intentionally writing to NULL (sigsegv) on Android CoreCLR, the
previously registered signal handler goes down this path
https://github.com/dotnet/runtime/blob/40e8c73b8f3b5f478a9bf03cf55c71d0608a8855/src/coreclr/pal/src/exception/signal.cpp#L454,
and the thread aborts before hitting PROCNotifyProcessShutdown and
PROCCreateCrashDumpIfEnabled.

### MacOS/Linux/NativeAOT(linux)
On MacOS, Linux, NativeAOT (Only checked linux at time of writing), the
same intentional SIGSEGV will hit
https://github.com/dotnet/runtime/blob/40e8c73b8f3b5f478a9bf03cf55c71d0608a8855/src/coreclr/pal/src/exception/signal.cpp#L431-L448
instead because there is no previously registered signal handler. In
those cases, PROCCreateCrashDumpIfEnabled is hit and managed callstacks
are captured in the dump.

## History investigation

From a github history dive, I didn't spot anything in particular
requiring the previous signal handler to be invoked before
PROCNotifyProcessShutdown + PROCCreateCrashDumpIfEnabled.

PROCNotifyProcessShutdown was first introduced in
dotnet@1433c3f.
It doesn't seem to state a particular reason for invoking it after the
previous signal handler.

PROCCreateCrashDumpIfEnabled was added to signal.cpp in
dotnet@7f9bd2c
because the PROCNotifyProcessShutdown didn't create a crash dump. It
doesn't state any particular reason for being invoked after the
previously registered signal handler, and was probably just placed next
to PROCNotifyProcessShutdown.

`invoke_previous_action` was introduced in
dotnet@a740f65
and was refactoring while maintaining the order.

## Android CoreCLR behavior after swapping order

Locally, I have POC changes to emit managed callstacks in Android's
PROCCreateCrashDumpIfEnabled.
```
01-28 17:26:40.951  2416  2440 F DOTNET  : Native crash detected; attempting managed stack trace.
01-28 17:26:40.951  2416  2440 F DOTNET  : {"stack":[
01-28 17:26:40.951  2416  2440 F DOTNET  : {"ip":"0x0","module":"0x0","offset":"0x0","name":"Program.MemSet(Void*, Int32, UIntPtr)"},
01-28 17:26:40.951  2416  2440 F DOTNET  : {"ip":"0x78d981145973","module":"0x0","offset":"0x0","name":"Program.MemSet(Void*, Int32, UIntPtr)"},
01-28 17:26:40.951  2416  2440 F DOTNET  : {"ip":"0x78d981145973","module":"0x0","offset":"0x73","name":"Program.ForceNativeSegv()"},
01-28 17:26:40.951  2416  2440 F DOTNET  : {"ip":"0x78d981141b60","module":"0x0","offset":"0x70","name":"Program.Main(System.String[])"}
01-28 17:26:40.951  2416  2440 F DOTNET  : ]}
01-28 17:26:40.952  2416  2440 F DOTNET  : Crash dump hook completed.
--------- beginning of crash
01-28 17:26:40.952  2416  2440 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 2440 (.dot.MonoRunner), pid 2416 (ulator.JIT.Test)
.....
01-28 17:26:46.882  2921  2921 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-28 17:26:46.882  2921  2921 F DEBUG   : Build fingerprint: 'google/sdk_gphone64_x86_64/emu64xa:16/BE2A.250530.026.D1/13818094:user/release-keys'
01-28 17:26:46.882  2921  2921 F DEBUG   : Revision: '0'
01-28 17:26:46.882  2921  2921 F DEBUG   : ABI: 'x86_64'
01-28 17:26:46.882  2921  2921 F DEBUG   : Timestamp: 2026-01-28 17:26:41.492831700-0500
01-28 17:26:46.882  2921  2921 F DEBUG   : Process uptime: 20s
01-28 17:26:46.883  2921  2921 F DEBUG   : Cmdline: net.dot.Android.Device_Emulator.JIT.Test
01-28 17:26:46.883  2921  2921 F DEBUG   : pid: 2416, tid: 2440, name: .dot.MonoRunner  >>> net.dot.Android.Device_Emulator.JIT.Test <<<
01-28 17:26:46.883  2921  2921 F DEBUG   : uid: 10219
01-28 17:26:46.883  2921  2921 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
01-28 17:26:46.883  2921  2921 F DEBUG   : Cause: null pointer dereference
01-28 17:26:46.883  2921  2921 F DEBUG   : Abort message: 'CoreCLR: previous handler for '
01-28 17:26:46.883  2921  2921 F DEBUG   :     rax 0000000000000000  rbx 000078da87ffade0  rcx 0000000000000000  rdx 0000000000000001
01-28 17:26:46.884  1237  1297 I s.nexuslauncher: AssetManager2(0x78dd08cd9178) locale list changing from [] to [en-US]
01-28 17:26:46.903  2447  2594 I BugleNotifications: Creating notification input ids [CONTEXT im_entry_input="" im_notification_input="" im_settings_store_input="" im_final_input="" ]
01-28 17:26:46.905  2921  2921 F DEBUG   :     r8  00007ffcde5a8080  r9  34d9bb0e67871eb0  r10 000078ddb4111870  r11 0000000000000293
01-28 17:26:46.906  2921  2921 F DEBUG   :     r12 0000000000000001  r13 000078da87ffafa0  r14 0000000000000000  r15 000078da87ffaf18
01-28 17:26:46.906  2921  2921 F DEBUG   :     rdi 0000000000000000  rsi 0000000000000000
01-28 17:26:46.906  2921  2921 F DEBUG   :     rbp 000078da87ffac40  rsp 000078da87ffabc8  rip 000078ddb41118a2
01-28 17:26:46.906  2921  2921 F DEBUG   : 2 total frames
01-28 17:26:46.906  2921  2921 F DEBUG   : backtrace:
01-28 17:26:46.906  2921  2921 F DEBUG   :       #00 pc 000000000008f8a2  /apex/com.android.runtime/lib64/bionic/libc.so (memset_avx2+50) (BuildId: fcb82240218d1473de1e3d2137c0be35)
01-28 17:26:46.906  2921  2921 F DEBUG   :       #1 pc 0000000000049972  /memfd:doublemapper (deleted) (offset 0x111000)
```
Now theres a window to log managed callstacks before the original signal
handler aborts and triggers a tombstone.

## Android Mono behavior

Mono provides two embeddings APIs to configure signal and crash chaining
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/driver.c#L2864-L2894
that determine whether synchronous faults would chain
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/mini-runtime.c#L3892-L3903
They would only chain to the previous signal handler
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/mini-posix.c#L193-L210
only after attempting to walk native and managed stacks
https://github.com/dotnet/runtime/blob/61d3943de41e948bb0ecf871b92eb456d2dd74d8/src/mono/mono/mini/mini-exceptions.c#L2992-L3012

## Alternatives

If there is any particular reason to preserve the order of
sa_sigaction/sa_handler with respect to PROCNotifyProcessShutdown and
PROCCreateCrashDumpIfEnabled for CoreCLR, a config knob can be added to
allow Android CoreCLR to opt into the swapped ordering behavior. This
may be in the form of config property key/values
https://github.com/dotnet/runtime/blob/54ca569eb62800cdb725d776e3dd2e564028594d/src/coreclr/dlls/mscoree/exports.cpp#L237-L238
or `clrconfigvalues`. That way AndroidSDK/AndroidAppBuilder may opt-in
at build-time.

Given that the history of the ordering didn't reveal any problems with
swapping the order, we can fallback to this behavior if the order swap
causes problems down the line.

The other way around is more restrictive. Should we first introduce all
the overhead to enable an opt-in/opt-out config knob, and later discover
that no platforms need to invoke their previous handlers before
PROCNotifyProcessShutdown/PROCCreateCrashDumpIfEnabled, it seems harder
to justify removing the knob.
maraf pushed a commit that referenced this pull request May 14, 2026
…128163)

> [!NOTE]
> This PR was authored with assistance from GitHub Copilot.

Fixes dotnet#128044.

## Problem

createdump SIGSEGVs on Linux when generating a Heap-type minidump for a
process running interpreted code. The crash reproduces locally with the
`InterpreterStack` DumpTests debuggee and matches the CI failure that
prompted `<DumpTypes>Full</DumpTypes>` to be added as a temporary
workaround.

The faulting backtrace is:

```
#0  Thread::IsAddressInStack    threads.cpp:6741
#1  Thread::EnumMemoryRegionsWorker  threads.cpp:6909 (calls IsAddressInStack(currentSP))
#2  Thread::EnumMemoryRegions        threads.cpp
#3  ThreadStore::EnumMemoryRegions
#4  ClrDataAccess::EnumMemDumpAllThreadsStack
#5  ClrDataAccess::EnumMemoryRegionsWorkerHeap   (HEAP2-only path)
```

## Root cause

`Thread::m_pInterpThreadContext` was declared as a raw
`InterpThreadContext *`. In non-DAC code that's a normal host pointer,
but in
DAC mode the field's value is a target-process address. When
`IsAddressInStack` (a DAC-callable helper) dereferenced
`m_pInterpThreadContext->pStackStart` it read from a target-process
address
as if it were a host address, which faults inside createdump.

## Fix

Change the field type to `PTR_InterpThreadContext` (DPTR), matching the
treatment of other Thread fields like `m_pFrame`. In non-DAC builds
`DPTR(T)` is just `T*`, so there is no overhead or behavior change. In
DAC
builds the read goes through `__DPtr<T>` and marshals correctly from the
target.

Also remove the `<DumpTypes>Full</DumpTypes>` workaround on the
`InterpreterStack` DumpTests debuggee so the Heap path that originally
failed is exercised again.

## Validation

Locally reproduced the original SIGSEGV on Linux x64 with the auto-dump
mechanism (`DOTNET_DbgMiniDumpType=2` + `DOTNET_Interpreter=MethodA`)
running the `InterpreterStack` debuggee. With this fix applied,
createdump
produces a complete Heap dump (~74 MB) instead of crashing.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
maraf pushed a commit that referenced this pull request Jul 16, 2026
An Android production app reported a native abort while building an
X.509 chain on arm64. The available tombstone snippet showed the process
aborting in `AndroidCryptoNative_X509ChainBuild` from `pal_x509chain.c`,
with the native guard reporting that parameter `ctx` was not a valid
pointer. The report did not include a repro or full tombstone, but the
observed failure mode means managed code reached the native build entry
point with a null `X509ChainContext*`.

```
Thread
/__w/1/s/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c:113 (AndroidCryptoNative_X509ChainBuild): Parameter 'ctx' must be a valid pointer
 
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 31609 >>> com.app.name <<<
 
backtrace:
  #00  pc 0x000000000002232c  /system/lib64/libc.so (abort+116)
  #1  pc 0x0000000000021fe8  [removed]-KwPZdoEumri00C7kBm3pQw==/lib/arm64/libSystem.Security.Cryptography.Native.Android.so
  #2  pc 0x00000000000220b0  [removed]-KwPZdoEumri00C7kBm3pQw==/lib/arm64/libSystem.Security.Cryptography.Native.Android.so (AndroidCryptoNative_X509ChainBuild+88)
  #3  pc 0x000000000000cfcc
```

`X509ChainContext` is created by
`AndroidCryptoNative_X509ChainCreateContext`. That initialization can
fail if Android certificate store setup or PKIX parameter construction
throws, or if required JNI global references cannot be created.
Previously, the managed Android chain path stored the returned
`SafeHandle` without checking whether context creation failed, so a
later build could pass a null native context to
`AndroidCryptoNative_X509ChainBuild` and terminate the app process.

This change makes context creation fail gracefully:

- The native create path checks Java exceptions around object creation
and method calls more consistently.
- Partial native contexts are destroyed if global-reference creation
fails.
- The Android interop wrapper checks the returned chain context
immediately, including a null safe-handle return, and throws
`CryptographicException` if initialization failed.

No regression test is included because the reliable failure modes depend
on Android platform/provider state or artificial fault injection, and a
test hook would be fragile and not representative.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Kevin Jones <kevin@vcsjones.com>
maraf pushed a commit that referenced this pull request Jul 16, 2026
…on ARM32 (dotnet#129672)

Enables the cDAC GC stress verification leg on `linux_arm` (arm32) in
`runtime-diagnostics.yml`. While bringing arm32 online surfaced a
long-standing type confusion in the cDAC managed side that this PR also
fixes.

## Pipeline change

Adds `linux_arm` to the `cdacStressPlatforms` default in
[`eng/pipelines/runtime-diagnostics.yml`](https://github.com/dotnet/runtime/blob/main/eng/pipelines/runtime-diagnostics.yml).
The Helix queue mapping already existed in
`prepare-cdac-stress-helix-steps.yml` (`helix_linux_arm32_oldest`), so
this is a one-line enablement.

## arm32 failure surfaced by enabling the leg

First run on arm32 failed every verification with the same shape - e.g.
`DynamicMethods`: `1694 verifications (18 pass / 1676 fail / 0
known-issue)`, with every frame appearing duplicated at consecutive IPs
differing by 1:

```
Frame #0 <0xea89cc4e> MISMATCH cDAC=0 RT=2  ONLY(RT)
Frame #1 <0xea89cc4f> MISMATCH cDAC=2 RT=0  ONLY(cDAC)   <-- same refs, IP|1
```

**Root cause:** ARM32 control PCs carry the Thumb bit (LSB) to indicate
execution mode. The native runtime applies `PCODEToPINSTR`
([utilcode.h](https://github.com/dotnet/runtime/blob/main/src/coreclr/inc/utilcode.h#L119))
before reporting an IP as `StackRefData.Source`:

- Legacy DAC: `src/coreclr/debug/daccess/daccess.cpp:7558` -- `dsc->pc =
PCODEToPINSTR(GetControlPC(pRD))`
- In-process stress oracle: `src/coreclr/vm/cdacstress.cpp:781-782` --
same masking

The cDAC stored raw PCODE in `GcScanContext.InstructionPointer` and
emitted it as the Source, so every cDAC ref got keyed at `IP|1` while
the runtime reported at `IP`.

## Fix: type the IP/return-address surface as `TargetCodePointer`

Rather than masking the Thumb bit ad-hoc at one consumer site, the
proper fix is to **type these values correctly throughout the stack** so
the compiler stops the next person from mixing code pointers and data
pointers:

**Managed contract surface promoted `TargetPointer` →
`TargetCodePointer`:**

- `IPlatformContext.InstructionPointer` and every per-arch impl
(`X86Context`, `AMD64Context`, `ARMContext`, `ARM64Context`,
`LoongArch64Context`, `RISCV64Context`)
- `IPlatformAgnosticContext.InstructionPointer` and
`ContextHolder<T>.InstructionPointer`
- `IStackWalk.GetInstructionPointer`,
`FrameIterator.GetCurrentReturnAddress`, `FrameHelpers.GetReturnAddress`
- `[Field]` properties on `Data.TransitionBlock.ReturnAddress`,
`Data.HijackFrame.ReturnAddress`,
`Data.SoftwareExceptionFrame.ReturnAddress`,
`Data.TailCallFrame.ReturnAddress`,
`Data.InlinedCallFrame.CallerReturnAddress`

**Native data-descriptor changes**
(`src/coreclr/vm/datadescriptor/datadescriptor.inc`) - the corresponding
5 `CDAC_TYPE_FIELD` declarations switched from `T_POINTER` to
`TYPE(CodePointer)` so the descriptor's advertised type matches what the
field actually holds. Each was verified to carry the Thumb bit on ARM32:

| Field | Evidence |
|---|---|
| `TransitionBlock::m_ReturnAddress` | `callingconvention.h:140-148` -
**explicitly aliased** to `{r4..r11, lr}` (saved LR = PC\|1) |
| `InlinedCallFrame::m_pCallerReturnAddress` | ARM asm `str lr, [...]`
(`pinvokestubs.S:96, 182`); read back as PCODE (`stubs.cpp:1348-1349`) |
| `HijackFrame::m_ReturnAddress` | ctor sourced from on-stack saved LR
(`threadsuspend.cpp:4546`) |
| `SoftwareExceptionFrame::m_ReturnAddress` | copied straight into ARM
`Pc` register field (`excep.cpp:10474-10475`) |
| `TailCallFrame::m_ReturnAddress` | x86-only (descriptor guarded by
`TARGET_X86`); `CodePointer` still semantically correct |

**Conversion lives in one place:** `GcScanContext.SetSource` calls
`CodePointerUtils.AddressFromCodePointer` (the existing single source of
truth for PCODE → PINSTR on a target) when populating
`StackRefData.Source`. Other consumers that want code pointers
(`IsManaged`, `IsInterpreterCode`, `_eman.GetCodeBlockHandle`) now
receive `TargetCodePointer` directly. The few places that need raw data
addresses (AMD64 unwinder's `controlPC` arithmetic with `imageBase`,
x64-only `SOSDacImpl.GetJumpThunkTarget`) call `.AsTargetPointer`
explicitly.

## Validation

- `./build.cmd clr.runtime -c Release` succeeded; data descriptor
regenerated with `TYPE(CodePointer)` fields.
- cDAC unit tests: `Passed: 2571, Failed: 0, Skipped: 16`.
- CI: every `CdacBuild`, `CdacDumpTest`, and `CdacStressTest` leg green
- **including the new `CdacStressTest linux-arm` leg** that surfaced the
bug, plus existing `linux-arm64`, `linux-x64`, `windows-arm64`,
`windows-x64` legs.

## Notes for reviewers

- `IStackWalk` and `IPlatformAgnosticContext` live in
`Microsoft.Diagnostics.DataContractReader.Abstractions`. Per the cDAC
`API Review` guidance
([`cdac.instructions.md`](https://github.com/dotnet/runtime/blob/main/.github/instructions/cdac.instructions.md#api-review-net-11-dev-branches-only)),
implementations of `IContract` are not under formal API review on .NET
11 dev branches, and the contract assemblies are internal/unstable.
Changing the IP/return-address types is intentional and not a
breaking-change event.
- `CodePointerUtils.AddressFromCodePointer` already throws
`NotImplementedException` for `HasArm64PtrAuth`; when that's wired up,
the single conversion in `SetSource` picks it up with no further
changes.

> [!NOTE]
> This PR was authored with assistance from GitHub Copilot.

---------

Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
maraf pushed a commit that referenced this pull request Jul 16, 2026
…dotnet#129280) (dotnet#129591)

## Problem


`Wasm.Build.Tests.WasmTemplateTests.TypeScriptDefinitionsCopiedToWwwrootOnBuild(config:
Debug, emitTypeScriptDts: True)` fails its `dotnet build -question`
rebuild check with:

```
MSBUILD : error : Building target "_BuildCopyStaticWebAssetsPreserveNewest" partially,
because some output files are out of date with respect to their input files.
[_BuildStaticWebAssetsPreserveNewest:
  Input  = obj\Debug\net11.0\compressed\{hash}-{0}-{fp}-{fp}.gz,
  Output = bin\Debug\net11.0\wwwroot\_framework\dotnet.{fp}.js.gz]
Input file is newer than output file.
```

This is the same family of bug as dotnet#129280 (different surface: upstream
variant where MSBuild flags `_WriteBuildWasmBootJsonFile` itself as
stale; ours is the downstream cascade through compression).

## Root cause

Binlog analysis:
1. `_WriteBuildWasmBootJsonFile` runs `GenerateWasmBootJson` (uses
`ArtifactWriter.PersistFileIfChanged`, preserves old mtime on unchanged
content) followed by `<Touch Files="$(_WasmBuildBootJsonPath)" />`
(added in dotnet#125367 to keep MSBuild's I/O check on this target happy).
2. `$(_WasmBuildBootJsonPath)` — `obj/{cfg}/{tfm}/dotnet.js` — is also a
source for the StaticWebAssets compression pipeline
(`GenerateBuildCompressedStaticWebAssets` → `GZipCompress`).
3. `GZipCompress.cs` skips when `input.mtime < output.mtime` (strict
`<`). When `Touch` lands close enough in time to the `.gz` write (or any
subsequent target re-stamps dotnet.js), equal/newer mtimes send the next
build's compression task down the re-compress path.
4. Re-compression on build #2 bumps `obj/.../{0}.gz` mtime past
`bin/.../dotnet.{fp}.js.gz` (which was copied during build #1 and isn't
touched since), so `_BuildCopyStaticWebAssetsPreserveNewest` reports its
input newer than its output. `-question` fails.

This is a regression of dotnet#118637 (Aug 2025, *"Override boot config only
when the content changes"*), which fixed the exact same
`_BuildCopyStaticWebAssetsPreserveNewest` symptom in
dotnet/aspnetcore#63207 by introducing
`ArtifactWriter.PersistFileIfChanged`. PR dotnet#125367's `<Touch>` undid that
protection.

## Fix

Touch a separate `wasm-bootjson-{build,publish}.complete.stamp` file
rather than the boot JSON itself, and use the stamp as the target's
`Outputs=`. MSBuild's incrementality check on the boot-JSON target stays
correct (its declared output has a current mtime after every successful
run), while the boot JSON's mtime remains content-derived — preserving
dotnet#118637's invariant for downstream consumers.

Applied to both:
- `_WriteBuildWasmBootJsonFile` (build)
- `GeneratePublishWasmBootJson` (publish)

Both have identical shape and the same downstream consumers
(StaticWebAssets compression / Copy targets).

## What's not fixed here

- `_ConvertBuildDllsToWebcil` (line 431) uses the same `<Touch>` pattern
but on per-item-batched `@(_WasmConvertedWebcilOutputs)`. It is
*probably* exposed to the same cascade for the webcil files; not
addressed here pending a per-item analysis.
- Defense-in-depth in `dotnet/sdk`: `GZipCompress`/`BrotliCompress` `<`
mtime check could become `<=` to harden the entire StaticWebAssets
pipeline against this class of cascade. Worth a separate dotnet/sdk PR.

## Verification

- Reproduces on `dotnet/runtime` PR dotnet#129454 build
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1470806
(`browser-wasm windows Release WasmBuildTests`, workitem
`WBT-NoWebcil-MONO-ST-Wasm.Build.Tests.WasmTemplateTests`).
- The WBT theory case
`TypeScriptDefinitionsCopiedToWwwrootOnBuild(Debug|Release,
emitTypeScriptDts:True)` exercises the `dotnet build -question`
second-build check that this fix addresses.

Fixes dotnet#129280

> [!NOTE]
> This pull request was created with the assistance of GitHub Copilot.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants