(gdb) frame 2
#2 0x0000000010167c2c in cache_inode_release_dirents (entry=0x3ff1907b5070, which=CACHE_INODE_AVL_NAMES)
at /usr/src/debug/nfs-ganesha-2.3.2-ibm59-0.1.1-Source/cache_inode/cache_inode_misc.c:804
804 avltree_remove(dirent_node, tree);
(gdb) p *dirent
$1 = {node_hk = {left = 0x0, right = 0x0, parent = 70347813813922}, hk = {k = 6039456505800813999, p = 0}, ckey = {
hk = 16814622367593888045, fsal = 0x3fff996b25f8 <GPFS>, kv = {addr = 0x3ffd3aaecce0, len = 40}}, flags = 0,
name = 0x3ffd39a9da8c "J2"}
(gdb) p *tree
$2 = {root = 0x3ffb2073fea0, cmp_fn = @0x10288238: 0x1016e834 <avl_dirent_hk_cmpf>, height = 1, first = 0x3ffb2073fea0,
last = 0x3ff70fab2120, size = 2}
(gdb) p *dirent_node
$3 = {left = 0x0, right = 0x0, parent = 70347813813922}
(gdb) frame 1
#1 0x000000001017f8f0 in avltree_remove (node=0x3ffb2073fea0, tree=0x3ff1907b5210)
at /usr/src/debug/nfs-ganesha-2.3.2-ibm59-0.1.1-Source/avl/avl.c:552
552 switch (get_balance(right)) {
(gdb) p *left
Cannot access memory at address 0x0
(gdb) p *right
Cannot access memory at address 0x0
(gdb) p *next
Cannot access memory at address 0x0
(gdb) p *tree
$4 = {root = 0x3ffb2073fea0, cmp_fn = @0x10288238: 0x1016e834 <avl_dirent_hk_cmpf>, height = 1, first = 0x3ffb2073fea0,
last = 0x3ff70fab2120, size = 2}
(gdb) p *parent
$5 = {left = 0x3ffb2073fea0, right = 0x0, parent = 70319593422913}
(gdb) p tree->root
$6 = (struct avltree_node *) 0x3ffb2073fea0
(gdb) p *tree->root
$7 = {left = 0x0, right = 0x0, parent = 70330352345380}
(gdb) p balance
$8 = 2
(gdb) p *node
$9 = {left = 0x0, right = 0x0, parent = 70330352345380}
When I checked the relevant code. I doubt on below code block:
if (is_left) {
is_left = parent && parent->left == node;
balance = inc_balance(node);
if (balance == 0) /* case 1 */
continue;
if (balance == 1) /* case 2 */
return;
right = node->right; /* case 3 */
switch (get_balance(right)) {
case 0: /* case 3.1 */
....
....
}
The block is for left side of the node/subtree (is_left is true), and we are actually trying to refer right side of the node/tree (which may be NULL, actually crash is due to NULL in the next line)
Does it mean that the block should be like :
if (! is_left) {
is_left = parent && parent->left == node;
balance = inc_balance(node);
if (balance == 0) /* case 1 */
continue;
if (balance == 1) /* case 2 */
return;
right = node->right; /* case 3 */
switch (get_balance(right)) {
case 0: /* case 3.1 */
....
....
}
Let me know if my understanding is incorrect.
--
with regards,
Sachin Punadikar