Repository navigation
Description
Description
Trimmed browser CoreCLR R2R library tests fail when filesystem timestamp tests initialize BaseGetSetTimes<T>. Its PlatformDetection.IsInAppContainer call throws DllNotFoundException for kernel32.dll, despite the helper having an early !IsWindows return before the Windows P/Invoke.
This is classified as R2R-only execution behavior rather than a missing trimming descriptor: a clean aggressively trimmed non-R2R run of an affected group passes. Eager P/Invoke fixup resolution is a possibility, but the precise cause has not been established.
Reproduction Steps
Build browser CoreCLR, libraries, host, packs, and host crossgen2. Reproduced on 798449390515fa02f4b20160bedc5e34f8fbdfb9 plus publishing prerequisite #133378 (245cb70d593f2c8f3a4e23bcc422e7da5926e15b), with the existing mobile filesystem and StreamConformance trimming descriptors also enabled for browser aggressive trimming.
XHARNESS_COMMAND=test-browser ./dotnet.sh build /t:Test \
src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/System.IO.FileSystem.Tests.csproj \
/p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release \
/p:PublishReadyToRun=true /p:EnableAggressiveTrimming=true \
/p:Scenario=WasmTestOnChrome /p:InstallChromeForTests=true /p:XunitShowProgress=trueFor the comparison, use clean project-specific browser-wasm obj/bin outputs, set PublishReadyToRun=false, retain EnableAggressiveTrimming=true, and add:
/p:WasmTestAppArgs="-class System.IO.Tests.File_GetSetTimes_SafeFileHandle"
Expected behavior
Browser execution should return false from PlatformDetection.IsInAppContainer without loading a Windows library, and the timestamp tests should run.
Actual behavior
The R2R suite completed with 6,454 total: 6,184 passed, 26 failed, 244 skipped. The failures share this type-initializer error:
System.TypeInitializationException: The type initializer for 'System.IO.Tests.BaseGetSetTimes`1' threw an exception.
---- System.DllNotFoundException: Unable to load shared library 'kernel32.dll' or one of its dependencies.
dynamic linking not enabled
at System.PlatformDetection.get_IsInAppContainer()
at System.IO.Tests.BaseGetSetTimes`1..cctor()
Affected methods are inherited timestamp cases such as SettingUpdatesProperties, SettingUpdatesPropertiesWhenReadOnly, SettingUpdatesPropertiesAfterAnother, TimesIncludeMillisecondPart, and TimesNotIncludeMillisecondPart, across File, FileInfo, Directory, and DirectoryInfo variants.
The clean trimmed non-R2R comparison group reports 14 total: 11 passed, 0 failed, 3 skipped.
Regression?
Unknown. Only R2R-on versus R2R-off was compared; both retain aggressive trimming.
Known Workarounds
Disable R2R. During library-test bring-up, quarantine the affected timestamp cases specifically for browser R2R while retaining interpreter coverage.
Configuration
Browser-wasm CoreCLR Release, macOS arm64 build host, Chromium 153.0.8010.0, SDK 11.0.100-rc.1.26420.103.
Other information
Found while standing up trimmed R2R library tests for #133193. #131874 describes different build-time P/Invoke/struct-mapping failures; this report concerns a runtime DLL load in a guarded platform-detection helper.
Note
This issue was generated by GitHub Copilot from local build and test results.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
dotnet-policy-service commentedon Sep 10, 2026
Tagging subscribers to this area: @dotnet/crossgen-contrib
See info in area-owners.md if you want to be subscribed.
lewing commentedon Sep 10, 2026
The same guarded-platform-probe failure affects networking: HTTP failed 577 cases through
TestUtilitiesprobes loadingkernel32.dllorlibSystem.Security.Cryptography.Native.Android, and WebSockets failed 117 cases through the Android ALPN probe.A narrowly scoped workaround is to keep only
TestUtilities.dllinterpreted, usingPublishReadyToRunExclude. With aggressive trimming unchanged:The served HTTP test assembly and
System.Net.HttpWASM files byte-match their compiler-generated R2R images; noTestUtilitiesnative R2R image is emitted. This does not disable library R2R coverage. It isolates the failure to compiling the support assembly, rather than missing trimming descriptors. Eager resolution of platform-specific P/Invoke fixups remains a hypothesis, not a fully proven VM root cause.Note
This update was generated by GitHub Copilot from local build and execution results.
dotnet-policy-service commentedon Sep 10, 2026
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.
jkotas commentedon Sep 10, 2026
Duplicate of #133259
Classify Wasm P/Invokes before R2R codegen (#133773)
lewing commentedon Sep 19, 2026
The failure still reproduces after #133773 with consistently rebuilt CI artifacts, so this is not SDK crossgen2 flow lag.
Structured inspection of build
1603680'sLibraryTestsCoreCLR_R2RBuild.binlogshowsSystem.Runtime.Extensions.Testsused the in-build compiler:The corresponding Helix job
99979e03-c8ff-4e09-bed4-556341a52a41finished all 24 work items. Three batches failed only throughTestUtilities.AdminHelpers.IsProcessElevatedreachingSystemNative_GetEUid:System.Runtime.Extensions.Tests: 1 failureSystem.IO.MemoryMappedFiles.Tests: 2 failuresSystem.IO.FileSystem.Tests: the read-only-file test familyAll report
DllNotFoundException: libSystem.Native/dynamic linking not enabled. This means #133773's module-level classification is still insufficient for a directSystem.NativeP/Invoke whose test-only entrypoint is absent from the prebuilt framework call-helper table. The original runtime browser guard is intentionally retained; the temporary bring-up workaround remains to keep onlyTestUtilities.dllinterpreted while product and test assemblies stay R2R.Note
This update was generated with GitHub Copilot from CI binlog and Helix evidence.
jkotas commentedon Sep 19, 2026
Tests that P/Invoke directly into
SystemNative_...shims do not represent supported user scenarios. These shims are internal implementation details of the core libraries and are not part of the supported surface. Code outside the core libraries should not P/Invoke them directly.jkotas commentedon Sep 19, 2026
Potential ways to fix this:
SystemNative_GetEUiddirectly. Some existing tests already avoid this by P/Invoking libc:runtime/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.RunAsClient.Unix.cs
Lines 19 to 20 in 229a331
lewing commentedon Sep 19, 2026
Root-cause clarification: the remaining failure is specific to running browser per-app ReadyToRun compilation while
WasmBuildNative=false.#133773's Crossgen2 policy is working as designed: configured modules retain direct
PINVOKE_TARGETcodegen. The browser app build currently passes framework modules such asSystem.Nativeto per-app Crossgen2 unconditionally. However, when native relinking is disabled, the app uses the prebuilt framework call-helper table, which was not generated from the app/test managed closure and therefore does not contain test-only entrypoints such asSystemNative_GetEUid.This creates a mismatched contract:
System.Nativeis directly available forTestUtilities.dll.GetEUidfrom the test assembly closure.PINVOKE_TARGETfixup for the guarded call, and resolving that fixup fails before normal managed control flow skips the P/Invoke.The focused follow-up fix is in browser build integration, not the compiler policy: browser ReadyToRun nested publishes must native-relink so the generated helper table and the per-app Crossgen2 direct-module policy are derived from the same managed closure. Explicit
WasmBuildNative=falseshould remain an incompatible configuration for browser R2R. WASI already performs per-app host/helper relinking and is unaffected.A validated prototype preserves direct
PINVOKE_TARGETcodegen, generatesDllImportEntry(SystemNative_GetEUid), and passes the full trimmedSystem.Runtime.Extensions.Testssuite (8,304 passed, 70 skipped, 0 failed). The current bring-up PR retains a narrow one-site #133614 guard until that follow-up lands.Note
This update was generated with GitHub Copilot from CI binlog, Helix, R2RDump, and focused build-test evidence.
lewing commentedon Sep 20, 2026
I worked around it in the test pr by using a platform guard the linker understand for now. The real cause is building PublishReadyToRun=true with WasmBuildNative=false and reachable pinvoke. #134291 makes that a build error. If we want to support that scenario we need to turn off direct pinvokes for that configuration, I'll open that version as well.
jkotas commentedon Sep 20, 2026
It is not some random reachable pinvoke. It is pinvoke into System.Native shim that no user code has a business of invoking. We should be treating tests as user code.
I think the preferred solution is to update the test so that it does not call System,Native shim. If it is not feasible for some tests, the tests have good reason to PInvoke System.Native shim should declare that they link against native library and that will in turn trigger relinking just for those tests.
lewing commentedon Sep 20, 2026
What is invalid about this code?
https://github.com/lewing/runtime/blob/555369171d198c49d45051e61dee2797ab0561fb/src/libraries/Common/tests/TestUtilities/System/AdminHelpers.cs#L37-L47
jkotas commentedon Sep 20, 2026
Interop.Sys.GetEUidPInvokes into SystemNative shim:runtime/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetEUid.cs
Line 10 in 7888fee
My suggestion would be replace this with pinvoke into libc directly, like what this test does:
runtime/src/libraries/System.IO.Pipes/tests/NamedPipeTests/NamedPipeTest.RunAsClient.Unix.cs
Lines 19 to 20 in 229a331
lewing commentedon Sep 20, 2026
Final direction after maintainer review: this failure should be fixed in the test utility, not by extending browser ReadyToRun product support.
TestUtilities.AdminHelpersis test/user code and should not call the runtime-ownedInterop.Sys.GetEUidshim. Runtime interop shims are implementation details and are not a supported user-code P/Invoke surface. The supported test-side pattern is to declare the platform import directly:The existing runtime Browser guard remains. On Browser, it prevents the direct
libcimport from being called; on supported Unix platforms the test utility invokeslibcdirectly. The .NET Framework target keeps the same runtime platform-check form.Local validation of this one-site change:
TestUtilitiesbuilds for bothnet10.0andnet481.System.Runtime.Extensions.Tests: 8,304 passed, 70 skipped, 0 failed.The earlier relinking/build-policy investigation was useful for identifying the boundary mismatch, but product changes to support user code calling runtime interop shims are not the intended resolution for this issue. The separate prototype PR was closed.
Note
This update was generated with GitHub Copilot based on maintainer guidance and local validation.
lewing commentedon Sep 21, 2026
#133656 fixed the test-side unsupported interop usage by changing
TestUtilities.AdminHelpersto P/Invokelibc!geteuiddirectly, while Browser and WASI return before making the import. The temporaryTestUtilities.dllReadyToRun exclusion was removed, and the trimmed browser R2RSystem.Runtime.Extensions.Testsvalidation passed 8,304 tests with zero failures.Note
This closure comment was generated with GitHub Copilot assistance.