I noticed that when I delete a node, the reference from parent node to deleted node remains to exist. Is this expected behavior or is it a bug?
e 8000x nodes with UA_Server_deleteNode(server, nodeid, true);
static char *nodeDisplayName(UA_NodeId *n)
{
static char buf[4097];
UA_LocalizedText dispname;
UA_StatusCode s = UA_Server_readDisplayName(server, *n, &dispname);
if (s)
{
sprintf(buf,"UA_Server_readDisplayName: 0x%x",s);
}
else
{
memcpy(buf,dispname.text.data,dispname.text.length);
buf[dispname.text.length] = '\0';
}
return buf;
}
static char spaces[] = " ";
static UA_StatusCode printnode(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void *handle)
{
if (isInverse)
return 0;
UA_NodeId hasTypeDefinition = UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION);
if (UA_NodeId_equal(&referenceTypeId,&hasTypeDefinition))
return 0;
intptr_t level = (intptr_t)handle;
printf("%.*s%s: ",(int)level,spaces,nodeDisplayName(&referenceTypeId));
printf("%s %s\n",nodeIdString(&childId),nodeDisplayName(&childId));
UA_Server_forEachChildNodeCall(server, childId, printnode, Handle(level+1));
return 0;
}
[...]
UA_Server_forEachChildNodeCall(server,nodeid,printnode,Handle(1));
[...]
On Monday, January 16, 2017 at 4:28:05 AM UTC-6, bostjan....@gmail.com wrote:I noticed that when I delete a node, the reference from parent node to deleted node remains to exist. Is this expected behavior or is it a bug?
Yes, I see the same thing (I'm using 0.2).
--- server_demo.c 2017-01-18 18:17:51.689206477 -0600
+++ server_demo-workaround.c 2017-01-18 18:17:11.635853665 -0600
@@ -112,25 +112,35 @@
}
void deleteChild(UA_NodeId *n, char *name)
{
UA_NodeId childid = UA_NODEID_STRING(1,name);
UA_StatusCode s = UA_Server_deleteNode(server,childid,true);
if (s)
printf("deleteChild: %08x\n",s);
}
+void deleteReference(UA_NodeId *n, char *name)
+{
+ UA_ExpandedNodeId childid = UA_EXPANDEDNODEID_STRING(1,name);
+ UA_StatusCode s = UA_Server_deleteReference(server, *n, UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), true, childid, false);
+ if (s)
+ printf("deleteReference: %08x\n",s);
+}
+
void deleteChildren(UA_NodeId *n)
{
printf("Deleting children...\n");
deleteChild(n,"the answer");
+ deleteReference(n,"the answer");
deleteChild(n,"other answer");
+ deleteReference(n,"other answer");
}
void showChildren(UA_NodeId *n)
{
printf("%s:\n",nodeDisplayName(n));
UA_Server_forEachChildNodeCall(server,*n,printnode,Handle(1));
}
int main(int argc, char** argv)
Fixed on master and 0.2.
static void deleteChildren_r(UA_NodeId *nodeid);
static UA_StatusCode deleteChildrenCallback(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void *handle)
{
if (isInverse)
return UA_STATUSCODE_GOOD;
UA_NodeId organizes = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
if (UA_NodeId_equal(&referenceTypeId,&organizes))
{
deleteChildren_r(&childId);
UA_Server_deleteNode(server,childId,true);
}
return UA_STATUSCODE_GOOD;
}
// recursive deletion of nodes that are "orgranized" by <nodid>
static void deleteChildren_r(UA_NodeId *nodeid)
{
UA_Server_forEachChildNodeCall(server,*nodeid,deleteChildrenCallback,NULL);
}
deleting children...
==18655== Invalid read of size 1
==18655== at 0x402BD0: fnv32 (ua_types.c:281)
==18655== by 0x402C59: UA_NodeId_hash (ua_types.c:295)
==18655== by 0x40D564: findNode (ua_nodestore.c:97)
==18655== by 0x40DD10: UA_NodeStore_remove (ua_nodestore.c:306)
==18655== by 0x414B15: Service_DeleteNodes_single (ua_services_nodemanagement.c:1185)
==18655== by 0x414C40: UA_Server_deleteNode (ua_services_nodemanagement.c:1216)
==18655== by 0x401B44: deleteChildrenCallback (server_demo.c:150)
==18655== by 0x40516A: UA_Server_forEachChildNodeCall (ua_server.c:128)
==18655== by 0x401B98: deleteChildren_r (server_demo.c:158)
==18655== by 0x401BC0: deleteChildren (server_demo.c:164)
==18655== by 0x401F07: main (server_demo.c:201)
==18655== Address 0x5234920 is 0 bytes inside a block of size 10 free'd
==18655== at 0x4C2D1CC: free (vg_replace_malloc.c:473)
==18655== by 0x4022EC: String_deleteMembers (ua_types.c:85)
==18655== by 0x4028E4: NodeId_deleteMembers (ua_types.c:194)
==18655== by 0x402CA1: ExpandedNodeId_deleteMembers (ua_types.c:304)
==18655== by 0x40468F: deleteMembers_noInit (ua_types.c:950)
==18655== by 0x40472A: UA_deleteMembers (ua_types.c:964)
==18655== by 0x41140D: UA_ReferenceNode_deleteMembers (ua_types_generated_handling.h:1474)
==18655== by 0x414D6F: deleteOneWayReference (ua_services_nodemanagement.c:1241)
==18655== by 0x41E2DF: UA_Server_editNode (ua_server_utils.c:262)
==18655== by 0x414EEA: Service_DeleteReferences_single (ua_services_nodemanagement.c:1260)
==18655== by 0x4149FA: removeReferences (ua_services_nodemanagement.c:1159)
==18655== by 0x414AFE: Service_DeleteNodes_single (ua_services_nodemanagement.c:1183)
==18655==
==18655== Invalid read of size 1
==18655== at 0x4C31FFC: __memcmp_sse4_1 (vg_replace_strmem.c:972)
==18655== by 0x4022BC: UA_String_equal (ua_types.c:78)
==18655== by 0x402B68: UA_NodeId_equal (ua_types.c:263)
==18655== by 0x40D5D9: findNode (ua_nodestore.c:107)
==18655== by 0x40DD10: UA_NodeStore_remove (ua_nodestore.c:306)
==18655== by 0x414B15: Service_DeleteNodes_single (ua_services_nodemanagement.c:1185)
==18655== by 0x414C40: UA_Server_deleteNode (ua_services_nodemanagement.c:1216)
==18655== by 0x401B44: deleteChildrenCallback (server_demo.c:150)
==18655== by 0x40516A: UA_Server_forEachChildNodeCall (ua_server.c:128)
==18655== by 0x401B98: deleteChildren_r (server_demo.c:158)
==18655== by 0x401BC0: deleteChildren (server_demo.c:164)
==18655== by 0x401F07: main (server_demo.c:201)
==18655== Address 0x5234920 is 0 bytes inside a block of size 10 free'd
==18655== at 0x4C2D1CC: free (vg_replace_malloc.c:473)
==18655== by 0x4022EC: String_deleteMembers (ua_types.c:85)
==18655== by 0x4028E4: NodeId_deleteMembers (ua_types.c:194)
==18655== by 0x402CA1: ExpandedNodeId_deleteMembers (ua_types.c:304)
==18655== by 0x40468F: deleteMembers_noInit (ua_types.c:950)
==18655== by 0x40472A: UA_deleteMembers (ua_types.c:964)
==18655== by 0x41140D: UA_ReferenceNode_deleteMembers (ua_types_generated_handling.h:1474)
==18655== by 0x414D6F: deleteOneWayReference (ua_services_nodemanagement.c:1241)
==18655== by 0x41E2DF: UA_Server_editNode (ua_server_utils.c:262)
==18655== by 0x414EEA: Service_DeleteReferences_single (ua_services_nodemanagement.c:1260)
==18655== by 0x4149FA: removeReferences (ua_services_nodemanagement.c:1159)
==18655== by 0x414AFE: Service_DeleteNodes_single (ua_services_nodemanagement.c:1183)
==18655==
==18655== Invalid read of size 1
==18655== at 0x4C32015: __memcmp_sse4_1 (vg_replace_strmem.c:972)
==18655== by 0x4022BC: UA_String_equal (ua_types.c:78)
==18655== by 0x402B68: UA_NodeId_equal (ua_types.c:263)
==18655== by 0x40D5D9: findNode (ua_nodestore.c:107)
==18655== by 0x40DD10: UA_NodeStore_remove (ua_nodestore.c:306)
==18655== by 0x414B15: Service_DeleteNodes_single (ua_services_nodemanagement.c:1185)
==18655== by 0x414C40: UA_Server_deleteNode (ua_services_nodemanagement.c:1216)
==18655== by 0x401B44: deleteChildrenCallback (server_demo.c:150)
==18655== by 0x40516A: UA_Server_forEachChildNodeCall (ua_server.c:128)
==18655== by 0x401B98: deleteChildren_r (server_demo.c:158)
==18655== by 0x401BC0: deleteChildren (server_demo.c:164)
==18655== by 0x401F07: main (server_demo.c:201)
==18655== Address 0x5234921 is 1 bytes inside a block of size 10 free'd
==18655== at 0x4C2D1CC: free (vg_replace_malloc.c:473)
==18655== by 0x4022EC: String_deleteMembers (ua_types.c:85)
==18655== by 0x4028E4: NodeId_deleteMembers (ua_types.c:194)
==18655== by 0x402CA1: ExpandedNodeId_deleteMembers (ua_types.c:304)
==18655== by 0x40468F: deleteMembers_noInit (ua_types.c:950)
==18655== by 0x40472A: UA_deleteMembers (ua_types.c:964)
==18655== by 0x41140D: UA_ReferenceNode_deleteMembers (ua_types_generated_handling.h:1474)
==18655== by 0x414D6F: deleteOneWayReference (ua_services_nodemanagement.c:1241)
==18655== by 0x41E2DF: UA_Server_editNode (ua_server_utils.c:262)
==18655== by 0x414EEA: Service_DeleteReferences_single (ua_services_nodemanagement.c:1260)
==18655== by 0x4149FA: removeReferences (ua_services_nodemanagement.c:1159)
==18655== by 0x414AFE: Service_DeleteNodes_single (ua_services_nodemanagement.c:1183)
==18655==
On Thursday, January 19, 2017 at 5:22:29 AM UTC-6, Julius Pfrommer wrote:Fixed on master and 0.2.
The dangling references are gone, but now I get valgrind errors that I didn't get before this fix.
The errors only seem to happen when I delete a node in a UA_Server_forEachChildNodeCall() callback function.
#define MaxNodeArray 64
typedef struct nodearray {
int n;
UA_NodeId nodes[MaxNodeArray];
} nodearray_t;
static UA_StatusCode listChildrenCallback(UA_NodeId childId, UA_Boolean isInverse, UA_NodeId referenceTypeId, void *handle)
{
if (isInverse)
return UA_STATUSCODE_GOOD;
UA_NodeId organizes = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
if (UA_NodeId_equal(&referenceTypeId,&organizes))
{
nodearray_t *nodearray = handle;
if (nodearray->n < MaxNodeArray)
{
UA_NodeId_copy(&childId,&nodearray->nodes[nodearray->n]);
nodearray->n++;
}
}
return UA_STATUSCODE_GOOD;
}
static void deleteChildren_r(UA_NodeId *nodeid)
{
nodearray_t nodes;
memset(&nodes,0,sizeof nodes);
UA_Server_forEachChildNodeCall(server,*nodeid,listChildrenCallback,&nodes);
for (int i=0; i<nodes.n; ++i)
{
deleteChildren_r(&nodes.nodes[i]);
UA_Server_deleteNode(server,nodes.nodes[i],true);
UA_NodeId_deleteMembers(nodes.nodes+i);
}
}
Wow. That took some time to figure out.
Fixed via https://github.com/open62541/open62541/commit/a22f371ee33d368f065621652dba95df95974469
This was an unfortunate situation where a reference is deleted from the array that is iterated over.