litho icon indicating copy to clipboard operation
litho copied to clipboard

NullPointerException in TextDrawable.Draw, seemingly from a race condition in ComponentHost$InterleavedDispatchDraw

Open cable729 opened this issue 3 years ago • 0 comments

Version

We are using quite an old version: v2021.10.25

Description

Stack trace:

12-27 22:03:35.873 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Canvas.save()' on a null object reference
12-27 22:03:35.873 E AndroidRuntime:    at com.facebook.litho.widget.TextDrawable.draw(TextDrawable.java:120)
12-27 22:03:35.873 E AndroidRuntime:    at com.facebook.litho.ComponentHost$InterleavedDispatchDraw.drawNext(ComponentHost.java:1406)
12-27 22:03:35.873 E AndroidRuntime:    at com.facebook.litho.ComponentHost$InterleavedDispatchDraw.-$$Nest$mdrawNext(ComponentHost.java:0)
12-27 22:03:35.873 E AndroidRuntime:    at com.facebook.litho.ComponentHost.getChildDrawingOrder(ComponentHost.java:800)
12-27 22:03:35.873 E AndroidRuntime:    at android.view.ViewGroup.getAndVerifyPreorderedIndex(ViewGroup.java:2097)
12-27 22:03:35.873 E AndroidRuntime:    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4287)
12-27 22:03:35.873 E AndroidRuntime:    at com.facebook.litho.ComponentHost.dispatchDraw(ComponentHost.java:749)
12-27 22:03:35.873 E AndroidRuntime:    at android.view.View.draw(View.java:23220)

Now, TextDrawable.draw(Canvas) is being passed a null canvas from ComponentHost$InterleavedDispatchDraw.-$$Nest$mdrawNext. That method checks that mcanvas != null, otherwise it returns. The only thing setting mCanvas to null is ComponentHost$InterleavedDispatchDraw.-$$Nest$mend. So it seems another thread is calling end() while drawNext() is in process.

Possible Fixes

  • Should end() call isRunning() and abort if it's still running? If so, callers would have to retry `end()
  • Should InterleavedDispatchDraw synchronize itself?

cable729 avatar Jan 12 '23 19:01 cable729