fix(phase1): import 依赖边改用局部映射副本,修复 ASan 崩溃

_TopoSortFiles 的 import 依赖边直接使用 GetSha1Store*Ptr() 返回值
(bytes|t.CPtr 联合)作为 str 参数传入 _FindSha1ByModName,跨函数
传参时指针异常(ASan: strcmp 读 0xffffffffffffffff)。改为先用
_BuildIncludesSha1Map 复制局部 bytes 数组(与 BFS 一致),Phase2 的
BuildTopoSortedIndices 调用同步修复。
This commit is contained in:
TermiNexus committed 2026-08-13 04:48:38 +08:00
1 parent 0d6891f7bc
commit 1145ef74c8
2 files changed
+42 -12

No files matched your search

+24 -5
View File
@@ -399,7 +399,8 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
sha1_set: str, set_count: int,
class_names_buf: bytes, parent_names_buf: bytes,
def_sha1s_buf: bytes, class_count: int,
out_order: t.CPtr, out_count: t.CPtr) -> int:
out_order: t.CPtr, out_count: t.CPtr,
temp_dir: str, td_len_ts: t.CSizeT) -> int:
"""根据类继承关系对文件进行拓扑排序"""
if result is None or out_order is None or out_count is None:
return -1
@@ -515,8 +516,19 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
# AST)、泛型模板(base.vp 用 list[...])都要求依赖模块先翻译,而它们
# 之间可能无类继承关系。deps(_includes_deps_*)由 Phase 1a-pre 填充
# (含容器按需注入的 _list/_dict)。
store_sz_imp: int = StubMerger.GetSha1StoreCount()
#
# 用 _BuildIncludesSha1Map 复制局部 sha1→模块名 数组(与
# _BuildReachableSha1Set 的 BFS 一致),避免直接使用全局 store 返回值
# 跨函数传参(bytes|t.CPtr 联合转 str 参数)的地址异常。
sha1_arr_ts: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 17)
mod_arr_ts: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 64)
map_count_ts: int = 0
if sha1_arr_ts is not None and mod_arr_ts is not None:
map_count_ts = StubMerger._BuildIncludesSha1Map(
temp_dir, td_len_ts, sha1_arr_ts, mod_arr_ts)
for fi_imp in range(file_count):
if map_count_ts <= 0:
break
fsha1_imp: str = file_sha1s_buf + fi_imp * SHA1_LEN
deps_imp: str = StubMerger.LookupIncludesDeps(fsha1_imp)
if deps_imp is None:
@@ -538,8 +550,7 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
string.strncpy(dname_imp, deps_imp + dstart_imp, dlen_imp)
dname_imp[dlen_imp] = '\0'
dsha1_imp: str = StubMerger._FindSha1ByModName(
StubMerger.GetSha1StoreArrPtr(), StubMerger.GetSha1StoreModArrPtr(),
store_sz_imp, dname_imp)
sha1_arr_ts, mod_arr_ts, map_count_ts, dname_imp)
stdlib.free(dname_imp)
if dsha1_imp is None:
continue
@@ -567,6 +578,12 @@ def _TopoSortFiles(mb: memhub.MemBuddy | t.CPtr,
cnt_ptr_imp[0] = cur_cnt_imp + 1
break
# 释放 import 边用的局部映射数组
if sha1_arr_ts is not None:
stdlib.free(sha1_arr_ts)
if mod_arr_ts is not None:
stdlib.free(mod_arr_ts)
# 3. Kahn 算法:InDegree = DepCount(依赖多少个父文件)
# 依赖为 0 的先处理,处理后减少依赖它的文件入度
for fi in range(file_count):
@@ -972,11 +989,13 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
generic_file_indices, generic_file_count_box)
if class_count_scanned > 0:
td_len_ts_call: t.CSizeT = string.strlen(temp_dir)
ret_topo: int = _TopoSortFiles(
mb, result, reachable_set, reachable_count,
use_reachable, sha1_set, set_count,
class_names_buf, parent_names_buf, def_sha1s_buf, class_count_scanned,
topo_order, topo_count_box)
topo_order, topo_count_box,
temp_dir, td_len_ts_call)
if ret_topo == 0:
tc_ptr: t.CPtr = (t.CInt | t.CPtr)(t.CVoid(topo_count_box, t.CPtr))
if tc_ptr is not None:
+18 -7
View File
@@ -720,13 +720,20 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
stdlib.free(app_deps_buf)
app_deps_buf = None
# 从全局存储器获取 SHA1/模块名/rel_path 数组(直接访问器,避免 box 解引用问题)
store_count_mi: int = StubMerger.GetSha1StoreCount()
# 从全局存储器获取 SHA1/模块名 数组:复制局部副本(bytes),
# 避免 store 联合返回值(bytes|t.CPtr)跨函数传参/索引的地址异常
# (与 _BuildReachableSha1Set 的 BFS 一致)。
# rel/incdir 仅本函数内按索引读取(不跨函数传参),保留 store 指针。
td_len_pb: t.CSizeT = string.strlen(temp_dir)
store_sha1_arr_mi: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 17)
store_mod_arr_mi: bytes = stdlib.malloc(StubMerger.MAX_INCLUDES * 64)
store_count_mi: int = 0
if store_sha1_arr_mi is not None and store_mod_arr_mi is not None:
store_count_mi = StubMerger._BuildIncludesSha1Map(
temp_dir, td_len_pb, store_sha1_arr_mi, store_mod_arr_mi)
store_rel_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreRelArrPtr()
store_incdir_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreIncdirArrPtr()
if store_count_mi > 0:
store_sha1_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreArrPtr()
store_mod_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreModArrPtr()
store_rel_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreRelArrPtr()
store_incdir_arr_mi: bytes | t.CPtr = StubMerger.GetSha1StoreIncdirArrPtr()
# 拓扑排序可达 includes:被依赖模块先完整翻译。跨模块 vtable 生成
# 需要依赖模块的函数 TypeStr 已注册到全局表(如 astaux 继承 base 的 AST)
@@ -949,9 +956,13 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
stdlib.free(src_fp_mi)
# 释放拓扑排序索引
# 释放拓扑排序索引与局部映射副本
if topo_idx is not None:
stdlib.free(topo_idx)
if store_sha1_arr_mi is not None:
stdlib.free(store_sha1_arr_mi)
if store_mod_arr_mi is not None:
stdlib.free(store_mod_arr_mi)
fb: str = VLogger.fmt_buf()
if fb is not None: