Skip to content

Commit

Permalink
Remove custom STUB_VIEW_ASSERT in favor of react_native_assert
Browse files Browse the repository at this point in the history
Summary:
We have a custom STUB_VIEW_ASSERT that helps debugging stub view issues on platforms (like iOS) where flushing logs around assert-time isn't 100% guaranteed.

Move that logic into react_native_assert since it's generally useful.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26567218

fbshipit-source-id: 79f5ae66fc65a0af48dbcf4c7204ac8245911cb0
  • Loading branch information
JoshuaGross authored and facebook-github-bot committed Feb 21, 2021
1 parent b3930f9 commit 1fe5cac
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 40 deletions.
16 changes: 14 additions & 2 deletions ReactCommon/react/debug/react_native_assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,22 @@ void react_native_assert_fail(

#else // __ANDROID__

#include <glog/logging.h>
#include <cassert>

#define react_native_assert(e) assert(e)
// For all platforms, but iOS+Xcode especially: flush logs because some might be
// lost on iOS if an assert is hit right after this. If you are trying to debug
// something actively and have added lots of LOG statements to track down an
// issue, there is race between flushing the final logs and stopping execution
// when the assert hits. Thus, if we know an assert will fail, we force flushing
// to happen right before the assert.
#define react_native_assert(cond) \
if (!(cond)) { \
LOG(ERROR) << "react_native_assert failure: " << #cond; \
google::FlushLogFiles(google::INFO); \
assert(cond); \
}

#endif // platforms besides __ANDROID__

#endif // NDEBUG
#endif // REACT_NATIVE_DEBUG
67 changes: 29 additions & 38 deletions ReactCommon/react/renderer/mounting/StubViewTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@
#include <glog/logging.h>
#include <react/debug/react_native_assert.h>

// For iOS especially: flush logs because some might be lost on iOS if an
// assert is hit right after this.
#define STUB_VIEW_ASSERT(cond) \
if (!(cond)) { \
LOG(ERROR) << "ASSERT FAILURE: " << #cond; \
google::FlushLogFiles(google::INFO); \
} \
react_native_assert(cond);

#ifdef STUB_VIEW_TREE_VERBOSE
#define STUB_VIEW_LOG(code) code
#else
Expand Down Expand Up @@ -52,74 +43,71 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
for (auto const &mutation : mutations) {
switch (mutation.type) {
case ShadowViewMutation::Create: {
STUB_VIEW_ASSERT(mutation.parentShadowView == ShadowView{});
STUB_VIEW_ASSERT(mutation.oldChildShadowView == ShadowView{});
STUB_VIEW_ASSERT(mutation.newChildShadowView.props);
react_native_assert(mutation.parentShadowView == ShadowView{});
react_native_assert(mutation.oldChildShadowView == ShadowView{});
react_native_assert(mutation.newChildShadowView.props);
auto stubView = std::make_shared<StubView>();
stubView->update(mutation.newChildShadowView);
auto tag = mutation.newChildShadowView.tag;
STUB_VIEW_LOG({ LOG(ERROR) << "StubView: Create: " << tag; });
STUB_VIEW_ASSERT(registry.find(tag) == registry.end());
react_native_assert(registry.find(tag) == registry.end());
registry[tag] = stubView;
break;
}

case ShadowViewMutation::Delete: {
STUB_VIEW_LOG(
{ LOG(ERROR) << "Delete " << mutation.oldChildShadowView.tag; });
STUB_VIEW_ASSERT(mutation.parentShadowView == ShadowView{});
STUB_VIEW_ASSERT(mutation.newChildShadowView == ShadowView{});
react_native_assert(mutation.parentShadowView == ShadowView{});
react_native_assert(mutation.newChildShadowView == ShadowView{});
auto tag = mutation.oldChildShadowView.tag;
/* Disable this assert until T76057501 is resolved.
STUB_VIEW_ASSERT(registry.find(tag) != registry.end());
react_native_assert(registry.find(tag) != registry.end());
auto stubView = registry[tag];
STUB_VIEW_ASSERT(
react_native_assert(
(ShadowView)(*stubView) == mutation.oldChildShadowView);
*/
registry.erase(tag);
break;
}

case ShadowViewMutation::Insert: {
STUB_VIEW_ASSERT(mutation.oldChildShadowView == ShadowView{});
react_native_assert(mutation.oldChildShadowView == ShadowView{});
auto parentTag = mutation.parentShadowView.tag;
STUB_VIEW_ASSERT(registry.find(parentTag) != registry.end());
react_native_assert(registry.find(parentTag) != registry.end());
auto parentStubView = registry[parentTag];
auto childTag = mutation.newChildShadowView.tag;
STUB_VIEW_ASSERT(registry.find(childTag) != registry.end());
react_native_assert(registry.find(childTag) != registry.end());
auto childStubView = registry[childTag];
STUB_VIEW_ASSERT(childStubView->parentTag == NO_VIEW_TAG);
react_native_assert(childStubView->parentTag == NO_VIEW_TAG);
childStubView->update(mutation.newChildShadowView);
STUB_VIEW_LOG({
LOG(ERROR) << "StubView: Insert: " << childTag << " into "
<< parentTag << " at " << mutation.index << "("
<< parentStubView->children.size() << " children)";
});
STUB_VIEW_ASSERT(parentStubView->children.size() >= mutation.index);
react_native_assert(parentStubView->children.size() >= mutation.index);
childStubView->parentTag = parentTag;
parentStubView->children.insert(
parentStubView->children.begin() + mutation.index, childStubView);
break;
}

case ShadowViewMutation::Remove: {
STUB_VIEW_ASSERT(mutation.newChildShadowView == ShadowView{});
react_native_assert(mutation.newChildShadowView == ShadowView{});
auto parentTag = mutation.parentShadowView.tag;
STUB_VIEW_ASSERT(registry.find(parentTag) != registry.end());
react_native_assert(registry.find(parentTag) != registry.end());
auto parentStubView = registry[parentTag];
auto childTag = mutation.oldChildShadowView.tag;
STUB_VIEW_LOG({
LOG(ERROR) << "StubView: Remove: " << childTag << " from "
<< parentTag << " at index " << mutation.index << " with "
<< parentStubView->children.size() << " children";
});
STUB_VIEW_ASSERT(parentStubView->children.size() > mutation.index);
STUB_VIEW_ASSERT(registry.find(childTag) != registry.end());
react_native_assert(parentStubView->children.size() > mutation.index);
react_native_assert(registry.find(childTag) != registry.end());
auto childStubView = registry[childTag];
STUB_VIEW_ASSERT(childStubView->parentTag == parentTag);
bool childIsCorrect =
parentStubView->children.size() > mutation.index &&
parentStubView->children[mutation.index]->tag == childStubView->tag;
react_native_assert(childStubView->parentTag == parentTag);
STUB_VIEW_LOG({
std::string strChildList = "";
int i = 0;
Expand All @@ -133,7 +121,10 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
LOG(ERROR) << "StubView: BEFORE REMOVE: Children of " << parentTag
<< ": " << strChildList;
});
STUB_VIEW_ASSERT(childIsCorrect);
react_native_assert(
parentStubView->children.size() > mutation.index &&
parentStubView->children[mutation.index]->tag ==
childStubView->tag);
childStubView->parentTag = NO_VIEW_TAG;
parentStubView->children.erase(
parentStubView->children.begin() + mutation.index);
Expand All @@ -144,16 +135,16 @@ void StubViewTree::mutate(ShadowViewMutationList const &mutations) {
STUB_VIEW_LOG({
LOG(ERROR) << "StubView: Update: " << mutation.newChildShadowView.tag;
});
STUB_VIEW_ASSERT(mutation.oldChildShadowView.tag != 0);
STUB_VIEW_ASSERT(mutation.newChildShadowView.tag != 0);
STUB_VIEW_ASSERT(mutation.newChildShadowView.props);
STUB_VIEW_ASSERT(
react_native_assert(mutation.oldChildShadowView.tag != 0);
react_native_assert(mutation.newChildShadowView.tag != 0);
react_native_assert(mutation.newChildShadowView.props);
react_native_assert(
mutation.newChildShadowView.tag == mutation.oldChildShadowView.tag);
STUB_VIEW_ASSERT(
react_native_assert(
registry.find(mutation.newChildShadowView.tag) != registry.end());
auto oldStubView = registry[mutation.newChildShadowView.tag];
STUB_VIEW_ASSERT(oldStubView->tag != 0);
STUB_VIEW_ASSERT(
react_native_assert(oldStubView->tag != 0);
react_native_assert(
(ShadowView)(*oldStubView) == mutation.oldChildShadowView);
oldStubView->update(mutation.newChildShadowView);
break;
Expand Down

0 comments on commit 1fe5cac

Please sign in to comment.