Page MenuHome

Fix crash when removing sockets used by internal link
AbandonedPublic

Authored by Jake (Welp) on Jan 5 2022, 12:54 AM.

Details

Summary

Fixes T94534

If a socket of a group node was removed and the socket was part of an internal link, updating the internal links would crash. Add a check to immediately rebuild internal links if it hits a broken link. Remove conflicting asserts.

Diff Detail

Repository
rB Blender
Branch
fix-internallink (branched from master)
Build Status
Buildable 19764
Build 19764: arc lint + arc unit

Event Timeline

Jake (Welp) requested review of this revision.Jan 5 2022, 12:54 AM
Jake (Welp) created this revision.

Can you check to see if this also fixes T94610. It seems that was a duplicate but it would be good to check there as well.

@Jesse Yurkovich (deadpin) Yeah, It's the same issue, just in a debug build. No crash with this patch

It's not clear to me yet that adding a null check here is the proper fix. Maybe I don't understand the situation well enough yet. I'm mainly wondering how the invalid internal link was able to persist long enough to cause a problem here.

Maybe it's because before the node tree update refactor, NodeTreeRef was never used in a situation with an invalid tree (maybe the update process used to fix these invalid internal links), now it does, but NodeTreeRef assumes they are valid.

I think that explanation probably makes sense. @Jacques Lucke (JacquesLucke) would know for sure though.

source/blender/nodes/NOD_node_tree_ref.hh
728

This function name seems quite generic, and could be confused with other things, like bNodeTreeType::validate_link for example. It could get a more specific name and/or a comment.

Maybe it's because before the node tree update refactor, NodeTreeRef was never used in a situation with an invalid tree (maybe the update process used to fix these invalid internal links), now it does, but NodeTreeRef assumes they are valid.

That's kind of what I was thinking. It looks like before the refactor it would just clear and rebuild the internal links list without checking them first, so it didn't need NodeTreeRef.

I think the error happens earlier already. When the NodeTreeRef is built, the internal links are in an invalid state.
What do you think about this patch as an alternative:

diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index f32db41f62d..42245e125d3 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -1985,6 +1985,14 @@ void nodeRemoveSocketEx(struct bNodeTree *ntree,
     }
   }
 
+  LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &node->internal_links) {
+    if (link->fromsock == sock || link->tosock == sock) {
+      BLI_remlink(&node->internal_links, link);
+      MEM_freeN(link);
+      BKE_ntree_update_tag_node_internal_link(ntree, node);
+    }
+  }
+
   /* this is fast, this way we don't need an in_out argument */
   BLI_remlink(&node->inputs, sock);
   BLI_remlink(&node->outputs, sock);

I think the error happens earlier already. When the NodeTreeRef is built, the internal links are in an invalid state.
What do you think about this patch as an alternative:

That seems to work. I was worried altering the internal links list outside of the existing function would be bad form.

Jake (Welp) abandoned this revision.Jan 8 2022, 5:56 PM