Figment.so
Mac hostingWebsite hostingGuidesHow to usePricing

Debug iOS Apps Remotely with LLDB on a Rented Mac

LLDB is a full command-line debugger and does not need the Xcode GUI to attach to a process, set breakpoints, or evaluate Swift expressions. On a rented Mac that you reach through a terminal, LLDB is the primary interface. This guide drives a complete debugging session from one shell: build, launch paused, attach by name, inspect, and save aliases.

Run the commands on the remote Mac itself. On Figment's virtual Intel macOS ($29/month), open the browser-console desktop terminal; inbound SSH to that VM is not exposed today. On an M-series Mac (from $95/month), confirm SSH access in the configuration quote and the commands below work over ssh -t as written.

How LLDB Attaches to iOS Simulator Processes

The iOS Simulator runs each app as a regular macOS process owned by your user account, so LLDB attaches with the same mechanisms it uses for any user process: by PID or by process name. No daemon, port forwarding, or extra entitlement is required.

Two attach strategies matter for a headless session:

  • Wait-for-name (lldb -n MyApp --waitfor): LLDB blocks until a process with that name launches, then stops it at the first instruction it can.
  • Attach by PID (lldb -p 12345): Useful when the app is already running. Find the PID with pgrep -f MyApp.app or from xcrun simctl launch output.

Combined with xcrun simctl launch --wait-for-debugger, this gives a deterministic "launch paused, attach, continue" loop without the Xcode GUI.

Build, Install, and Launch Paused

The sequence below uses a sample scheme and bundle ID — replace MyApp, MyAppScheme, and com.example.MyApp with your project's actual values.

Build a debug configuration and capture the simulator .app:

cd ~/MyApp
set -euo pipefail

xcodebuild \
  -scheme MyAppScheme \
  -destination 'platform=iOS Simulator,name=iPhone 16' \
  -configuration Debug \
  -derivedDataPath /tmp/MyApp-derived \
  build

APP_PATH=$(find /tmp/MyApp-derived/Build/Products/Debug-iphonesimulator \
  -maxdepth 2 -name 'MyApp.app' -not -path '*Tests*' | head -1)
echo "APP_PATH=$APP_PATH"

set -euo pipefail makes the script stop on the first failing command, so a failed build never falls through to install or launch.

Boot the simulator and install the app:

xcrun simctl boot 'iPhone 16' 2>/dev/null || true
xcrun simctl install booted "$APP_PATH"

Launch the app paused, waiting for a debugger to attach:

xcrun simctl launch --wait-for-debugger --console-pty booted com.example.MyApp
# Output example:
# com.example.MyApp: 48123

The PID is the number after the colon. Open a second shell on the same Mac and attach:

lldb -p 48123

Or, if you prefer attach-by-name so you can relaunch without copying a PID:

# Shell A on the Mac
lldb -n MyApp --waitfor

# Shell B on the Mac
xcrun simctl launch --wait-for-debugger booted com.example.MyApp

Once attached, LLDB sits at the first user frame. continue resumes execution; your breakpoints take over from there.

Set Breakpoints and Step

LLDB's breakpoint set accepts file-and-line, function name, and Objective-C selector forms:

(lldb) breakpoint set --file ContentView.swift --line 42
(lldb) breakpoint set --name viewDidLoad
(lldb) breakpoint set --selector dealloc
(lldb) breakpoint list
(lldb) breakpoint disable 1
(lldb) continue

thread step-over, thread step-in, and thread step-out move through a stopped frame. The aliases later in this guide shorten them to n, s, and f.

Inspect Swift Structs with frame variable and expression

At a stop, frame variable enumerates locals and arguments in the current frame:

(lldb) frame variable          # all locals, current values
(lldb) frame variable self     # self and its stored properties
(lldb) frame variable -T       # add type annotations

For Swift value printing, po runs the debug description and expression evaluates arbitrary Swift in the current frame:

(lldb) po self.viewModel
(lldb) po self.viewModel.items.count

(lldb) expression self.viewModel.items.count
(lldb) expression var $copy = self.viewModel; $copy.reset(); po $copy

If Swift type checking fails on complex generics — a recurring annoyance — fall back to p for a simpler value print or frame variable for a non-evaluated dump.

A .lldbinit for Headless Sessions

LLDB reads ~/.lldbinit on the Mac at startup. These aliases map to the commands you actually type during a terminal session:

# ~/.lldbinit on the remote Mac

command alias vt frame variable -T
command alias vs frame variable self
command alias dump expression -O --
command alias wp  watchpoint set variable
command alias bts thread backtrace --count 20
command alias n   thread step-over
command alias s   thread step-in
command alias f   thread step-out

Confirm the file loaded after restarting LLDB:

(lldb) help vt
# Current executable set to 'Alias for: frame variable -T'

A watchpoint on a property setter is a strong pattern for "who is writing this value":

(lldb) breakpoint set --name viewDidLoad
(lldb) continue
# ... hits viewDidLoad ...
(lldb) wp self.count
# Watchpoint created; LLDB stops on the next write to self.count
(lldb) continue

Which Figment Mac Fits This Workflow

Pick by the toolchain, not by price alone. Our $29/month plan is a virtual Intel macOS environment (2 vCPU, 8 GiB RAM, 80 GiB disk) running under Linux/KVM — real macOS, no GPU acceleration or audio, no inbound SSH today. It runs Intel-compatible Xcode toolchains, which Apple documents as Xcode 26 or earlier, and that is enough for the LLDB workflow above when you drive it from the browser-console terminal. It is the lowest entry price; it is not an M-series Mac and is not equivalent hardware to an M4.

For SSH-driven sessions as written, newer Xcode on Apple silicon, or visionOS targets, request an M-series Mac (from $95/month) and confirm the exact chip, RAM, disk, and SSH access in the quote. If you want the signing, CI wiring, backups, and monitoring handled, Managed Build Mac is $249/month (one M-series Mac, 30 minutes of monthly support) and Managed Mac Team is $999/month (two M-series Macs, two CI runners, one hour of monthly support).

Request a configuration at /mac-hosting or begin at /mac-hosting/start.


Related guides:


Subscribe for Figma design and website publishing guides.


Figment.so

Contact

Twitter

Website pricing

Compute index

About

Privacy

Terms