fix(mlirlitetest): 子池改在 main 帧内构造,修复返回本帧栈对象指针导致的悬空写穿
现象:Test 1 第一次 alloc 就报 memhub "_split_to_order max_order 非法(字段被写穿): max_order=450754216 usable_size=2096864"(子池对象只有 max_order 是垃圾、相邻字段正常)。 静态查 IR 定根因(temp/a2/a2d629ccc917eaa6.ll):_sub_pool 内 %13 = alloca %MemBuddy,__before_init__/__init__ 都作用在这个栈对象上,最后 ret %MemBuddy* —— Viper 中无 __new__ 的类实例是值语义(降级为栈 alloca),返回"指向本帧局部对象"的指针即悬空;调用方第一次 alloc 读 max_order 落到复用后的栈垃圾。 修复:删掉返回 MemBuddy* 的 _sub_pool 助手,改为在 main 帧内逐测试构造子池(与原代码在 main 建池同款;main 内同样的 alloca %MemBuddy 一直有效,故原版能跑到 Test 14)。
This commit is contained in:
1 parent
ceccd4aa1e
commit
4203b4754f
1 file changed
+54
-35
+54
-35
@@ -1451,28 +1451,10 @@ def test_extractvalue_multi_asm(pool: memhub.MemBuddy | t.CPtr):
|
||||
"extractvalue result not referenced")
|
||||
|
||||
|
||||
def _sub_pool(main_pool: memhub.MemBuddy | t.CPtr) -> memhub.MemBuddy | t.CPtr:
|
||||
"""从主池切一块子池给单个测试用(伙伴分配器返回 2 的幂块,可直接作 arena)
|
||||
|
||||
每个测试在自己的子池里分配:测试内的 IR 对象与渲染器每函数重分配的
|
||||
scratch/常量表都落在子池,互不叠加(理由见 SUB_POOL_SIZE 注释)。子池不
|
||||
单独回收——主池按"每个测试一块"给足,测试进程短命。
|
||||
"""
|
||||
mem: rawptr = main_pool.alloc(SUB_POOL_SIZE)
|
||||
if mem is None:
|
||||
stdio.printf("FAIL: sub pool alloc failed (raise POOL_SIZE)\n")
|
||||
stdlib.exit(1)
|
||||
sub: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(mem, SUB_POOL_SIZE)
|
||||
if sub is None:
|
||||
stdio.printf("FAIL: sub pool MemBuddy init failed\n")
|
||||
stdlib.exit(1)
|
||||
return sub
|
||||
|
||||
|
||||
def main() -> int:
|
||||
testcheck.begin("MLIRLiteTest: mlirlite 库(MLIR llvm 方言文本生成)")
|
||||
|
||||
# 初始化主池:仅用于切子池(测试内分配一律走各自的子池)
|
||||
# 初始化主池:仅用于给每个测试切子池(测试内分配一律走各自的子池)
|
||||
pool_mem: bytes = stdlib.malloc(POOL_SIZE)
|
||||
if pool_mem is None:
|
||||
stdio.printf("FAIL: malloc for pool failed\n")
|
||||
@@ -1482,21 +1464,58 @@ def main() -> int:
|
||||
stdio.printf("FAIL: memhub.MemBuddy init failed\n")
|
||||
return 1
|
||||
|
||||
test_type_print(_sub_pool(pool))
|
||||
test_value_print(_sub_pool(pool))
|
||||
test_build_add(_sub_pool(pool))
|
||||
test_build_if_else(_sub_pool(pool))
|
||||
test_build_void(_sub_pool(pool))
|
||||
test_module_print(_sub_pool(pool))
|
||||
test_const_materialize(_sub_pool(pool))
|
||||
test_phi_block_args(_sub_pool(pool))
|
||||
test_mem_call_cast(_sub_pool(pool))
|
||||
test_globals(_sub_pool(pool))
|
||||
test_verify_valid(_sub_pool(pool))
|
||||
test_struct_global(_sub_pool(pool))
|
||||
test_alloca_align_switch_asm(_sub_pool(pool))
|
||||
test_vararg_vaarg_cmpxchg(_sub_pool(pool))
|
||||
test_named_struct(_sub_pool(pool))
|
||||
test_extractvalue_multi_asm(_sub_pool(pool))
|
||||
# 子池必须在 **main 的帧内** 构造:Viper 中无 __new__ 的类实例是值语义,
|
||||
# `MemBuddy(...)` 被降级为栈 alloca;若把它放进"返回 MemBuddy*"的助手函数,
|
||||
# 返回的就是**指向已销毁栈帧的指针**(IR 物证:_sub_pool 内
|
||||
# `%13 = alloca %MemBuddy` … `ret %MemBuddy* %28`),随后第一次 alloc 读
|
||||
# `max_order` 即落到复用的栈垃圾 → memhub 报
|
||||
# "_split_to_order max_order 非法(字段被写穿)"。故此处在 main 内逐测试构造。
|
||||
sub: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_type_print(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_value_print(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_build_add(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_build_if_else(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_build_void(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_module_print(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_const_materialize(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_phi_block_args(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_mem_call_cast(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_globals(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_verify_valid(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_struct_global(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_alloca_align_switch_asm(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_vararg_vaarg_cmpxchg(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_named_struct(sub)
|
||||
|
||||
sub = memhub.MemBuddy(pool.alloc(SUB_POOL_SIZE), SUB_POOL_SIZE)
|
||||
test_extractvalue_multi_asm(sub)
|
||||
|
||||
return testcheck.end()
|
||||
Reference in new issue
Block a user