Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added linker hint for DirectWriteForwarder #4353

Conversation

ThomasGoulet73
Copy link
Contributor

@ThomasGoulet73 ThomasGoulet73 commented Mar 30, 2021

Fixes Issue #3903

Description

I added a linker hint for a dependency of DirectWriteForwarder. The linker does not currently C++/CLI assembly (See dotnet/linker#676). This assembly might have been missed by #1387 because the exception does not occur at startup.

Customer Impact

Adds a 23,5 Kb dll when using the linker.

Regression

I don't think it ever worked.

Testing

I tested using a simple repro that failed with <TrimMode>link</TrimMode> and it worked with <TrimmerRootAssembly Include="System.Runtime.InteropServices" />.

Risk

I don't think there is a risk, it only sets an assembly as never trimmed when a WPF application is trimmed.

@ThomasGoulet73 ThomasGoulet73 requested a review from a team as a code owner March 30, 2021 17:12
@ghost ghost added the PR metadata: Label to tag PRs, to facilitate with triage label Mar 30, 2021
@ghost ghost requested review from fabiant3, ryalanms and SamBent March 30, 2021 17:12
@vatsan-madhavan
Copy link
Member

This wasn't missed.It wasn't included - that's all. 😄 We didn't want to include a lot of things by default - so we included what we thought was a reasonable min-set at that time.

If every WPF app in .NET 5 or .NET 6 is encountering a crash during trimming due to the lack of this entry, then it makes sense to add it here. It will cause bloat for self-contained apps, but it will make trimming more reliable. It may be a good trade-off to make.

If only some WPF apps are encountering this crash, but they represent nearly all of the real-world WPF apps, then it may still make sense think about what our defaults ought to be and be somewhat reflective about this decision. Questions like (i) what other assemblies should be included in this list of "needed by real world apps", (ii) should that list be incorporated into WPF directly as liker hints or should it be added as a documentation somewhere, (iii) should such a list perhaps be incorporated into MSBuild targets in the trimming related logic in the SDK someplace that only real-world apps can opt-into etc. should be considered and answered.

If this is a one-off problem encountered by only a few apps, then I don't think it should be added here at all. I'm sure there is some way for apps to directly specify linker hints like this - for e.g. TrimmerRootAssembly.

/cc @danmoseley, @dsplaisted

@ThomasGoulet73
Copy link
Contributor Author

ThomasGoulet73 commented Mar 30, 2021

@vatsan-madhavan Sorry, couldn't see in your PR if it was intentional or missed 😄.

The issue is for an exception that causes the application to crash when a user tries to copy the content of a TextBox (I didn't test for other controls or manipulations other than Copy).

Also, the exception is almost impossible to diagnose (See the issue description), which makes it more difficult for the developer to fix it, contrary to #4321, which points to the missing assembly.

I wouldn't expect DirectWriteForwarder to change a lot in the future so there probably won't be another assembly included for trimming like this.

I would expect any real-word application to come accross this exception.

I think the size trade-off is very minimized by the size of the dll (23,5 Kb).

If this is a one-off problem encountered by only a few apps, then I don't think it should be added here at all. I'm sure there is some way for apps to directly specify linker hints like this - for e.g. TrimmerRootAssembly.

I was able to fix my application using TrimmerRootAssembly, see my comment here.

I'm happy to close this PR if the WPF team judges that it's not worth it but IMO, it is. (I might be biased because I spent lot of time finding the source of the exception 😄 )

@ThomasGoulet73
Copy link
Contributor Author

I should also mention that the size of System.Runtime.InteropServices when trimmed in a very barebone application is 14 Kb, while the size not trimmed is 23,5 Kb so we only increase the size of every self-contained trimmed WPF application by 9,5 Kb. Which I think is very minimal for a desktop application.

@danmoseley
Copy link
Member

danmoseley commented Mar 31, 2021

cc @eerhardt who can better answer your question/provide guidance.

@vatsan-madhavan
Copy link
Member

I tried a simple textbox and it crashes immediately on Ctrl+C. Something as simple as this:

<Window x:Class="test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:test"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
    <TextBox HorizontalAlignment="Center" Text="TextBox" TextWrapping="Wrap" VerticalAlignment="Center"/>
    </Grid>
</Window>

Including this it as a dependency of DirectWriteForwarder makes sense given that's the assembly responsible for most of text functionality. I think it will also affect any other non-text copy/paste scenario given this is the crash stack I'm seeing:

STACK_TEXT:  
000000e4`daf7d118 00007ffd`344c9c6e coreclr!ComCallPreStub+0x2e
000000e4`daf7d1e8 000001f4`c678f3a8 unknown!unknown+0x0
000000e4`daf7d1f0 000001f4`c678f320 unknown!unknown+0x0
000000e4`daf7d1f8 000001f4`c109c810 unknown!unknown+0x0
000000e4`daf7d200 000001f4`c5ce7a01 unknown!unknown+0x0
000000e4`daf7d208 00000000`00000001 unknown!unknown+0x0
000000e4`daf7d210 00007ffd`bba2f0af USER32!SetClipboardData+0x1bf
000000e4`daf7d270 00007ffd`346a08b8 coreclr!Unknown_AddRef_Internal+0x28
000000e4`daf7d2a0 00007ffd`bb8d379a ole32!SetClipboardDataObject+0x242
000000e4`daf7d2f0 00007ffd`bb8d2d49 ole32!OleSetClipboardInternal+0xb5
000000e4`daf7d330 00007ffd`bb8d4775 ole32!OleSetClipboard+0x165
000000e4`daf7d520 00007ffc`d583a784 DirectWriteForwarder!ILStubClass.IL_STUB_PInvoke+0xa4
000000e4`daf7d5f0 00007ffc`d583a6c1 PresentationCore!System.Windows.OleServicesContext.OleSetClipboard+0x81
000000e4`daf7d630 00007ffc`d583a5a6 PresentationCore!System.Windows.Clipboard.CriticalSetDataObject+0x96

Ultimately the team should sign off on this approach - to me this looks to be something that will affect any WPF app and so looks like a reasonable fix.

@eerhardt
Copy link
Member

cc @mateoatr - who is working on analyzing C++/CLI in https://github.com/mono/linker. Once that work is done, this ILLinkTrim.xml workaround file should be able to be removed.

@pchaurasia14 pchaurasia14 added the Community Contribution A label for all community Contributions label Jul 20, 2022
@ghost ghost assigned ThomasGoulet73 Jul 20, 2022
@dipeshmsft
Copy link
Member

@ThomasGoulet73 since the related issues are closed, and as mentioned in #1392, it looks like we can safely remove this workaround. Can you check this and modify the PR accordingly?

@dipeshmsft dipeshmsft self-assigned this Mar 20, 2023
@dipeshmsft
Copy link
Member

@eerhardt @mateoatr - is it safe to remove the workaround ?

@eerhardt
Copy link
Member

I'm not sure. The best way to check would be to remove it and test if it still works.

cc @agocke

@rchauhan18
Copy link
Contributor

@ThomasGoulet73 - We tried to repro the original issue mentioned in this PR and it looks like the issue has already been addressed by changes in dotnet/linker#676.

I think we should close this PR. Additionally, we need to create another PR that reverts the changes in #1387 .

@dipeshmsft
Copy link
Member

@ThomasGoulet73 any comments regarding this?

@ThomasGoulet73
Copy link
Contributor Author

@rchauhan18 @dipeshmsft: I'm still able to reproduce the issue. Here's a simple repro:

MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBox />
    </Grid>
</Window>
WpfApp1.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
    <PublishTrimmed>true</PublishTrimmed>
    <_SuppressWpfTrimError>true</_SuppressWpfTrimError>
    <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
  </PropertyGroup>

  <ItemGroup>
    <TrimmerRootAssembly Include="WpfApp1" />
    <TrimmerRootAssembly Include="PresentationCore" />
    <TrimmerRootAssembly Include="PresentationFramework" />
    <TrimmerRootAssembly Include="PresentationFramework.Aero2" />
    <TrimmerRootAssembly Include="System.Runtime.InteropServices" />
    <TrimmerRootAssembly Include="System.Runtime" />
    <TrimmerRootAssembly Include="System.Runtime.Extensions" />
    <TrimmerRootAssembly Include="System.Xaml" />
    <TrimmerRootAssembly Include="WindowsBase" />
  </ItemGroup>

</Project>

When publishing with <TrimmerRootAssembly Include="System.Runtime.InteropServices" />, copying text in the textbox works and when publishing without <TrimmerRootAssembly Include="System.Runtime.InteropServices" />, copying text in the textbox crashes the app. I'm not sure whether this should be fixed in WPF (This PR) or in the trimmer.

@rchauhan18
Copy link
Contributor

rchauhan18 commented Aug 4, 2023

@ThomasGoulet73 I have created one sample application (Wpfapp1) with the details given by you.
Here is the zip:
WpfApp1.zip

I am not able to repo it.
Can you help me, what I am missing?

Dotnet version

.NET SDK:
 Version:   8.0.100-preview.5.23303.2
 Commit:    3fe444af72

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22621
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.100-preview.5.23303.2\

.NET workloads installed:
There are no installed workloads to display.

Host:
  Version:      8.0.0-preview.5.23280.8
  Architecture: x64
  Commit:       bc78804f5d

.NET SDKs installed:
  3.0.103 [C:\Program Files\dotnet\sdk]
  5.0.408 [C:\Program Files\dotnet\sdk]
  6.0.302 [C:\Program Files\dotnet\sdk]
  6.0.315 [C:\Program Files\dotnet\sdk]
  7.0.306 [C:\Program Files\dotnet\sdk]
  8.0.100-preview.5.23303.2 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.0-preview.5.23302.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.0-preview.5.23280.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.9 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.0-preview.5.23302.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

Visual Studio version
Microsoft Visual Studio Enterprise 2022 (64-bit) - Current
Version 17.6.5
Publish Command
dotnet publish -c Release --self-contained true 

@rchauhan18
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rchauhan18 rchauhan18 merged commit 0bccdc2 into dotnet:main Oct 9, 2023
7 checks passed
@rchauhan18
Copy link
Contributor

Thanks @ThomasGoulet73 for your contribution.

@ThomasGoulet73 ThomasGoulet73 deleted the add-linker-hint-for-directwriteforwarder branch October 10, 2023 12:46
@ghost ghost locked as resolved and limited conversation to collaborators Nov 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Community Contribution A label for all community Contributions PR metadata: Label to tag PRs, to facilitate with triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants