4.2 KiB
4.2 KiB
堆栈解析工具 (hstack)
hstack 是用于将 Release 应用混淆后的 crash 堆栈解析为源码对应堆栈的工具,支持 Windows、Mac、Linux 三个平台。
命令格式
hstack [options]
命令参数
| 参数 | 说明 |
|---|---|
-i, --input |
指定 crash 文件归档目录 |
-c, --crash |
指定一条 crash 堆栈 |
-o, --output |
指定解析结果输出目录(使用 -c 时指定输出文件) |
-s, --sourcemapDir |
指定 sourcemap 文件归档目录 |
--so, --soDir |
指定 shared object (.so) 文件归档目录 |
-n, --nameObfuscation |
指定 nameCache 文件归档目录 |
-v, --version |
查看版本 |
-h, --help |
查询帮助 |
参数约束
- crash 文件目录 (
-i) 与 crash 堆栈 (-c) 必须且只能提供一项 - sourcemap (
-s) 与 shared object (--so) 目录至少提供一项 - 如需还原混淆的方法名,需同时提供 sourcemap 和 nameCache 文件
- 路径参数不支持特殊字符:
`~!@#$^&*=|{};,\s\[\]<>?
环境配置
- 将 Command Line Tools 的
bin目录配置到 PATH 环境变量 - 配置 Node.js 到环境变量
- 解析 C++ 异常需配置 SDK 的
native\llvm\bin目录到环境变量ADDR2LINE_PATH
使用示例
解析 crash 文件目录
# 完整解析命令
hstack -i crashDir -o outputDir -s sourcemapDir --so soDir -n nameCacheDir
# 仅使用 sourcemap 解析 (ArkTS)
hstack -i crashDir -o outputDir -s sourcemapDir
# 仅使用 so 文件解析 (C++)
hstack -i crashDir -o outputDir --so soDir
# 包含方法名还原
hstack -i crashDir -o outputDir -s sourcemapDir -n nameCacheDir
解析单条堆栈
# 输出到控制台
hstack -c "at har (entry|har|1.0.0|src/main/ets/pages/Index.ts:58:58)" -s sourcemapDir
# 输出到文件
hstack -c "at har (entry|har|1.0.0|src/main/ets/pages/Index.ts:58:58)" -s sourcemapDir -o result.txt
输出说明
- 解析结果输出到
-o指定目录,文件以原始 crash 文件名加_前缀命名 - 不指定
-o时:- 使用
-i输入:输出到 crashDir 目录 - 使用
-c输入:直接输出到控制台
- 使用
文件获取
Sourcemap 文件
构建产物中的 sourcemap 文件,包含:
- 路径信息映射
- 行列号映射 (mappings 字段)
- package-info 信息
NameCache 文件
构建产物中的 nameCache 文件,包含:
IdentifierCache: 标识符混淆映射MemberMethodCache: 成员方法混淆映射,格式为"源码方法名:起始行:结束行": "混淆后方法名"
Shared Object (.so) 文件
构建 Release 应用时,默认 so 文件不包含符号表。如需生成包含符号表的 so 文件,在模块 build-profile.json5 中配置:
{
"buildOption": {
"externalNativeOptions": {
"arguments": "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
}
}
}
堆栈解析原理
Crash 堆栈格式
at har (entry|har|1.0.0|src/main/ets/components/mainpage/MainPage.js:58:58)
at i (entry|entry|1.0.0|src/main/ets/pages/Index.ts:71:71)
路径格式:引用方packageName|被引用方packageName|version|源码相对路径
解析步骤
-
根据路径信息找到 sourcemap
- 从路径
entry|har|1.0.0|src/main/ets/...在 entry 模块 sourcemap 中查找对应字段
- 从路径
-
利用 sourcemap 还原路径和行列号
- 根据
sources和mappings字段解析 - 如包含
package-info,可进行二次解析获取更准确的源码位置
- 根据
-
利用 nameCache 还原方法名
- 查找混淆后方法名对应的所有条目
- 根据还原后的行号范围匹配正确的源码方法名
解析示例
原始堆栈:
at i (entry|entry|1.0.0|src/main/ets/pages/Index.ts:71:71)
还原后:
at callHarFunction (entry/src/main/ets/pages/Index.ets:25:3)
CI/CD 集成
# 自动化解析脚本示例
hstack \
-i ./crash-logs \
-o ./parsed-logs \
-s ./build/sourcemap \
--so ./build/libs \
-n ./build/nameCache
常见问题
- 方法名未还原: 确保同时提供
-s和-n参数 - C++ 堆栈未解析: 检查
ADDR2LINE_PATH环境变量配置 - so 文件无符号表: 配置
RelWithDebInfo构建选项