How do you symbolicate one crash address by hand: load address, ASLR slide, atos, stripped binaries and dSYMs?

23.10.2 · L5 · Interview

Predict first

A function address is looked up with the right load address, then against a stripped binary, then with a wrong load address. What do you get?

// === main.swift ===
struct Account {
    var balance = 0
    mutating func deposit(_ x: Int) { balance += x }
}
var a = Account(); a.deposit(2); print(a.balance)
  • function and line from the dSYM; a raw address for the stripped binary and for the wrong slide
  • the function every time
  • a raw address every time

Mental model. A street number seen from a different map origin: you must subtract the offset before you can look it up.

Addresses in a crash report are runtime addresses: the image was loaded at a random offset (ASLR). atos -o <dSYM binary> -arch arm64 -l <load address> <address> subtracts the load address to find the symbol. The load address comes from the report’s binary-image list (for the app it is the first image’s base). In the check the image’s link-time base is 0x100000000; giving the right -l resolves the function and line (Account.deposit(_:) (in app) (main.swift:3)), while a wrong load address (0x100004000 for the same input) prints the raw address back, which is the symptom of a mismatched slide.

A fully stripped binary has no symbol table, so atos on it returns a bare address; with the dSYM, line information returns. That is why Release apps are stripped and shipped separately from their dSYM, matched by UUID (Q461). In practice you rarely do this manually: Xcode, Organizer and crash services do it, but doing one by hand verifies that the dSYM and report really correspond.

Symbols and the correct slide are both required.

Common traps

  • Using the wrong load address. You get the raw address or the wrong function.
  • Symbolicating against a different build’s dSYM. Check UUIDs first.

They might follow up with

  • Inlined frames? atos -i prints them.
  • Where is the UUID? dwarfdump --uuid (Q461).

Related questions

  • 23.5.1 How do you read a crash report, what do the exception types and Swift runtime messages mean, and how does…
  • 23.10.3 Why can a dSYM exist yet give no file and line numbers, and how do you check it?
  • 23.10.1 What are Swift mangled names such as $s3sym7AccountV7deposityySiF, how do you read them, and where do they…

← What are Swift mangled names such as $s3sym7AccountV7deposityySiF…   Why can a dSYM exist yet give no file and line numbers, and how do… →