Commit e0a661af authored by Aaron Leventhal's avatar Aaron Leventhal Committed by Commit Bot

Add some crash debugging checks

Bug: 1065122
Change-Id: I2d73a5d5d1e9ed59f26afe10fcce421572ca7fe6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2147813Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#758849}
parent db19268d
...@@ -180,6 +180,8 @@ class AXTreeSerializer { ...@@ -180,6 +180,8 @@ class AXTreeSerializer {
// like when Reset() is called. // like when Reset() is called.
void InternalReset(); void InternalReset();
ClientTreeNode* GetClientTreeNodeParent(ClientTreeNode* obj);
// The tree source. // The tree source.
AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree_; AXTreeSource<AXSourceNode, AXNodeData, AXTreeData>* tree_;
...@@ -269,7 +271,7 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor( ...@@ -269,7 +271,7 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
std::vector<ClientTreeNode*> client_ancestors; std::vector<ClientTreeNode*> client_ancestors;
while (client_node) { while (client_node) {
client_ancestors.push_back(client_node); client_ancestors.push_back(client_node);
client_node = client_node->parent; client_node = GetClientTreeNodeParent(client_node);
} }
// Start at the root. Keep going until the source ancestor chain and // Start at the root. Keep going until the source ancestor chain and
...@@ -304,9 +306,12 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor( ...@@ -304,9 +306,12 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::LeastCommonAncestor(
// that we're inside of an invalid subtree that all needs to be // that we're inside of an invalid subtree that all needs to be
// re-serialized, so the LCA should be higher. // re-serialized, so the LCA should be higher.
ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node)); ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
while ( while (tree_->IsValid(node)) {
tree_->IsValid(node) && if (client_node) {
(!client_node || (client_node->parent && client_node->parent->invalid))) { ClientTreeNode* parent = GetClientTreeNodeParent(client_node);
if (!parent || !parent->invalid)
break;
}
node = tree_->GetParent(node); node = tree_->GetParent(node);
if (tree_->IsValid(node)) if (tree_->IsValid(node))
client_node = ClientTreeNodeById(tree_->GetId(node)); client_node = ClientTreeNodeById(tree_->GetId(node));
...@@ -326,12 +331,13 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>:: ...@@ -326,12 +331,13 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
int child_id = tree_->GetId(child); int child_id = tree_->GetId(child);
ClientTreeNode* client_child = ClientTreeNodeById(child_id); ClientTreeNode* client_child = ClientTreeNodeById(child_id);
if (client_child) { if (client_child) {
if (!client_child->parent) { ClientTreeNode* parent = client_child->parent;
if (!parent) {
// If the client child has no parent, it must have been the // If the client child has no parent, it must have been the
// previous root node, so there is no LCA and we can exit early. // previous root node, so there is no LCA and we can exit early.
*out_lca = tree_->GetNull(); *out_lca = tree_->GetNull();
return true; return true;
} else if (client_child->parent->id != id) { } else if (parent->id != id) {
// If the client child's parent is not this node, update the LCA // If the client child's parent is not this node, update the LCA
// and return true (reparenting was found). // and return true (reparenting was found).
*out_lca = LeastCommonAncestor(*out_lca, client_child); *out_lca = LeastCommonAncestor(*out_lca, client_child);
...@@ -366,6 +372,19 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::ClientTreeNodeById( ...@@ -366,6 +372,19 @@ AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::ClientTreeNodeById(
return nullptr; return nullptr;
} }
template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
ClientTreeNode*
AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::GetClientTreeNodeParent(
ClientTreeNode* obj) {
ClientTreeNode* parent = obj->parent;
#if DCHECK_IS_ON()
if (!parent)
return nullptr;
DCHECK(ClientTreeNodeById(parent->id)) << "Parent not in id map.";
#endif // DCHECK_IS_ON()
return parent;
}
template <typename AXSourceNode, typename AXNodeData, typename AXTreeData> template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::SerializeChanges( bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::SerializeChanges(
AXSourceNode node, AXSourceNode node,
...@@ -549,7 +568,7 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>:: ...@@ -549,7 +568,7 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
// above. If this happens, reset and return an error. // above. If this happens, reset and return an error.
ClientTreeNode* client_child = ClientTreeNodeById(new_child_id); ClientTreeNode* client_child = ClientTreeNodeById(new_child_id);
if (client_child && client_child->parent != client_node) { if (client_child && GetClientTreeNodeParent(client_child) != client_node) {
DVLOG(1) << "Illegal reparenting detected"; DVLOG(1) << "Illegal reparenting detected";
#if defined(ADDRESS_SANITIZER) #if defined(ADDRESS_SANITIZER)
// Wrapping this in ADDRESS_SANITIZER will cause it to run on // Wrapping this in ADDRESS_SANITIZER will cause it to run on
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment