Crash when unlinking group with directly connected sockets
Closed, ResolvedPublic

Description

Exact steps for others to reproduce the error

  1. Unpack attached blend-files
  2. Open 1.blend
  3. Press the the "unlink" button
  4. Press Alt-G to ungroup
  5. Crash!

A brief research shows that if you add reroute in group between "Normal" sockets, the crash disappears

Germano Cavalcante (mano-wii) triaged this task as "Confirmed" priority.EditedJul 17 2017, 5:45 PM

I don't know if it is related to the same bug, but I could simplify the file even more (no link):

I Debug Build works.

I noticed that Debug differs from Release in nodeAddLink of line 322 of file node_group.c

But in Debug it seems to be working incorrectly because it uses values from a sock already freed

Seems that this is a use-after free bug, delaying the free fixes:

diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 914f8ffbe10..23c0cb196dc 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -37,6 +37,7 @@
 #include "DNA_anim_types.h"
 
 #include "BLI_listbase.h"
+#include "BLI_linklist.h"
 #include "BLI_math.h"
 
 #include "BLT_translation.h"
@@ -186,6 +187,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
 	bNode *node, *nextnode;
 	bNodeTree *ngroup, *wgroup;
 	ListBase anim_basepaths = {NULL, NULL};
+	LinkNode *group_delayed_free = NULL;
 	
 	ngroup = (bNodeTree *)gnode->id;
 	
@@ -208,8 +210,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
 		 * This also removes remaining links to and from interface nodes.
 		 */
 		if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
-			nodeFreeNode(wgroup, node);
-			continue;
+			BLI_linklist_prepend(&group_delayed_free, node);
 		}
 		
 		/* keep track of this node's RNA "base" path (the part of the path identifying the node) 
@@ -336,6 +337,11 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
 		}
 	}
 	
+	while (group_delayed_free) {
+		node = BLI_linklist_pop(&group_delayed_free);
+		nodeFreeNode(ntree, node);
+	}
+
 	/* delete the group instance */
 	nodeFreeNode(ntree, gnode);