现象
reopen 一个已填充的 shm arena 后,对已存在的 key 做覆盖写(kvspace_set 命中 shm_set_raw 的 old→sbo_free + sbo_alloc 路径),在大量覆盖写翻搅后触发 slotsboxmalloc 内部损坏,sbo_alloc 在 blocks_alloc 里死循环(100% CPU)。
slotsboxmalloc 侧根因见 array2d/slotsboxmalloc 对应 issue(下降到越界 slot_id 的 box → 取到全 0xFF 的 pool meta → spin_lock 无限自旋)。本 issue 记录 kvspace-c 侧的触发路径与可疑点。
触发链
kvlang 两阶段:kvlanglayout 先把 stdlib 写进 shm(创建 arena),随后 runtime kvlang boot 时再次 layout 同一份 stdlib 到同一个 shm(reopen)。redis 后端下这是幂等 SET,无害;shm 下每次覆盖走:
// shm_set_raw (src/kvspace.c:945)
if (old && old->has_value) sbo_free(kv->sbo_meta, old->box_offset);
uint64_t off = sbo_alloc(kv->sbo_meta, val_len);
约 900 个 key 逐个 free+realloc,翻搅出 slotsbox 树的损坏。
复现
cd kvlang
SHM=/tmp/x.shm; rm -f $SHM
./bin/kvlanglayout stdlib/string.kv shm://$SHM # rc=0
KVSPACE=shm://$SHM ./bin/kvlang test # reopen + 覆盖写 → 挂
- 全新 arena 单次写:正常(
kvlang hello.kv 到 “bootstrap test 失败”)。
- reopen + 覆盖写:挂。
可疑点 / 待确认
-
kvspaceShmOpen 创建路径 data_size 校验不足(src/kvspace.c:696-700):只检查 2 的幂,未检查 sbo_init 要求的 8×64ᵏ(power-of-64)。当前调用方传的是 128MB(=8×64⁴,恰好合法),但非 64 的幂的 2 的幂会让 sbo_init 静默返回 -1、arena 半初始化,set 时同样炸。建议 create 路径与 sbo_init 对齐校验,失败即报错而非继续。
-
覆盖写路径是否让 slotsbox 进入病态复用:shm_set_raw 的 free+alloc 序列是触发 slotsbox 损坏的直接输入。需与 slotsboxmalloc issue 联合定位——若确认为 slotsbox 内部 bug,kvspace-c 侧至少应在 sbo_alloc 返回 -1 时有明确报错路径(现在 off==-1 直接 return -1,但死循环发生在 sbo_alloc 内部、根本回不来)。
-
两阶段是否应重复 layout stdlib 到 shm:runtime boot 重新 layout 已在 kvspace 中的 stdlib,纯属冗余覆盖写。可考虑 boot 时检测 stdlib 已存在则跳过 re-layout(这条属 kvlang runtime 设计,非本仓,但它是本 bug 的放大器,记此备查)。
环境:Linux x86_64;libkvspace-c.so.1 74936B;slotsboxmalloc 24024B;blockmalloc 0.1.1。
现象
reopen 一个已填充的 shm arena 后,对已存在的 key 做覆盖写(
kvspace_set命中shm_set_raw的old→sbo_free+sbo_alloc路径),在大量覆盖写翻搅后触发 slotsboxmalloc 内部损坏,sbo_alloc在blocks_alloc里死循环(100% CPU)。slotsboxmalloc 侧根因见 array2d/slotsboxmalloc 对应 issue(下降到越界
slot_id的 box → 取到全 0xFF 的 pool meta →spin_lock无限自旋)。本 issue 记录 kvspace-c 侧的触发路径与可疑点。触发链
kvlang 两阶段:
kvlanglayout先把 stdlib 写进 shm(创建 arena),随后 runtimekvlangboot 时再次 layout 同一份 stdlib 到同一个 shm(reopen)。redis 后端下这是幂等 SET,无害;shm 下每次覆盖走:约 900 个 key 逐个 free+realloc,翻搅出 slotsbox 树的损坏。
复现
kvlang hello.kv到 “bootstrap test 失败”)。可疑点 / 待确认
kvspaceShmOpen创建路径 data_size 校验不足(src/kvspace.c:696-700):只检查 2 的幂,未检查sbo_init要求的 8×64ᵏ(power-of-64)。当前调用方传的是 128MB(=8×64⁴,恰好合法),但非 64 的幂的 2 的幂会让sbo_init静默返回 -1、arena 半初始化,set时同样炸。建议 create 路径与sbo_init对齐校验,失败即报错而非继续。覆盖写路径是否让 slotsbox 进入病态复用:
shm_set_raw的 free+alloc 序列是触发 slotsbox 损坏的直接输入。需与 slotsboxmalloc issue 联合定位——若确认为 slotsbox 内部 bug,kvspace-c 侧至少应在sbo_alloc返回 -1 时有明确报错路径(现在off==-1直接return -1,但死循环发生在sbo_alloc内部、根本回不来)。两阶段是否应重复 layout stdlib 到 shm:runtime boot 重新 layout 已在 kvspace 中的 stdlib,纯属冗余覆盖写。可考虑 boot 时检测 stdlib 已存在则跳过 re-layout(这条属 kvlang runtime 设计,非本仓,但它是本 bug 的放大器,记此备查)。
环境:Linux x86_64;libkvspace-c.so.1 74936B;slotsboxmalloc 24024B;blockmalloc 0.1.1。