NaN in Geometry causes UCEERR_RENDERTHREADFAILURE
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
* .NET 6 ( 6.0.401 installed )
* Windows version: Windows 10 Version 22H2 ( OS Build 19045.2251 )
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
* Is this bug related specifically to tooling in Visual Studio - NO
**Problem description:**
I have code that creates Geometry. Due to a bug in my code a NaN was being used to create this Geometry. In most places in WPF if you pass in illegal arguments ( NaN in geometry string, negative Rect size, etc ) an easy to understand Exception is created. In this case a `System.Runtime.InteropServices.COMException: 'UCEERR_RENDERTHREADFAILURE (0x88980406)'` Is created.
Given the behavior of other parts of WPF I think this is a bug. I would expect the UI thread to generate an Exception and not have the entire application crash.
**Actual behavior:**
Exception :
```
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in PresentationCore.dll
UCEERR_RENDERTHREADFAILURE (0x88980406)
```
Call Stack
```
> PresentationCore.dll!System.Windows.Media.Composition.DUCE.Channel.SyncFlush() Unknown
PresentationCore.dll!System.Windows.Interop.HwndTarget.UpdateWindowSettings(bool enableRenderTarget, System.Windows.Media.Composition.DUCE.ChannelSet? channelSet) Unknown
PresentationCore.dll!System.Windows.Interop.HwndTarget.UpdateWindowPos(System.IntPtr lParam) Unknown
PresentationCore.dll!System.Windows.Interop.HwndTarget.HandleMessage(MS.Internal.Interop.WindowMessage msg, System.IntPtr wparam, System.IntPtr lparam) Unknown
PresentationCore.dll!System.Windows.Interop.HwndSource.HwndTargetFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
PresentationFramework.dll!System.Windows.Window.Flush() Unknown
PresentationFramework.dll!System.Windows.Window.HwndStyleManager.System.IDisposable.Dispose() Unknown
PresentationFramework.dll!System.Windows.Window.CreateSourceWindow(bool duringShow) Unknown
PresentationFramework.dll!System.Windows.Window.CreateSourceWindowDuringShow() Unknown
PresentationFramework.dll!System.Windows.Window.SafeCreateWindowDuringShow() Unknown
PresentationFramework.dll!System.Windows.Window.ShowHelper(object booleanBox) Unknown
PresentationFramework.dll!System.Windows.Window.Show() Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.WpfVisualTreeService.Adorners.AdornerWindow.SafeShow() Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.WpfVisualTreeService.Adorners.AdornerWindow.UpdatePlacement() Unknown
Microsoft.VisualStudio.DesignTools.WpfTap.dll!Microsoft.VisualStudio.DesignTools.WpfTap.Utility.DispatcherUtility.SafeInvokeAsync.AnonymousMethod__0() Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeDelegateCore() Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) Unknown
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj) Unknown
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
System.Private.CoreLib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Unknown
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown
PresentationFramework.dll!System.Windows.Application.Run() Unknown
NaN-Crash.dll!NaN_Crash.App.Main() Unknown
```
**Expected behavior:**
App should not crash in rendering thread and instead generate an Exception on the UI thread.
**Minimal repro:**
Here's a simple Control which shows the issue. It's a little convoluted since I stripped out a bunch of code that wasn't necessary to cause the issue.
```
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace NaN_Crash
{
internal class Class1 : Control
{
protected override void OnRender(DrawingContext dc)
{
var rc = new Rect(0, 0, ActualWidth, ActualHeight);
// bad rc
rc = new Rect(0, double.NaN, 36, 144);
Geometry.DrawRoundedRect(dc, rc, 18);
}
}
internal static class Geometry
{
static void Curve(PathFigure pf, double x, double y, double cr, bool clockwise)
{
pf.Segments.Add(
new ArcSegment(
new Point(x, y),
new Size(cr, cr),
0,
false,
clockwise ? SweepDirection.Clockwise : SweepDirection.Counterclockwise,
true));
}
static void Line(PathFigure pf, double x, double y)
{
pf.Segments.Add(new LineSegment(new Point(x, y), true));
}
public static PathGeometry GetRoundedRect(Rect rect, double cr)
{
PathGeometry pg = new PathGeometry();
PathFigure pf = new PathFigure();
pf.StartPoint = new Point(rect.Left + cr, rect.Top);
Line(pf, rect.Right - cr, rect.Top);
Curve(pf, rect.Right, rect.Top + cr, cr, true);
Line(pf, rect.Right, rect.Bottom - cr);
Curve(pf, rect.Right - cr, rect.Bottom, cr, true);
Line(pf, rect.Left + cr, rect.Bottom);
Curve(pf, rect.Left, rect.Bottom - cr, cr, true);
Line(pf, rect.Left, rect.Top + cr);
Curve(pf, rect.Left + cr, rect.Top, cr, true);
pf.IsClosed = true;
pf.Freeze();
pg.Figures.Add(pf);
pg.Freeze();
return pg;
}
public struct InnerGeometryInfo
{
public System.Windows.Media.Geometry Geo { get; set; }
public double InnerBr { get; set; }
public Rect InnerRect { get; set; }
}
public static InnerGeometryInfo GetInnerGeo(Rect rect, double br)
{
var th = new Thickness(1, 1, 1, 1);
var innerRect = Adjust(rect, th);
double innerBr = Math.Max(0, br - 1.0);
return new InnerGeometryInfo()
{
Geo = GetRoundedRect(innerRect, innerBr),
InnerBr = innerBr,
InnerRect = innerRect
};
}
public static void DrawRoundedRect(DrawingContext dc, Rect rect, double br)
{
var geo1 = GetRoundedRect(rect, br);
var innerInfo = GetInnerGeo(rect, br);
var innerBr = innerInfo.InnerBr;
var innerRect = Adjust(rect, new Thickness(1.0));
var geo = new CombinedGeometry(GeometryCombineMode.Exclude, geo1,innerInfo.Geo);
dc.PushClip(geo);
dc.Pop();
}
public static Rect SafeRect(double x, double y, double w, double h)
{
return new Rect(x, y, Math.Max(0, w), Math.Max(0, h));
}
public static Rect Adjust(Rect rc, Thickness? th)
{
if (th.HasValue)
{
return SafeRect(rc.Left + th.Value.Left, rc.Top + th.Value.Top, rc.Width - th.Value.Left - th.Value.Right, rc.Height - th.Value.Top - th.Value.Bottom);
}
return rc;
}
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.