Reputation: 19
I am traversing a HB tree. I am passing a pointer that contains root node address. In subsequent function call my argument (root) is modified.
Can someone help what could be a possible reason for this?
static inline hbt_node_t *
hbt_descendent (hbt_node_t *node, uintptr_t dir)
{
hbt_node_t *desc;
uintptr_t value;
switch (dir) {
case HBT_MINUS:
desc = (hbt_node_t *)(node->hbt_data[0] & ~HBT_SIGN_MASK);
break;
case HBT_PLUS:
value = node->hbt_data[1];
if (!BIT_ISSET(value, HBT_NEXT)) {
desc = (hbt_node_t *)(value);
} else {
desc = NULL;
}
break;
default:
assert(FALSE);
desc = NULL;
}
return (desc);
}
/*
* hbt_find_leftmost
*
*/
static inline hbt_node_t *
hbt_find_leftmost (hbt_node_t *node)
{
hbt_node_t *next;
while (TRUE) {
next = hbt_descendent(node, HBT_MINUS);
if (next == NULL) {
break;
}
node = next;
}
return (node);
}
/*
* hbt_iterate_next
*
* Find the successor of a given node. Node must be present in the tree.
*/
hbt_node_t *
hbt_iterate_next (hbt_node_t *root, hbt_node_t *current)
{
hbt_node_t *node;
boolean climb;
if (current == NULL) {
if (root == NULL) {
return (NULL);
}
node = hbt_find_leftmost(root);
if (node) {
return (node);
}
}
node = hbt_node_next(current, &climb);
if (node && !climb) {
node = hbt_find_leftmost(node);
}
return (node);
}
As per backtrace:
(gdb) bt
#0 hbt_descendent (node=0x5a5a5a58, dir=3) at ../../../../../../src/dsa/lib/hbtree/hbtree.c:59
#1 hbt_find_leftmost (node=0x5a5a5a58) at ../../../../../../src/dsa/lib/hbtree/hbtree.c:775
#2 hbt_iterate_next (root=0x3494224, current=0x0) at ../../../../../../src/dsa/lib/hbtree/hbtree.c:800
#3 0x00b43ca2 in vlan_config_delete_one (vconf=0x37b9738) at ../../../../../../src/junos/usr.sbin/l2cpd/stp/vlan_config.c:803
(gdb) f 3
#3 0x00b43ca2 in vlan_config_delete_one (vconf=0x37b9738) at ../../../../../../src/junos/usr.sbin/l2cpd/stp/vlan_config.c:803
803 hnode = hbt_iterate_next(vconf->vc_voipiflist, NULL);
(gdb) p vconf->vc_voipiflist
$8 = (hbt_node_t *) 0x3494224
This is how application is using this
hnode = hbt_iterate_next(vconf->vc_voipiflist, NULL);
vc_voipiflist is of type hbt_node_t
Root = 0x3494224 , same root is passed to hbt_find_leftmost with argument as node = 0x5a5a5a58. This is corrupted causing SIGSEGV.
PS: This HB tree implementation is part of the library and has been there for years ~20 yrs. Don't think there is an issue with this code.
Upvotes: 0
Views: 45