Crash Collection in iOS

Source: Internet
Author: User

There are many third-party good tools for the collection of crashes, such as bugly. However, if you want to collect the crash log yourself (for example, for applications that are published internally within the intranet), there is a natural way to do it.

Here are two ways to crawl the crash stack information, and if you find a problem, I hope to enlighten you. Make a note of yourself, too. :-)

Method One: Call the C function to grab the stack information, say no more, the code to

#import <Foundation/Foundation.h>

extern nsstring *const Sksappexceptioninfo;

@interface Sksexceptionrecord:nsobject

+ (void) Startexceptionhandler;

@end

#import "SKSExceptionRecord.h"

#include <execinfo.h>

NSString *const sksappexceptioninfo = @ "Sksappexceptioninfo";

static int s_fatal_signals[] = {

SIGABRT,

Sigbus,

SIGFPE,

Sigill,

SIGSEGV,

SIGTRAP,

SIGTERM,

SIGKILL,

};

static const char* s_fatal_signal_names[] = {

"SIGABRT",

"Sigbus",

"SIGFPE",

"Sigill",

"SIGSEGV",

"SIGTRAP",

"SIGTERM",

"SIGKILL",

};

static int s_fatal_signal_num = sizeof (s_fatal_signals)/sizeof (s_fatal_signals[0]);

Signal processing functions

void Signalhandler (int signal) {

for (int i = 0; i < S_fatal_signal_num; ++i) {

if (signal = = S_fatal_signals[i]) {

Signal exception does not upload log, but also need to capture, or exception exception is not uploaded

[Sksexceptionrecord handleexception:[nsstring stringwithformat:@ "%s", S_fatal_signal_names[i]] description:[ Sksexceptionrecord BackTrace]];

Break

}

}

}

