feat(debugserver): attach lldb to a running process by pid (ios debug --pid) - #801
Open
danielpaulus wants to merge 3 commits into
Open
feat(debugserver): attach lldb to a running process by pid (ios debug --pid)#801danielpaulus wants to merge 3 commits into
danielpaulus wants to merge 3 commits into
Conversation
ios debug now supports --pid=<processID> to attach lldb to an already running process via com.apple.debugserver, instead of only launching an app from a local .app path. The lldb/python script generation is refactored into a pure renderLLDBScripts function with unit tests covering launch, launch --stop-at-entry, and attach modes. Fixes #387 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8eMENxJ1nec9CeHp4tjWk
Owner
Author
|
/test-devices |
Contributor
Contributor
|
❌ Real-device tests failed — see run. |
The per-command help catalog (internal/clihelp/help.yaml) is what `ios help debug` / `ios debug --help` renders, separate from the top-level docopt usage in main.go. PR #801 updated the docopt usage to `(<app_path> | --pid=<processID>)` but left the clihelp entry showing only `<app_path>`, so the new attach-by-pid mode was invisible in command help. Sync the usage and summary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8eMENxJ1nec9CeHp4tjWk
Owner
Author
Adversarial review — attach-by-pidReviewed the lldb attach semantics, docopt changes, and refactor fidelity. One real defect found and fixed; the rest of the PR is sound. Fixed (pushed to this branch, f889cfb)
Verified correct (no change needed)
Status
|
The clihelp change in f889cfb updated the debug command help but did not refresh the golden the help test compares against, failing TestHelp_GlobalNoArgs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8eMENxJ1nec9CeHp4tjWk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ios debugcan only launch an app from a local.apppath. Issue #387 asks for Xcode-style "attach to running process": connect lldb to a process that is already running on the device, addressed by its pid (ios debug --pid <pid>).Design
The existing debug flow already does everything needed except the lldb command sequence: it connects to
com.apple.debugservervia lockdown, proxies it on a random local port, and drives/usr/bin/lldbwith a generated command script plus a python helper. Attach mode reuses that connection/proxy path unchanged and only swaps the tail of the lldb script:target create "<app>"…connect…runtarget create(there is no local binary) …connect…process attach --pid <pid>The python
connect_commandcreates an empty target when none is selected (attach mode), soConnectRemotehas a target to work with; lldb'sTarget::Attachthen reuses the already-connected remote process, which is the standard flow for attaching through a gdb-remote stub. App install lookup, bundle-id resolution andInfo.plistparsing are skipped entirely for attach.Implementation
ios/debugserver/debugserver.gorenderLLDBScripts(cfg)— pure function rendering both the lldb command script and the python helper from alldbScriptConfig(launch fields orpid, plus proxy port);startLLDBnow just renders, writes the files, and executes lldb.AttachByPid(device, pid)— new public entry point; validatespid > 0, logs withmodule/udid/pidattrs viagolog.runSession(device, cfg)— the connection/proxy/lldb plumbing factored out ofStart;Start(launch) andAttachByPidboth call it.ios/debugserver/format.go—LLDB_FMTgains template conditionals for thetarget createline andrunvsprocess attach --pid;PY_FMTconnect_commandcreates an empty target if none exists (no-op in launch mode).main.go/cmd_device_debug.go— usage is nowios debug [options] [--stop-at-entry] (<app_path> | --pid=<processID>); docopt's alternation enforces exactly one of the two.--stop-at-entrywith--pidis rejected with a clear error (attaching always stops the process).Options considered
--pid=<processID>only (chosen). Pid is unambiguous, maps 1:1 to lldb'sprocess attach --pid, matches what the issue asks for, and users can resolve names to pids withios ps. It also mirrors the existing--pidoption onkill/pcap/ostrace.--attach-name=<name>(deferred). lldb supportsprocess attach --name(vAttachName/vAttachWait on the stub), which would also enable "wait for launch" semantics. Deferred because name matching on the remote stub is less predictable (partial/duplicate names), it doubles the surface to e2e-verify, and it composes cleanly on top of this PR later without touching the design.ios attachsubcommand. Rejected: attach is a mode of the same debugserver session, not a different feature; keeping it underios debugmatches Xcode's "Debug > Attach to Process" mental model and avoids duplicated docs/plumbing.Test plan
ios/debugserver/debugserver_test.gofor the purerenderLLDBScripts:target create,device_app,connect_urlport, finalrun, noprocess attach, no stop-at-entry flag in the python helper--stop-at-entry: python helper containsSetLaunchFlags(lldb.eLaunchFlagStopAtEntry)process attach --pid 1337, notarget create, norun, python helper creates the empty targetgo build ./...andgo test ./...pass;gofmt -lclean on changed files.ios debug --pid=1337parses and proceeds to device resolution;ios debugalone andios debug --pid=1 app.appare rejected by docopt.ios debugcurrently has no e2e coverage either).Fixes #387
🤖 Generated with Claude Code
https://claude.ai/code/session_01J8eMENxJ1nec9CeHp4tjWk