From 1145ef74c8ebffc4511d8007f61d02d79a63b574 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 13 Aug 2026 04:48:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(phase1):=20import=20=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E8=BE=B9=E6=94=B9=E7=94=A8=E5=B1=80=E9=83=A8=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E5=89=AF=E6=9C=AC=EF=BC=8C=E4=BF=AE=E5=A4=8D=20ASan=20?= =?UTF-8?q?=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _TopoSortFiles 的 import 依赖边直接使用 GetSha1Store*Ptr() 返回值 (bytes|t.CPtr 联合)作为 str 参数传入 _FindSha1ByModName,跨函数 传参时指针异常(ASan: strcmp 读 0xffffffffffffffff)。改为先用 _BuildIncludesSha1Map 复制局部 bytes 数组(与 BFS 一致),Phase2 的 BuildTopoSortedIndices 调用同步修复。 --- App/lib/core/Phase1.vp | 29 ++++++++++++++++++++++++----- App/lib/core/Phase2.vp | 25 ++++++++++++++++++------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/App/lib/core/Phase1.vp b/App/lib/core/Phase1.vp index a4edde2..33d3052 100644 --- a/App/lib/core/Phase1.vp +++ b/App/lib/core/Phase1.vp @@ -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: diff --git a/App/lib/core/Phase2.vp b/App/lib/core/Phase2.vp index 9da66af..a74a86c 100644 --- a/App/lib/core/Phase2.vp +++ b/App/lib/core/Phase2.vp @@ -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: