Bug 53382

Summary: CarouselView reliably crashing with DivideByZeroException as of pre3
Product: Forms Reporter: Philipp Sumi <hardcodet>
Component: FormsAssignee: Chris King <chris.king>
Status: RESOLVED NOT_ON_ROADMAP    
Severity: normal CC: alberto, bellju, chaselfromal, chris.king, david, emmanvazzbs, FieldstrikeMobile, jas, jimmy.garrido, mirko.dacorte, sahou, sonmezosman, steve
Priority: ---    
Version: 2.3.4   
Target Milestone: ---   
Hardware: PC   
OS: Windows   
Tags: ac Is this bug a regression?: ---
Last known good build:
Attachments: Repro with Monkeys project

Description Philipp Sumi 2017-03-16 08:50:04 UTC
CarouselView was working on pre2, but crashes the app hard after the upgrade to pre5/pre3:


CarouselViewRenderer+VirtualLayoutManager.GetPosition
android.runtime.JavaProxyThrowable: System.DivideByZeroException: Attempted to divide by zero.

Xamarin caused by: android.runtime.JavaProxyThrowable: System.DivideByZeroException: Attempted to divide by zero.
Xamarin.Forms.Platform.CarouselViewRenderer.VirtualLayoutManager.GetPosition(int itemCount, int positionOrigin, int x, bool exclusive)<98ef4d3d8b214c838f1b190032afb88a>:0
Xamarin.Forms.Platform.CarouselViewRenderer.VirtualLayoutManager.GetPositions(int positionOrigin, int itemCount, Rectangle viewport)<98ef4d3d8b214c838f1b190032afb88a>:0
Xamarin.Forms.Platform.PhysicalLayoutManager.OnLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state)<98ef4d3d8b214c838f1b190032afb88a>:0
Android.Support.V7.Widget.RecyclerView.LayoutManager.n_OnLayoutChildren_Landroid_support_v7_widget_RecyclerView_Recycler_Landroid_support_v7_widget_RecyclerView_State_(IntPtr jnienv, IntPtr native__this, IntPtr native_recycler, IntPtr native_state)<62f1973e22584368bc73846a0798f0bd>:0
at (wrapper dynamic-method) System.Object:7ce69b0c-299c-4729-9d79-93780c44dcbd (intptr,intptr,intptr,intptr)
md56987f6cc1cad2bad7d1513f02edd2700.PhysicalLayoutManager.n_onLayoutChildren(Native Method)
md56987f6cc1cad2bad7d1513f02edd2700.PhysicalLayoutManager.onLayoutChildren()PhysicalLayoutManager.java:149
android.support.v7.widget.RecyclerView.dispatchLayoutStep2()RecyclerView.java:3506
android.support.v7.widget.RecyclerView.dispatchLayout()RecyclerView.java:3254
android.support.v7.widget.RecyclerView.onLayout()RecyclerView.java:3767
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
md56987f6cc1cad2bad7d1513f02edd2700.CarouselViewRenderer.n_onLayout(Native Method)
md56987f6cc1cad2bad7d1513f02edd2700.CarouselViewRenderer.onLayout()CarouselViewRenderer.java:45
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout()FormsViewGroup.java:29
md5b60ffeb829f638581ab2bb9b1a7f4f3f.VisualElementRenderer_1.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.VisualElementRenderer_1.onLayout()VisualElementRenderer_1.java:58
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout()FormsViewGroup.java:29
md5270abb39e60627f0f200893b490a1ade.NavigationPageRenderer.n_onLayout(Native Method)
md5270abb39e60627f0f200893b490a1ade.NavigationPageRenderer.onLayout()NavigationPageRenderer.java:65
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
com.xamarin.forms.platform.android.FormsViewGroup.measureAndLayout()FormsViewGroup.java:29
md5270abb39e60627f0f200893b490a1ade.MasterDetailContainer.n_onLayout(Native Method)
md5270abb39e60627f0f200893b490a1ade.MasterDetailContainer.onLayout()MasterDetailContainer.java:53
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
android.support.v4.widget.DrawerLayout.onLayout()DrawerLayout.java:1193
md5270abb39e60627f0f200893b490a1ade.MasterDetailPageRenderer.n_onLayout(Native Method)
md5270abb39e60627f0f200893b490a1ade.MasterDetailPageRenderer.onLayout()MasterDetailPageRenderer.java:68
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
md5b60ffeb829f638581ab2bb9b1a7f4f3f.PlatformRenderer.n_onLayout(Native Method)
md5b60ffeb829f638581ab2bb9b1a7f4f3f.PlatformRenderer.onLayout()PlatformRenderer.java:63
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
android.widget.RelativeLayout.onLayout()RelativeLayout.java:1080
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
android.widget.FrameLayout.layoutChildren()FrameLayout.java:344
android.widget.FrameLayout.onLayout()FrameLayout.java:281
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
android.widget.LinearLayout.setChildFrame()LinearLayout.java:1742
android.widget.LinearLayout.layoutVertical()LinearLayout.java:1585
android.widget.LinearLayout.onLayout()LinearLayout.java:1494
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
android.widget.FrameLayout.layoutChildren()FrameLayout.java:344
android.widget.FrameLayout.onLayout()FrameLayout.java:281
com.android.internal.policy.PhoneWindow$DecorView.onLayout()PhoneWindow.java:3178
android.view.View.layout()View.java:17945
android.view.ViewGroup.layout()ViewGroup.java:5812
android.view.ViewRootImpl.performLayout()ViewRootImpl.java:2716
android.view.ViewRootImpl.performTraversals()ViewRootImpl.java:2417
android.view.ViewRootImpl.doTraversal()ViewRootImpl.java:1487
android.view.ViewRootImpl$TraversalRunnable.run()ViewRootImpl.java:7450
android.view.Choreographer$CallbackRecord.run()Choreographer.java:920
android.view.Choreographer.doCallbacks()Choreographer.java:695
android.view.Choreographer.doFrame()Choreographer.java:631
android.view.Choreographer$FrameDisplayEventReceiver.run()Choreographer.java:906
android.os.Handler.handleCallback()Handler.java:739
android.os.Handler.dispatchMessage()Handler.java:95
android.os.Looper.loop()Looper.java:158
android.app.ActivityThread.main()ActivityThread.java:7229
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()ZygoteInit.java:1230
com.android.internal.os.ZygoteInit.main()ZygoteInit.java:1120
Comment 1 Jimmy [MSFT] 2017-03-16 14:45:25 UTC
Let me try reproducing this crash to confirm if it is a regression and I will update the report with my results.
Comment 2 Jimmy [MSFT] 2017-03-16 15:51:54 UTC
I was not able to reproduce this crash with the Xamarin.Forms-Monkeys CarouselView sample[1]. I ran the sample on an Android 6.0 emulator and was able to scroll through the CarouselView items successfully. I tested with the following versions:

Forms 2.3.4-pre5    GOOD
Forms 2.3.4-pre3    GOOD
Forms 2.3.4-pre2    GOOD
Forms 2.3.3.193     GOOD


Can you attach a sample, along with any necessary repro steps, so we can continue looking into this? Thanks!

[1] https://github.com/jamesmontemagno/Xamarin.Forms-Monkeys
Comment 3 Emman Vazz 2017-03-17 06:22:48 UTC
I am also experiencing this crash. Trying to create a sample repo that produces this crash for you.
Comment 4 Philipp Sumi 2017-03-17 18:38:17 UTC
I think I've seen that issue very, very rarely before, but never could repro it reliably. Hopefully, finding the code that can cause a DivideByZeroException won't be too hard - this smells like a robustness issue that is surfacing.
Comment 5 Philipp Sumi 2017-03-17 19:43:24 UTC
Btw: David mentioned that the development on the control has progressed a lot, so this may not be an issue in the first place anymore. Any idea on when we could get a hand on it? The GitHub version is so riddled with bugs and UX issues that it's a show stopper for a prod release.
Comment 6 Emman Vazz 2017-03-27 23:34:13 UTC
I just tried this with -pre6 and the crash still happens.
Comment 7 Philipp Sumi 2017-03-28 08:54:44 UTC
Xamarin, can we please have an update of that control? I guess I can speak for any developer when I say that I really don't care whether it's final or not - it's probably safe to say that this works more reliably than the old version on GitHub that prevents us from upgrading our XF installation :/
Comment 8 Philipp Sumi 2017-04-01 12:55:39 UTC
I guess it's this line here:

https://github.com/xamarin/Xamarin.Forms.CarouselView/blob/master/txt/src/carouselView/dev/Shared.Android/CarouselViewExtensions.cs#L267

int position = x / _itemSize.Width + positionOrigin;

That does look brittle - I guess all it takes is some rendering while the control hasn't calculated it's layout or isn't visible yet and thus doesn't have a width.
Comment 9 Philipp Sumi 2017-04-01 12:57:53 UTC
Or the mod operation below if itemSize.Width is 0;

bool hasRemainder = x % _itemSize.Width != 0;
Comment 10 Philipp Sumi 2017-04-01 14:16:55 UTC
I think I found a repro: My Carousel is wrapped in a StackPanel like this:

            <!-- ride cards -->
            <StackLayout IsVisible="{Binding HasRides}"
                         VerticalOptions="FillAndExpand"
                         Grid.Row="1">
                
                <forms:CarouselView x:Name="RideCarousel"



That IsVisible binding is initially false, causing the CarouselView to be invisible too. This would cause the Width to be zero, and the rendering crash.
I can repro this by manually setting the visibility to true (no longer crashes) and false (crashes).

Setting this to confirmed.
Comment 11 Philipp Sumi 2017-04-01 15:14:55 UTC
Created attachment 21140 [details]
Repro with Monkeys project

Changes:

* referencing latest pre2
* updated to XF pre6
* wrapped the CarouselView into a StackPanel that isn't visible.

This crashes the app. If the StackPanel is made visible, it renders.
Comment 12 Emman Vazz 2017-04-05 22:18:54 UTC
My workaround was different. I handle the height of the CarouselView with a binding. I originally initialized the height to zero and changed it to one. That resolved the crash for me.
Comment 13 Dmitry 2017-04-16 19:50:40 UTC
I have this issue on 2.3.4.231 as well.
Comment 14 Chris King 2017-04-18 19:02:18 UTC
The GitHub CV will be deprecated shortly and replaced with the CV being pulled from https://github.com/xamarin/Xamarin.Forms/pull/853.