void Exceptionhandler (NSException *exception) {

[Sksexceptionrecord handleexception:[exception reason] description:[exception callstacksymbols];

}

@implementation Sksexceptionrecord

+ (Nsarray *) BackTrace {

void *callstack[128];

int frames = BackTrace (callstack, 128);

Char **strs = Backtrace_symbols (callstack, frames);

Nsmutablearray *backtrace = [Nsmutablearray arraywithcapacity:frames];

for (int i = 0; i < frames; ++i) {

[BackTrace addobject:[nsstring Stringwithutf8string:strs[i]];

}

Free (STRs);

return backtrace;

}

+ (void) Startcrashhandler

{

1 Linux error signal capture

for (int i = 0; i < S_fatal_signal_num; ++i) {

Signal (S_fatal_signals[i], signalhandler);

}

2 objective-c Catch of uncaught exception

Nssetuncaughtexceptionhandler (&exceptionhandler);

}

+ (void) HandleException: (NSString *) reason description: (ID) description

{

This throws the message, the application can listen to the message as needed, to do the corresponding crash processing, such as uploading to the server

Nsdictionary *dicinfo = [nsdictionary Dictionarywithobjectsandkeys:reason, @ "Reason", description, @ "description", nil ];

[[Nsnotificationcenter Defaultcenter] Postnotificationname:sksappexceptioninfo object:nil UserInfo:dicInfo];

[Self keepappsurvive];

}

+ (void) keepappsurvive

//{

Cfrunloopref Runloop = Cfrunloopgetcurrent ();

Cfarrayref allmodes = Cfrunloopcopyallmodes (Runloop);

//

BOOL dismissed = NO;

while (YES)

//    {

For (NSString *mode in (__bridge Nsarray *) allmodes)

//        {

Cfrunloopruninmode ((__bridge cfstringref) mode, 0.001, false);

//        }

Sleep (2);

dismissed = YES;

//    }

//

Cfrelease (Allmodes);

//}

@end

The flaw of this method, if the symbol table is disable, then the crawled information will not be readable, just a pure memory stack.

Method Two: Using Kscrash, the advantage is that the crash stack can be parsed directly into a readable character. First you need to go to git to download the Kscrash, add the source directory to the app project, or add the Kscrash project directly to the app. After adding the basic need to expand their own methods to handle the crash information, because the methods already included (such as mail) may not be the long-term crash tracking method you want.

Here's how I defined the crash log collection:

#import <Foundation/Foundation.h>

#import "KSCrashInstallation.h"

#import "KSCRASH.H"

#import "KSCrashAdvanced.h"

@interface Skscrashmanager:nsobject

+ (Skscrashmanager *) Sharedmanager;

-(void) Checklocalcrashlogs: (kscrashreportfiltercompletion) block;

@end

#import "SKSCrashManager.h"

#import "Kscrashinstallation+private.h"

#import "KSSingleton.h"

#import "KSCrashReportFilterAppleFmt.h"

#import "SkySeaManager.h"

#import "SKSEncrypt.h"

NSString *const Sksappexceptionwithkscrash = @ "Sksappexceptionwithkscrash";

-----------------Skscrashreportsink----------------------------------------------

@interface Skscrashreportsink:nsobject <KSCrashReportFilter>

-(ID <KSCrashReportFilter>) Defaultcrashreportfilterset;

@end

@implementation Skscrashreportsink

-(ID <KSCrashReportFilter>) defaultcrashreportfilterset

{

This method is important to ksapplereportstylesymbolicated this format to return a readable crash log

return [Kscrashreportfilterpipeline filterwithfilters:

[Kscrashreportfilterapplefmt filterwithreportstyle:ksapplereportstylesymbolicated],

Self

NIL];

}

-(void) Filterreports: (nsarray*) reports

Oncompletion: (kscrashreportfiltercompletion) oncompletion

{

Nsdictionary *dicinfo = [nsdictionary dictionarywithobjectsandkeys:reports, @ "reports", Oncompletion, @ "callback", nil ];

[[Nsnotificationcenter Defaultcenter] Postnotificationname:sksappexceptionwithkscrash object:nil UserInfo:dicInfo] ;

}

@end

--------------------skscrashinstallation-----------------------------------------

@interface skscrashinstallation:kscrashinstallation

+ (skscrashinstallation*) sharedinstance;

@end

@implementation Skscrashinstallation

Implement_exclusive_shared_instance (skscrashinstallation)

-(ID) init

{

if (self = [super Initwithrequiredproperties:nil])

{

}

return self;

}

-(id<kscrashreportfilter>) sink

{

skscrashreportsink* sink = [[Skscrashreportsink alloc] init];

return [Kscrashreportfilterpipeline Filterwithfilters:[sink Defaultcrashreportfilterset], nil];

}

@end

static Skscrashmanager *g_crashmanager = NULL;

@interface Skscrashmanager ()

@property (Strong, nonatomic) kscrashinstallation* crashinstallation;

@end

@implementation Skscrashmanager

+ (Skscrashmanager *) Sharedmanager {

Static dispatch_once_t Oncetoken;

Dispatch_once (&oncetoken, ^{

if (G_crashmanager = = NULL) {

G_crashmanager = [[Skscrashmanager alloc] init];

[G_crashmanager Installcrashhandler];

}

});

return g_crashmanager;

}

-(void) dealloc

{

[[Nsnotificationcenter Defaultcenter] removeobserver:self];

}

-(void) Installcrashhandler

{

[Self configureadvancedsettings];

Self.crashinstallation = [Skscrashinstallation sharedinstance];

[Self.crashinstallation install];

[[Nsnotificationcenter Defaultcenter] addobserver:self selector: @selector (uploadexceptionlog:) Name: Sksappexceptionwithkscrash Object:nil];

}

static void Advanced_crash_callback (const kscrashreportwriter* writer)

{

You can add extra user data at crash time if you want.

Writer->addbooleanelement (writer, "Some_bool_value", NO);

}

-(void) configureadvancedsettings

{

kscrash* handler = [Kscrash sharedinstance];

Handler.deletebehavioraftersendall = kscdeleteonsucess;

Handler.zombiecachesize = 16384*4;

Handler.deadlockwatchdoginterval = 0;

Handler.userinfo = @{@ "Somekey": @ "somevalue"};

Handler.oncrash = Advanced_crash_callback;

Handler.printtracetostdout = NO;

Handler.searchthreadnames = YES;

Handler.searchqueuenames = YES;

Handler.handlingcrashtypes = Kscrashtypeall;

}

-(void) Checklocalcrashlogs: (kscrashreportfiltercompletion) Block {

[Self.crashinstallation Sendallreportswithcompletion:block];

}

-(void) Uploadexceptionlog: (nsnotification *) Note

{

Here to do the corresponding crash processing

}

@end

All of these are thrown after a crash, throw a message, and then you can do a crash in any place. Can be changed according to their own architectural requirements.

Crash Collection in iOS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.