fix(gen): 模块前言的声明池逐级判空,避免 PermPool 未就绪时空指针崩溃
现象:TransPyV.exe 编译任何工程都 AddressSanitizer access-violation on address 0x0(pc=0)。根因:_emit_module_prelude 跑在每个模块翻译的开头,此时 CompilerFactory.factory 或其 PermPool 可能尚未就绪,直接 factory.PermPool.alloc(...) 解引用空指针(PermPool 是 factory 的首字段,偏移 0,与 ASan 报的地址 0x0 吻合)。改为 factory / PermPool 逐级判空,不可用时回退模块池。
This commit is contained in:
1 parent
b71ed43f10
commit
8b63ae4ca2
1 file changed
+9
-7
@@ -414,13 +414,15 @@ novirtual class Translator:
|
||||
i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool)
|
||||
i8_ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, i8_ty)
|
||||
|
||||
# 模块前言里 C 库声明的**名字**必须落在 PermPool:create_declare 会 _str_dup(pool, name)
|
||||
# 把名字拷进传入的池,而本模块池(trans.Pool)在大模块上会被复用/回绕,覆盖早期分配 →
|
||||
# 名字悬空(现场:@malloc 被渲染成乱码 @"PL\xEF\xBF\xBDp…",mlir-opt 报
|
||||
# "'llvm.call' op 'malloc' does not reference a symbol in the current scope";
|
||||
# 类型是 mlirlite 内部 interned 的,所以只有名字坏、参数类型正常)。
|
||||
# PermPool 是"persistent data; never reset",正好符合声明名的生命周期。
|
||||
decl_pool: memhub.MemBuddy* = CompilerFactory.factory.PermPool
|
||||
# 模块前言里 C 库声明的**名字**应当落在长生命周期池(PermPool):create_declare 会
|
||||
# _str_dup(pool, name) 把名字拷进传入的池,而本模块池(trans.Pool)在大模块上会被
|
||||
# 复用/回绕,覆盖早期分配 → 名字悬空(现场:@malloc 渲染成乱码)。
|
||||
# **但本函数跑得非常早**(每个模块翻译的开头),此时 CompilerFactory.factory 或它的
|
||||
# PermPool 可能尚未就绪:直接 `factory.PermPool.alloc(...)` 会解引用空指针
|
||||
# (现场:TransPyV.exe 编译任何工程都 access-violation on address 0x0 —— PermPool 是
|
||||
# factory 的首字段,偏移 0)。故逐级判空并回退到模块池。
|
||||
decl_pool: memhub.MemBuddy* = None
|
||||
if CompilerFactory.factory is not None: decl_pool = CompilerFactory.factory.PermPool
|
||||
if decl_pool is None: decl_pool = pool
|
||||
|
||||
# Declare printf
|
||||
|
||||
Reference in new issue
Block a user