Skip to content

[ci-fix] Needs review: Marshal mono_ios_* string args as UTF-8 for NativeAOT ILC (refs #130219) - #130232

Closed
github-actions[bot] wants to merge 1 commit into
mainfrom
ci-fix/appletestrunner-nativeaot-marshal-130219-880714c1b42b5ea5
Closed

[ci-fix] Needs review: Marshal mono_ios_* string args as UTF-8 for NativeAOT ILC (refs #130219)#130232
github-actions[bot] wants to merge 1 commit into
mainfrom
ci-fix/appletestrunner-nativeaot-marshal-130219-880714c1b42b5ea5

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Workflow artifact: ci-fix
Artifact kind: help
Linked KBE: #130219

Note

AI/Copilot-generated best-effort fix. The root cause and change below are well-supported by the native contract, but I could not run the ILC/NativeAOT tvOS cross-compile in this environment to confirm the compiler error is gone. Please have a mobile/interop owner validate before merging.

Root cause

Every work item on the tvos-arm64 Release AllSubsets_NativeAOT leg (and the other Apple NativeAOT library-test legs enabled by #125437) aborts on startup:

System.Runtime.InteropServices.MarshalDirectiveException: Method
'SimpleTestRunner.mono_ios_set_summary(string)' requires marshalling that is not yet supported by this compiler.
   at SimpleTestRunner.<Main>d__5.MoveNext() in .../AppleTestRunner.cs:line 97

The harness declares the UI-callback p/invokes with default DllImport string marshalling:

[DllImport("__Internal")]
public extern static void mono_ios_append_output (string value);

[DllImport("__Internal")]
public extern static void mono_ios_set_summary (string value);

Default DllImport string marshalling is CharSet.Ansi. Under Mono AOT this was tolerated, but the ILC (NativeAOT) compiler rejects it here with MarshalDirectiveException. Native symbol resolution itself is fine — #125437 wires DirectPInvoke __Internal so mono_ios_set_summary resolves statically — the failure is purely the marshalling directive, so the process fails before the first test runs.

Attempted fix

Annotate both string parameters with [MarshalAs(UnmanagedType.LPUTF8Str)]. This is not an arbitrary choice: the native implementations in src/tasks/AppleAppBuilder/Templates/main-console.m take const char* and immediately call [NSString stringWithUTF8String:value], i.e. they expect a UTF-8 C string. So LPUTF8Str:

  • matches the real native contract exactly (the previous ANSI default was also semantically wrong for any non-ASCII test name), and
  • gives ILC an explicit, supported marshalling directive instead of the unsupported implicit one.

These are test-harness display hooks (they update the on-device summary/output UI); no test logic or assertion is changed, and nothing is skipped or disabled.

What is unverified / where I need help

  • I could not run the NativeAOT ILC compile for the tvOS/iOS leg locally, so I have not empirically confirmed the MarshalDirectiveException is eliminated. Please confirm that LPUTF8Str on a DirectPInvoke __Internal import compiles under ILC for these legs.
  • If the team would rather convert these to source-generated [LibraryImport] marshalling for NativeAOT correctness, that is a reasonable alternative — this PR takes the minimal directive-only approach.

Validation

  • Command: NativeAOT/ILC tvOS cross-compile of AppleTestRunner — not run because the Apple NativeAOT toolchain and cross-compile exceed this environment's capabilities/time budget.
  • Result: not run. Change is a marshalling-attribute-only edit; UnmanagedType.LPUTF8Str and System.Runtime.InteropServices are already in scope in the file.

Evidence

Help wanted

Suggested reviewers / area contacts

  • area-NativeAOT-coreclr: @agocke, @dotnet/ilc-contrib
  • Apple mobile (os-ios): @kotlarmilos, @steveisok

Filed by ci-failure-fix. Comment here or on the workflow file to suggest changes; ci-failure-scan-feedback reads in-scope feedback daily and opens (or updates) a PR with prompt edits.

Note

🔒 Integrity filter blocked 6 items

The following items were blocked because they don't meet the GitHub integrity level.

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by CI Outer-Loop Failure Fixer · ● 9.2M ·

…lity

The Apple test harness p/invokes mono_ios_append_output/mono_ios_set_summary
declared 'string value' with default (ANSI) DllImport marshalling. The ILC
NativeAOT compiler rejects this with MarshalDirectiveException, breaking every
work item on the tvos-arm64/ios AllSubsets_NativeAOT legs enabled by #125437.
The native implementations take 'const char*' and call
[NSString stringWithUTF8String:], so UTF-8 (LPUTF8Str) marshalling is the
correct, ILC-supported directive.

Refs #130219

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.

@MichalStrehovsky

Copy link
Copy Markdown
Member

/azp run runtime-extra-platforms

@MichalStrehovsky

Copy link
Copy Markdown
Member

I would be surprised if this fixes anything. Without this annotation, it should marshal as an ansi string, not throw this exception. This exception is very unexpected.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).
@github-actions github-actions Bot mentioned this pull request Jul 26, 2026
@kotlarmilos

Copy link
Copy Markdown
Member

This should be already fixed

kotlarmilos added a commit that referenced this pull request Aug 18, 2026
…fixed & retired-leg PRs (#132318)

The `ci-failure-fix` workflow keeps opening help-wanted PRs for failures
that no longer happen — retired legs (#129653, "Mono
mobile doesn't run on CI anymore"), already-merged fixes
(#130231), and stale KBEs (#130232). This is
the dominant closed-unmerged class over the last several ticks, and
prior feedback issues (#131644, #131699)
flagged it without a guard ever landing.

## Changes

`.github/workflows/ci-failure-fix.md` only — prompt text, no code:

- **Step 4, new gate before any fix attempt** (inserted as item 2;
following items renumbered 3/4). Three checks, first trip ends the KBE
with a recorded skip — no PR, no loop-in comment:
- **Recent occurrence** — signature checked against the newest completed
builds of the definition plus Build Analysis occurrence data in the KBE
body; nothing in 14d → `skipped: no occurrence in last 14d, likely
already fixed or retired`
- **Live leg** — the leg must appear in the newest completed build's
timeline *and* still be defined in `eng/pipelines/**` at `HEAD`; retired
Mono-mobile/wasm legs, deleted queues, dropped images → `skipped:
failing leg retired, no longer runs at HEAD`
- **Fix already landed** — failing source read at `HEAD` plus `git log`
since KBE creation; faulty path already removed → `skipped: fix already
present at HEAD; KBE stale`
- **Recognized skip reasons list** — the three phrasings registered
verbatim so the feedback workflow's tally aggregation stays stable.
- One pre-existing trailing space removed (line 192); markdownlint runs
repo-wide on any PR touching `.md` and MD009 is the sole enabled rule.

Placement is deliberate: after Step 3 dedup, before Step 5's fix
attempt, mirroring the existing Step 5.1.1 pipeline-category gate.
`Recorded skip` is already a valid outcome in the Step-summary table, so
no downstream change is needed.

## Notes

No lock-file regeneration: `ci-failure-fix.lock.yml` pulls the prompt
via `{{#runtime-import .github/workflows/ci-failure-fix.md}}` and stores
no hash of the body — only frontmatter changes require a recompile, and
the frontmatter is untouched. No other prompt references Step 4 items by
number, so the renumbering is contained.

Verified `markdownlint-cli` clean on the file. Nothing built or tested —
there is no code here.

<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #131873

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: kotlarmilos <11523312+kotlarmilos@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.