Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'System.ArithmeticException' while updating layout

Tags:

c#

wpf

dispatcher

This happens only in x64 version

An unhandled exception of type 'System.ArithmeticException' occurred in WindowsBase.dll Additional information: Overflow or underflow in the arithmetic operation.

Crashing at line

gridcontainer.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);

If I remove the line it crashes as soon as it starts updating layout with no source available

00000101  test        ecx,ecx 
00000103  je          0000000000000124 
00000105  lea         rdx,[rbp+18h] 
00000109  mov         rcx,qword ptr [rbp+70h] 
0000010d  call        0000000000216100 
00000112  cmp         byte ptr [rdi],0 

Do you know how to prevent it?

Exception:

    System.ArithmeticException: Overflow or underflow in the arithmetic operation.
   at System.Windows.UIElement.RoundLayoutSize(Size size, Double dpiScaleX, Double dpiScaleY)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(IItemContainerGenerator& generator, IContainItemStorage& itemStorageProvider, IContainItemStorage& parentItemStorageProvider, Object& parentItem, Boolean& hasUniformOrAverageContainerSizeBeenSet, Double& computedUniformOrAverageContainerSize, Boolean& computedAreContainersUniformlySized, IList& items, Object& item, IList& children, Int32& childIndex, Boolean& visualOrderChanged, Boolean& isHorizontal, Size& childConstraint, Rect& viewport, VirtualizationCacheLength& cacheSize, VirtualizationCacheLengthUnit& cacheUnit, Boolean& foundFirstItemInViewport, Double& firstItemInViewportOffset, Size& stackPixelSize, Size& stackPixelSizeInViewport, Size& stackPixelSizeInCacheBeforeViewport, Size& stackPixelSizeInCacheAfterViewport, Size& stackLogicalSize, Size& stackLogicalSizeInViewport, Size& stackLogicalSizeInCacheBeforeViewport, Size& stackLogicalSizeInCacheAfterViewport, Boolean& mustDisableVirtualization, Boolean isBeforeFirstItem, Boolean isAfterFirstItem, Boolean isAfterLastItem, Boolean skipActualMeasure, Boolean skipGeneration, Boolean& hasBringIntoViewContainerBeenMeasured, Boolean& hasVirtualizingChildren)
   at System.Windows.Controls.VirtualizingStackPanel.MeasureOverrideImpl(Size constraint, Nullable`1& lastPageSafeOffset, List`1& previouslyMeasuredOffsets, Boolean remeasure)
   at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ItemsPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   at System.Windows.Controls.ScrollContentPresenter.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Border.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Control.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.DockPanel.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged)
   at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV)
   at System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
like image 527
Daniel Avatar asked Aug 14 '14 14:08

Daniel


1 Answers

We occasionally receive such reports from our users. It seems the issue is related to floating point unit corruption, like described in this question. Unfortunately it is not clear how to handle such error inside framework calls.

UPD: I created following workaround based on presentation framework source code. Initialize workaround with single call: UIHelper.InitWPFArithmeticExceptionWorkaround()

public static class UIHelper
{
    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int _fpreset();

    private static DispatcherOperationCallback _oldUpdateLayoutCallback;
    private static object UpdateLayoutCallback(object arg)
    {
        try
        {
            _oldUpdateLayoutCallback(arg);
            return null;
        }
        catch (System.Xaml.XamlParseException ex)
        {
            if (!(ex.InnerException is ArithmeticException))
            {
                throw;
            }
        }
        // Try to update layout second time after floating point unit reset
        _fpreset();
        _oldUpdateLayoutCallback(arg);
        return null;
    }

    public static bool InitWPFArithmeticExceptionWorkaround()
    {
        try
        {
            // Call fpreset early just to handle case with missed "msvcrt.dll" 
            // in future Windows versions
            _fpreset();
            Assembly assembly = typeof(System.Windows.UIElement).Assembly;
            Type managerType = assembly.GetType("System.Windows.ContextLayoutManager");
            if (managerType != null)
            {
                FieldInfo field = managerType.GetField("_updateCallback", BindingFlags.Static | BindingFlags.NonPublic);
                if (field != null)
                {
                    _oldUpdateLayoutCallback = field.GetValue(null) as DispatcherOperationCallback;
                    if (_oldUpdateLayoutCallback != null)
                    {
                        field.SetValue(null, new DispatcherOperationCallback(UpdateLayoutCallback));
                        return true;
                    }
                }
            }
        }
        catch
        {
        }
        return false;
    }
}
like image 63
Andrey Avatar answered Sep 23 '22 06:09

Andrey