Obtaining and Analyzing iOS Crash Logs with LLDB and Crashlog Scripts
This article explains how iOS developers can retrieve crash logs from simulators, test devices, and App Store releases, then use LLDB and custom crashlog scripts to symbolicate, inspect stack traces, and resolve hard‑to‑reproduce crashes caused by memory‑management issues such as over‑release.
When an iOS app crashes intermittently, the crash information recorded by the system can be far more detailed than typical analytics tools provide. The article assumes familiarity with stack traces and symbolication and focuses on using raw crash logs to debug elusive bugs.
Where to get crash logs
Simulator: locate logs in ~/Library/Logs/DiagnosticReports (files named processName+date+timestamp+deviceName.crash ).
Physical device: connect the device, open Xcode → Window → Devices and Simulators, select the device and click View Device Logs to list logs of type crash .
App Store / TestFlight: after users opt‑in to share crash data, logs appear in Xcode → Window → Organizer → Crashes. Right‑click a crash, choose Show in Finder , then navigate to the .crash file inside the .xccrashpoint package.
The article also notes that third‑party services (Crashlytics, Bugly, etc.) provide limited information compared to the full system‑generated crash log.
Crash‑log contents
The log begins with a header (incident identifier, hardware model, process, OS version, etc.), followed by an Exception Type section (e.g., EXC_BAD_ACCESS (SIGSEGV) with subtype KERN_INVALID_ADDRESS ) and, when available, an Application Specific Information line that may pinpoint the exact cause (e.g., an unexpected nil optional).
After the header comes the stack trace (backtrace). The first frame often belongs to a system library such as libobjc.A.dylib , indicating a memory‑management problem, while the lowest frame that belongs to the app points to the offending method (e.g., TelisFlowQuestionStreamer.reset() ).
Using LLDB to analyse the log
Launch LLDB from the terminal:
$ lldbImport the built‑in crash‑log helper script:
command script import lldb.macosx.crashlogRun the script on the crash file:
(lldb) crashlog path/to/crashlog.crashIf the script cannot find the matching binary, the article explains how to edit the Binary Images paths in the log to point to the local .xcarchive and ensure the correct dSYM files are available.
It also discusses common pitfalls such as missing symbols due to Bitcode, mismatched device support files, and Python import issues when LLDB uses a non‑system Python interpreter.
Custom crash‑log cracker
A modified script ( CrashlogCracker ) can be invoked as:
$ python CrashlogCracker.py --archive Telis.xcarchive/ crashlog.crashAfter rebuilding the log, re‑run the crashlog command in LLDB to obtain a fully symbolicated stack, revealing the exact source line (e.g., TelisFlowQuestionStreamer.swift:81 ) that triggered the over‑release.
The article concludes with a brief explanation of why objc_object::release() can cause EXC_BAD_ACCESS when an object has been over‑released, and points readers to Apple’s open‑source repositories for deeper understanding of Objective‑C object layout and malloc internals.
Liulishuo Tech Team
Help everyone become a global citizen!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.