iOS Crash Log Parsing and Symbolication: Challenges and Solutions in the Haishen Platform
This article explains how the Haishen platform collects iOS crash logs, uses KSCrash to capture rich crash context, overcomes background‑session upload limitations, extracts system symbol tables from firmware, and implements a fast, JSON‑based crash‑symbolication pipeline using atos while handling symbolicatecrash bugs.
The article begins by describing common ways to obtain iOS crash logs—including Xcode export, third‑party tools, iTunes Connection, imobiledevice, and commercial platforms like Bugly—highlighting that only the first four are practical during development, while the latter require server‑side collection.
Haishen adopts KSCrash for crash collection, which outputs crash data in JSON format that is easy for server processing, while also providing a tool to convert the JSON to Apple’s human‑readable format.
{
"report": {
"id": "2BF8D28A-A2A5-4076-952C-F8EFB4A42456",
"process_name": "LJBaseCrashReporter_Example",
"timestamp": 1569731896698234,
...
},
"binary_images": [
{
"image_addr": 4377903104,
"image_vmaddr": 4294967296,
"image_size": 2818048,
"name": "/var/containers/Bundle/Application/.../LJBaseCrashReporter_Example",
"uuid": "FE056305-553D-3ED3-AB93-7AAB60BDE692",
"cpu_type": 16777228,
"cpu_subtype": 0,
"major_version": 0,
"minor_version": 0,
"revision_version": 0
},
...
],
"system": {
"system_name": "iOS",
"system_version": "12.4",
"machine": "iPhone8,2",
"model": "N66mAP",
"CFBundleIdentifier": "com.lianjia.LJBaseCrashReporter",
...
},
"crash": {
"error": {
"mach": {
"exception": 1,
"exception_name": "EXC_BAD_ACCESS",
"code": 1,
"code_name": "KERN_INVALID_ADDRESS",
"subcode": 8
},
"signal": {
"signal": 11,
"name": "SIGSEGV",
"code": 0,
"code_name": "SEGV_NOOP"
},
"address": 1,
"type": "mach"
},
"threads": [
{
"backtrace": {
"contents": [
{
"object_name": "LJBaseCrashReporter_Example",
"object_addr": 4377903104,
"symbol_name": "-[LJCrashDebugMachsController tableView:didSelectRowAtIndexPath:]",
"symbol_addr": 4378464516,
"instruction_addr": 4378464680
},
...
],
"skipped": 0
}
}
]
}
}Because JSON is server‑friendly and Apple format is developer‑friendly, Haishen stores crash data in JSON and provides a cross‑compiler to generate Apple‑format files for manual inspection.
For real‑time upload, the platform switched from NSURLConnection (deprecated) to NSURLSession background sessions. The article shows a working Objective‑C snippet that creates a background upload task, which succeeds on iOS 12.4 but fails on older versions due to known bugs:
NSURL *URL = [NSURL URLWithString:url];
NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:URL];
requestM.HTTPMethod = @"POST";
[requestM setHTTPBody:body];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:NSUUID.UUID.UUIDString];
NSURLSession *sharedInstance = [NSURLSession sessionWithConfiguration:configuration];
NSURLSessionUploadTask *task = [sharedInstance uploadTaskWithStreamedRequest:requestM];
[task resume];Testing revealed three failure types on older iOS: (1) background session creation hangs the process on iOS 9/10, (2) Swift apps on iOS 11 encounter a pthread‑mutex deadlock, and (3) background sessions are unsupported on iOS 8 (which Haishen does not support).
To avoid the dead‑lock, Haishen replaced the Objective‑C networking stack with a trimmed libcurl implementation, illustrated by the following C code:
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POST, 1);
// set request header
struct curl_slist *headers = curl_slist_append(NULL, "Content-Encoding:gzip");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// set request body
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body_size);
curl_easy_perform(curl);The platform also needs system symbol tables to translate raw addresses. It extracts them from iOS firmware (IPSW files) by converting the IPSW to ZIP, locating the dyld_shared_cache, and using the open‑source dyld tools (dsc_extractor) to unpack the cache. The build steps are:
clang dsc_extractor.cpp dsc_iterator.cpp -lc++ -o dsc_extractor ./dsc_extractor dyld_shared_cache_arm64 arm64
./dsc_extractor dyld_shared_cache_arm64e arm64eAfter extraction, the architecture‑specific symbol files are merged with lipo to produce a universal symbol bundle, then placed under the Xcode DeviceSupport directory so that symbolicatecrash can locate them.
However, symbolicatecrash fails on some system symbols because the tool cannot handle the LC_SEGMENT_SPLIT_INFO load command (a known Apple bug). The article shows the offending Perl comment and the resulting error messages from size and objdump .
Haishen’s own parser sidesteps these issues by storing crash data as JSON, looking up symbol files directly via UUID, and invoking atos for address‑to‑symbol conversion:
atos -o LJBaseCrashReporter_Example.app.dSYM/Contents/Resources/DWARF/LJBaseCrashReporter_Example -arch arm64 -l 0x104F18000 0x104FA11A8The atos output provides method name, source file, and line number, which Haishen aggregates across threads to produce a concise, searchable crash report.
In conclusion, the article outlines a complete pipeline—from crash capture with KSCrash, through reliable background upload, automated system‑symbol extraction, and fast JSON‑based symbolication using atos —that overcomes legacy tool limitations and supports stable crash analysis for the Haishen platform.
Beike Product & Technology
As Beike's official product and technology account, we are committed to building a platform for sharing Beike's product and technology insights, targeting internet/O2O developers and product professionals. We share high-quality original articles, tech salon events, and recruitment information weekly. Welcome to follow us.
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.