Skip to content

Commit

Permalink
fix: ensure foreground stats are recorded for handled errors
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Jul 16, 2020
1 parent 9251dc0 commit 7c45873
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@
*/
- (NSArray<BugsnagThread *> *)captureThreads:(NSException *)exc depth:(int)depth;

/**
* Collects information about the application's foreground state (duration in foreground/background)
*/
- (NSDictionary *)captureApplicationStatsInfo;

/** If YES, reports will be sent even if a debugger is attached
*
* Default: NO
Expand Down
7 changes: 7 additions & 0 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,13 @@ - (void)sendAllReports {
return @[];
}

- (NSDictionary *)captureApplicationStatsInfo {
char *trace = bsg_kscrash_captureAppForegroundStats();
NSDictionary *json = BSGDeserializeJson(trace);
free(trace);
return json;
}

- (void)reportUserException:(NSString *)name
reason:(NSString *)reason
handledState:(NSDictionary *)handledState
Expand Down
5 changes: 4 additions & 1 deletion Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,5 +243,8 @@ char *bsg_kscrash_captureThreadTrace(int discardDepth, int frameCount, uintptr_t
bsg_kscrashsentry_resume_threads_user(false);
}
return trace;

}

char *bsg_kscrash_captureAppForegroundStats() {
return bsg_kscrw_i_captureAppForegroundStats(crashContext());
}
5 changes: 5 additions & 0 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashC.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ BSG_KSCrash_Context *crashContext(void);
*/
char *bsg_kscrash_captureThreadTrace(int discardDepth, int frameCount, uintptr_t *callstack);

/**
* Captures application foreground state info and returns it as a JSON string.
*/
char *bsg_kscrash_captureAppForegroundStats();

#ifdef __cplusplus
}
#endif
Expand Down
18 changes: 15 additions & 3 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ typedef ucontext_t SignalUserContext;
typedef struct {
char *data;
size_t allocated_size;
} BSG_ThreadDataBuffer;
} BSG_JsonDataBuffer;

// ============================================================================
#pragma mark - Formatting -
Expand Down Expand Up @@ -1660,7 +1660,7 @@ void bsg_kscrashreport_logCrash(const BSG_KSCrash_Context *const crashContext) {
}

int bsg_kscrw_i_collectJsonData(const char *const data, const size_t length, void *const userData) {
BSG_ThreadDataBuffer *thread_data = (BSG_ThreadDataBuffer *)userData;
BSG_JsonDataBuffer *thread_data = (BSG_JsonDataBuffer *)userData;
if (thread_data->data == NULL) {
// Allocate initial memory for JSON data
void *ptr = malloc(BSG_THREAD_DATA_SIZE_INITIAL);
Expand Down Expand Up @@ -1691,7 +1691,7 @@ char *bsg_kscrw_i_captureThreadTrace(const BSG_KSCrash_Context *crashContext) {
BSG_KSCrashReportWriter concreteWriter;
BSG_KSCrashReportWriter *writer = &concreteWriter;
bsg_kscrw_i_prepareReportWriter(writer, &jsonContext);
BSG_ThreadDataBuffer userData = { NULL, 0 };
BSG_JsonDataBuffer userData = { NULL, 0 };
bsg_ksjsonbeginEncode(bsg_getJsonContext(writer), false, bsg_kscrw_i_collectJsonData, &userData);
writer->beginObject(writer, BSG_KSCrashField_Report);
bsg_kscrw_i_writeTraceInfo(crashContext, writer);
Expand All @@ -1700,6 +1700,18 @@ char *bsg_kscrw_i_captureThreadTrace(const BSG_KSCrash_Context *crashContext) {
return userData.data;
}

char *bsg_kscrw_i_captureAppForegroundStats(const BSG_KSCrash_Context *crashContext) {
BSG_KSJSONEncodeContext jsonContext;
BSG_KSCrashReportWriter concreteWriter;
BSG_KSCrashReportWriter *writer = &concreteWriter;
bsg_kscrw_i_prepareReportWriter(writer, &jsonContext);
BSG_JsonDataBuffer userData = { NULL, 0 };
bsg_ksjsonbeginEncode(bsg_getJsonContext(writer), false, bsg_kscrw_i_collectJsonData, &userData);
bsg_kscrw_i_writeAppStats(writer, BSG_KSCrashField_AppStats, &crashContext->state);
bsg_ksjsonendEncode(bsg_getJsonContext(writer));
return userData.data;
}

void bsg_kscrw_i_writeTraceInfo(const BSG_KSCrash_Context *crashContext,
const BSG_KSCrashReportWriter *writer) {
bool unhandledCrash = crashContext->crash.crashType != BSG_KSCrashTypeUserReported;
Expand Down
7 changes: 7 additions & 0 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ void bsg_kscrashreport_logCrash(const BSG_KSCrash_Context *const crashContext);
*/
char *bsg_kscrw_i_captureThreadTrace(const BSG_KSCrash_Context *crashContext);

/**
* Captures app foreground stats for use by the Objective-C layer to append to handled errors.
*
* @return the stats encoded as a JSON string
*/
char *bsg_kscrw_i_captureAppForegroundStats(const BSG_KSCrash_Context *crashContext);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSSystemInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#import "BSG_KSLogger.h"
#import "BSG_KSCrashReportFields.h"
#import "BSG_KSMach.h"
#import "BSG_KSCrash.h"

#import <CommonCrypto/CommonDigest.h>
#if BSG_PLATFORM_IOS || BSG_PLATFORM_TVOS
Expand Down Expand Up @@ -416,6 +417,8 @@ + (NSDictionary *)systemInfo {
};
BSGDictSetSafeObject(sysInfo, memory, @BSG_KSSystemField_Memory);

NSDictionary *statsInfo = [[BSG_KSCrash sharedInstance] captureApplicationStatsInfo];
BSGDictSetSafeObject(sysInfo, statsInfo, @BSG_KSCrashField_AppStats);
return sysInfo;
}

Expand Down

0 comments on commit 7c45873

Please sign in to comment.