From 7c2f46ce3fa5b9fd1e4663c37f70806f9cd48558 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Wed, 7 Oct 2020 23:10:48 -0700 Subject: [PATCH] Collect extra logging if ReactViewGroup.dispatchDraw crashes Summary: dispatchDraw, dispatchGetDisplayList, updateDisplayListIfDirty, recreateChildDisplayList, etc, can all crash internally for a variety of reasons and it can be very tricky to track down the root cause. This isn't a fix, this just adds extra logging to hopefully make debugging easier. Changelog: [Internal] Reviewed By: shergin Differential Revision: D24166149 fbshipit-source-id: 1bbaf34a92a9bcac5a594a25522c66e6e0cc80ca --- .../react/views/view/ReactViewGroup.java | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index f8fc85cf582..7d26307e249 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -23,6 +23,7 @@ import android.os.Build; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewParent; import android.view.ViewStructure; import android.view.animation.Animation; import androidx.annotation.Nullable; @@ -674,9 +675,40 @@ public class ReactViewGroup extends ViewGroup try { dispatchOverflowDraw(canvas); super.dispatchDraw(canvas); - } catch (NullPointerException e) { - FLog.e(TAG, "NullPointerException when executing ViewGroup.dispatchDraw method", e); - } catch (StackOverflowError e) { + } catch (NullPointerException | StackOverflowError e) { + // Catch errors and log additional diagnostics to logcat for debugging + FLog.e( + TAG, + "Exception thrown when executing ReactViewGroup.dispatchDraw method on ReactViewGroup[" + + getId() + + "]", + e); + + // Log all children of view, if any + FLog.e(TAG, "Child List:"); + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + FLog.e( + TAG, + "Child #" + + i + + ": " + + (child != null ? child.getId() : -1337) + + " - " + + (child != null ? child.toString() : "")); + } + + // Log all ancestors of view + ViewParent viewParent = getParent(); + FLog.e(TAG, "Ancestor List:"); + while (viewParent != null) { + ViewGroup parentViewGroup = + (viewParent instanceof ViewGroup ? (ViewGroup) viewParent : null); + int parentViewGroupId = (parentViewGroup != null ? parentViewGroup.getId() : -1337); + FLog.e(TAG, "Ancestor[" + parentViewGroupId + "]: " + viewParent.toString()); + viewParent = viewParent.getParent(); + } + // Adding special exception management for StackOverflowError for logging purposes. // This will be removed in the future. RootView rootView = RootViewUtil.getRootView(ReactViewGroup.this);