# oh_tools **Repository Path**: Cooper0/oh_tools ## Basic Information - **Project Name**: oh_tools - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-18 - **Last Updated**: 2026-09-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 堆栈解析工具 Tauri v2 桌面应用,面向 OpenHarmony/HarmonyOS 开发调试场景,集成堆栈解析、反汇编、HDC 设备操作、本地文件夹并发拷贝等功能。 ## 功能概览 | 页面 | 功能 | 说明 | |------|------|------| | 文本解析 | 堆栈解行号 | 粘贴堆栈文本,自动提取库名/偏移/BuildId,从 unstrip 目录查找 ELF,调用 llvm-addr2line 解析(含内联帧) | | 文件解析 | 批量堆栈解析 | 选择含堆栈的文本文件,解析后写回原文件或新文件 | | 反汇编 | ELF 反汇编 | 选择 ELF 文件,调用 llvm-objdump + llvm-cxxfilt 生成带源码注释的汇编 | | HDC 工具 | 设备操作 | 连接 HDC 服务器,刷新设备列表,执行预置命令(hilog/selinux/设备信息等),文件推送/拉取 | | 文件夹拷贝 | 并发拷贝 | 多线程并发拷贝本地文件夹(SMB/本地),实时显示进度,可取消 | > 同一二进制支持命令行模式:带子命令参数运行时进入 CLI(不启动图形界面),详见 [命令行模式](#命令行模式cli)。 ## 技术栈 - **后端**: Rust + Tauri v2(async 命令 + spawn_blocking) - **前端**: 纯 HTML/CSS/JS(无框架) - **嵌入工具**: llvm-addr2line / llvm-objdump / llvm-cxxfilt / llvm-readelf(include_bytes! 编译期嵌入,运行时提取) - **HDC**: hdc_lib_rs(内嵌 hdc 二进制 + libusb) - **并发拷贝**: threadpool(遍历线程独立于线程池,边遍历边拷贝) ## 平台支持 - **Linux**: x86_64-unknown-linux-gnu(原生编译) - **Windows**: x86_64-pc-windows-gnu(Linux 交叉编译,mingw 工具链) ## 编译 ### 环境准备 ```bash # 1. 安装 Tauri v2 系统依赖(Linux) sudo apt install -y libwebkit2gtk-4.1-dev libgtk-3-dev libglib2.0-dev librsvg2-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev libayatana-appindicator3-dev # 2. 安装 Tauri CLI cargo install tauri-cli --version "^2.0" # 3. 安装 Windows 交叉编译目标 rustup target add x86_64-pc-windows-gnu # 4. 准备 llvm 工具二进制 ./setup-llvm.sh ``` ### 编译命令 ```bash ./build.sh # 编译 Linux release ./build.sh windows # 交叉编译 Windows release ./build.sh all # 同时编译 Linux + Windows ./build.sh all --debug # 全部用 debug profile ./build.sh all --dist # 编译并打包分发压缩包 ./build.sh --help # 帮助菜单 ``` ### 产物 | 平台 | 路径 | 说明 | |------|------|------| | Linux | `target/release/tauri_test` | 单一二进制,内嵌全部工具 | | Windows | `target/x86_64-pc-windows-gnu/release/tauri_test.exe` | 需同目录放 `WebView2Loader.dll` | ## 堆栈格式支持 ### 格式 A(Android/OpenHarmony 风格) ``` #00 pc 000a7d3c /system/lib/ld-musl-arm.so.1(get_meta+92)(e7f9c7b2f43af570ea0042af00f4d899) ``` - 支持函数名含嵌套括号的 C++ 签名(如 `WriteBinder(unsigned long, void*)+66`) - BuildId 可选,有则校验,无则按 basename 查找 ### 格式 B(带 0x 地址 + BuildId 标签) ``` #0 0x651a5c0fa0 (/data/storage/el1/bundle/libs/arm64/libijk.so+0x2c0fa0) (BuildId: 84383086df874d94fa191ddbbc25091cc14992c5) ``` ## 命令行模式(CLI) 同一二进制支持双模式:**无参数启动 GUI**;**带子命令参数进入 CLI**(不拉起图形界面,结果输出到 stdout/stderr)。CLI 错误统一用 `anyhow`,带 context 链,退出码非 0。 ### 子命令 | 子命令 | 短选项 | 参数(短/长) | 说明 | |--------|------|------|------| | `stack-text` | `-s` | `-u/--unstrip [-i/--input ]` | 解析堆栈文本;省略 `--input` 时从 stdin 读取 | | `stack-file` | `-f` | `-u/--unstrip -i/--input [-o/--overwrite] [-d/--out-dir ] [-n/--out-name ]` | 批量解析文件并写回 | | `disasm` | `-d` | `-e/--elf [-p/--prefix ]` | 反汇编 ELF 为 `.asm` | | `hdc-list` | `-l` | `[-i/--ip ] [-p/--port ]` | 列出 HDC 设备 | | `hdc-exec` | `-e` | `-d/--device [-i] [-p] -c/--cmd "..."` | 执行 hdc 命令;`-c` 可多次,每条空格分隔 | | `hdc-config` | `-c` | `-g/--get` 或 `-s/--save ` | 读取/保存 HDC 按钮配置 JSON | | `hdc-send` | `-n` | `-d/--device -l/--local -r/--remote [-i] [-p]` | 推送文件/文件夹到设备 | | `hdc-recv` | `-r` | `-d/--device -r/--remote -l/--local [-i] [-p]` | 从设备拉取文件/文件夹 | | `copy` | `-p` | `-s/--src -d/--dst ` | 本地文件夹并发拷贝,进度刷新到 stderr | 子命令可用短选项触发(程序内部翻译为对应子命令):`-s`/`-f`/`-d`/`-l`/`-e`/`-c`/`-n`/`-r`/`-p`。例 `tauri_test -s -u ` 等同 `tauri_test stack-text -u `。 全局选项:`-v/--verbose` 详细日志(等价 `RUST_LOG=debug`)。 ### 示例 ```bash # 从 stdin 解析堆栈 echo "#0 0x0 (/data/lib/libfoo.so+0x1234)" | tauri_test stack-text --unstrip /path/to/unstripped # 解析文件写回新文件 tauri_test stack-file --unstrip /path/to/unstripped --input crash.txt --out-name crash_parsed.txt # 反汇编 tauri_test disasm --elf libfoo.so --prefix /source/root # 列设备 + 执行命令 tauri_test hdc-list tauri_test hdc-exec --device 123456789 --cmd "shell getenforce" --cmd "shell param get const.product.model" # 读取/保存配置 tauri_test hdc-config --get > cmd_config.json tauri_test hdc-config --save cmd_config.json # 本地文件夹拷贝 tauri_test copy --src /from --dst /to ``` ### 退出码 - `0`:成功 - `1`:业务错误(解析失败、文件读写失败、hdc 报错等,错误信息打到 stderr) - `2`:参数错误(clap 自动处理) ### Windows 控制台说明 Windows release 为 GUI 子系统(双击不弹黑框)。CLI 模式从 cmd/powershell 调用时自动 `AttachConsole(ATTACH_PARENT_PROCESS)` 附加父进程控制台,stdout/stderr 正常输出。父进程无控制台(如资源管理器双击)时输出丢失,但逻辑仍执行,日志落盘到 exe 同目录 `tauri_test_{pid}.log`。Linux 原生正常。 ## 项目结构 ``` tauri_test/ ├── src/ # 前端(HTML/CSS/JS) │ ├── index.html # 五个 Tab 页面 │ ├── main.js # 事件绑定、invoke 调用 │ └── styles.css # 深色主题 ├── src-tauri/ # Rust 后端 │ ├── resources/{linux,windows}/ # 嵌入的 llvm 工具 │ └── src/ │ ├── cli.rs # CLI 子命令(clap)与 Windows 控制台附加 │ ├── commands.rs # async Tauri 命令(薄封装 core) │ ├── core.rs # 堆栈解析核心逻辑(GUI/CLI 共用) │ ├── stack_parser.rs # 堆栈解析 │ ├── elf_resolver.rs # ELF 查找 + BuildId 校验 │ ├── addr2line.rs # 解行号(--inlines 保留内联帧) │ ├── objdump.rs # 反汇编 │ ├── bin_manager.rs # 工具嵌入/提取/子进程管理 │ ├── hdc_tool/ # HDC 设备操作 │ ├── dir_copy/ # 并发文件夹拷贝 │ ├── edge_hide.rs # 窗口靠边吸附隐藏(仅 Windows) │ └── logger.rs # 日志系统 ├── build.sh # 编译脚本 ├── setup-llvm.sh # llvm 工具准备 └── plant.md # 设计文档与进展记录 ``` ## 测试 ```bash cd src-tauri cargo test --lib # 单元测试 cargo clippy --lib # 代码检查 ``` ## 依赖 - [Tauri v2](https://v2.tauri.app/) — 桌面应用框架 - [hdc_lib_rs](https://gitee.com/Cooper0/hdc_lib_rs) — HDC 设备通信库 - [threadpool](https://crates.io/crates/threadpool) — 线程池 - [anyhow](https://crates.io/crates/anyhow) — 错误处理 - [clap](https://crates.io/crates/clap) — CLI 参数解析 - [regex](https://crates.io/crates/regex) — 正则表达式 - [log](https://crates.io/crates/log) + [env_logger](https://crates.io/crates/env_logger) — 日志系统,落盘到 exe 同目录 ## 插件化(动态库扩展) 框架支持动态库插件,新插件=新页面,C ABI 边界 + SDK 宏封装(开发者无感 CString)。 ### 插件开发 1. 新建 crate,`crate-type = ["cdylib"]`,依赖 `plugin-sdk` 2. 实现 `Plugin` trait(`manifest`/`frontend_html`/`frontend_script`/`invoke`) 3. `declare_plugin!(MyPlugin, MyPlugin);` 生成 C ABI 符号 4. `cargo build` 产出 `.so`/`.dll`,放 exe 同级 `plugins/` 5. 重启应用,Tab 自动出现 ### 示例 见 `examples/hello-world/`。插件 JS 调 `window.framework.pluginCall(id, cmd, args)` 与后端通信。 ### 约束 C ABI 边界,插件可用任意 rustc 编译(跨 rustc 稳定);`plugin_abi_version` 校验 SDK 版本,不符拒载。框架自动调 `plugin_free_str` 防内存泄漏。