Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps by Copilot · Pull Request #130603 · dotnet/runtime · GitHub
Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps by Copilot · Pull Request #130603 · dotnet/runtime · GitHub
Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps by Copilot · Pull Request #130603 · dotnet/runtime · GitHub
Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps by Copilot · Pull Request #130603 · dotnet/runtime · GitHub
Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps by Copilot · Pull Request #130603 · dotnet/runtime · GitHub
Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps by Copilot · Pull Request #130603 · dotnet/runtime · GitHub
Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps by Copilot · Pull Request #130603 · dotnet/runtime · GitHub
Skip to content

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps - #130603

Merged
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm
Jul 15, 2026
Merged

Trim STAThreadAttribute in single-threaded (browser/wasi) Mono apps#130603
pavelsavara merged 6 commits into
mainfrom
copilot/remove-stathreadattribute-blazor-wasm

Conversation

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

System.STAThreadAttribute was unnecessarily retained in trimmed single-threaded Mono apps (browser/WASI).

This PR now addresses both sides of the behavior:

  • src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml keeps System.STAThreadAttribute rooted only when System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported is true.
  • src/mono/mono/metadata/object.c was updated to tolerate the attribute type being absent by using a try-load path when checking for [STAThread] on entrypoint methods.

This preserves existing behavior on multithreaded Mono platforms while allowing single-threaded browser/WASI apps to trim the attribute safely.

Customer Impact

Without this fix, trimmed single-threaded Mono apps can retain unnecessary metadata, and WASI startup could fail when the attribute is trimmed.

Regression

No known product regression is introduced. The native startup path now handles missing System.STAThreadAttribute gracefully instead of assuming it is always present.

Testing

  • Baseline build: ./build.sh mono+libs
  • Targeted runtime build: ./build.sh mono.runtime -c Release
  • Targeted WASI/Mono build: ./build.sh -os wasi -subset mono+libs -c Debug
  • Parallel validation (code review + security scan) completed.

Risk

Low to medium. The change is narrowly scoped to STA attribute lookup in Mono startup and linker rooting configuration. Multithreaded platforms continue to root the type; single-threaded platforms can trim it, and runtime lookup now safely handles absence.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

CopilotAI self-assigned this Jul 13, 2026
CopilotAI review requested due to automatic review settings July 13, 2026 08:10
CopilotAI removed the request for review from CopilotJuly 13, 2026 08:10
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 08:14
@dotnet-policy-servicedotnet-policy-serviceBot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 13, 2026
CopilotAI changed the title [WIP] Remove STAThreadAttribute from Blazor WASM appTrim STAThread/MTAThread attributes when multithreading is unsupportedJul 13, 2026
CopilotAI requested a review from pavelsavaraJuly 13, 2026 08:16
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture size-reduction Issues impacting final app size primary for size sensitive workloads labels Jul 13, 2026
@MichalStrehovsky

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the attribute on Main for some reason? Or roots some other code that needs it? I think this is the core part that should be addressed.

@pavelsavara

Copy link
Copy Markdown
Member

How are we ending up needing these attribute in the first place?

Great question, thanks

<type fullname="System.STAThreadAttribute" /> in

https://github.com/dotnet/runtime/blame/0ded4d28b4990cc4bdb6f1e44bafca3f22aa6eda/src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml#L338

@copilot removing root cause is better alternative. Investigate if this type rooting is still necessary on other Mono/mobile platforms. If not, remove it from ILLink.Descriptors.xml

If it's still need, make it only explicitly used for those (MT) Mono platforms.

…tributes change
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotJuly 13, 2026 09:34

CopilotAI commented Jul 13, 2026

Copy link
Copy Markdown
ContributorAuthor

How are we ending up needing these attribute in the first place? When I make a new console app (on Windows even!), and PublishTrimmed the app, this attribute trims just fine. Does Blazor place the att...

Good catch — the attribute trims fine on CoreCLR because nothing roots it. On Mono it's the descriptor that keeps it alive: src/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml unconditionally roots System.STAThreadAttribute because the native runtime (object.c: prepare_thread_to_exec_main) looks it up via mono_class_load_from_name (which aborts if the type is missing) to set apartment state when launching an entry point through mono_runtime_run_main. Blazor WASM doesn't reach that path (the entry point is invoked directly), so the root was pure dead weight there. I've switched to fixing the root cause — see the updated commit.

Note

This comment was generated by GitHub Copilot.

How are we ending up needing these attribute in the first place?

Great question, thanks
...

Done in the latest commit. I confirmed the root is still needed on multithreaded Mono platforms (desktop/iOS/Android launch the entry point via mono_runtime_run_mainprepare_thread_to_exec_main, which calls mono_class_load_from_name for System.STAThreadAttribute and aborts if it's missing). Browser/wasi invoke the entry point directly and never hit that path, and apartment state is meaningless there.

So rather than removing the root outright, I gated it in ILLink.Descriptors.xml on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported (featurevalue="true" featuredefault="true") — kept for MT platforms, trimmed on single-threaded browser/wasi where that switch is false. I also reverted the earlier ILLink.LinkAttributes.Shared.xml change in favor of this root-cause fix.

Note

This comment was generated by GitHub Copilot.

CopilotAI changed the title Trim STAThread/MTAThread attributes when multithreading is unsupportedTrim STAThreadAttribute in single-threaded (browser/wasi) Mono appsJul 13, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review July 13, 2026 13:54
CopilotAI review requested due to automatic review settings July 13, 2026 13:54
@pavelsavara

Copy link
Copy Markdown
Member

/ba-g CI failure is #130618

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to reduce trimming roots for Mono single-threaded WebAssembly targets by making System.STAThreadAttribute no longer unconditionally rooted in Mono’s ILLink descriptors, instead gating its retention on RuntimeFeature.IsMultithreadingSupported.

Changes:

  • Removes the unconditional System.STAThreadAttribute root from the main System.Private.CoreLib descriptor list.
  • Re-adds System.STAThreadAttribute as a feature-gated root conditioned on System.Runtime.CompilerServices.RuntimeFeature.IsMultithreadingSupported == true.

Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
Co-authored-by: pavelsavara <271576+pavelsavara@users.noreply.github.com>
Comment threadsrc/mono/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml Outdated
CopilotAI review requested due to automatic review settings July 14, 2026 09:06

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment threadsrc/mono/mono/metadata/object.c
CopilotAI requested review from Copilot and removed request for CopilotJuly 14, 2026 09:11

@MichalStrehovskyMichalStrehovsky left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to address copilot's startup concern, I can sign off again.

@pavelsavara

Copy link
Copy Markdown
Member

/ba-g known issue #130616

@pavelsavara
pavelsavara merged commit fe97964 into mainJul 15, 2026
74 of 77 checks passed
@pavelsavara
pavelsavara deleted the copilot/remove-stathreadattribute-blazor-wasm branch July 15, 2026 07:39
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-preview7 milestone Jul 16, 2026
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 16, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-System.Threadinglinkable-frameworkIssues associated with delivering a linker friendly frameworksize-reductionIssues impacting final app size primary for size sensitive workloads

Projects

None yet

Development

Successfully merging this pull request may close these issues.

STAThreadAttribute is unnecessarily being left in a Blazor WASM default app

5 participants

@MichalStrehovsky@pavelsavara@MichalPetryka