Commit b0cd598
committed
feat(symbols): use running-process for c++filt + project-mode + dual JSON/MD output
Three improvements bundled in response to maintainer feedback on #424:
## 1. Use `running_process` for the c++filt subprocess
`demangle_batch` previously called `std::process::Command::spawn`
directly with a hand-rolled writer thread to avoid the Windows
pipe-buffer deadlock. That bypassed fbuild's subprocess discipline
(dylint allowlist entry + `// allow-direct-spawn` annotation + the
Python `ci/find_direct_subprocess.py` gate all had to be wired in).
Route through `NativeProcess` instead via a new helper
`fbuild_core::subprocess::run_command_with_stdin(args, stdin_bytes,
…)`. running-process's `start()` spawns reader threads for
stdout/stderr the moment the child launches, so the drain happens
concurrently with our `write_stdin` call — same race-free behavior
the manual thread provided, but with the standard subprocess plumbing.
Side effects: drop the
`crates/fbuild-build/src/symbol_analyzer.rs` entry from
`dylints/ban_raw_subprocess/src/allowlist.txt`, drop the inline
`// allow-direct-spawn:` annotation. No more raw spawn = no more
exemption needed = simpler audit story going forward.
## 2. `fbuild symbols` now accepts a project directory
`<input>` may be either an ELF path or a project root. When a
directory is given, `discover_elf_in_project` walks in priority
order:
1. `<dir>/build_info.json` or `build_info_<env>.json` and read
`prog_path` (PIO / fbuild emitter convention).
2. `<dir>/.fbuild/build/**/firmware.elf` (fbuild native output).
3. `<dir>/.pio/build/**/firmware.elf` (PlatformIO output).
4. Any `*.elf` directly inside `<dir>` (newest wins).
This means `fbuild symbols .` Just Works for both build backends.
A follow-up issue (#428) tracks extending `build_info.json` to
include `nm_path`, `cppfilt_path`, `readelf_path`, `objdump_path`
so the orchestrator stops needing `--nm` for non-fbuild ELFs.
## 3. `--output-dir <dir>` writes BOTH report.json + report.md
The existing `--json <path>` writes a single machine-readable file.
The new `--output-dir <dir>` produces *both* `report.json`
(machine) and `report.md` (human-readable, GitHub-style tables)
side by side so reviewers can scan the markdown without losing the
machine-parseable view.
Tests
-----
10 new unit tests cover:
- elf_from_build_info: PIO env-keyed shape, flat shape,
missing-field fallback.
- discover_elf_in_project: prefers build_info.json over loose
.elf, falls back to loose .elf, returns None when nothing.
- format_markdown_report: header, flash/ram tables, archive
roll-up table, pipe-escaping for operator overloads in symbol
names.
End-to-end: same 3696 sized symbols (316,368 B flash / 34,927 B ram)
on the master ELF as before — no behavior change, just plumbing.
Refs #428 (build_info.json toolchain-path follow-up).1 parent a409c4c commit b0cd598
6 files changed
Lines changed: 526 additions & 84 deletions
File tree
- crates
- fbuild-build/src
- fbuild-cli/src/cli
- fbuild-core/src
- dylints/ban_raw_subprocess/src
0 commit comments