microsoft-ui-xaml icon indicating copy to clipboard operation
microsoft-ui-xaml copied to clipboard

Access violation in auto generated x:Bind code

Open sylveon opened this issue 5 years ago • 8 comments

Describe the bug The auto generated x:Bind code triggers an access violation.

Additionally, both TemplateBinding and Binding seems to fail here... TemplateBinding says "Setter does not have a value" (despite that being entirely false) and Binding says "The parameter is incorrect"

Steps to reproduce the bug Steps to reproduce the behavior:

  1. Clone and run https://github.com/sylveon/xaml-bug-repro
  2. Observe access violation

Expected behavior No access violation, the app runs successfully and shows the button.

Screenshots image

Version Info

NuGet package version: [Microsoft.Windows.CppWinRT 2.0.200514.2]

Windows 10 version Saw the problem?
Insider Build (19041) Yes
November 2019 Update (18363)
May 2019 Update (18362)
October 2018 Update (17763)
April 2018 Update (17134)
Fall Creators Update (16299)
Creators Update (15063)
Device form factor Saw the problem?
Desktop Yes
Mobile
Xbox
Surface Hub
IoT

Additional context I found this bug when writing XAML for an XAML Islands application, but it reproduces in UWP.

sylveon avatar May 29 '20 18:05 sylveon

I stepped through the code yesterday, and it seems the issue is this:

  • Connect with id 6 acquires a reference to the ColorAnimation that has its property bound to a value
  • Connect with id 2 updates all values, assuming all other connections where done prior and all references are valid

For some reason, Connect with id 2 is called but Connect with id 6 never got called prior to that, resulting in the framework trying to access a null pointer

sylveon avatar May 29 '20 19:05 sylveon

Some more updates:

  • This happens in C# as well, both x:Bind and TemplateBinding
  • Binding decided to work in C# and C++ now because ???

sylveon avatar May 29 '20 20:05 sylveon

Even more updates:

  • Binding was working because I forgot I had changed the Setter for the Normal visual state to use a constant rather than a Binding...
  • If I revert that change in C# and C++ UWP projects it still works, however my XAML Islands project crashes when doing that (and that's my scenario, I don't write UWP)

Change in question being

                         <VisualState x:Name="Normal">
                             <VisualState.Setters>
-                                <Setter Target="ForegroundBrush.Color" Value="White" />
+                                <Setter Target="ForegroundBrush.Color" Value="{Binding NormalForeground, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=OneWay}" />
                             </VisualState.Setters>

(or TemplateBinding or x:Bind)

sylveon avatar May 29 '20 21:05 sylveon

Adding @evelynwu-msft who might have an idea of what's going on.

It looks like the parser isn't calling Connect on the ColorAnimation. Alan, is the VisualTransition deferred?

stevenbrix avatar May 29 '20 21:05 stevenbrix

Yeah, they're deferred, but I would expect Connect() to be called when the transition is undeferred. Although I wonder if the undeferred ColorAnimation is then being immediately thrown away, rather than remaining undeferred... I'm not familiar with what VSM is doing under the covers so I don't know the answer off the top of my head.

evelynwu-msft avatar May 29 '20 21:05 evelynwu-msft

Was about to report the same bug then found this issue. This issue is affecting VisualState.StateTrigger as well. In fact, I bet it's affecting anything that is bindable.

A minimal repro for state trigger:

<Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomControl">
                    <Border
                        x:Name="border"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup>
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="PointerOver">
                                    <VisualState.Setters>
                                        <Setter Target="border.Background" Value="Red"/>
                                    </VisualState.Setters>
                                    <VisualState.StateTriggers>
                                        <StateTrigger IsActive="{x:Bind IsShown, Mode=OneWay}"/> // Crashes with null pointer deference when binding this state trigger
                                    </VisualState.StateTriggers>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <TextBlock Text="Hello World"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

Did the same debugging sequence and could confirm the reference for the state trigger is never set in Connect prior to updating its value.

roxk avatar Jul 03 '21 04:07 roxk

This 4 years old bug is, hilariously, still an issue in WinUI 3

sylveon avatar Jun 16 '24 02:06 sylveon

However, the tags are incorrect. The bug was originally encountered in system XAML, with no WinUI at all.

sylveon avatar Jun 16 '24 02:06 sylveon