# TransPyC 调试器(vdb)设计文档 > **状态**:设计阶段,暂不实现 > **创建时间**:2026-06-26 > **目标**:为 TransPyC 编译的程序提供源码级调试能力,支持断点、变量查看、单步、调用栈、异常栈跟踪 --- ## 1. 背景与动机 TransPyC 将 Python 子集编译为 LLVM IR 再编译为原生机器码。当前编译产物**完全不含调试信息**(无 DWARF/PDB),运行时崩溃只能看到错误码和消息,无法定位源码行、查看变量、回溯调用栈。 本设计文档规划一个 TransPyC 专用调试器 **vdb**,目标是: - 源码级断点(`break main.py:30`) - 变量查看(`print x` / `info locals`) - 单步执行(`step` / `next`) - 调用栈回溯(`backtrace`) - 异常栈跟踪(`raise` 时记录栈帧) - 硬错误捕获(segfault / 溢出) --- ## 2. 现状分析 ### 2.1 已有可复用资产 | 资产 | 位置 | 复用方式 | |------|------|---------| | 变量映射三件套 `variables`/`_direct_values`/`_reg_values` | `lib/core/LLVMCG/BaseGen.py:79-81` | 序列化到 .tpd 供变量查看 | | 变量类型信息 `var_type_info`/`var_signedness`/`var_struct_class` | `lib/core/LLVMCG/BaseGen.py:82-112,124` | 序列化为 VarBinding.TypeDesc | | 源码行号跟踪 `_current_lineno`/`_set_node_info`/`_get_source_line` | `lib/core/LLVMCG/BaseGen.py:126-127,138,297-440` | 扩展为 SourceMap | | 类元信息表 `class_members`/`class_member_defaults`/`class_parent`/`Vtables` | `lib/core/LLVMCG/BaseGen.py:85-100` | 序列化为 TypeMeta | | 符号表序列化 `SymbolTable.ToDict` | `lib/core/SymbolTable.py:265-319` | vdb 直接加载,无需重建 | | 异常机制 `__eh_msg_out__`/`__eh_code_out__` | `lib/core/Handles/HandlesRaise.py` / `HandlesTry.py` / `HandlesExprCall.py` | 扩展携带栈信息 | | VLogger `compile_error(file, line, code)` 三元组 | `lib/core/VLogger.py:286` | 复用错误位置格式 | | 本地堆指针记录 `_local_heap_ptrs`/`_var_to_heap_ptr` | `lib/core/LLVMCG/MemoryOps.py:7-15` | 堆对象追踪起点 | ### 2.2 关键缺口 | 能力 | 现状 | 缺口说明 | |------|------|---------| | DWARF 调试信息 | ❌ 完全未生成 | `lib/` 下无任何 `DIBuilder`/`!dbg`/`DICompileUnit` 调用 | | PDB 调试信息 | ❌ 完全未生成 | Windows 下 WinDbg/VS 无法源码级调试 | | 源码行 → IR 指令映射 | ❌ 无数据结构 | 最核心缺口,需从零构建 SourceMap | | 变量名 → 运行时内存 | ⚠️ 仅编译期 ephemeral | `Gen.variables` 随 Gen 实例销毁,需持久化 | | 类型元信息运行时查询 | ❌ 无 RTTI/反射 | `class_members` 等均编译期状态,未发射到二进制 | | 运行时调用栈 | ❌ 完全无 | 异常仅传 `(code, msg)`,无栈帧链 | | 硬错误处理 | ❌ 无 | `__builtin_trap` 仅声明未实现,segfault/SIGFPE 无捕获 | | 断点/单步/变量查看 | ❌ 完全无 | `lib/` 下搜索 `breakpoint`/`step`/`watch` 零命中 | --- ## 3. 路线选择 ### 3.1 方案 A:纯 DWARF + GDB/LLDB **优点**:生态成熟,无需自研前端 **缺点**: - llvmlite 的 DIBuilder 支持度需验证 - Python 语义与 C 不完全对应(`self` 是指针但 Python 视为对象) - SHA1 命名导致符号名难读 - 泛型特化类型(`Stack[int]`)在 DWARF 中表达困难 - 跨模块符号(`6d71a13705da41ad.main`)可读性差 ### 3.2 方案 B:纯自研 vdb **优点**:完全匹配 Python 语义,可显示原始源码,理解泛型/SHA1/跨模块 **缺点**:开发量大,需自研调试协议与前端 ### 3.3 方案 C:混合(推荐) - 生成轻量 DWARF(仅行号 + 变量名)让 GDB 可用作后备 - 同时生成 TransPyC 专用调试元数据 `.tpd` 文件 - vdb 前端优先使用 `.tpd`,可降级到 GDB 后端 **本设计采用方案 C**,但优先实现 `.tpd` + vdb,DWARF 作为可选增强。 --- ## 4. 核心数据结构 ### 4.1 .tpd 文件格式(TransPyC Debug) 每个 `.ll` 文件配套生成一个 `.tpd` 文件(JSON 格式),包含以下结构: ```python from dataclasses import dataclass, field from typing import Any @dataclass class IrLocation: """单条 IR 指令的源码位置映射""" FuncName: str # mangled 函数名(含 SHA1 头,如 '6d71a13705da41ad.main') BlockName: str # 基本块名(如 'entry'、'if.then') InstrIdx: int # 指令在块中的索引 SourceFile: str # 源码相对路径 LineNo: int # 源码行号 ColNo: int # 列号 @dataclass class VarBinding: """变量绑定信息(作用域内)""" VarName: str # Python 变量名(如 'x'、'self') LlvmName: str # alloca 名或 SSA(如 '%x'、'%".1"') TypeDesc: str # 类型描述('i32' / 'Stack[int]*' / 'i8*') IsSigned: bool # 是否有符号整数 StructClass: str | None # 所属结构体类名(如 'Stack[int]') StartLine: int # 作用域起始行 EndLine: int # 作用域结束行 Storage: str # 'stack' | 'register' | 'direct' | 'global' StackOffset: int | None # 栈偏移(仅 'stack') @dataclass class TypeMeta: """类型元数据""" TypeName: str # 'Stack[int]' / 'IntPair' / 'memory_block' Members: list[tuple[str, str, int]] # (成员名, 类型, 字节偏移) Size: int # 总大小(字节) Align: int # 对齐 Parent: str | None # 父类名 IsException: bool # 是否异常类 ExceptionCode: int # 异常码(仅 IsException=True) HasVTable: bool # 是否有虚表 IsPacked: bool # 是否紧凑布局 @dataclass class FuncSig: """函数签名""" FuncName: str # mangled 名 RawName: str # 原始 Python 名(去 SHA1) ReturnType: str # 返回类型描述 ParamNames: list[str] ParamTypes: list[str] IsExport: bool # 是否导出(@t.CExport) IsMethod: bool # 是否实例方法 ClassName: str | None # 所属类名(方法) SourceFile: str StartLine: int EndLine: int HasException: bool # 是否可能抛异常(有 __eh_msg_out__) @dataclass class TpdFile: """完整的 .tpd 调试信息文件""" SourceMap: list[IrLocation] VarScopes: dict[str, list[VarBinding]] # FuncName -> bindings TypeMeta: dict[str, TypeMeta] FuncSignatures: dict[str, FuncSig] ExceptionCodes: dict[int, str] # code -> exception name SourceFiles: dict[str, list[str]] # file -> 源码行列表(供 vdb 显示上下文) ModuleSha1: str | None Version: str = "1.0" ``` ### 4.2 序列化格式 `.tpd` 文件使用 JSON,字段名采用 PascalCase(与代码一致)。示例: ```json { "Version": "1.0", "ModuleSha1": "6d71a13705da41ad", "SourceFiles": { "App/main.py": ["import t", "import stdio", ...] }, "SourceMap": [ {"FuncName": "main", "BlockName": "entry", "InstrIdx": 0, "SourceFile": "App/main.py", "LineNo": 255, "ColNo": 0}, ... ], "VarScopes": { "6d71a13705da41ad.test_generic_stack": [ {"VarName": "s", "LlvmName": "%s", "TypeDesc": "Stack[int]*", "IsSigned": false, "StructClass": "Stack[int]", "StartLine": 66, "EndLine": 73, "Storage": "stack", "StackOffset": 0} ] }, "TypeMeta": { "Stack[int]": { "TypeName": "Stack[int]", "Members": [["data", "[16 x i32]", 0], ["top", "i32", 64]], "Size": 68, "Align": 4, "Parent": null, "IsException": false, "ExceptionCode": 0, "HasVTable": false, "IsPacked": false } }, "ExceptionCodes": { "1": "ValueError", "2": "TypeError", "99": "Exception", "100": "MyCustomError" } } ``` --- ## 5. 实现阶段 ### 5.1 Phase 1:源码级断点(最小可用) **目标**:`break main.py:30` + `continue` + `run` #### 5.1.1 编译器改动 **位置**:`lib/core/LLVMCG/BaseGen.py` 1. **扩展 `_set_node_info`**:记录当前指令的源码位置到 `SourceMap` ```python def _set_node_info(self, Node: ast.AST) -> None: self._current_lineno = getattr(Node, 'lineno', 0) self._current_col = getattr(Node, 'col_offset', 0) self._current_node_info = f" [line {self._current_lineno}, col {self._current_col}]" # 新增:记录到 SourceMap if self.func and self.builder and self.builder.block: loc: IrLocation = IrLocation( FuncName=self.func.name, BlockName=self.builder.block.name, InstrIdx=len(self.builder.block.instructions), SourceFile=self._current_source_file or '', LineNo=self._current_lineno, ColNo=self._current_col ) self._source_map.append(loc) ``` 2. **插入断点桩**:在每行源码对应的首条 IR 指令前插入 ```llvm ; 运行时断点桩声明 declare void @__tpc_breakpoint(i32 %line, i8* %file) ; 在 main.py:255 的首条指令前插入 %src_file_ptr = getelementptr [12 x i8], [12 x i8]* @.src.main_py, i32 0, i32 0 call void @__tpc_breakpoint(i32 255, i8* %src_file_ptr) ``` 3. **条件性插入**:仅当 `--debug` 编译选项启用时插入,release 构建完全剥离 4. **生成 .tpd 文件**:函数编译结束时,序列化 `SourceMap` 到 `.tpd` #### 5.1.2 运行时库 新建 `includes/vdb_runtime.py`: ```python import t import c # 全局断点表(行号 -> 是否启用) _Breakpoints: t.CArray[t.CInt, 65536] | t.CPtr = [0] # 当前调试器状态(0=运行, 1=暂停) _DebugState: t.CInt = 0 # 当前源码文件名(用于断点匹配) _CurrentFile: t.CArray[t.CInt8T, 256] | t.CPtr = [0] @t.CExport def __tpc_breakpoint(line: t.CInt, file: t.CPtr) -> None: """断点桩入口,由编译器在每个源码行前插入调用""" # 检查是否启用断点 if _Breakpoints[line] == 0: return # 命中断点,陷入调试器循环 _DebugState = 1 _tpc_debug_loop(line, file) def _tpc_debug_loop(line: t.CInt, file: t.CPtr) -> None: """调试器主循环,等待用户命令""" # 通过 IPC 或 stdio 与 vdb 前端通信 # 解析命令:continue / step / next / print / info / backtrace while _DebugState == 1: cmd: t.CArray[t.CInt8T, 256] | t.CPtr = [0] stdio.scanf("%s", cmd) # ... 命令分派 ``` #### 5.1.3 vdb 前端 新建 `lib/vdb/` 目录: ``` lib/vdb/ ├── __init__.py ├── TpdLoader.py # .tpd 文件加载器 ├── BreakpointManager.py # 断点管理 ├── DebugSession.py # 调试会话主循环 ├── CommandParser.py # 命令解析 └── SourceView.py # 源码显示 ``` **核心命令**: - `break :` / `b :` — 设置断点 - `delete ` / `d ` — 删除断点 - `continue` / `c` — 继续执行 - `run` / `r` — 启动程序 - `list` / `l` — 显示当前源码上下文 - `info breakpoints` — 列出断点 ### 5.2 Phase 2:变量查看 **目标**:`print x` / `info locals` / `info args` #### 5.2.1 编译器改动 **位置**:`lib/core/LLVMCG/FuncGen.py` 或 `lib/core/Handles/HandlesFunctions.py` 函数编译结束时,序列化变量绑定: ```python def _serialize_var_scope(self, FuncName: str) -> list[VarBinding]: bindings: list[VarBinding] = [] for var_name, llvm_val in self.variables.items(): if llvm_val is None: continue binding: VarBinding = VarBinding( VarName=var_name, LlvmName=llvm_val.name if hasattr(llvm_val, 'name') else '', TypeDesc=self._describe_llvm_type(llvm_val.type), IsSigned=self.var_signedness.get(var_name, True), StructClass=self.var_struct_class.get(var_name), StartLine=self._func_start_line, EndLine=self._func_end_line, Storage='stack', StackOffset=self._get_alloca_offset(llvm_val) # 新增:记录栈偏移 ) bindings.append(binding) # 同样处理 _direct_values 和全局变量 return bindings ``` #### 5.2.2 运行时变量读取 调试器通过以下方式读取变量值: 1. **栈变量**:通过 `StackOffset` + 当前栈帧基址读取 2. **全局变量**:通过符号表查找全局符号地址 3. **寄存器变量**:需调试器理解 SSA 值(较复杂,Phase 2 可跳过,仅支持 stack) #### 5.2.3 类型渲染 ```python def RenderValue(llvm_val: bytes, type_meta: TypeMeta, type_desc: str) -> str: """根据类型渲染变量值""" if type_desc == 'i32': return str(int.from_bytes(llvm_val, 'little', signed=True)) elif type_desc == 'i8*': # 尝试作为 C 字符串读取 return f'"{read_cstring(llvm_val)}"' elif type_desc.endswith('*') and type_meta: # 结构体指针:展开成员 return RenderStruct(llvm_val, type_meta) ... ``` ### 5.3 Phase 3:单步执行 **目标**:`step` / `next` / `finish` 基于 SourceMap 实现: - `step`(步入):在下一行源码的首条 IR 指令前设临时断点,包括被调用函数内部 - `next`(步过):在当前函数的下一行设临时断点,跳过函数调用 - `finish`(步出):在当前函数的返回点设临时断点 **实现**: 1. 查 SourceMap 找到当前行的下一个源码行 2. 设置临时断点(一次性) 3. `continue` 4. 命中后自动删除临时断点 ### 5.4 Phase 4:调用栈跟踪 **目标**:`backtrace` / `bt` / `frame ` #### 5.4.1 编译器改动 每个函数入口/出口插入栈帧维护调用: ```llvm ; 函数入口 call void @__tpc_push_frame( i8* getelementptr([N x i8], [N x i8]* @.func.name, i32 0, i32 0), ; 函数名 i8* getelementptr([M x i8], [M x i8]* @.src.file, i32 0, i32 0), ; 源文件 i32 255 ; 起始行 ) ; 函数出口(每个 ret 前) call void @__tpc_pop_frame() ``` #### 5.4.2 运行时栈结构 ```python import t @t.CStruct class FrameInfo: FuncName: t.CPtr # i8* 函数名 SrcFile: t.CPtr # i8* 源文件 LineNo: t.CInt # 当前行号(动态更新) PrevFrame: 'FrameInfo' | t.CPtr # 上一帧(链表) # 全局栈顶 _FrameTop: FrameInfo | t.CPtr = t.CPtr(0) @t.CExport def __tpc_push_frame(func_name: t.CPtr, src_file: t.CPtr, line: t.CInt) -> None: frame: FrameInfo | t.CPtr = c.cast(FrameInfo, mb.alloc(FrameInfo.__sizeof__())) frame.FuncName = func_name frame.SrcFile = src_file frame.LineNo = line frame.PrevFrame = _FrameTop _FrameTop = frame @t.CExport def __tpc_pop_frame() -> None: if _FrameTop != t.CPtr(0): old: FrameInfo | t.CPtr = _FrameTop _FrameTop = _FrameTop.PrevFrame mb.free(old) ``` #### 5.4.3 断点桩更新当前行 `__tpc_breakpoint` 命中时,更新 `_FrameTop.LineNo`: ```python @t.CExport def __tpc_breakpoint(line: t.CInt, file: t.CPtr) -> None: if _Breakpoints[line] == 0: return if _FrameTop != t.CPtr(0): _FrameTop.LineNo = line _DebugState = 1 _tpc_debug_loop(line, file) ``` ### 5.5 Phase 5:异常栈跟踪 **目标**:`raise ValueError("msg")` 时输出完整调用栈 #### 5.5.1 编译器改动 **位置**:`lib/core/Handles/HandlesRaise.py` 在 `_HandleRaiseLlvm` 中,抛异常前捕获栈: ```python def _HandleRaiseLlvm(self, Node: ast.Raise) -> None: # ... 原有错误码计算 ... # 新增:捕获调用栈 capture_call = self.Gen.builder.call( self._get_or_declare_function('__tpc_capture_trace', ir.FunctionType(ir.VoidType(), [])), [] ) # ... 原有异常传播逻辑 ... ``` #### 5.5.2 异常结构扩展 将 `__eh_msg_out__`(i8**)扩展为指向包含栈的结构: ```python import t @t.CStruct class ExceptionInfo: Code: t.CInt Message: t.CArray[t.CInt8T, 256] | t.CPtr TraceDepth: t.CInt TraceFuncs: t.CArray[t.CPtr, 64] # 函数名指针数组 TraceLines: t.CArray[t.CInt, 64] # 对应行号 TraceFiles: t.CArray[t.CPtr, 64] # 对应源文件 ``` #### 5.5.3 未捕获异常处理 在 `main` 函数返回前检查异常,打印栈: ```python def main() -> t.CInt: # ... 用户代码 ... # 编译器自动插入:检查未捕获异常 if _UnhandledException != t.CPtr(0): _tpc_print_trace(_UnhandledException) return 1 return testcheck.end() ``` ### 5.6 Phase 6:硬错误捕获 **目标**:segfault / 除零 / 栈溢出时进入调试器 #### 5.6.1 信号处理器注册 ```python import t import c @t.CExport def __tpc_signal_handler(sig: t.CInt) -> None: """OS 信号处理入口""" __tpc_capture_trace() # 打印信号类型 if sig == 11: # SIGSEGV stdio.printf("Segmentation fault\n") elif sig == 8: # SIGFPE stdio.printf("Arithmetic exception\n") # 陷入调试器 _tpc_debug_loop(0, t.CPtr(0)) def __tpc_install_signal_handlers() -> None: """在 main 入口前自动调用""" c.signal(11, __tpc_signal_handler) # SIGSEGV c.signal(8, __tpc_signal_handler) # SIGFPE ``` #### 5.6.2 编译器改动 在 `main` 函数入口自动插入 `__tpc_install_signal_handlers()` 调用(仅 `--debug` 模式)。 --- ## 6. vdb 命令参考 ### 6.1 启动与控制 | 命令 | 缩写 | 说明 | |------|------|------| | `run [args]` | `r` | 启动被调试程序 | | `continue` | `c` | 继续执行至下一断点 | | `step` | `s` | 单步进入函数 | | `next` | `n` | 单步跳过函数 | | `finish` | `f` | 执行至当前函数返回 | | `quit` | `q` | 退出调试器 | ### 6.2 断点管理 | 命令 | 缩写 | 说明 | |------|------|------| | `break :` | `b` | 设置源码行断点 | | `break ` | `b` | 设置函数入口断点 | | `tbreak :` | `tb` | 临时断点(命中后删除) | | `delete ` | `d` | 删除断点 n | | `info breakpoints` | `i b` | 列出所有断点 | ### 6.3 变量查看 | 命令 | 缩写 | 说明 | |------|------|------| | `print ` | `p` | 打印表达式值 | | `info locals` | `i lo` | 列出当前局部变量 | | `info args` | `i ar` | 列出函数参数 | | `display ` | - | 每次暂停自动显示 | | `set =` | - |修改变量值 | ### 6.4 栈操作 | 命令 | 缩写 | 说明 | |------|------|------| | `backtrace` | `bt` | 显示调用栈 | | `frame ` | `fr` | 切换到第 n 帧 | | `up` | - | 向上切换一帧 | | `down` | `do` | 向下切换一帧 | ### 6.5 源码浏览 | 命令 | 缩写 | 说明 | |------|------|------| | `list` | `l` | 显示当前行上下文 | | `list :` | `l` | 显示指定位置 | | `info source` | `i so` | 显示当前源文件信息 | ### 6.6 类型与结构 | 命令 | 缩写 | 说明 | |------|------|------| | `ptype ` | `pt` | 显示类型定义 | | `info types` | `i ty` | 列出所有类型 | | `info exceptions` | `i ex` | 列出异常码表 | --- ## 7. 实现优先级 | 优先级 | 阶段 | 价值 | 改动量 | |--------|------|------|--------| | P0 | Phase 1(源码断点)+ Phase 2(变量查看) | 80% 调试价值 | 小 | | P1 | Phase 4(调用栈) | 崩溃定位关键 | 中 | | P2 | Phase 5(异常栈) | Python 语义匹配 | 中 | | P3 | Phase 3(单步) | 体验提升 | 中(依赖 Phase 1) | | P4 | Phase 6(硬错误) | 兜底保护 | 中 | | P5 | DWARF 生成 | GDB 互操作 | 大(可选) | --- ## 8. 风险与考量 ### 8.1 性能开销 - **断点桩**:仅 `--debug` 构建启用,release 完全剥离 - **IR 膨胀**:每行插入断点桩约增加 10-20% IR 体积,可接受 - **运行时开销**:断点桩检查为单次数组访问 + 分支预测,开销极低 - **栈帧维护**:每函数调用增加 2 次 `push/pop_frame`,约 5-10% 调用开销 ### 8.2 兼容性 - **SHA1 命名**:vdb 需理解 SHA1 前缀,通过 `ModuleSha1` 字段还原为 `模块名.函数名` 显示 - **泛型特化**:`Stack[int]` 需作为完整类型名处理,TypeMeta 中保留特化名 - **跨模块**:`.tpd` 文件按模块生成,vdb 启动时合并所有相关 `.tpd` - **`main` 特化**:`main` 函数无 SHA1 头,vdb 需特殊处理 ### 8.3 安全性 - **栈帧分配**:使用 `mb.alloc` 而非 `c.malloc`,确保与 TransPyC 内存管理一致 - **信号处理器**:异步信号中避免调用非异步信号安全函数,仅设置标志位 ### 8.4 限制 - **优化构建**:高优化级别(`-O2`+)下变量可能被优化掉,`.tpd` 中的 VarBinding 可能失效 - **内联函数**:内联后栈帧信息丢失,需在 `.tpd` 中标记 `IsInline` - **尾调用优化**:破坏调用栈链,需禁用或特殊处理 --- ## 9. 文件结构规划 ``` lib/vdb/ # vdb 调试器前端 ├── __init__.py ├── TpdLoader.py # .tpd 文件加载与合并 ├── BreakpointManager.py # 断点管理 ├── DebugSession.py # 调试会话主循环 ├── CommandParser.py # 命令解析 ├── SourceView.py # 源码显示 ├── ValueRenderer.py # 变量值渲染 ├── StackWalker.py # 调用栈遍历 └── IpcChannel.py # 与被调试进程的 IPC 通信 lib/core/LLVMCG/ └── DebugInfoGen.py # 新增:.tpd 生成器(编译器侧) includes/ └── vdb_runtime.py # 运行时断点/栈帧/信号处理库 ``` --- ## 10. 与现有系统的集成点 ### 10.1 编译器集成 - **`Phase2Translator.py`**:在生成 `.ll` 后,调用 `DebugInfoGen.GenerateTpd(module, gen, output_path)` - **`BaseGen.py`**:`_set_node_info` 扩展记录 SourceMap;函数编译结束序列化 VarScope - **`HandlesFunctions.py`**:函数入口/出口插入 `__tpc_push_frame`/`__tpc_pop_frame`(仅 debug 模式) - **`HandlesRaise.py`**:`_HandleRaiseLlvm` 插入 `__tpc_capture_trace` ### 10.2 project.json 配置 新增 `debug` 选项: ```json { "options": { "debug": true, "debug_info": "tpd" } } ``` - `debug: true` — 启用调试构建(插入断点桩、栈帧维护、信号处理) - `debug_info: "tpd"` — 生成 .tpd 文件(默认) - `debug_info: "dwarf"` — 生成 DWARF(未来支持) - `debug_info: "both"` — 同时生成(未来支持) ### 10.3 命令行集成 ```bash # 编译带调试信息 transpyc build --debug # 直接启动调试器 transpyc debug ./output/MyApp.exe # 等价于 vdb ./output/MyApp.exe ``` --- ## 11. 开放问题 1. **llvmlite DIBuilder 支持度**:需验证 llvmlite 是否暴露 DIBuilder 接口,决定 DWARF 生成可行性 2. **IPC 协议**:vdb 前端与被调试进程的通信方式(管道/Socket/共享内存)待定 3. **远程调试**:是否支持远程调试(如 ViperOS 裸机目标)需进一步设计 4. **表达式求值**:`print x.y.z` 等复杂表达式是否需要完整 Python 解释器,还是简化为路径访问 5. **多线程**:TransPyC 当前是否支持多线程,调试器如何处理线程切换 --- ## 12. 参考文档 - 现状分析:基于 2026-06-26 对 `lib/core/` 和 `lib/Projectrans/` 的完整搜索 - 异常机制:`wiki/09-exceptions.md` - 导入机制:`wiki/10-imports.md` - 符号表:`lib/core/SymbolTable.py` - 类型系统:`lib/core/TypeSpec.py` / `lib/core/Handles/HandlesBase.py` - LLVM 生成:`lib/core/LLVMCG/BaseGen.py` / `FuncGen.py` / `MemoryOps.py` --- > **本文档为设计阶段产物,暂不实现。待社区需求或开发优先级提升后,按 Phase 1 → 2 → 4 → 5 → 3 → 6 顺序推进。**