feat(cli): upload Mach-O executables as native debug symbols#72776
Conversation
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
|
1bf9d6e to
347d9c7
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1bf9d6e78d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Agreed that the original high severity wording overstated the practical threat model: exploitation requires an authenticated upload context plus the ability to place or replace an artifact in the scanned directory, and the resulting symbol set is scoped to that project. I would still treat the path handling as a security boundary worth fixing centrally, since artifact write access does not necessarily imply read access to the uploader’s local/CI credentials (for example, a compromised build dependency or artifact step). The impact is arbitrary files readable by that upload process being bundled into the project’s symbol upload—not anonymous cross-project access. A shared fix across the existing source-bundling paths is the right approach. |
…ostHog/posthog#72776 adds Mach-O executable support to\n`symbol-sets upload`, enabling Go on macOS to upload debug symbols\ndirectly (Go never produces dSYM bundles).\n\n- Update CalloutBox to remove 'symbol set uploads not available' note\n- Add optional step for building with uncompressed DWARF and uploading
Reflects PostHog/posthog#72776 which extends the CLI to accept standalone Mach-O executables, dylibs, and debug companions alongside ELF files and dSYM bundles. Universal (fat) binaries are automatically split per architecture slice.
Problem
symbol-sets uploadaccepts ELF files and Apple.dSYMbundles, but not standalone Mach-O executables. That leaves Go on macOS with no upload path at all: Go embeds DWARF directly in the executable and never produces a dSYM (dsymutilreports "no debug symbols in executable" because Go's linker emits no debug map). With the Go SDK now sending native frames and$debug_imageson macOS (PostHog/posthog-go#260), those events can never be re-symbolicated server-side.Changes
0xcafebabf) stays unsupported, matching the parser.LC_UUID, uppercased to match the SDKs anddsym upload; packaging uses theAppleDsymcontainer with the binary atdwarfin the ZIP, the layout the server already parses. Files inside.dSYMbundles stay owned by the dsym packaging path.__zdebugsections), which symbolication can't read yet. Those binaries are classified separately and skipped with guidance to rebuild with-ldflags=-compressdwarf=false, rather than uploaded as a names-only set that would resolve worse than the SDK's own runtime symbolication. Mach-O files missing anLC_UUIDalso get their own guidance instead of the ELF build-id advice.--include-sourceworks unchanged (DWARF source-path extraction is format-agnostic); the native source filter also drops/go/pkg/mod/now.test_go_binary_macho.zst(uncompressed DWARF) andtest_go_binary_macho_zdebug.zst(default build), generated by the existingbuild.sh.How did you test this code?
New integration tests: thin Mach-O discovery and packaging (uppercase
LC_UUIDchunk id,AppleDsymcontainer, Mach-O magic atdwarf), compressed-DWARF classification with a hard error when nothing else is uploadable, and a two-slice fat container asserting each slice uploads separately under its own UUID with its own bytes. Full CLI suite (149 tests) andcargo clippy --all-targets -- -D warningspass locally. Also verified end-to-end against symbolic 12.17.2 that an uncompressed-DWARF Go darwin binary converts to a symcache with files, lines, and inline expansions, while the default compressed build yields symbol-table names only, which is what motivates the skip-with-guidance behavior.Automatic notifications
Docs update
cli/README.mdupdated in this PR; a release changeset is included (minor). The posthog.com error tracking docs get the Go/macOS setup flags in a separate docs PR.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Claude Code authored this after a tester hit the dSYM dead end with a Go macOS binary. I (Claude) verified the failure boundary first: Go's
__DWARFsegment is embedded in the executable,dsymutilcan't consume it, and symbolic reads it fully only when built with-compressdwarf=false(the compressed default degrades to symbol-table-only). Review rounds tightened the initial version: fat64 magic removed since the parser doesn't support it, missingLC_UUIDsplit out of the ELF build-id guidance, and the fat test extended to two slices with distinct UUIDs.