Skip to content

System.ArgumentException in PresentationFramework.dll!System.Windows.Controls.ToolBarTray.MeasureOverride #2189

@rladuca

Description

@rladuca

This bug was ported over from an internal bug.

Call Stack
The call stack provided below is only a SAMPLE. Please use the cab search link above to obtain latest cabs and call stacks.
WindowsBase.ni!System.Windows.Size.set_Width
at PresentationFramework.ni!System.Windows.Controls.ToolBarTray.MeasureOverride in ToolBarTray.cs
at PresentationFramework.ni!System.Windows.FrameworkElement.MeasureCore
at PresentationCore.ni!System.Windows.UIElement.Measure in UIElement.cs
at PresentationFramework.ni!System.Windows.Controls.Border.MeasureOverride in Border.cs
at PresentationFramework.ni!System.Windows.FrameworkElement.MeasureCore
at PresentationCore.ni!System.Windows.UIElement.Measure in UIElement.cs
at PresentationFramework.ni!System.Windows.Controls.DockPanel.MeasureOverride in DockPanel.cs
at PresentationFramework.ni!System.Windows.FrameworkElement.MeasureCore
at PresentationCore.ni!System.Windows.UIElement.Measure in UIElement.cs
at PresentationCore.ni!System.Windows.ContextLayoutManager.UpdateLayout in LayoutManager.cs
at PresentationCore.ni!System.Windows.ContextLayoutManager.UpdateLayoutCallback in LayoutManager.cs
at PresentationCore.ni!System.Windows.Media.MediaContext in MediaContext.cs
at PresentationCore.ni!System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks in MediaContext.cs
at PresentationCore.ni!System.Windows.Media.MediaContext.RenderMessageHandlerCore in MediaContext.cs
at PresentationCore.ni!System.Windows.Media.MediaContext.RenderMessageHandler in MediaContext.cs
at WindowsBase.ni!System.Windows.Threading.ExceptionWrapper.InternalRealCall in ExceptionWrapper.cs
at WindowsBase.ni!System.Windows.Threading.ExceptionWrapper.TryCatchWhen in ExceptionWrapper.cs
at WindowsBase.ni!System.Windows.Threading.DispatcherOperation.InvokeImpl in DispatcherOperation.cs
at WindowsBase.ni!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext in DispatcherOperation.cs
at WindowsBase.ni!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper in CulturePreservingExecutionContext.cs
at mscorlib.ni!System.Threading.ExecutionContext.RunInternal in executioncontext.cs
at mscorlib.ni!System.Threading.ExecutionContext.Run in executioncontext.cs
at mscorlib.ni!System.Threading.ExecutionContext.Run in executioncontext.cs
at WindowsBase.ni!MS.Internal.CulturePreservingExecutionContext.Run in CulturePreservingExecutionContext.cs
at WindowsBase.ni!System.Windows.Threading.DispatcherOperation.Invoke in DispatcherOperation.cs
at WindowsBase.ni!System.Windows.Threading.Dispatcher.ProcessQueue in Dispatcher.cs
at WindowsBase.ni!System.Windows.Threading.Dispatcher.WndProcHook in Dispatcher.cs
at WindowsBase.ni!MS.Win32.HwndWrapper.WndProc in HwndWrapper.cs
at WindowsBase.ni!MS.Win32.HwndSubclass.DispatcherCallbackOperation in HwndSubclass.cs
at WindowsBase.ni!System.Windows.Threading.ExceptionWrapper.InternalRealCall in ExceptionWrapper.cs
at WindowsBase.ni!System.Windows.Threading.ExceptionWrapper.TryCatchWhen in ExceptionWrapper.cs
at WindowsBase.ni!System.Windows.Threading.Dispatcher.LegacyInvokeImpl in Dispatcher.cs
at WindowsBase.ni!MS.Win32.HwndSubclass.SubclassWndProc in HwndSubclass.cs

Anonymized analysis comments:

This is a dupe of a bug in the old tracking system.

The bug is and always has been in WPF, specifically this code inside ToolBarTray.MeasureOverride

<snip>
for (toolBarIndex = 0; toolBarIndex < band.Count; toolBarIndex++)
{
    ToolBar toolBar = band[toolBarIndex];
    remainingLength -= toolBar.MinLength;
    if (DoubleUtil.LessThan(remainingLength, 0))
    {
        remainingLength = 0;
        break;
    }
}
// Measure all children passing the remainingLength as a constraint
for (toolBarIndex = 0; toolBarIndex < band.Count; toolBarIndex++)
{
    ToolBar toolBar = band[toolBarIndex];
    remainingLength += toolBar.MinLength;
    if (fHorizontal)
        childConstraint.Width = remainingLength;
    else
        childConstraint.Height = remainingLength;
    toolBar.Measure(childConstraint);
<snip>

The first for loop gets it correct, in that it uses DoubleUtil.LessThan(remainingLength, 0) to ensure that if the remaningLength drops below 0 it is capped back to 0. The lower loop does not. In this crash after measuring the MinLength for 19 toolbars remainingLength has ended up as -0.0 (yes, doubles have a concept of negative 0), that is set as Width and the Size class throws saying that width cannot be negative.
Reopening this for WPF to investigate potentially fixing this. The real bug seems to be in DoubleUtil.LessThan(). If the value being checked is close to zero but slightly negative, it can slip through this check and result in setting the Width or Height of a Size object to a negative value resulting in the exception. One way to fix this could be to change the if check to something like this:

if (remainingLength < double.Epsilon)
    remainingLength = 0;

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions