Skip to content

shm reopen 后 sbo_alloc 在 blocks_alloc 死循环:下降到越界 slot_id 的 box → 全 0xFF pool meta 上自旋 #1

Description

@miaobyte

现象

在 shm 后端复用(reopen)已填充的 arena 后继续写入时,sbo_allocblocks_alloc用户态 100% CPU 死循环,永不返回。gdb 显示进程稳定卡在 blocks_allocspin_lock cmpxchg 循环里。

调用栈(gdb,稳定复现)

#0 blocks_alloc            (libblockmalloc)  ← spin_lock(&meta->lock) 死转
#1 sbo_find_alloc          (深度 3)
#2 sbo_find_alloc
#3 sbo_find_alloc
#4 sbo_alloc
#5 shm_set_raw             (kvspace-c)
   ... kvspaceSet -> 上层

反汇编确认 #0 停在 spin_lockpause/xchg/test %rdx,%rdx/jne 自旋序列。

根因(已定位)

传给 blocks_allocblocks_meta_t全 0xFF 的未初始化内存

total_size    = 0xFFFFFFFFFFFFFFFF (-1)
malloc_blocks = -1
free_next_id  = -1
lock          = 1        ← 读到非零“锁”,自旋永远抢不到

地址换算:该 meta 落在 sbo_meta 区内偏移 +0x7e0(2016B),即 sbo_pool_meta(meta, si) 的结果。而本 arena:

  • data_size = 134217728 (128MB = 8×64⁴)
  • sbo_align_to(16777216) = {level=5, multiple=1}root_slots = 1

只有 si=0 一个合法 pool。但被下降到的 box 的 slot_id ≈ 40(由 +0x7e0 偏移反推),sbo_pool_meta(meta, 40) 越过 slot_pools[1] 数组、读到未初始化区域 → 全 0xFF meta。

sbo_find_alloc 里两处 sbo_pool_meta(meta, box->slot_id) / sbo_pool_mem(...)(约 slotsboxobj.h:400-401、216-223)信任 box->slot_id。当树在 free + 重新 alloc 翻搅下某个被下降的 box 的 slot_id 变成越界值时,就会取到垃圾 pool。

触发条件

  • 全新 arena 单次写入:正常(所有 key 都是新 alloc,无 free)。
  • reopen 已填充 arena 后重写同一批 key:挂(约 900 个 key 各做一次 sbo_free+sbo_alloc)。

fresh 无 free,reopen 有大量 free+realloc 翻搅——差异点即 sbo_free/复用路径与 box 树状态维护。

两个应修的问题

  1. 正确性(主):free + realloc 翻搅后,被 sbo_find_alloc 下降的 box 出现越界 slot_id(root_slots=1 时任何非 0 都非法)。需查 sbo_free_obj_slots / sbo_update_parent / children[] / sbo_child 在复用路径下是否会写坏 box 或 slot_id。注:sbo_free_obj_slots/sbo_alloc_obj_slotsif (box->parent > 0) 对 root(parent=0)与「parent 恰为 block 0」的子节点语义有歧义(0 既表示 root 又表示 block-id 0),疑点之一。

  2. 健壮性(纵深防御)blocks_alloc/spin_lock 对未初始化/损坏的 meta(magic 或 total_size 越界)无任何校验,直接在垃圾 lock 上无限自旋,而非返回 -1 或断言失败。建议 sbo_find_allocsbo_pool_meta 前校验 box->slot_id < meta->root_slotsblocks_alloc 入口对 meta 做基本合法性检查(如 total_size 合理、magic)。

复现

cd kvlang
SHM=/tmp/x.shm; rm -f $SHM
./bin/kvlanglayout stdlib/string.kv shm://$SHM          # rc=0,写入 stdlib
KVSPACE=shm://$SHM ./bin/kvlang test                    # reopen + 重 layout stdlib → 挂

环境:Linux x86_64;slotsboxmalloc.so 24024B;blockmalloc 0.1.1。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions