Mobile Development 21 min read

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.

Liulishuo Tech Team
Liulishuo Tech Team
Liulishuo Tech Team
Obtaining and Analyzing iOS Crash Logs with LLDB and Crashlog Scripts

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:

$ lldb

Import the built‑in crash‑log helper script:

command script import lldb.macosx.crashlog

Run the script on the crash file:

(lldb) crashlog path/to/crashlog.crash

If 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.crash

After 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.

DebuggingMobile DevelopmentiOScrash logsymbolicationLLDB
Liulishuo Tech Team
Written by

Liulishuo Tech Team

Help everyone become a global citizen!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.