https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111731

            Bug ID: 111731
           Summary: [13/14 regression] gcc_assert is hit at
                    libgcc/unwind-dw2-fde.c#L291
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libgcc
          Assignee: unassigned at gcc dot gnu.org
          Reporter: crazylht at gmail dot com
  Target Milestone: ---

The issue is not solved by PR110956'fix.

I did some debugging with gdb, and here are the logs:

The first time gdb stop at
https://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-dw2-fde.c#L143

│   138           ob->next = unseen_objects;                                    
│   139           unseen_objects = ob;                                          
│   140                                                                         
│   141           __gthread_mutex_unlock (&object_mutex);                       
│   142         #endif                                                          
│  >143         }            

(gdb) frame
#0  __register_frame_info_bases (begin=0x7fffd551e000, ob=0x1e386d0, tbase=0x0,
dbase=0x0) at ../../../libgcc/unwind-dw2-fde.c:143
(gdb) p registered_frames->root->entry_count
$31 = 2
(gdb) p registered_frames->root->content.entries[0]
$32 = {base = 140736772300800, size = 1, ob = 0x1e386d0}
(gdb) p registered_frames->root->content.entries[1]
$33 = {base = 140736772317184, size = 178483158, ob = 0x1e386d0}

The second time gdb stop at
https://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-dw2-fde.c#L143

│   138           ob->next = unseen_objects;                                    
│   139           unseen_objects = ob;                                          
│   140                                                                         
│   141           __gthread_mutex_unlock (&object_mutex);                       
│   142         #endif                                                          
│  >143         }    

(gdb) frame
#0  __register_frame_info_bases (begin=0x7fffd409c000, ob=0x26b2e00, tbase=0x0,
dbase=0x0) at ../../../libgcc/unwind-dw2-fde.c:143
(gdb) p registered_frames->root->entry_count
$34 = 4
(gdb) p registered_frames->root->content.entries[0]
$35 = {base = 140736750796800, size = 1, ob = 0x26b2e00}
(gdb) p registered_frames->root->content.entries[1]
$36 = {base = 140736750817280, size = 199987168, ob = 0x26b2e00}
(gdb) p registered_frames->root->content.entries[2]
$37 = {base = 140736772300800, size = 1, ob = 0x1e386d0}
(gdb) p registered_frames->root->content.entries[3]
$38 = {base = 140736772317184, size = 178483158, ob = 0x1e386d0}

The first time gdb stop at unexpected line
https://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-dw2-btree.h#L829:

│   825           unsigned slot = btree_node_find_leaf_slot (iter, base);       
│   826           if ((slot >= iter->entry_count) ||
(iter->content.entries[slot].base != base))                                     
│   827             {                                                           
│   828               // Not found, this should never happen.                   
│  >829               btree_node_unlock_exclusive (iter);                       
│   830               return NULL;                                              
│   831             } 

(gdb) p slot
$26 = 1
(gdb) p iter->content.entries[slot]
$27 = {base = 140736750817280, size = 199987168, ob = 0x26e7900}
(gdb) p iter->content.entries[2]
$28 = {base = 140736772300800, size = 1, ob = 0x1e386d0}
We can see that when we try to remove btree node of
0x7fffd551e000(140736772300800).

 The return value of btree_node_find_leaf_slot is 1, but I think it should
return 2. 


Both btree_insert and btree_remove will call

// Find the position for a slot in a leaf node.
static unsigned
btree_node_find_leaf_slot (const struct btree_node *n, uintptr_type value)
{
  for (unsigned index = 0, ec = n->entry_count; index != ec; ++index)
   if (n->content.entries[index].base + n->content.entries[index].size > value) 
     return index;
  return n->entry_count;
} 


But

registered_frames->root->content.entries[1].base +
registered_frames->root->content.entries[1].size >
registered_frames->root->content.entries[2].base

registered_frames->root->content.entries[2].base +
registered_frames->root->content.entries[2].size >
registered_frames->root->content.entries[1].base 

and it makes btree_node_find_leaf_slot return wrong slot(at btree_insert, it
will return slot 1 for base1, and move base2 to slot2, but at btree_remove, it
still return slot 1 bacause of upper logic), I'm not sure if this is the
rootcause.

Reply via email to