3

As I mentioned I am trying to recover the line of a crash and also the function in wich it occurs.

I need to metion that I have tried the next code in AppDelegate and I get the stack not symbolicated and the class and also the error throwed:

NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);

void uncaughtExceptionHandler(NSException *exception) {

    NSLog(@"Exception description - %@",[exception description]);
    NSLog(@"Exception name - %@", [exception name]);
    NSLog(@"Reason - %@", [exception reason]);
    NSLog(@"\n\n - %@", [exception callStackSymbols]);
    NSLog(@"\n\n - %@", [exception callStackReturnAddresses]);
}

But by using these I don't get the line of the crash, as I intend to save it in CoreData.

Also I am not interested in xcode aproaches as: "Add Exception Breakpoint" or other aproaces as: XCode > Window > Devices > view crash logs on a device, Test Flight aproaches or implementing other frameworks in the app as Crashlytics.

I mention these because I am very interested in the way it can be done by code.

Also am able to get dsym of the app archive it when an app archive is made and upload it to a server using a RunScript written using Bash. So I can use the dsym if it is needed to achive the crash line.

Also I know that the next aproach can be used to obtain the current code line: LINE and _FUNCTION__ to get the function name.

Also if you can provide code examples from open source PLCrashReporter on how they do it I will much apreciate.

Than you all in advance! :)

chedabob
  • 5,835
  • 2
  • 24
  • 44
Laur Stefan
  • 1,519
  • 5
  • 23
  • 50

2 Answers2

4

There are basically two types of crashes:

  1. Uncaught exceptions, which can be catched with code similar to yours
  2. Signal based crashes, which can be catched with signal handlers (or Mach Exception handlers, but that won't catch all Signals)

Then catching any of these crashes, you need to get the stack trace (of all threads). [NSException callStackSymbols] will give you some symbols (only for an exception crash), for lots of OS symbols it will only show redacted, for your app it will provide some symbols if you don't strip them from your binary. It is recommended to strip the symbols from the binary to get the file size down (a lot), and these symbols would also never provide the filenames and line numbers anyway.

So instead you need to get the following information from the stack frames: binary, binary UUID, cpu architecture and memory address. [NSException callStackReturnAddresses] will give you the memory addresses, but again only for an exception based crash. In addition it doesn't provide the binary image corresponding to a memory address.

So you need to get the binary images list with the range of addresses in memory each binary image covers, and also a way to get the memory addresses of stack frames for threads also for non exception based crashes. If want to learn how that is that, you basically can take a look at ALL of PLCrashReporters code, since that is the purpose of the open source project and it is not the scope of StackOverflow to explain such complex scenarios. Read the code, the documentation and learn :) To give you the short gist: don't do it yourself, simply use PLCrashReporter.

Now to get the symbols including filenames and line numbers, you need to symbolicate the crash reports by using the OS symbols for the corresponding OS version and the corresponding CPU architecture from the device where the crash report happened. Also you need the symbols (dSYM) packages from the exact binary (and frameworks) that triggered the crash report from your app. Each binary image has a unique UUID and the symbol file your are using to get the symbols need to have the same UUID for the same CPU architecture.

Now you need to run the tool atos to get the symbols for a specific memory address from a specific symbol file. The following stack overflow answer shows how to do that: https://stackoverflow.com/a/13576028/474794

As an alternative, you can use the symbolicatecrash.pl script which comes with Xcode and takes a Apple standard formatted crash report (PLCrashReporter has a conversion tool to create such reports from its more compact reports).

Community
  • 1
  • 1
Kerni
  • 15,241
  • 5
  • 36
  • 57
  • I just integrated PLCrashReporter and I am interested in how can I retrieve the line of the crash if it exists? Thank you in advance – Laur Stefan Jan 08 '16 at 12:56
  • PLCrashReporter can't do that. You need to symbolicate the report it generates as I described. – Kerni Jan 08 '16 at 13:01
  • Do you mean that I should use : `NSLog(@"Crashed with signal %@ (code %@, address=0x%" PRIx64 ")", report.signalInfo.name, report.signalInfo.code, report.signalInfo.address);` or should I use: `NSString *humanReadable = [PLCrashReportTextFormatter stringValueForCrashReport:report withTextFormat:PLCrashReportTextFormatiOS]; NSLog(@"Report: %@", humanReadable)` – Laur Stefan Jan 08 '16 at 13:09
  • You should create an report that is formatted as text and can be processed with the Apple perl script or with a custom script to add the symbols. Your first example only writes one line with no real crash report that can be symbolicated. The second writes such a report. Please use the PLCrashReporter mailing list for specific questions and check the sample projects and documentation too: https://groups.google.com/forum/#!forum/plcrashreporter – Kerni Jan 08 '16 at 14:24
2

You can use __PRETTY_FUNCTION__ in your logs, that will give you the line, class and name of function.

NSLog(@"%@", __PRETTY_FUNCTION__);

You can fill out the rest of the log with any other information you like.

Beau Nouvelle
  • 6,962
  • 3
  • 39
  • 54
  • How can I add it? Can you give more details? Can I add it in the: uncaughtExceptionHandler for generical use? – Laur Stefan Jan 07 '16 at 23:44
  • Yes but it returns the function and line from where it is called not the function name where the app crashes, I am interested in usig it to find the name of the funstion withouth calling it throug out my apps code – Laur Stefan Jan 07 '16 at 23:50
  • Ah I understand now. Why don't you look into the source code for PLCrashReporter and see how it's done there? There also an interesting post written by the author or PLCrashReporter on why exception catching is not recommended. http://landonf.bikemonkey.org/code/objc/Reliable_Crash_Reporting.20110912.html – Beau Nouvelle Jan 08 '16 at 00:00
  • can you provide some actual guide to PLCrashReporter? – Laur Stefan Jan 21 '16 at 14:27