# 故障排除

<cite>
**本文档引用的文件**
- [Cargo.toml](file://Cargo.toml)
- [src/main.rs](file://src/main.rs)
- [src/lib.rs](file://src/lib.rs)
- [loader/src/main.rs](file://loader/src/main.rs)
- [runtime/src/lib.rs](file://runtime/src/lib.rs)
- [build.rs](file://build.rs)
- [src/codegen.rs](file://src/codegen.rs)
- [src/swc_transform.rs](file://src/swc_transform.rs)
- [src/project.rs](file://src/project.rs)
- [src/project_compiler.rs](file://src/project_compiler.rs)
- [src/standalone_loader.rs](file://src/standalone_loader.rs)
- [src/native_linker.rs](file://src/native_linker.rs)
</cite>

## 更新摘要
**变更内容**
- 新增调试技巧章节，包含详细的问题诊断方法
- 增强日志配置说明，涵盖更详细的日志级别和关键词
- 添加性能分析工具和内存监控建议
- 扩展常见问题解决方案，包含编译器、加载器和链接器的具体问题
- 新增故障排除流程图和诊断步骤

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [调试技巧与诊断方法](#调试技巧与诊断方法)
10. [结论](#结论)
11. [附录](#附录)

## 简介
本指南面向 ts-native 项目使用者与维护者，系统化梳理编译错误、运行时问题与性能问题的诊断与解决方法。内容覆盖命令行工具与加载器的日志配置、错误信息解读、常见问题排查、性能优化建议以及社区支持渠道。文档以仓库现有实现为依据，确保方法有效且可操作。

## 项目结构
ts-native 采用 Rust 主工程，配合 SWC 解析 TypeScript、Cranelift 生成机器码、COFF 对象文件与独立加载器/链接器组合的产物交付方式。关键模块如下：
- CLI 编译器：解析参数、调用 SWC 与 CodeGen，输出 COFF
- 运行时库：提供 JS 运行时函数与类型系统支持
- 加载器：支持直接加载 COFF 或通过 DLL 编译后执行，并可选择保存中间产物
- 项目编译器：多模块项目发现、依赖图构建、按拓扑顺序编译、生成独立可执行
- 原生链接器：合并多个 .obj、处理重定位、生成完整 PE（可选）

```mermaid
graph TB
subgraph "CLI 工具"
CLI["ts-native<br/>src/main.rs"]
LINKER_CLI["native-linker<br/>src/bin/native_linker_main.rs"]
end
subgraph "编译管线"
SWC["SWC 解析<br/>src/swc_transform.rs"]
CG["CodeGen<br/>src/codegen.rs"]
COFF["COFF 输出<br/>.obj"]
end
subgraph "运行时"
RT["tsn_runtime.dll<br/>runtime/src/lib.rs"]
end
subgraph "加载器"
LOADER["tsn-loader<br/>loader/src/main.rs"]
STANDALONE["独立加载器<br/>src/standalone_loader.rs"]
end
subgraph "链接器"
NATIVE_LINKER["原生链接器<br/>src/native_linker.rs"]
end
CLI --> SWC --> CG --> COFF
LOADER --> RT
STANDALONE --> RT
NATIVE_LINKER --> COFF
```

**图表来源**
- [src/main.rs:1-79](file://src/main.rs#L1-L79)
- [src/swc_transform.rs:1-800](file://src/swc_transform.rs#L1-L800)
- [src/codegen.rs:520-604](file://src/codegen.rs#L520-L604)
- [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)
- [loader/src/main.rs:130-510](file://loader/src/main.rs#L130-L510)
- [src/standalone_loader.rs:127-302](file://src/standalone_loader.rs#L127-L302)
- [src/native_linker.rs:308-382](file://src/native_linker.rs#L308-L382)

**章节来源**
- [Cargo.toml:1-57](file://Cargo.toml#L1-L57)
- [src/lib.rs:1-17](file://src/lib.rs#L1-L17)

## 核心组件
- CLI 编译器：解析输入与输出参数，调用 SWC 与 CodeGen，输出 COFF 并提示如何使用加载器
- 运行时库：提供 js_* 外部函数（打印、数组、对象、JSON、文件系统等），支持日志回调
- 加载器：支持多种日志级别、插件加载、从 COFF 直接执行或通过 DLL 编译执行
- 项目编译器：项目结构发现、依赖图、模块编译顺序、独立可执行生成
- 原生链接器：合并节区、符号解析、导入表、重定位、PE 输出与诊断反馈

**章节来源**
- [src/main.rs:7-78](file://src/main.rs#L7-L78)
- [runtime/src/lib.rs:135-800](file://runtime/src/lib.rs#L135-L800)
- [loader/src/main.rs:42-127](file://loader/src/main.rs#L42-L127)
- [src/project_compiler.rs:205-332](file://src/project_compiler.rs#L205-L332)
- [src/native_linker.rs:308-382](file://src/native_linker.rs#L308-L382)

## 架构总览
下图展示从 TypeScript 输入到执行的关键流程与交互点，包括编译期（CLI/项目编译器）、运行期（加载器/独立加载器）与链接期（原生链接器）。

```mermaid
sequenceDiagram
participant U as "用户"
participant CLI as "ts-native<br/>src/main.rs"
participant SWC as "SWC 解析<br/>src/swc_transform.rs"
participant CG as "CodeGen<br/>src/codegen.rs"
participant OBJ as "COFF(.obj)"
participant LDR as "tsn-loader<br/>loader/src/main.rs"
participant RT as "tsn_runtime.dll<br/>runtime/src/lib.rs"
U->>CLI : 传入输入 TS 与可选输出
CLI->>SWC : parse(source)
SWC-->>CLI : HIR
CLI->>CG : compile_coff(HIR)
CG-->>OBJ : COFF 字节流
CLI-->>U : 输出 .obj 并提示使用 tsn-loader
U->>LDR : tsn-loader <file.ts> --compile
LDR->>RT : 加载运行时 DLL
LDR->>CG : 调用 ts-native.dll 编译并执行
CG-->>LDR : 代码/数据/重定位
LDR->>LDR : 应用重定位并执行入口
LDR-->>U : 返回执行结果
```

**图表来源**
- [src/main.rs:55-76](file://src/main.rs#L55-L76)
- [src/swc_transform.rs:10-34](file://src/swc_transform.rs#L10-L34)
- [src/codegen.rs:520-604](file://src/codegen.rs#L520-L604)
- [loader/src/main.rs:337-502](file://loader/src/main.rs#L337-L502)
- [runtime/src/lib.rs:135-800](file://runtime/src/lib.rs#L135-L800)

## 详细组件分析

### CLI 编译器（ts-native）
- 功能：解析命令行参数、读取输入、调用 SWC 与 CodeGen、写出 COFF、提示加载器用法
- 关键点：若未指定输出，自动推导 .obj；若输入为空，打印用法并退出
- 常见问题：输入文件不存在、输出路径权限不足、未安装依赖

```mermaid
flowchart TD
Start(["启动"]) --> Args["解析参数<br/>输入/输出"]
Args --> HasInput{"是否提供输入文件？"}
HasInput --> |否| Usage["打印用法并退出"]
HasInput --> |是| Read["读取源文件"]
Read --> Parse["SWC 解析为 HIR"]
Parse --> Gen["CodeGen 生成 COFF"]
Gen --> Write["写入 .obj"]
Write --> Done(["完成"])
```

**图表来源**
- [src/main.rs:7-78](file://src/main.rs#L7-L78)

**章节来源**
- [src/main.rs:7-78](file://src/main.rs#L7-L78)

### 运行时库（tsn_runtime.dll）
- 功能：提供 js_* 外部函数（打印、数组、对象、JSON、文件系统、Math 等），支持日志回调
- 关键点：NaN-tagging 类型系统，字符串/数组/对象池，导出函数以 C ABI 暴露
- 常见问题：运行时缺失函数导致链接失败、类型不匹配、字符串/数组访问越界

```mermaid
classDiagram
class Runtime {
+js_print(value) f64
+js_array_push(arr, elem) f64
+js_object_get(obj, key) f64
+js_fs_read_file_sync(path) f64
+js_set_log_callback(cb)
}
class Types {
+TAG_NUMBER
+TAG_STRING
+TAG_OBJECT
+TAG_BOOLEAN
+TAG_UNDEFINED
+TAG_NULL
+TAG_FUNCTION
+TAG_ARRAY
}
Runtime --> Types : "使用"
```

**图表来源**
- [runtime/src/lib.rs:135-800](file://runtime/src/lib.rs#L135-L800)

**章节来源**
- [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)

### 加载器（tsn-loader）
- 功能：支持多种日志级别、插件加载、从 COFF 直接执行或通过 DLL 编译执行
- 关键点：StageTimer 计时、ExecSummary 统计、PluginManager 管理插件符号解析
- 常见问题：Windows 限定、插件加载失败、符号未解析、重定位失败

```mermaid
sequenceDiagram
participant L as "tsn-loader"
participant PM as "PluginManager"
participant RT as "tsn_runtime.dll"
participant CG as "ts-native.dll(可选)"
L->>PM : 加载插件 DLL
alt 从 COFF 执行
L->>L : 解析 COFF 符号/重定位
L->>L : 分配可执行/数据内存
L->>L : 应用重定位
L->>L : 调用入口(main)
else 通过 DLL 编译
L->>CG : tsn_compile(source)
CG-->>L : 代码/数据/重定位
L->>RT : 加载运行时
L->>L : 应用重定位并执行
end
```

**图表来源**
- [loader/src/main.rs:272-510](file://loader/src/main.rs#L272-L510)
- [runtime/src/lib.rs:135-800](file://runtime/src/lib.rs#L135-L800)

**章节来源**
- [loader/src/main.rs:42-127](file://loader/src/main.rs#L42-L127)
- [loader/src/main.rs:272-510](file://loader/src/main.rs#L272-L510)

### 项目编译器（多模块）
- 功能：项目结构发现、依赖图构建、按拓扑顺序编译、生成独立可执行
- 关键点：估计内存使用、阶段计时、合并模块数据、重命名跨模块符号
- 常见问题：入口闭包不完整、符号冲突、找不到预编译 loader、缺少 runtime DLL

**章节来源**
- [src/project.rs:58-153](file://src/project.rs#L58-L153)
- [src/project_compiler.rs:205-332](file://src/project_compiler.rs#L205-L332)
- [src/project_compiler.rs:384-567](file://src/project_compiler.rs#L384-L567)

### 原生链接器（native-linker）
- 功能：合并多个 .obj、构建符号表、解析导入、处理重定位、生成 PE 并输出诊断
- 关键点：自动注入 runtime 对象、诊断反馈（警告/错误/建议）、统计信息
- 常见问题：缺少 .pdata、.rdata 不可写、未定义符号、入口点配置不当

**章节来源**
- [src/native_linker.rs:147-382](file://src/native_linker.rs#L147-L382)
- [src/native_linker.rs:204-283](file://src/native_linker.rs#L204-L283)

## 依赖关系分析
- 构建与运行时依赖：SWC、Cranelift、object、log/env_logger、serde 等
- CLI 与库：CLI 依赖 CodeGen 与 SWC；库导出 FFI 结构供加载器使用
- 加载器与运行时：加载器依赖运行时 DLL；运行时提供 js_* 外部函数
- 项目编译器与链接器：项目编译器产出 .obj，原生链接器可进一步生成 PE

```mermaid
graph LR
Cargo["Cargo.toml 依赖"] --> SWC["swc_*"]
Cargo --> CL["cranelift-*"]
Cargo --> OBJ["object"]
Cargo --> LOG["log/env_logger"]
CLI["ts-native<br/>src/main.rs"] --> SWC
CLI --> CG["CodeGen<br/>src/codegen.rs"]
CG --> CL
CG --> OBJ
LDR["tsn-loader<br/>loader/src/main.rs"] --> RT["runtime/src/lib.rs"]
PC["project_compiler.rs"] --> CG
PC --> LDR
NL["native_linker.rs"] --> OBJ
```

**图表来源**
- [Cargo.toml:22-57](file://Cargo.toml#L22-L57)
- [src/main.rs:3-6](file://src/main.rs#L3-L6)
- [src/codegen.rs:6-18](file://src/codegen.rs#L6-L18)
- [loader/src/main.rs:130-510](file://loader/src/main.rs#L130-L510)
- [runtime/src/lib.rs:1-800](file://runtime/src/lib.rs#L1-L800)
- [src/project_compiler.rs:16-25](file://src/project_compiler.rs#L16-L25)
- [src/native_linker.rs:11-14](file://src/native_linker.rs#L11-L14)

**章节来源**
- [Cargo.toml:1-57](file://Cargo.toml#L1-L57)
- [src/lib.rs:7-16](file://src/lib.rs#L7-L16)

## 性能考虑
- 编译性能：CodeGen 收集字符串池、函数签名、重定位，统计编译时间与代码大小
- 运行性能：加载器使用 StageTimer 计时各阶段耗时；重定位数量与类型影响执行速度
- 内存估算：项目编译器在 Windows 上使用 GetProcessMemoryInfo，在其他平台读取 /proc/self/status
- 优化建议：减少不必要的字符串常量、避免过度复杂的数据结构、合理组织模块以降低重定位数量

**章节来源**
- [src/codegen.rs:240-252](file://src/codegen.rs#L240-L252)
- [loader/src/main.rs:202-222](file://loader/src/main.rs#L202-L222)
- [src/project_compiler.rs:54-121](file://src/project_compiler.rs#L54-L121)

## 故障排除指南

### 一、编译错误（CLI/项目编译器）
- 症状：命令行提示用法、退出码 1
- 排查步骤：
  - 确认输入文件存在且可读
  - 检查输出目录权限
  - 若使用项目编译器，确认入口文件与模块路径解析正确
- 相关实现参考：
  - CLI 参数解析与错误输出：[src/main.rs:7-43](file://src/main.rs#L7-L43)
  - 项目入口识别与默认策略：[src/project.rs:83-137](file://src/project.rs#L83-L137)

**章节来源**
- [src/main.rs:7-43](file://src/main.rs#L7-L43)
- [src/project.rs:83-137](file://src/project.rs#L83-L137)

### 二、运行时错误（加载器/运行时）
- 症状：加载器报错"未找到文件"、"插件加载失败"、"符号未解析"、"重定位失败"
- 排查步骤：
  - 确认 tsn_runtime.dll 存在且可被加载
  - 检查插件路径与名称，确保符号存在于 DLL 导出
  - 核对重定位类型与目标符号是否匹配
  - 使用更详细的日志级别（--log-level debug/trace）
- 相关实现参考：
  - 插件加载与符号解析：[loader/src/main.rs:272-325](file://loader/src/main.rs#L272-L325)
  - 重定位应用与错误统计：[loader/src/main.rs:632-711](file://loader/src/main.rs#L632-L711)
  - 运行时导出函数：[runtime/src/lib.rs:135-800](file://runtime/src/lib.rs#L135-L800)

**章节来源**
- [loader/src/main.rs:272-325](file://loader/src/main.rs#L272-L325)
- [loader/src/main.rs:632-711](file://loader/src/main.rs#L632-L711)
- [runtime/src/lib.rs:135-800](file://runtime/src/lib.rs#L135-L800)

### 三、链接器错误（原生链接器）
- 症状：缺少 .pdata、.rdata 不可写、未定义符号、入口点错误
- 排查步骤：
  - 检查合并节区是否包含 .pdata
  - 确保 .rdata 节区具备可写标志
  - 核对导入函数列表与符号表
  - 按诊断反馈修正配置
- 相关实现参考：
  - 诊断反馈与建议：[src/native_linker.rs:204-283](file://src/native_linker.rs#L204-L283)
  - 合并节区与特性清理：[src/native_linker.rs:384-489](file://src/native_linker.rs#L384-L489)
  - 解析外部符号与导入：[src/native_linker.rs:555-700](file://src/native_linker.rs#L555-L700)

**章节来源**
- [src/native_linker.rs:204-283](file://src/native_linker.rs#L204-L283)
- [src/native_linker.rs:384-489](file://src/native_linker.rs#L384-L489)
- [src/native_linker.rs:555-700](file://src/native_linker.rs#L555-L700)

### 四、日志配置与错误信息解读
- 日志级别：支持 error/warn/info/debug/trace，可通过 --log-level 或环境变量 RUST_LOG 控制
- 时间戳与目标：加载器自定义日志格式包含时间戳与目标模块
- 常见日志关键词：
  - "Reloc"：重定位统计与失败项
  - "Plugin"：插件加载与符号解析
  - "Compiler"：编译阶段统计
  - "Exec"：执行阶段统计
- 相关实现参考：
  - 日志初始化与格式化：[loader/src/main.rs:157-200](file://loader/src/main.rs#L157-L200)
  - 阶段计时器：[loader/src/main.rs:202-222](file://loader/src/main.rs#L202-L222)

**章节来源**
- [loader/src/main.rs:157-200](file://loader/src/main.rs#L157-L200)
- [loader/src/main.rs:202-222](file://loader/src/main.rs#L202-L222)

### 五、性能问题与优化建议
- 编译期：
  - 减少字符串常量数量，避免重复池化开销
  - 合理拆分模块，降低单模块函数数量
- 运行期：
  - 降低重定位数量与类型复杂度
  - 使用更细粒度的日志级别，避免过多 trace 输出
- 内存：
  - 在 Windows 上关注工作集大小，避免频繁分配/释放
- 相关实现参考：
  - 编译统计与字符串池：[src/codegen.rs:240-252](file://src/codegen.rs#L240-L252)
  - 内存估算与格式化：[src/project_compiler.rs:54-137](file://src/project_compiler.rs#L54-L137)

**章节来源**
- [src/codegen.rs:240-252](file://src/codegen.rs#L240-L252)
- [src/project_compiler.rs:54-137](file://src/project_compiler.rs#L54-L137)

### 六、已知问题与限制
- Windows 限定：加载器在非 Windows 平台直接报错
- 项目模块优先级：非相对路径导入优先匹配用户模块，可能导致与内置模块混淆
- 链接器诊断：部分 PE 特性（如 .pdata、对齐标志）需人工校验
- 相关实现参考：
  - 平台限制与错误提示：[loader/src/main.rs:122-127](file://loader/src/main.rs#L122-L127)
  - 模块导入解析与提示：[src/project.rs:232-257](file://src/project.rs#L232-L257)
  - 诊断反馈：[src/native_linker.rs:204-283](file://src/native_linker.rs#L204-L283)

**章节来源**
- [loader/src/main.rs:122-127](file://loader/src/main.rs#L122-L127)
- [src/project.rs:232-257](file://src/project.rs#L232-L257)
- [src/native_linker.rs:204-283](file://src/native_linker.rs#L204-L283)

### 七、社区支持与问题报告
- GitHub Issues：请在仓库提交问题，附带最小复现、日志与版本信息
- 提交规范：遵循模板，提供编译/运行环境、输入文件片段、期望与实际行为对比
- 相关实现参考：
  - 项目元信息与依赖：[Cargo.toml:1-57](file://Cargo.toml#L1-L57)

**章节来源**
- [Cargo.toml:1-57](file://Cargo.toml#L1-L57)

## 调试技巧与诊断方法

### 一、系统化故障排除流程
```mermaid
flowchart TD
A["问题出现"] --> B["收集基本信息<br/>操作系统、版本、日志"]
B --> C["确定问题类型<br/>编译/运行/链接"]
C --> D["查看对应日志<br/>--log-level debug/trace"]
D --> E["检查关键组件<br/>CLI/加载器/链接器"]
E --> F["隔离问题范围<br/>逐步缩小"]
F --> G["应用解决方案<br/>修改配置/修复代码"]
G --> H["验证修复<br/>重新测试"]
H --> I["记录解决方案<br/>更新文档"]
```

**图表来源**
- [loader/src/main.rs:1163-1186](file://loader/src/main.rs#L1163-L1186)

### 二、详细调试步骤

#### 1. 编译期调试
- 启用详细编译日志：使用 `--log-level trace`
- 检查编译统计信息：关注函数数量、字符串数量、代码大小
- 验证中间产物：检查生成的 .obj 文件完整性
- 调整编译参数：优化字符串池大小、函数内联策略

#### 2. 运行期调试
- 使用阶段计时器：观察各阶段耗时差异
- 监控重定位过程：检查重定位类型和成功率
- 分析符号解析：确认内部符号和外部符号解析正确
- 检查内存分配：验证代码段、数据段、重定位段分配

#### 3. 链接期调试
- 分析链接诊断：仔细阅读警告、错误、建议信息
- 检查节区特性：验证对齐标志、COMDAT 标志
- 验证导入表：确认所有必需的 DLL 导入都已正确解析
- 测试入口点：确保入口点配置正确

**章节来源**
- [loader/src/main.rs:202-222](file://loader/src/main.rs#L202-L222)
- [src/native_linker.rs:204-283](file://src/native_linker.rs#L204-L283)

### 三、高级诊断工具

#### 1. 性能分析工具
- 编译性能监控：使用 `CompileStats` 结构体收集编译统计数据
- 运行时性能追踪：利用 `StageTimer` 计时各阶段执行时间
- 内存使用分析：监控工作集大小和内存分配模式

#### 2. 错误诊断技巧
- 分层排查：从最外层组件向内层组件逐步深入
- 关键词搜索：在日志中搜索特定关键词（如 "Reloc"、"Plugin"）
- 状态检查：验证每个组件的状态和配置
- 依赖验证：确认所有必需的依赖都已正确安装和配置

#### 3. 日志分析方法
- 时间序列分析：按时间顺序分析日志事件
- 组件关联分析：将不同组件的日志事件关联起来
- 异常模式识别：识别重复出现的错误模式
- 根因分析：从异常事件回溯到初始原因

**章节来源**
- [src/codegen.rs:240-252](file://src/codegen.rs#L240-L252)
- [loader/src/main.rs:157-200](file://loader/src/main.rs#L157-L200)

### 四、常见问题深度解析

#### 1. 编译器相关问题
- **编译失败但无明确错误信息**：启用 `--log-level trace` 获取详细编译日志
- **编译速度慢**：检查字符串池大小、函数内联设置、优化级别
- **生成的 .obj 文件过大**：分析代码生成统计，优化数据结构设计

#### 2. 加载器相关问题
- **插件加载失败**：检查插件路径、文件权限、符号导出
- **符号未解析**：验证符号名称格式、导出函数签名
- **重定位失败**：检查重定位类型、目标地址有效性

#### 3. 链接器相关问题
- **PE 文件无法运行**：检查 .pdata 节区、对齐标志、入口点配置
- **导入函数缺失**：验证导入表构建、符号解析过程
- **链接时间过长**：优化节区合并策略、重定位处理

**章节来源**
- [loader/src/main.rs:272-325](file://loader/src/main.rs#L272-L325)
- [src/native_linker.rs:204-283](file://src/native_linker.rs#L204-L283)

## 结论
本指南基于仓库现有实现，提供了从编译、运行到链接的全流程故障排除方法与优化建议。建议在日常使用中：
- 使用更详细的日志级别定位问题
- 严格遵循模块导入与入口配置
- 参考链接器诊断反馈修正 PE 生成
- 在 Windows 环境下进行加载器与运行时交互验证
- 建立系统化的调试流程和问题记录机制

## 附录
- 构建脚本：通过 build.rs 编译 runtime_nocrt.c 与 start_nocrt.c，设置优化等级与输出目录
- 相关实现参考：
  - 构建脚本：[build.rs:4-32](file://build.rs#L4-L32)

**章节来源**
- [build.rs:4-32](file://build.rs#L4-L32)