facebook / facebook/litho

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

Open
#927 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
7.8k
Forks
768
PR merge metrics
No merged PRs in 30d

Description

- [x] I have searched [existing issues](https://github.com/facebook/litho/issues) and this is not a duplicate

## 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?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.