diff --git a/.clang-format b/.clang-format index f04876ef9..825ec7d48 100644 --- a/.clang-format +++ b/.clang-format @@ -1,36 +1,9 @@ BasedOnStyle: Google IndentWidth: 4 -TabWidth: 4 -UseTab: Never -ColumnLimit: 120 -BreakBeforeBraces: Custom -BraceWrapping: - AfterClass: true - AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterObjCDeclaration: true - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true - IndentBraces: false -AllowShortIfStatementsOnASingleLine: true -AllowShortCaseLabelsOnASingleLine: true -AllowShortFunctionsOnASingleLine: All -ObjCSpaceAfterProperty: true ObjCBlockIndentWidth: 4 -ObjCSpaceBeforeProtocolList: true -SpaceAfterCStyleCast: false -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: false -SpacesInAngles: false -SpacesInContainerLiterals: false -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Cpp11BracedListStyle: false +ColumnLimit: 120 +BreakBeforeBraces: Linux +PointerAlignment: Right DerivePointerAlignment: false -PointerAlignment: Left -IndentCaseLabels: true +SpaceBeforeCpp11BracedList: true +Cpp11BracedListStyle: false diff --git a/.clang-format-ignore b/.clang-format-ignore new file mode 100644 index 000000000..e866a0e03 --- /dev/null +++ b/.clang-format-ignore @@ -0,0 +1,5 @@ +Sources/KSCrashRecordingCore/KSObjCApple.h +Sources/KSCrashRecordingCore/llvm/* +Sources/KSCrashRecordingCore/llvm/*/* +Sources/KSCrashRecordingCore/swift/* +Sources/KSCrashRecordingCore/swift/*/* diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 000000000..a7fdb0670 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,61 @@ +name: Clang Format Check +on: + pull_request: + paths: + - 'Sources/**' + - 'Tests/**' + - 'Samples/Common/Sources/CrashTriggers/**' + - '.github/workflows/clang-format.yml' + - '.clang-format-ignore' + +jobs: + formatting-check: + name: Formatting Check + runs-on: ubuntu-latest + env: + DIRS: 'Sources Tests Samples/Common/Sources/CrashTriggers' + steps: + - uses: actions/checkout@v4 + + - name: Install clang-format-18 + run: | + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh 18 + sudo apt-get install -y clang-format-18 + + - name: Check formatting + id: check_format + run: | + find $DIRS -name '*.c' -o -name '*.cpp' -o -name '*.h' -o -name '*.m' -o -name '*.mm' | \ + xargs -r clang-format-18 -style=file -n -Werror 2> clang_format_errors.log + + - name: Suggest formatting fixes + if: failure() + run: | + echo "##[error]Formatting issues found. Please run clang-format-18 on your code." + + - name: Create summary and annotations + if: failure() + run: | + echo "### Formatting issues found" >> $GITHUB_STEP_SUMMARY + echo "Please run clang-format-18 on your code." >> $GITHUB_STEP_SUMMARY + echo "Note: Some files may be excluded from formatting based on .clang-format-ignore file." >> $GITHUB_STEP_SUMMARY + echo "::group::Formatting issues" + awk ' + /^.*error:/ { + split($0, parts, ":") + file=parts[1] + line=parts[2] + col=parts[3] + message=$0 + getline code_line + getline caret_line + sub(/:.*$/, "", file) + sub(/[^0-9]/, "", line) + sub(/[^0-9]/, "", col) + # Remove the "error: " prefix from the message + sub(/^[^:]+: [^:]+: [^:]+: /, "", message) + print "::error file="file",line="line",col="col"::"message + }' clang_format_errors.log + echo "::endgroup::" diff --git a/Samples/Common/Sources/CrashTriggers/CrashTriggers.mm b/Samples/Common/Sources/CrashTriggers/CrashTriggers.mm index d0e8dd2fe..75cdfba06 100644 --- a/Samples/Common/Sources/CrashTriggers/CrashTriggers.mm +++ b/Samples/Common/Sources/CrashTriggers/CrashTriggers.mm @@ -30,9 +30,7 @@ @implementation CrashTriggers + (void)nsexception { - NSException *exc = [NSException exceptionWithName:NSGenericException - reason:@"Test" - userInfo:@{ @"a": @"b"}]; + NSException *exc = [NSException exceptionWithName:NSGenericException reason:@"Test" userInfo:@{ @"a" : @"b" }]; [exc raise]; } diff --git a/Sources/KSCrashBootTimeMonitor/KSCrashMonitor_BootTime.m b/Sources/KSCrashBootTimeMonitor/KSCrashMonitor_BootTime.m index 8dc404efd..d1fa2965f 100644 --- a/Sources/KSCrashBootTimeMonitor/KSCrashMonitor_BootTime.m +++ b/Sources/KSCrashBootTimeMonitor/KSCrashMonitor_BootTime.m @@ -27,11 +27,11 @@ #import "KSCrashMonitor_BootTime.h" #import "KSCrashMonitorContext.h" -#import "KSSysCtl.h" #import "KSDate.h" +#import "KSSysCtl.h" -#import #import +#import static volatile bool g_isEnabled = false; @@ -47,58 +47,43 @@ void kscm_bootTime_resetState(void) * * @return The result of the sysctl call. */ -static const char* dateSysctl(const char* name) +static const char *dateSysctl(const char *name) { struct timeval value = kssysctl_timevalForName(name); - char* buffer = malloc(21); + char *buffer = malloc(21); ksdate_utcStringFromTimestamp(value.tv_sec, buffer); return buffer; } #pragma mark - API - -static const char* monitorId(void) -{ - return "BootTime"; -} +static const char *monitorId(void) { return "BootTime"; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(KSCrash_MonitorContext *eventContext) { - if(g_isEnabled) - { + if (g_isEnabled) { eventContext->System.bootTime = dateSysctl("kern.boottime"); } } -KSCrashMonitorAPI* kscm_boottime_getAPI(void) +KSCrashMonitorAPI *kscm_boottime_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent - }; + static KSCrashMonitorAPI api = { .monitorId = monitorId, + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; return &api; } #pragma mark - Injection - -__attribute__((constructor)) -static void kscm_boottime_register(void) -{ - kscm_addMonitor(kscm_boottime_getAPI()); -} +__attribute__((constructor)) static void kscm_boottime_register(void) { kscm_addMonitor(kscm_boottime_getAPI()); } diff --git a/Sources/KSCrashBootTimeMonitor/include/KSCrashMonitor_BootTime.h b/Sources/KSCrashBootTimeMonitor/include/KSCrashMonitor_BootTime.h index e32b1cf51..c07658500 100644 --- a/Sources/KSCrashBootTimeMonitor/include/KSCrashMonitor_BootTime.h +++ b/Sources/KSCrashBootTimeMonitor/include/KSCrashMonitor_BootTime.h @@ -1,6 +1,6 @@ // // KSCrashMonitor_BootTime.h -// +// // Created by Gleb Linnik on 04.06.2024. // // Copyright (c) 2012 Karl Stenerud. All rights reserved. @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #ifndef KSCrashMonitor_BootTime_h #define KSCrashMonitor_BootTime_h @@ -36,7 +35,7 @@ extern "C" { /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_boottime_getAPI(void); +KSCrashMonitorAPI *kscm_boottime_getAPI(void); #ifdef __cplusplus } diff --git a/Sources/KSCrashCore/NSError+SimpleConstructor.m b/Sources/KSCrashCore/NSError+SimpleConstructor.m index 26962f109..cf87d04b5 100644 --- a/Sources/KSCrashCore/NSError+SimpleConstructor.m +++ b/Sources/KSCrashCore/NSError+SimpleConstructor.m @@ -26,48 +26,43 @@ #import "NSError+SimpleConstructor.h" - @implementation NSError (SimpleConstructor) -+ (NSError*) errorWithDomain:(NSString*) domain code:(NSInteger) code description:(NSString*) fmt, ... ++ (NSError *)errorWithDomain:(NSString *)domain code:(NSInteger)code description:(NSString *)fmt, ... { va_list args; va_start(args, fmt); - - NSString* desc = [[NSString alloc] initWithFormat:fmt arguments:args]; + + NSString *desc = [[NSString alloc] initWithFormat:fmt arguments:args]; va_end(args); - + return [NSError errorWithDomain:domain code:code - userInfo:[NSDictionary dictionaryWithObject:desc - forKey:NSLocalizedDescriptionKey]]; + userInfo:[NSDictionary dictionaryWithObject:desc forKey:NSLocalizedDescriptionKey]]; } -+ (BOOL) fillError:(NSError* __autoreleasing *) error - withDomain:(NSString*) domain - code:(NSInteger) code - description:(NSString*) fmt, ... ++ (BOOL)fillError:(NSError *__autoreleasing *)error + withDomain:(NSString *)domain + code:(NSInteger)code + description:(NSString *)fmt, ... { - if(error != nil) - { + if (error != nil) { va_list args; va_start(args, fmt); - - NSString* desc = [[NSString alloc] initWithFormat:fmt arguments:args]; + + NSString *desc = [[NSString alloc] initWithFormat:fmt arguments:args]; va_end(args); - + *error = [NSError errorWithDomain:domain code:code - userInfo:[NSDictionary dictionaryWithObject:desc - forKey:NSLocalizedDescriptionKey]]; + userInfo:[NSDictionary dictionaryWithObject:desc forKey:NSLocalizedDescriptionKey]]; } return NO; } -+ (BOOL) clearError:(NSError* __autoreleasing *) error ++ (BOOL)clearError:(NSError *__autoreleasing *)error { - if(error != nil) - { + if (error != nil) { *error = nil; } return NO; @@ -75,5 +70,7 @@ + (BOOL) clearError:(NSError* __autoreleasing *) error @end -@interface NSError_SimpleConstructor_AOG8G : NSObject @end @implementation NSError_SimpleConstructor_AOG8G @end - +@interface NSError_SimpleConstructor_AOG8G : NSObject +@end +@implementation NSError_SimpleConstructor_AOG8G +@end diff --git a/Sources/KSCrashCore/include/KSSystemCapabilities.h b/Sources/KSCrashCore/include/KSSystemCapabilities.h index 2bfc95644..db4d14241 100644 --- a/Sources/KSCrashCore/include/KSSystemCapabilities.h +++ b/Sources/KSCrashCore/include/KSSystemCapabilities.h @@ -22,7 +22,6 @@ // THE SOFTWARE. // - #ifndef HDR_KSSystemCapabilities_h #define HDR_KSSystemCapabilities_h @@ -44,7 +43,8 @@ #define KSCRASH_HOST_IOS (KSCRASH_HOST_APPLE && TARGET_OS_IOS) #define KSCRASH_HOST_TV (KSCRASH_HOST_APPLE && TARGET_OS_TV) #define KSCRASH_HOST_WATCH (KSCRASH_HOST_APPLE && TARGET_OS_WATCH) -#define KSCRASH_HOST_MAC (KSCRASH_HOST_APPLE && TARGET_OS_MAC && !(TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH || KSCRASH_HOST_VISION)) +#define KSCRASH_HOST_MAC \ + (KSCRASH_HOST_APPLE && TARGET_OS_MAC && !(TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH || KSCRASH_HOST_VISION)) #if KSCRASH_HOST_APPLE #define KSCRASH_CAN_GET_MAC_ADDRESS 1 @@ -151,4 +151,4 @@ #define KSCRASH_HAS_REACHABILITY 0 #endif -#endif // HDR_KSSystemCapabilities_h +#endif // HDR_KSSystemCapabilities_h diff --git a/Sources/KSCrashCore/include/NSError+SimpleConstructor.h b/Sources/KSCrashCore/include/NSError+SimpleConstructor.h index e324e12c9..aa55baf1b 100644 --- a/Sources/KSCrashCore/include/NSError+SimpleConstructor.h +++ b/Sources/KSCrashCore/include/NSError+SimpleConstructor.h @@ -40,9 +40,7 @@ * @param fmt Description of the error (gets placed into the user data with the key * NSLocalizedDescriptionKey). */ -+ (NSError*) errorWithDomain:(NSString*) domain - code:(NSInteger) code - description:(NSString*) fmt, ...; ++ (NSError *)errorWithDomain:(NSString *)domain code:(NSInteger)code description:(NSString *)fmt, ...; /** Fill an error pointer with an NSError object if it's not nil. * @@ -53,17 +51,14 @@ * NSLocalizedDescriptionKey). * @return NO (to keep the analyzer happy). */ -+ (BOOL) fillError:(NSError**) error - withDomain:(NSString*) domain - code:(NSInteger) code - description:(NSString*) fmt, ...; ++ (BOOL)fillError:(NSError **)error withDomain:(NSString *)domain code:(NSInteger)code description:(NSString *)fmt, ...; /** Clear a pointer-to-error to nil of its pointer is not nil. * * @param error Error pointer to fill (ignored if nil). * @return NO (to keep the analyzer happy). */ -+ (BOOL) clearError:(NSError**) error; ++ (BOOL)clearError:(NSError **)error; @end diff --git a/Sources/KSCrashDiscSpaceMonitor/KSCrashMonitor_DiscSpace.m b/Sources/KSCrashDiscSpaceMonitor/KSCrashMonitor_DiscSpace.m index 1f5fc935f..61c1a60c1 100644 --- a/Sources/KSCrashDiscSpaceMonitor/KSCrashMonitor_DiscSpace.m +++ b/Sources/KSCrashDiscSpaceMonitor/KSCrashMonitor_DiscSpace.m @@ -1,6 +1,6 @@ // // KSCrashMonitor_DiscSpace.c -// +// // Created by Gleb Linnik on 04.06.2024. // // Copyright (c) 2012 Karl Stenerud. All rights reserved. @@ -40,57 +40,40 @@ void kscm_discSpace_resetState(void) static uint64_t getStorageSize(void) { - NSNumber *storageSize = [[[NSFileManager defaultManager] - attributesOfFileSystemForPath:NSHomeDirectory() - error:nil] - objectForKey:NSFileSystemSize]; + NSNumber *storageSize = [[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] + objectForKey:NSFileSystemSize]; return storageSize.unsignedLongLongValue; } #pragma mark - API - -static const char* monitorId(void) -{ - return "DiscSpace"; -} +static const char *monitorId(void) { return "DiscSpace"; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(KSCrash_MonitorContext *eventContext) { - if(g_isEnabled) - { + if (g_isEnabled) { eventContext->System.storageSize = getStorageSize(); } } -KSCrashMonitorAPI* kscm_discspace_getAPI(void) +KSCrashMonitorAPI *kscm_discspace_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent - }; + static KSCrashMonitorAPI api = { .monitorId = monitorId, + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; return &api; } #pragma mark - Injection - -__attribute__((constructor)) -static void kscm_discspace_register(void) -{ - kscm_addMonitor(kscm_discspace_getAPI()); -} +__attribute__((constructor)) static void kscm_discspace_register(void) { kscm_addMonitor(kscm_discspace_getAPI()); } diff --git a/Sources/KSCrashDiscSpaceMonitor/include/KSCrashMonitor_DiscSpace.h b/Sources/KSCrashDiscSpaceMonitor/include/KSCrashMonitor_DiscSpace.h index 746478b72..ddb028316 100644 --- a/Sources/KSCrashDiscSpaceMonitor/include/KSCrashMonitor_DiscSpace.h +++ b/Sources/KSCrashDiscSpaceMonitor/include/KSCrashMonitor_DiscSpace.h @@ -1,6 +1,6 @@ // // KSCrashMonitor_DiscSpace.h -// +// // Created by Gleb Linnik on 04.06.2024. // // Copyright (c) 2012 Karl Stenerud. All rights reserved. @@ -35,7 +35,7 @@ extern "C" { /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_discspace_getAPI(void); +KSCrashMonitorAPI *kscm_discspace_getAPI(void); #ifdef __cplusplus } diff --git a/Sources/KSCrashFilters/KSCrashReportFilterAlert.m b/Sources/KSCrashFilters/KSCrashReportFilterAlert.m index 75b4a68eb..c4859cadd 100644 --- a/Sources/KSCrashFilters/KSCrashReportFilterAlert.m +++ b/Sources/KSCrashFilters/KSCrashReportFilterAlert.m @@ -26,10 +26,10 @@ #import "KSCrashReportFilterAlert.h" -#import "KSSystemCapabilities.h" #import "KSCrashReport.h" +#import "KSSystemCapabilities.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" #if KSCRASH_HAS_ALERTVIEW @@ -44,18 +44,18 @@ @interface KSCrashAlertViewProcess : NSObject -@property(nonatomic,readwrite,copy) NSArray* reports; -@property(nonatomic,readwrite,copy) KSCrashReportFilterCompletion onCompletion; -@property(nonatomic,readwrite,assign) NSInteger expectedButtonIndex; +@property(nonatomic, readwrite, copy) NSArray *reports; +@property(nonatomic, readwrite, copy) KSCrashReportFilterCompletion onCompletion; +@property(nonatomic, readwrite, assign) NSInteger expectedButtonIndex; -+ (KSCrashAlertViewProcess*) process; ++ (KSCrashAlertViewProcess *)process; -- (void) startWithTitle:(NSString*) title - message:(NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(NSString*) noAnswer - reports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion; +- (void)startWithTitle:(NSString *)title + message:(NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(NSString *)noAnswer + reports:(NSArray *)reports + onCompletion:(KSCrashReportFilterCompletion)onCompletion; @end @@ -65,17 +65,17 @@ @implementation KSCrashAlertViewProcess @synthesize onCompletion = _onCompletion; @synthesize expectedButtonIndex = _expectedButtonIndex; -+ (KSCrashAlertViewProcess*) process ++ (KSCrashAlertViewProcess *)process { return [[self alloc] init]; } -- (void) startWithTitle:(NSString*) title - message:(NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(NSString*) noAnswer - reports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)startWithTitle:(NSString *)title + message:(NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(NSString *)noAnswer + reports:(NSArray *)reports + onCompletion:(KSCrashReportFilterCompletion)onCompletion { KSLOG_TRACE(@"Starting alert view process"); self.reports = [reports copy]; @@ -86,16 +86,18 @@ - (void) startWithTitle:(NSString*) title UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction *yesAction = [UIAlertAction actionWithTitle:yesAnswer - style:UIAlertActionStyleDefault - handler:^(__unused UIAlertAction * _Nonnull action) { - kscrash_callCompletion(self.onCompletion, self.reports, YES, nil); - }]; - UIAlertAction *noAction = [UIAlertAction actionWithTitle:noAnswer - style:UIAlertActionStyleCancel - handler:^(__unused UIAlertAction * _Nonnull action) { - kscrash_callCompletion(self.onCompletion, self.reports, NO, nil); - }]; + UIAlertAction *yesAction = + [UIAlertAction actionWithTitle:yesAnswer + style:UIAlertActionStyleDefault + handler:^(__unused UIAlertAction *_Nonnull action) { + kscrash_callCompletion(self.onCompletion, self.reports, YES, nil); + }]; + UIAlertAction *noAction = + [UIAlertAction actionWithTitle:noAnswer + style:UIAlertActionStyleCancel + handler:^(__unused UIAlertAction *_Nonnull action) { + kscrash_callCompletion(self.onCompletion, self.reports, NO, nil); + }]; [alertController addAction:yesAction]; [alertController addAction:noAction]; UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; @@ -103,24 +105,22 @@ - (void) startWithTitle:(NSString*) title #elif KSCRASH_HAS_NSALERT NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle:yesAnswer]; - if(noAnswer != nil) - { + if (noAnswer != nil) { [alert addButtonWithTitle:noAnswer]; } [alert setMessageText:title]; [alert setInformativeText:message]; [alert setAlertStyle:NSAlertStyleInformational]; - + BOOL success = NO; - if([alert runModal] == NSAlertFirstButtonReturn) - { + if ([alert runModal] == NSAlertFirstButtonReturn) { success = noAnswer != nil; } kscrash_callCompletion(self.onCompletion, self.reports, success, nil); #endif } -- (void) alertView:(__unused id) alertView clickedButtonAtIndex:(NSInteger) buttonIndex +- (void)alertView:(__unused id)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { BOOL success = buttonIndex == self.expectedButtonIndex; kscrash_callCompletion(self.onCompletion, self.reports, success, nil); @@ -128,13 +128,12 @@ - (void) alertView:(__unused id) alertView clickedButtonAtIndex:(NSInteger) butt @end - @interface KSCrashReportFilterAlert () -@property(nonatomic, readwrite, retain) NSString* title; -@property(nonatomic, readwrite, retain) NSString* message; -@property(nonatomic, readwrite, retain) NSString* yesAnswer; -@property(nonatomic, readwrite, retain) NSString* noAnswer; +@property(nonatomic, readwrite, retain) NSString *title; +@property(nonatomic, readwrite, retain) NSString *message; +@property(nonatomic, readwrite, retain) NSString *yesAnswer; +@property(nonatomic, readwrite, retain) NSString *noAnswer; @end @@ -145,24 +144,20 @@ @implementation KSCrashReportFilterAlert @synthesize yesAnswer = _yesAnswer; @synthesize noAnswer = _noAnswer; -+ (instancetype) filterWithTitle:(NSString*) title - message:(nullable NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(nullable NSString*) noAnswer; ++ (instancetype)filterWithTitle:(NSString *)title + message:(nullable NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(nullable NSString *)noAnswer; { - return [[self alloc] initWithTitle:title - message:message - yesAnswer:yesAnswer - noAnswer:noAnswer]; + return [[self alloc] initWithTitle:title message:message yesAnswer:yesAnswer noAnswer:noAnswer]; } -- (instancetype) initWithTitle:(NSString*) title - message:(nullable NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(nullable NSString*) noAnswer; +- (instancetype)initWithTitle:(NSString *)title + message:(nullable NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(nullable NSString *)noAnswer; { - if((self = [super init])) - { + if ((self = [super init])) { self.title = title; self.message = message; self.yesAnswer = yesAnswer; @@ -171,30 +166,24 @@ - (instancetype) initWithTitle:(NSString*) title return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - dispatch_async(dispatch_get_main_queue(), ^ - { - KSLOG_TRACE(@"Launching new alert view process"); - __block KSCrashAlertViewProcess* process = [[KSCrashAlertViewProcess alloc] init]; - [process startWithTitle:self.title - message:self.message - yesAnswer:self.yesAnswer - noAnswer:self.noAnswer - reports:reports - onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - KSLOG_TRACE(@"alert process complete"); - kscrash_callCompletion(onCompletion, filteredReports, completed, error); - dispatch_async(dispatch_get_main_queue(), ^ - { - process = nil; - }); - }]; - }); + dispatch_async(dispatch_get_main_queue(), ^{ + KSLOG_TRACE(@"Launching new alert view process"); + __block KSCrashAlertViewProcess *process = [[KSCrashAlertViewProcess alloc] init]; + [process startWithTitle:self.title + message:self.message + yesAnswer:self.yesAnswer + noAnswer:self.noAnswer + reports:reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + KSLOG_TRACE(@"alert process complete"); + kscrash_callCompletion(onCompletion, filteredReports, completed, error); + dispatch_async(dispatch_get_main_queue(), ^{ + process = nil; + }); + }]; + }); } @end @@ -203,31 +192,26 @@ - (void) filterReports:(NSArray*) reports @implementation KSCrashReportFilterAlert -+ (KSCrashReportFilterAlert*) filterWithTitle:(NSString*) title - message:(NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(NSString*) noAnswer ++ (KSCrashReportFilterAlert *)filterWithTitle:(NSString *)title + message:(NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(NSString *)noAnswer { - return [[self alloc] initWithTitle:title - message:message - yesAnswer:yesAnswer - noAnswer:noAnswer]; + return [[self alloc] initWithTitle:title message:message yesAnswer:yesAnswer noAnswer:noAnswer]; } -- (id) initWithTitle:(__unused NSString*) title - message:(__unused NSString*) message - yesAnswer:(__unused NSString*) yesAnswer - noAnswer:(__unused NSString*) noAnswer +- (id)initWithTitle:(__unused NSString *)title + message:(__unused NSString *)message + yesAnswer:(__unused NSString *)yesAnswer + noAnswer:(__unused NSString *)noAnswer { - if((self = [super init])) - { + if ((self = [super init])) { KSLOG_WARN(@"Alert filter not available on this platform."); } return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { KSLOG_WARN(@"Alert filter not available on this platform."); kscrash_callCompletion(onCompletion, reports, YES, nil); diff --git a/Sources/KSCrashFilters/KSCrashReportFilterAppleFmt.m b/Sources/KSCrashFilters/KSCrashReportFilterAppleFmt.m index 5ea434dbc..71071abb6 100644 --- a/Sources/KSCrashFilters/KSCrashReportFilterAppleFmt.m +++ b/Sources/KSCrashFilters/KSCrashReportFilterAppleFmt.m @@ -24,47 +24,45 @@ // THE SOFTWARE. // - #import "KSCrashReportFilterAppleFmt.h" -#import "KSSystemCapabilities.h" #import "KSCrashReport.h" +#import "KSSystemCapabilities.h" #import -#import #include +#import +#import "KSCPU.h" #import "KSCrashReportFields.h" #import "KSJSONCodecObjC.h" -#import "KSCPU.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" #if defined(__LP64__) - #define FMT_LONG_DIGITS "16" - #define FMT_RJ_SPACES "18" +#define FMT_LONG_DIGITS "16" +#define FMT_RJ_SPACES "18" #else - #define FMT_LONG_DIGITS "8" - #define FMT_RJ_SPACES "10" +#define FMT_LONG_DIGITS "8" +#define FMT_RJ_SPACES "10" #endif -#define FMT_PTR_SHORT @"0x%" PRIxPTR -#define FMT_PTR_LONG @"0x%0" FMT_LONG_DIGITS PRIxPTR -//#define FMT_PTR_RJ @"%#" FMT_RJ_SPACES PRIxPTR -#define FMT_PTR_RJ @"%#" PRIxPTR -#define FMT_OFFSET @"%" PRIuPTR -#define FMT_TRACE_PREAMBLE @"%-4d%-30s\t" FMT_PTR_LONG +#define FMT_PTR_SHORT @"0x%" PRIxPTR +#define FMT_PTR_LONG @"0x%0" FMT_LONG_DIGITS PRIxPTR +// #define FMT_PTR_RJ @"%#" FMT_RJ_SPACES PRIxPTR +#define FMT_PTR_RJ @"%#" PRIxPTR +#define FMT_OFFSET @"%" PRIuPTR +#define FMT_TRACE_PREAMBLE @"%-4d%-30s\t" FMT_PTR_LONG #define FMT_TRACE_UNSYMBOLICATED FMT_PTR_SHORT @" + " FMT_OFFSET -#define FMT_TRACE_SYMBOLICATED @"%@ + " FMT_OFFSET +#define FMT_TRACE_SYMBOLICATED @"%@ + " FMT_OFFSET #define kAppleRedactedText @"" #define kExpectedMajorVersion 3 - @interface KSCrashReportFilterAppleFmt () -@property(nonatomic,readwrite,assign) KSAppleReportStyle reportStyle; +@property(nonatomic, readwrite, assign) KSAppleReportStyle reportStyle; /** Convert a crash report to Apple format. * @@ -72,7 +70,7 @@ @interface KSCrashReportFilterAppleFmt () * * @return The converted crash report. */ -- (NSString*) toAppleFormat:(NSDictionary*) JSONReport; +- (NSString *)toAppleFormat:(NSDictionary *)JSONReport; /** Determine the major CPU type. * @@ -83,7 +81,7 @@ - (NSString*) toAppleFormat:(NSDictionary*) JSONReport; * @return the major CPU type. */ -- (NSString*) CPUType:(NSString*) CPUArch isSystemInfoHeader:(BOOL) isSystemInfoHeader; +- (NSString *)CPUType:(NSString *)CPUArch isSystemInfoHeader:(BOOL)isSystemInfoHeader; /** Determine the CPU architecture based on major/minor CPU architecture codes. * @@ -93,7 +91,7 @@ - (NSString*) CPUType:(NSString*) CPUArch isSystemInfoHeader:(BOOL) isSystemInfo * * @return The CPU architecture. */ -- (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minorCode; +- (NSString *)CPUArchForMajor:(cpu_type_t)majorCode minor:(cpu_subtype_t)minorCode; /** Take a UUID string and strip out all the dashes. * @@ -101,7 +99,7 @@ - (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minor * * @return the UUID in compact form. */ -- (NSString*) toCompactUUID:(NSString*) uuid; +- (NSString *)toCompactUUID:(NSString *)uuid; @end @@ -113,9 +111,11 @@ - (NSComparisonResult)kscrash_compareRegisterName:(NSString *)other; @implementation NSString (CompareRegisterNames) -- (NSComparisonResult)kscrash_compareRegisterName:(NSString *)other { +- (NSComparisonResult)kscrash_compareRegisterName:(NSString *)other +{ BOOL containsNum = [self rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound; - BOOL otherContainsNum = [other rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound; + BOOL otherContainsNum = + [other rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound; if (containsNum && !otherContainsNum) { return NSOrderedAscending; @@ -128,21 +128,20 @@ - (NSComparisonResult)kscrash_compareRegisterName:(NSString *)other { @end - @implementation KSCrashReportFilterAppleFmt @synthesize reportStyle = _reportStyle; /** Date formatter for Apple date format in crash reports. */ -static NSDateFormatter* g_dateFormatter; +static NSDateFormatter *g_dateFormatter; /** Date formatter for RFC3339 date format. */ -static NSDateFormatter* g_rfc3339DateFormatter; +static NSDateFormatter *g_rfc3339DateFormatter; /** Printing order for registers. */ -static NSDictionary* g_registerOrders; +static NSDictionary *g_registerOrders; -+ (void) initialize ++ (void)initialize { g_dateFormatter = [[NSDateFormatter alloc] init]; [g_dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; @@ -153,93 +152,62 @@ + (void) initialize [g_rfc3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSSSSS'Z'"]; [g_rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; - NSArray* armOrder = [NSArray arrayWithObjects: - @"r0", @"r1", @"r2", @"r3", @"r4", @"r5", @"r6", @"r7", - @"r8", @"r9", @"r10", @"r11", @"ip", - @"sp", @"lr", @"pc", @"cpsr", - nil]; - - NSArray* x86Order = [NSArray arrayWithObjects: - @"eax", @"ebx", @"ecx", @"edx", - @"edi", @"esi", - @"ebp", @"esp", @"ss", - @"eflags", @"eip", - @"cs", @"ds", @"es", @"fs", @"gs", - nil]; - - NSArray* x86_64Order = [NSArray arrayWithObjects: - @"rax", @"rbx", @"rcx", @"rdx", - @"rdi", @"rsi", - @"rbp", @"rsp", - @"r8", @"r9", @"r10", @"r11", @"r12", @"r13", - @"r14", @"r15", - @"rip", @"rflags", - @"cs", @"fs", @"gs", - nil]; - - g_registerOrders = [[NSDictionary alloc] initWithObjectsAndKeys: - armOrder, @"arm", - armOrder, @"armv6", - armOrder, @"armv7", - armOrder, @"armv7f", - armOrder, @"armv7k", - armOrder, @"armv7s", - x86Order, @"x86", - x86Order, @"i386", - x86Order, @"i486", - x86Order, @"i686", - x86_64Order, @"x86_64", - nil]; -} - -+ (instancetype) filterWithReportStyle:(KSAppleReportStyle) reportStyle + NSArray *armOrder = [NSArray arrayWithObjects:@"r0", @"r1", @"r2", @"r3", @"r4", @"r5", @"r6", @"r7", @"r8", @"r9", + @"r10", @"r11", @"ip", @"sp", @"lr", @"pc", @"cpsr", nil]; + + NSArray *x86Order = [NSArray arrayWithObjects:@"eax", @"ebx", @"ecx", @"edx", @"edi", @"esi", @"ebp", @"esp", @"ss", + @"eflags", @"eip", @"cs", @"ds", @"es", @"fs", @"gs", nil]; + + NSArray *x86_64Order = + [NSArray arrayWithObjects:@"rax", @"rbx", @"rcx", @"rdx", @"rdi", @"rsi", @"rbp", @"rsp", @"r8", @"r9", @"r10", + @"r11", @"r12", @"r13", @"r14", @"r15", @"rip", @"rflags", @"cs", @"fs", @"gs", nil]; + + g_registerOrders = [[NSDictionary alloc] + initWithObjectsAndKeys:armOrder, @"arm", armOrder, @"armv6", armOrder, @"armv7", armOrder, @"armv7f", armOrder, + @"armv7k", armOrder, @"armv7s", x86Order, @"x86", x86Order, @"i386", x86Order, @"i486", + x86Order, @"i686", x86_64Order, @"x86_64", nil]; +} + ++ (instancetype)filterWithReportStyle:(KSAppleReportStyle)reportStyle { return [[self alloc] initWithReportStyle:reportStyle]; } -- (instancetype) initWithReportStyle:(KSAppleReportStyle) reportStyle +- (instancetype)initWithReportStyle:(KSAppleReportStyle)reportStyle { - if((self = [super init])) - { + if ((self = [super init])) { self.reportStyle = reportStyle; } return self; } -- (int) majorVersion:(NSDictionary*) report +- (int)majorVersion:(NSDictionary *)report { - NSDictionary* info = [self infoReport:report]; - NSString* version = [info objectForKey:KSCrashField_Version]; - if ([version isKindOfClass:[NSDictionary class]]) - { + NSDictionary *info = [self infoReport:report]; + NSString *version = [info objectForKey:KSCrashField_Version]; + if ([version isKindOfClass:[NSDictionary class]]) { NSDictionary *oldVersion = (NSDictionary *)version; version = oldVersion[@"major"]; } - if([version respondsToSelector:@selector(intValue)]) - { + if ([version respondsToSelector:@selector(intValue)]) { return version.intValue; } return 0; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { NSDictionary *reportDict = report.dictionaryValue; - if(reportDict == nil) - { + if (reportDict == nil) { KSLOG_ERROR(@"Unexpected non-dictionary report: %@", report); continue; } - if([self majorVersion:reportDict] == kExpectedMajorVersion) - { - NSString* appleReportString = [self toAppleFormat:reportDict]; - if(appleReportString != nil) - { + if ([self majorVersion:reportDict] == kExpectedMajorVersion) { + NSString *appleReportString = [self toAppleFormat:reportDict]; + if (appleReportString != nil) { [filteredReports addObject:[KSCrashReport reportWithString:appleReportString]]; } } @@ -248,48 +216,39 @@ - (void) filterReports:(NSArray*) reports kscrash_callCompletion(onCompletion, filteredReports, YES, nil); } -- (NSString*) CPUType:(NSString*) CPUArch isSystemInfoHeader:(BOOL) isSystemInfoHeader +- (NSString *)CPUType:(NSString *)CPUArch isSystemInfoHeader:(BOOL)isSystemInfoHeader { - if(isSystemInfoHeader && [CPUArch rangeOfString:@"arm64e"].location == 0) - { + if (isSystemInfoHeader && [CPUArch rangeOfString:@"arm64e"].location == 0) { return @"ARM-64 (Native)"; } - if([CPUArch rangeOfString:@"arm64"].location == 0) - { + if ([CPUArch rangeOfString:@"arm64"].location == 0) { return @"ARM-64"; } - if([CPUArch rangeOfString:@"arm"].location == 0) - { + if ([CPUArch rangeOfString:@"arm"].location == 0) { return @"ARM"; } - if([CPUArch isEqualToString:@"x86"]) - { + if ([CPUArch isEqualToString:@"x86"]) { return @"X86"; } - if([CPUArch isEqualToString:@"x86_64"]) - { + if ([CPUArch isEqualToString:@"x86_64"]) { return @"X86_64"; } return @"Unknown"; } -- (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minorCode +- (NSString *)CPUArchForMajor:(cpu_type_t)majorCode minor:(cpu_subtype_t)minorCode { #if KSCRASH_HOST_APPLE // In Apple platforms we can use this function to get the name of a particular architecture const char *archName = kscpu_archForCPU(majorCode, minorCode); - if(archName) - { + if (archName) { return [[NSString alloc] initWithUTF8String:archName]; } #endif - switch(majorCode) - { - case CPU_TYPE_ARM: - { - switch (minorCode) - { + switch (majorCode) { + case CPU_TYPE_ARM: { + switch (minorCode) { case CPU_SUBTYPE_ARM_V6: return @"armv6"; case CPU_SUBTYPE_ARM_V7: @@ -305,10 +264,8 @@ - (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minor } return @"arm"; } - case CPU_TYPE_ARM64: - { - switch (minorCode) - { + case CPU_TYPE_ARM64: { + switch (minorCode) { case CPU_SUBTYPE_ARM64E: return @"arm64e"; } @@ -332,58 +289,49 @@ - (NSString*) CPUArchForMajor:(cpu_type_t) majorCode minor:(cpu_subtype_t) minor * * @return The converted string. */ -- (NSString*) backtraceString:(NSDictionary*) backtrace - reportStyle:(KSAppleReportStyle) reportStyle - mainExecutableName:(NSString*) mainExecutableName +- (NSString *)backtraceString:(NSDictionary *)backtrace + reportStyle:(KSAppleReportStyle)reportStyle + mainExecutableName:(NSString *)mainExecutableName { - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; int traceNum = 0; - for(NSDictionary* trace in [backtrace objectForKey:KSCrashField_Contents]) - { + for (NSDictionary *trace in [backtrace objectForKey:KSCrashField_Contents]) { uintptr_t pc = (uintptr_t)[[trace objectForKey:KSCrashField_InstructionAddr] longLongValue]; uintptr_t objAddr = (uintptr_t)[[trace objectForKey:KSCrashField_ObjectAddr] longLongValue]; - NSString* objName = [[trace objectForKey:KSCrashField_ObjectName] lastPathComponent]; + NSString *objName = [[trace objectForKey:KSCrashField_ObjectName] lastPathComponent]; uintptr_t symAddr = (uintptr_t)[[trace objectForKey:KSCrashField_SymbolAddr] longLongValue]; - NSString* symName = [trace objectForKey:KSCrashField_SymbolName]; + NSString *symName = [trace objectForKey:KSCrashField_SymbolName]; bool isMainExecutable = mainExecutableName && [objName isEqualToString:mainExecutableName]; KSAppleReportStyle thisLineStyle = reportStyle; - if(thisLineStyle == KSAppleReportStylePartiallySymbolicated) - { + if (thisLineStyle == KSAppleReportStylePartiallySymbolicated) { thisLineStyle = isMainExecutable ? KSAppleReportStyleUnsymbolicated : KSAppleReportStyleSymbolicated; } - NSString* preamble = [NSString stringWithFormat:FMT_TRACE_PREAMBLE, traceNum, [objName UTF8String], pc]; - NSString* unsymbolicated = [NSString stringWithFormat:FMT_TRACE_UNSYMBOLICATED, objAddr, pc - objAddr]; - NSString* symbolicated = @"(null)"; - if(thisLineStyle != KSAppleReportStyleUnsymbolicated && [symName isKindOfClass:[NSString class]]) - { + NSString *preamble = [NSString stringWithFormat:FMT_TRACE_PREAMBLE, traceNum, [objName UTF8String], pc]; + NSString *unsymbolicated = [NSString stringWithFormat:FMT_TRACE_UNSYMBOLICATED, objAddr, pc - objAddr]; + NSString *symbolicated = @"(null)"; + if (thisLineStyle != KSAppleReportStyleUnsymbolicated && [symName isKindOfClass:[NSString class]]) { symbolicated = [NSString stringWithFormat:FMT_TRACE_SYMBOLICATED, symName, pc - symAddr]; - } - else - { + } else { thisLineStyle = KSAppleReportStyleUnsymbolicated; } - // Apple has started replacing symbols for any function/method // beginning with an underscore with "" in iOS 6. // No, I can't think of any valid reason to do this, either. - if(thisLineStyle == KSAppleReportStyleSymbolicated && - [symName isEqualToString:kAppleRedactedText]) - { + if (thisLineStyle == KSAppleReportStyleSymbolicated && [symName isEqualToString:kAppleRedactedText]) { thisLineStyle = KSAppleReportStyleUnsymbolicated; } - switch (thisLineStyle) - { + switch (thisLineStyle) { case KSAppleReportStyleSymbolicatedSideBySide: [str appendFormat:@"%@ %@ (%@)\n", preamble, unsymbolicated, symbolicated]; break; case KSAppleReportStyleSymbolicated: [str appendFormat:@"%@ %@\n", preamble, symbolicated]; break; - case KSAppleReportStylePartiallySymbolicated: // Should not happen + case KSAppleReportStylePartiallySymbolicated: // Should not happen case KSAppleReportStyleUnsymbolicated: [str appendFormat:@"%@ %@\n", preamble, unsymbolicated]; break; @@ -394,59 +342,56 @@ - (NSString*) backtraceString:(NSDictionary*) backtrace return str; } -- (NSString*) toCompactUUID:(NSString*) uuid +- (NSString *)toCompactUUID:(NSString *)uuid { return [[uuid lowercaseString] stringByReplacingOccurrencesOfString:@"-" withString:@""]; } -- (NSString*) stringFromDate:(NSDate*) date +- (NSString *)stringFromDate:(NSDate *)date { - if(![date isKindOfClass:[NSDate class]]) - { + if (![date isKindOfClass:[NSDate class]]) { return nil; } return [g_dateFormatter stringFromDate:date]; } -- (NSDictionary*) recrashReport:(NSDictionary*) report +- (NSDictionary *)recrashReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_RecrashReport]; } -- (NSDictionary*) systemReport:(NSDictionary*) report +- (NSDictionary *)systemReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_System]; } -- (NSDictionary*) infoReport:(NSDictionary*) report +- (NSDictionary *)infoReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_Report]; } -- (NSDictionary*) processReport:(NSDictionary*) report +- (NSDictionary *)processReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_ProcessState]; } -- (NSDictionary*) crashReport:(NSDictionary*) report +- (NSDictionary *)crashReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_Crash]; } -- (NSArray*) binaryImagesReport:(NSDictionary*) report +- (NSArray *)binaryImagesReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_BinaryImages]; } -- (NSDictionary*) crashedThread:(NSDictionary*) report +- (NSDictionary *)crashedThread:(NSDictionary *)report { - NSDictionary* crash = [self crashReport:report]; - NSArray* threads = [crash objectForKey:KSCrashField_Threads]; - for(NSDictionary* thread in threads) - { + NSDictionary *crash = [self crashReport:report]; + NSArray *threads = [crash objectForKey:KSCrashField_Threads]; + for (NSDictionary *thread in threads) { BOOL crashed = [[thread objectForKey:KSCrashField_Crashed] boolValue]; - if(crashed) - { + if (crashed) { return thread; } } @@ -454,103 +399,93 @@ - (NSDictionary*) crashedThread:(NSDictionary*) report return [crash objectForKey:KSCrashField_CrashedThread]; } -- (NSString*) mainExecutableNameForReport:(NSDictionary*) report +- (NSString *)mainExecutableNameForReport:(NSDictionary *)report { - NSDictionary* info = [self infoReport:report]; + NSDictionary *info = [self infoReport:report]; return [info objectForKey:KSCrashField_ProcessName]; } -- (NSString*) cpuArchForReport:(NSDictionary*) report +- (NSString *)cpuArchForReport:(NSDictionary *)report { - NSDictionary* system = [self systemReport:report]; + NSDictionary *system = [self systemReport:report]; cpu_type_t cpuType = [[system objectForKey:KSCrashField_BinaryCPUType] intValue]; cpu_subtype_t cpuSubType = [[system objectForKey:KSCrashField_BinaryCPUSubType] intValue]; return [self CPUArchForMajor:cpuType minor:cpuSubType]; } -- (NSString*) headerStringForReport:(NSDictionary*) report +- (NSString *)headerStringForReport:(NSDictionary *)report { - NSDictionary* system = [self systemReport:report]; - NSDictionary* reportInfo = [self infoReport:report]; + NSDictionary *system = [self systemReport:report]; + NSDictionary *reportInfo = [self infoReport:report]; NSString *reportID = [reportInfo objectForKey:KSCrashField_ID]; - NSDate* crashTime = [g_rfc3339DateFormatter dateFromString:[reportInfo objectForKey:KSCrashField_Timestamp]]; + NSDate *crashTime = [g_rfc3339DateFormatter dateFromString:[reportInfo objectForKey:KSCrashField_Timestamp]]; return [self headerStringForSystemInfo:system reportID:reportID crashTime:crashTime]; } -- (NSString*)headerStringForSystemInfo:(NSDictionary*)system - reportID:(nullable NSString*)reportID - crashTime:(nullable NSDate*)crashTime +- (NSString *)headerStringForSystemInfo:(NSDictionary *)system + reportID:(nullable NSString *)reportID + crashTime:(nullable NSDate *)crashTime { - NSMutableString* str = [NSMutableString string]; - NSString* executablePath = [system objectForKey:KSCrashField_ExecutablePath]; - NSString* cpuArch = [system objectForKey:KSCrashField_CPUArch]; - NSString* cpuArchType = [self CPUType:cpuArch isSystemInfoHeader:YES]; - NSString* parentProcess = @"launchd"; // In iOS and most macOS regulard apps "launchd" is always the launcher. This might need a fix for other kind of apps - NSString* processRole = @"Foreground"; // In iOS and most macOS regulard apps the role is "Foreground". This might need a fix for other kind of apps + NSMutableString *str = [NSMutableString string]; + NSString *executablePath = [system objectForKey:KSCrashField_ExecutablePath]; + NSString *cpuArch = [system objectForKey:KSCrashField_CPUArch]; + NSString *cpuArchType = [self CPUType:cpuArch isSystemInfoHeader:YES]; + NSString *parentProcess = @"launchd"; // In iOS and most macOS regulard apps "launchd" is always the launcher. This + // might need a fix for other kind of apps + NSString *processRole = @"Foreground"; // In iOS and most macOS regulard apps the role is "Foreground". This might + // need a fix for other kind of apps [str appendFormat:@"Incident Identifier: %@\n", reportID]; [str appendFormat:@"CrashReporter Key: %@\n", [system objectForKey:KSCrashField_DeviceAppHash]]; [str appendFormat:@"Hardware Model: %@\n", [system objectForKey:KSCrashField_Machine]]; - [str appendFormat:@"Process: %@ [%@]\n", - [system objectForKey:KSCrashField_ProcessName], - [system objectForKey:KSCrashField_ProcessID]]; + [str appendFormat:@"Process: %@ [%@]\n", [system objectForKey:KSCrashField_ProcessName], + [system objectForKey:KSCrashField_ProcessID]]; [str appendFormat:@"Path: %@\n", executablePath]; [str appendFormat:@"Identifier: %@\n", [system objectForKey:KSCrashField_BundleID]]; - [str appendFormat:@"Version: %@ (%@)\n", - [system objectForKey:KSCrashField_BundleVersion], - [system objectForKey:KSCrashField_BundleShortVersion]]; + [str appendFormat:@"Version: %@ (%@)\n", [system objectForKey:KSCrashField_BundleVersion], + [system objectForKey:KSCrashField_BundleShortVersion]]; [str appendFormat:@"Code Type: %@\n", cpuArchType]; [str appendFormat:@"Role: %@\n", processRole]; - [str appendFormat:@"Parent Process: %@ [%@]\n", parentProcess, [system objectForKey:KSCrashField_ParentProcessID]]; + [str appendFormat:@"Parent Process: %@ [%@]\n", parentProcess, + [system objectForKey:KSCrashField_ParentProcessID]]; [str appendFormat:@"\n"]; [str appendFormat:@"Date/Time: %@\n", [self stringFromDate:crashTime]]; - [str appendFormat:@"OS Version: %@ %@ (%@)\n", - [system objectForKey:KSCrashField_SystemName], - [system objectForKey:KSCrashField_SystemVersion], - [system objectForKey:KSCrashField_OSVersion]]; + [str appendFormat:@"OS Version: %@ %@ (%@)\n", [system objectForKey:KSCrashField_SystemName], + [system objectForKey:KSCrashField_SystemVersion], [system objectForKey:KSCrashField_OSVersion]]; [str appendFormat:@"Report Version: 104\n"]; return str; } -- (NSString*) binaryImagesStringForReport:(NSDictionary*) report +- (NSString *)binaryImagesStringForReport:(NSDictionary *)report { - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; - NSArray* binaryImages = [self binaryImagesReport:report]; + NSArray *binaryImages = [self binaryImagesReport:report]; [str appendString:@"\nBinary Images:\n"]; - if(binaryImages) - { - NSMutableArray* images = [NSMutableArray arrayWithArray:binaryImages]; - [images sortUsingComparator:^NSComparisonResult(id obj1, id obj2) - { - NSNumber* num1 = [(NSDictionary*)obj1 objectForKey:KSCrashField_ImageAddress]; - NSNumber* num2 = [(NSDictionary*)obj2 objectForKey:KSCrashField_ImageAddress]; - if(num1 == nil || num2 == nil) - { - return NSOrderedSame; - } - return [num1 compare:num2]; - }]; - for(NSDictionary* image in images) - { + if (binaryImages) { + NSMutableArray *images = [NSMutableArray arrayWithArray:binaryImages]; + [images sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { + NSNumber *num1 = [(NSDictionary *)obj1 objectForKey:KSCrashField_ImageAddress]; + NSNumber *num2 = [(NSDictionary *)obj2 objectForKey:KSCrashField_ImageAddress]; + if (num1 == nil || num2 == nil) { + return NSOrderedSame; + } + return [num1 compare:num2]; + }]; + for (NSDictionary *image in images) { cpu_type_t cpuType = [[image objectForKey:KSCrashField_CPUType] intValue]; cpu_subtype_t cpuSubtype = [[image objectForKey:KSCrashField_CPUSubType] intValue]; uintptr_t imageAddr = (uintptr_t)[[image objectForKey:KSCrashField_ImageAddress] longLongValue]; uintptr_t imageSize = (uintptr_t)[[image objectForKey:KSCrashField_ImageSize] longLongValue]; - NSString* path = [image objectForKey:KSCrashField_Name]; - NSString* name = [path lastPathComponent]; - NSString* uuid = [self toCompactUUID:[image objectForKey:KSCrashField_UUID]]; - NSString* arch = [self CPUArchForMajor:cpuType minor:cpuSubtype]; - [str appendFormat:FMT_PTR_RJ @" - " FMT_PTR_RJ @" %@ %@ <%@> %@\n", - imageAddr, - imageAddr + imageSize - 1, - name, - arch, - uuid, - path]; + NSString *path = [image objectForKey:KSCrashField_Name]; + NSString *name = [path lastPathComponent]; + NSString *uuid = [self toCompactUUID:[image objectForKey:KSCrashField_UUID]]; + NSString *arch = [self CPUArchForMajor:cpuType minor:cpuSubtype]; + [str appendFormat:FMT_PTR_RJ @" - " FMT_PTR_RJ @" %@ %@ <%@> %@\n", imageAddr, imageAddr + imageSize - 1, + name, arch, uuid, path]; } } @@ -559,45 +494,37 @@ - (NSString*) binaryImagesStringForReport:(NSDictionary*) report return str; } -- (NSString*) crashedThreadCPUStateStringForReport:(NSDictionary*) report - cpuArch:(NSString*) cpuArch +- (NSString *)crashedThreadCPUStateStringForReport:(NSDictionary *)report cpuArch:(NSString *)cpuArch { - NSDictionary* thread = [self crashedThread:report]; - if(thread == nil) - { + NSDictionary *thread = [self crashedThread:report]; + if (thread == nil) { return @""; } int threadIndex = [[thread objectForKey:KSCrashField_Index] intValue]; - NSString* cpuArchType = [self CPUType:cpuArch isSystemInfoHeader:NO]; + NSString *cpuArchType = [self CPUType:cpuArch isSystemInfoHeader:NO]; - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; - [str appendFormat:@"\nThread %d crashed with %@ Thread State:\n", - threadIndex, cpuArchType]; + [str appendFormat:@"\nThread %d crashed with %@ Thread State:\n", threadIndex, cpuArchType]; - NSDictionary* registers = [(NSDictionary*)[thread objectForKey:KSCrashField_Registers] objectForKey:KSCrashField_Basic]; - NSArray* regOrder = [g_registerOrders objectForKey:cpuArch]; - if(regOrder == nil) - { + NSDictionary *registers = + [(NSDictionary *)[thread objectForKey:KSCrashField_Registers] objectForKey:KSCrashField_Basic]; + NSArray *regOrder = [g_registerOrders objectForKey:cpuArch]; + if (regOrder == nil) { regOrder = [[registers allKeys] sortedArrayUsingSelector:@selector(kscrash_compareRegisterName:)]; } NSUInteger numRegisters = [regOrder count]; NSUInteger i = 0; - while(i < numRegisters) - { + while (i < numRegisters) { NSUInteger nextBreak = i + 4; - if(nextBreak > numRegisters) - { + if (nextBreak > numRegisters) { nextBreak = numRegisters; } - for(;i < nextBreak; i++) - { - NSString* regName = [regOrder objectAtIndex:i]; + for (; i < nextBreak; i++) { + NSString *regName = [regOrder objectAtIndex:i]; uintptr_t addr = (uintptr_t)[[registers objectForKey:regName] longLongValue]; - [str appendFormat:@"%6s: " FMT_PTR_LONG @" ", - [regName cStringUsingEncoding:NSUTF8StringEncoding], - addr]; + [str appendFormat:@"%6s: " FMT_PTR_LONG @" ", [regName cStringUsingEncoding:NSUTF8StringEncoding], addr]; } [str appendString:@"\n"]; } @@ -605,128 +532,108 @@ - (NSString*) crashedThreadCPUStateStringForReport:(NSDictionary*) report return str; } -- (NSString*) extraInfoStringForReport:(NSDictionary*) report - mainExecutableName:(NSString*) mainExecutableName +- (NSString *)extraInfoStringForReport:(NSDictionary *)report mainExecutableName:(NSString *)mainExecutableName { - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; [str appendString:@"\nExtra Information:\n"]; - NSDictionary* system = [self systemReport:report]; - NSDictionary* crash = [self crashReport:report]; - NSDictionary* error = [crash objectForKey:KSCrashField_Error]; - NSDictionary* nsexception = [error objectForKey:KSCrashField_NSException]; - NSDictionary* referencedObject = [nsexception objectForKey:KSCrashField_ReferencedObject]; - if(referencedObject != nil) - { + NSDictionary *system = [self systemReport:report]; + NSDictionary *crash = [self crashReport:report]; + NSDictionary *error = [crash objectForKey:KSCrashField_Error]; + NSDictionary *nsexception = [error objectForKey:KSCrashField_NSException]; + NSDictionary *referencedObject = [nsexception objectForKey:KSCrashField_ReferencedObject]; + if (referencedObject != nil) { [str appendFormat:@"Object referenced by NSException:\n%@\n", [self JSONForObject:referencedObject]]; } - NSDictionary* crashedThread = [self crashedThread:report]; - if(crashedThread != nil) - { - NSDictionary* stack = [crashedThread objectForKey:KSCrashField_Stack]; - if(stack != nil) - { + NSDictionary *crashedThread = [self crashedThread:report]; + if (crashedThread != nil) { + NSDictionary *stack = [crashedThread objectForKey:KSCrashField_Stack]; + if (stack != nil) { [str appendFormat:@"\nStack Dump (" FMT_PTR_LONG "-" FMT_PTR_LONG "):\n\n%@\n", - (uintptr_t)[[stack objectForKey:KSCrashField_DumpStart] unsignedLongLongValue], - (uintptr_t)[[stack objectForKey:KSCrashField_DumpEnd] unsignedLongLongValue], - [stack objectForKey:KSCrashField_Contents]]; + (uintptr_t)[[stack objectForKey:KSCrashField_DumpStart] unsignedLongLongValue], + (uintptr_t)[[stack objectForKey:KSCrashField_DumpEnd] unsignedLongLongValue], + [stack objectForKey:KSCrashField_Contents]]; } - NSDictionary* notableAddresses = [crashedThread objectForKey:KSCrashField_NotableAddresses]; - if(notableAddresses.count) - { + NSDictionary *notableAddresses = [crashedThread objectForKey:KSCrashField_NotableAddresses]; + if (notableAddresses.count) { [str appendFormat:@"\nNotable Addresses:\n%@\n", [self JSONForObject:notableAddresses]]; } } - NSDictionary* lastException = [[self processReport:report] objectForKey:KSCrashField_LastDeallocedNSException]; - if(lastException != nil) - { + NSDictionary *lastException = [[self processReport:report] objectForKey:KSCrashField_LastDeallocedNSException]; + if (lastException != nil) { uintptr_t address = (uintptr_t)[[lastException objectForKey:KSCrashField_Address] unsignedLongLongValue]; - NSString* name = [lastException objectForKey:KSCrashField_Name]; - NSString* reason = [lastException objectForKey:KSCrashField_Reason]; + NSString *name = [lastException objectForKey:KSCrashField_Name]; + NSString *reason = [lastException objectForKey:KSCrashField_Reason]; referencedObject = [lastException objectForKey:KSCrashField_ReferencedObject]; - [str appendFormat:@"\nLast deallocated NSException (" FMT_PTR_LONG "): %@: %@\n", - address, name, reason]; - if(referencedObject != nil) - { + [str appendFormat:@"\nLast deallocated NSException (" FMT_PTR_LONG "): %@: %@\n", address, name, reason]; + if (referencedObject != nil) { [str appendFormat:@"Referenced object:\n%@\n", [self JSONForObject:referencedObject]]; } - [str appendString: - [self backtraceString:[lastException objectForKey:KSCrashField_Backtrace] - reportStyle:self.reportStyle - mainExecutableName:mainExecutableName]]; + [str appendString:[self backtraceString:[lastException objectForKey:KSCrashField_Backtrace] + reportStyle:self.reportStyle + mainExecutableName:mainExecutableName]]; } - NSDictionary* appStats = [system objectForKey:KSCrashField_AppStats]; - if(appStats != nil) - { + NSDictionary *appStats = [system objectForKey:KSCrashField_AppStats]; + if (appStats != nil) { [str appendFormat:@"\nApplication Stats:\n%@\n", [self JSONForObject:appStats]]; } - - NSDictionary* memoryStats = [system objectForKey:KSCrashField_AppMemory]; - if(memoryStats != nil) - { + + NSDictionary *memoryStats = [system objectForKey:KSCrashField_AppMemory]; + if (memoryStats != nil) { [str appendFormat:@"\nMemory Statistics:\n%@\n", [self JSONForObject:memoryStats]]; } - - NSDictionary* crashReport = [report objectForKey:KSCrashField_Crash]; - NSString* diagnosis = [crashReport objectForKey:KSCrashField_Diagnosis]; - if(diagnosis != nil) - { + + NSDictionary *crashReport = [report objectForKey:KSCrashField_Crash]; + NSString *diagnosis = [crashReport objectForKey:KSCrashField_Diagnosis]; + if (diagnosis != nil) { [str appendFormat:@"\nCrashDoctor Diagnosis: %@\n", diagnosis]; } return str; } -- (NSString*) JSONForObject:(id) object +- (NSString *)JSONForObject:(id)object { - NSError* error = nil; - NSData* encoded = [KSJSONCodec encode:object - options:KSJSONEncodeOptionPretty | - KSJSONEncodeOptionSorted + NSError *error = nil; + NSData *encoded = [KSJSONCodec encode:object + options:KSJSONEncodeOptionPretty | KSJSONEncodeOptionSorted error:&error]; - if(error != nil) - { + if (error != nil) { return [NSString stringWithFormat:@"Error encoding JSON: %@", error]; - } - else - { + } else { return [[NSString alloc] initWithData:encoded encoding:NSUTF8StringEncoding]; } } -- (BOOL) isZombieNSException:(NSDictionary*) report +- (BOOL)isZombieNSException:(NSDictionary *)report { - NSDictionary* crash = [self crashReport:report]; - NSDictionary* error = [crash objectForKey:KSCrashField_Error]; - NSDictionary* mach = [error objectForKey:KSCrashField_Mach]; - NSString* machExcName = [mach objectForKey:KSCrashField_ExceptionName]; - NSString* machCodeName = [mach objectForKey:KSCrashField_CodeName]; - if(![machExcName isEqualToString:@"EXC_BAD_ACCESS"] || - ![machCodeName isEqualToString:@"KERN_INVALID_ADDRESS"]) - { + NSDictionary *crash = [self crashReport:report]; + NSDictionary *error = [crash objectForKey:KSCrashField_Error]; + NSDictionary *mach = [error objectForKey:KSCrashField_Mach]; + NSString *machExcName = [mach objectForKey:KSCrashField_ExceptionName]; + NSString *machCodeName = [mach objectForKey:KSCrashField_CodeName]; + if (![machExcName isEqualToString:@"EXC_BAD_ACCESS"] || ![machCodeName isEqualToString:@"KERN_INVALID_ADDRESS"]) { return NO; } - NSDictionary* lastException = [[self processReport:report] objectForKey:KSCrashField_LastDeallocedNSException]; - if(lastException == nil) - { + NSDictionary *lastException = [[self processReport:report] objectForKey:KSCrashField_LastDeallocedNSException]; + if (lastException == nil) { return NO; } - NSNumber* lastExceptionAddress = [lastException objectForKey:KSCrashField_Address]; + NSNumber *lastExceptionAddress = [lastException objectForKey:KSCrashField_Address]; - NSDictionary* thread = [self crashedThread:report]; - NSDictionary* registers = [(NSDictionary*)[thread objectForKey:KSCrashField_Registers] objectForKey:KSCrashField_Basic]; + NSDictionary *thread = [self crashedThread:report]; + NSDictionary *registers = + [(NSDictionary *)[thread objectForKey:KSCrashField_Registers] objectForKey:KSCrashField_Basic]; - for(NSString* reg in registers) - { - NSNumber* address = [registers objectForKey:reg]; - if(lastExceptionAddress && [address isEqualToNumber:lastExceptionAddress]) - { + for (NSString *reg in registers) { + NSNumber *address = [registers objectForKey:reg]; + if (lastExceptionAddress && [address isEqualToNumber:lastExceptionAddress]) { return YES; } } @@ -734,169 +641,142 @@ - (BOOL) isZombieNSException:(NSDictionary*) report return NO; } -- (NSString*) errorInfoStringForReport:(NSDictionary*) report +- (NSString *)errorInfoStringForReport:(NSDictionary *)report { - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; - NSDictionary* thread = [self crashedThread:report]; - NSDictionary* crash = [self crashReport:report]; - NSDictionary* error = [crash objectForKey:KSCrashField_Error]; - NSDictionary* type = [error objectForKey:KSCrashField_Type]; + NSDictionary *thread = [self crashedThread:report]; + NSDictionary *crash = [self crashReport:report]; + NSDictionary *error = [crash objectForKey:KSCrashField_Error]; + NSDictionary *type = [error objectForKey:KSCrashField_Type]; - NSDictionary* nsexception = [error objectForKey:KSCrashField_NSException]; - NSDictionary* cppexception = [error objectForKey:KSCrashField_CPPException]; - NSDictionary* lastException = [[self processReport:report] objectForKey:KSCrashField_LastDeallocedNSException]; - NSDictionary* userException = [error objectForKey:KSCrashField_UserReported]; - NSDictionary* mach = [error objectForKey:KSCrashField_Mach]; - NSDictionary* signal = [error objectForKey:KSCrashField_Signal]; + NSDictionary *nsexception = [error objectForKey:KSCrashField_NSException]; + NSDictionary *cppexception = [error objectForKey:KSCrashField_CPPException]; + NSDictionary *lastException = [[self processReport:report] objectForKey:KSCrashField_LastDeallocedNSException]; + NSDictionary *userException = [error objectForKey:KSCrashField_UserReported]; + NSDictionary *mach = [error objectForKey:KSCrashField_Mach]; + NSDictionary *signal = [error objectForKey:KSCrashField_Signal]; - NSString* machExcName = [mach objectForKey:KSCrashField_ExceptionName]; - if(machExcName == nil) - { + NSString *machExcName = [mach objectForKey:KSCrashField_ExceptionName]; + if (machExcName == nil) { machExcName = @"0"; } - NSString* signalName = [signal objectForKey:KSCrashField_Name]; - if(signalName == nil) - { + NSString *signalName = [signal objectForKey:KSCrashField_Name]; + if (signalName == nil) { signalName = [[signal objectForKey:KSCrashField_Signal] stringValue]; } - NSString* machCodeName = [mach objectForKey:KSCrashField_CodeName]; - if(machCodeName == nil) - { + NSString *machCodeName = [mach objectForKey:KSCrashField_CodeName]; + if (machCodeName == nil) { machCodeName = @"0x00000000"; } [str appendFormat:@"\n"]; [str appendFormat:@"Exception Type: %@ (%@)\n", machExcName, signalName]; - [str appendFormat:@"Exception Codes: %@ at " FMT_PTR_LONG @"\n", - machCodeName, - (uintptr_t)[[error objectForKey:KSCrashField_Address] longLongValue]]; + [str appendFormat:@"Exception Codes: %@ at " FMT_PTR_LONG @"\n", machCodeName, + (uintptr_t)[[error objectForKey:KSCrashField_Address] longLongValue]]; - [str appendFormat:@"Triggered by Thread: %d\n", - [[thread objectForKey:KSCrashField_Index] intValue]]; + [str appendFormat:@"Triggered by Thread: %d\n", [[thread objectForKey:KSCrashField_Index] intValue]]; - if(nsexception != nil) - { + if (nsexception != nil) { [str appendString:[self stringWithUncaughtExceptionName:[nsexception objectForKey:KSCrashField_Name] reason:[error objectForKey:KSCrashField_Reason]]]; - } - else if([self isZombieNSException:report]) - { + } else if ([self isZombieNSException:report]) { [str appendString:[self stringWithUncaughtExceptionName:[lastException objectForKey:KSCrashField_Name] reason:[lastException objectForKey:KSCrashField_Reason]]]; - [str appendString:@"NOTE: This exception has been deallocated! Stack trace is crash from attempting to access this zombie exception.\n"]; - } - else if(userException != nil) - { + [str appendString:@"NOTE: This exception has been deallocated! Stack trace is crash from attempting to access " + @"this zombie exception.\n"]; + } else if (userException != nil) { [str appendString:[self stringWithUncaughtExceptionName:[userException objectForKey:KSCrashField_Name] reason:[error objectForKey:KSCrashField_Reason]]]; - NSString* trace = [self userExceptionTrace:userException]; - if(trace.length > 0) - { + NSString *trace = [self userExceptionTrace:userException]; + if (trace.length > 0) { [str appendFormat:@"\n%@\n", trace]; } - } - else if([type isEqual:KSCrashExcType_CPPException]) - { + } else if ([type isEqual:KSCrashExcType_CPPException]) { [str appendString:[self stringWithUncaughtExceptionName:[cppexception objectForKey:KSCrashField_Name] reason:[error objectForKey:KSCrashField_Reason]]]; } - NSString* crashType = [error objectForKey:KSCrashField_Type]; - if(crashType && [KSCrashExcType_Deadlock isEqualToString:crashType]) - { + NSString *crashType = [error objectForKey:KSCrashField_Type]; + if (crashType && [KSCrashExcType_Deadlock isEqualToString:crashType]) { [str appendFormat:@"\nApplication main thread deadlocked\n"]; } return str; } -- (NSString*) stringWithUncaughtExceptionName:(NSString*) name reason:(NSString*) reason +- (NSString *)stringWithUncaughtExceptionName:(NSString *)name reason:(NSString *)reason { - return [NSString stringWithFormat: - @"\nApplication Specific Information:\n" - @"*** Terminating app due to uncaught exception '%@', reason: '%@'\n", - name, reason]; + return [NSString stringWithFormat:@"\nApplication Specific Information:\n" + @"*** Terminating app due to uncaught exception '%@', reason: '%@'\n", + name, reason]; } -- (NSString*) userExceptionTrace:(NSDictionary*)userException +- (NSString *)userExceptionTrace:(NSDictionary *)userException { - NSMutableString* str = [NSMutableString string]; - NSString* line = [userException objectForKey:KSCrashField_LineOfCode]; - if(line != nil) - { + NSMutableString *str = [NSMutableString string]; + NSString *line = [userException objectForKey:KSCrashField_LineOfCode]; + if (line != nil) { [str appendFormat:@"Line: %@\n", line]; } - NSArray* backtrace = [userException objectForKey:KSCrashField_Backtrace]; - for(NSString* entry in backtrace) - { + NSArray *backtrace = [userException objectForKey:KSCrashField_Backtrace]; + for (NSString *entry in backtrace) { [str appendFormat:@"%@\n", entry]; } - if(str.length > 0) - { + if (str.length > 0) { return [@"Custom Backtrace:\n" stringByAppendingString:str]; } return @""; } -- (NSString*) threadStringForThread:(NSDictionary*) thread - mainExecutableName:(NSString*) mainExecutableName +- (NSString *)threadStringForThread:(NSDictionary *)thread mainExecutableName:(NSString *)mainExecutableName { - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; [str appendFormat:@"\n"]; BOOL crashed = [[thread objectForKey:KSCrashField_Crashed] boolValue]; int index = [[thread objectForKey:KSCrashField_Index] intValue]; - NSString* name = [thread objectForKey:KSCrashField_Name]; - NSString* queueName = [thread objectForKey:KSCrashField_DispatchQueue]; + NSString *name = [thread objectForKey:KSCrashField_Name]; + NSString *queueName = [thread objectForKey:KSCrashField_DispatchQueue]; - if(name != nil) - { + if (name != nil) { [str appendFormat:@"Thread %d name: %@\n", index, name]; - } - else if(queueName != nil) - { + } else if (queueName != nil) { [str appendFormat:@"Thread %d name: Dispatch queue: %@\n", index, queueName]; } - if(crashed) - { + if (crashed) { [str appendFormat:@"Thread %d Crashed:\n", index]; - } - else - { + } else { [str appendFormat:@"Thread %d:\n", index]; } - [str appendString: - [self backtraceString:[thread objectForKey:KSCrashField_Backtrace] - reportStyle:self.reportStyle - mainExecutableName:mainExecutableName]]; + [str appendString:[self backtraceString:[thread objectForKey:KSCrashField_Backtrace] + reportStyle:self.reportStyle + mainExecutableName:mainExecutableName]]; return str; } -- (NSString*) threadListStringForReport:(NSDictionary*) report - mainExecutableName:(NSString*) mainExecutableName +- (NSString *)threadListStringForReport:(NSDictionary *)report mainExecutableName:(NSString *)mainExecutableName { - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; - NSDictionary* crash = [self crashReport:report]; - NSArray* threads = [crash objectForKey:KSCrashField_Threads]; + NSDictionary *crash = [self crashReport:report]; + NSArray *threads = [crash objectForKey:KSCrashField_Threads]; - for(NSDictionary* thread in threads) - { + for (NSDictionary *thread in threads) { [str appendString:[self threadStringForThread:thread mainExecutableName:mainExecutableName]]; } return str; } -- (NSString*) crashReportString:(NSDictionary*) report +- (NSString *)crashReportString:(NSDictionary *)report { - NSMutableString* str = [NSMutableString string]; - NSString* executableName = [self mainExecutableNameForReport:report]; + NSMutableString *str = [NSMutableString string]; + NSString *executableName = [self mainExecutableNameForReport:report]; [str appendString:[self headerStringForReport:report]]; [str appendString:[self errorInfoStringForReport:report]]; @@ -908,37 +788,34 @@ - (NSString*) crashReportString:(NSDictionary*) report return str; } -- (NSString*) recrashReportString:(NSDictionary*) report +- (NSString *)recrashReportString:(NSDictionary *)report { - NSMutableString* str = [NSMutableString string]; - - NSDictionary* recrashReport = [self recrashReport:report]; - NSDictionary* system = [self systemReport:recrashReport]; - NSString* executablePath = [system objectForKey:KSCrashField_ExecutablePath]; - NSString* executableName = [executablePath lastPathComponent]; - NSDictionary* crash = [self crashReport:report]; - NSDictionary* thread = [crash objectForKey:KSCrashField_CrashedThread]; + NSMutableString *str = [NSMutableString string]; + + NSDictionary *recrashReport = [self recrashReport:report]; + NSDictionary *system = [self systemReport:recrashReport]; + NSString *executablePath = [system objectForKey:KSCrashField_ExecutablePath]; + NSString *executableName = [executablePath lastPathComponent]; + NSDictionary *crash = [self crashReport:report]; + NSDictionary *thread = [crash objectForKey:KSCrashField_CrashedThread]; [str appendString:@"\nHandler crashed while reporting:\n"]; [str appendString:[self errorInfoStringForReport:report]]; [str appendString:[self threadStringForThread:thread mainExecutableName:executableName]]; - [str appendString:[self crashedThreadCPUStateStringForReport:report - cpuArch:[self cpuArchForReport:recrashReport]]]; - NSString* diagnosis = [crash objectForKey:KSCrashField_Diagnosis]; - if(diagnosis != nil) - { + [str appendString:[self crashedThreadCPUStateStringForReport:report cpuArch:[self cpuArchForReport:recrashReport]]]; + NSString *diagnosis = [crash objectForKey:KSCrashField_Diagnosis]; + if (diagnosis != nil) { [str appendFormat:@"\nRecrash Diagnosis: %@", diagnosis]; } return str; } - -- (NSString*) toAppleFormat:(NSDictionary*) report +- (NSString *)toAppleFormat:(NSDictionary *)report { - NSMutableString* str = [NSMutableString string]; - - NSDictionary* recrashReport = report[KSCrashField_RecrashReport]; + NSMutableString *str = [NSMutableString string]; + + NSDictionary *recrashReport = report[KSCrashField_RecrashReport]; if (recrashReport) { [str appendString:[self crashReportString:recrashReport]]; [str appendString:[self recrashReportString:report]]; diff --git a/Sources/KSCrashFilters/KSCrashReportFilterBasic.m b/Sources/KSCrashFilters/KSCrashReportFilterBasic.m index d13cdc8e9..138e528e9 100644 --- a/Sources/KSCrashFilters/KSCrashReportFilterBasic.m +++ b/Sources/KSCrashFilters/KSCrashReportFilterBasic.m @@ -24,86 +24,69 @@ // THE SOFTWARE. // - #import "KSCrashReportFilterBasic.h" -#import "NSError+SimpleConstructor.h" #import "Container+DeepSearch.h" -#import "KSVarArgs.h" #import "KSCrashReport.h" +#import "KSVarArgs.h" +#import "NSError+SimpleConstructor.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" - @implementation KSCrashReportFilterPassthrough -+ (instancetype) filter ++ (instancetype)filter { return [[self alloc] init]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { kscrash_callCompletion(onCompletion, reports, YES, nil); } @end - @interface KSCrashReportFilterCombine () -@property(nonatomic,readwrite,retain) NSArray* filters; -@property(nonatomic,readwrite,retain) NSArray* keys; +@property(nonatomic, readwrite, retain) NSArray *filters; +@property(nonatomic, readwrite, retain) NSArray *keys; @end - @implementation KSCrashReportFilterCombine @synthesize filters = _filters; @synthesize keys = _keys; -- (instancetype) initWithFilters:(NSArray*) filters keys:(NSArray*) keys +- (instancetype)initWithFilters:(NSArray *)filters keys:(NSArray *)keys { - if((self = [super init])) - { + if ((self = [super init])) { self.filters = filters; self.keys = keys; } return self; } -+ (KSVA_Block) argBlockWithFilters:(NSMutableArray*) filters andKeys:(NSMutableArray*) keys ++ (KSVA_Block)argBlockWithFilters:(NSMutableArray *)filters andKeys:(NSMutableArray *)keys { __block BOOL isKey = FALSE; - KSVA_Block block = ^(id entry) - { - if(isKey) - { - if(entry == nil) - { + KSVA_Block block = ^(id entry) { + if (isKey) { + if (entry == nil) { KSLOG_ERROR(@"key entry was nil"); - } - else - { + } else { [keys addObject:entry]; } - } - else - { - if([entry isKindOfClass:[NSArray class]]) - { + } else { + if ([entry isKindOfClass:[NSArray class]]) { entry = [KSCrashReportFilterPipeline filterWithFilters:entry, nil]; } - if(![entry conformsToProtocol:@protocol(KSCrashReportFilter)]) - { + if (![entry conformsToProtocol:@protocol(KSCrashReportFilter)]) { KSLOG_ERROR(@"Not a filter: %@", entry); // Cause next key entry to fail as well. return; - } - else - { + } else { [filters addObject:entry]; } } @@ -112,171 +95,145 @@ + (KSVA_Block) argBlockWithFilters:(NSMutableArray*) filters andKeys:(NSMutableA return [block copy]; } -+ (instancetype) filterWithFiltersAndKeys:(id) firstFilter, ... ++ (instancetype)filterWithFiltersAndKeys:(id)firstFilter, ... { - NSMutableArray* filters = [NSMutableArray array]; - NSMutableArray* keys = [NSMutableArray array]; + NSMutableArray *filters = [NSMutableArray array]; + NSMutableArray *keys = [NSMutableArray array]; ksva_iterate_list(firstFilter, [self argBlockWithFilters:filters andKeys:keys]); return [[self class] filterWithFilters:filters keys:keys]; } -+ (instancetype)filterWithFilters:(NSArray*)filters keys:(NSArray*)keys ++ (instancetype)filterWithFilters:(NSArray *)filters keys:(NSArray *)keys { return [[self alloc] initWithFilters:filters keys:keys]; } -- (instancetype) initWithFiltersAndKeys:(id) firstFilter, ... +- (instancetype)initWithFiltersAndKeys:(id)firstFilter, ... { - NSMutableArray* filters = [NSMutableArray array]; - NSMutableArray* keys = [NSMutableArray array]; + NSMutableArray *filters = [NSMutableArray array]; + NSMutableArray *keys = [NSMutableArray array]; ksva_iterate_list(firstFilter, [[self class] argBlockWithFilters:filters andKeys:keys]); return [self initWithFilters:filters keys:keys]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSArray* filters = self.filters; - NSArray* keys = self.keys; + NSArray *filters = self.filters; + NSArray *keys = self.keys; NSUInteger filterCount = [filters count]; - - if(filterCount == 0) - { + + if (filterCount == 0) { kscrash_callCompletion(onCompletion, reports, YES, nil); return; } - - if(filterCount != [keys count]) - { - kscrash_callCompletion(onCompletion, reports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"Key/filter mismatch (%d keys, %d filters", - [keys count], filterCount]); + + if (filterCount != [keys count]) { + kscrash_callCompletion( + onCompletion, reports, NO, + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"Key/filter mismatch (%d keys, %d filters", [keys count], filterCount]); return; } - - NSMutableArray* reportSets = [NSMutableArray arrayWithCapacity:filterCount]; - + + NSMutableArray *reportSets = [NSMutableArray arrayWithCapacity:filterCount]; + __block NSUInteger iFilter = 0; __block KSCrashReportFilterCompletion filterCompletion = nil; __block __weak KSCrashReportFilterCompletion weakFilterCompletion = nil; - dispatch_block_t disposeOfCompletion = [^ - { - // Release self-reference on the main thread. - dispatch_async(dispatch_get_main_queue(), ^ - { - filterCompletion = nil; - }); - } copy]; - filterCompletion = [^(NSArray* filteredReports, - BOOL completed, - NSError* filterError) - { - if(!completed || filteredReports == nil) - { - if(!completed) - { - kscrash_callCompletion(onCompletion, - filteredReports, - completed, - filterError); - } - else if(filteredReports == nil) - { - kscrash_callCompletion(onCompletion, filteredReports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"filteredReports was nil"]); - } - disposeOfCompletion(); - return; - } - - // Normal run until all filters exhausted. - [reportSets addObject:filteredReports]; - if(++iFilter < filterCount) - { - id filter = [filters objectAtIndex:iFilter]; - [filter filterReports:reports onCompletion:weakFilterCompletion]; - return; - } - - // All filters complete, or a filter failed. - // Build final "filteredReports" array. - NSUInteger reportCount = [(NSArray*)[reportSets objectAtIndex:0] count]; - NSMutableArray* combinedReports = [NSMutableArray arrayWithCapacity:reportCount]; - for(NSUInteger iReport = 0; iReport < reportCount; iReport++) - { - NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithCapacity:filterCount]; - for(NSUInteger iSet = 0; iSet < filterCount; iSet++) - { - NSString* key = keys[iSet]; - NSArray* reportSet = reportSets[iSet]; - if(iReport < reportSet.count){ - KSCrashReport* report = reportSet[iReport]; - dict[key] = report.dictionaryValue ?: report.stringValue ?: report.dataValue; - } - } - KSCrashReport* report = [KSCrashReport reportWithDictionary:dict]; - [combinedReports addObject:report]; - } - - kscrash_callCompletion(onCompletion, combinedReports, completed, filterError); - disposeOfCompletion(); - } copy]; + dispatch_block_t disposeOfCompletion = [^{ + // Release self-reference on the main thread. + dispatch_async(dispatch_get_main_queue(), ^{ + filterCompletion = nil; + }); + } copy]; + filterCompletion = [^(NSArray *filteredReports, BOOL completed, NSError *filterError) { + if (!completed || filteredReports == nil) { + if (!completed) { + kscrash_callCompletion(onCompletion, filteredReports, completed, filterError); + } else if (filteredReports == nil) { + kscrash_callCompletion(onCompletion, filteredReports, NO, + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"filteredReports was nil"]); + } + disposeOfCompletion(); + return; + } + + // Normal run until all filters exhausted. + [reportSets addObject:filteredReports]; + if (++iFilter < filterCount) { + id filter = [filters objectAtIndex:iFilter]; + [filter filterReports:reports onCompletion:weakFilterCompletion]; + return; + } + + // All filters complete, or a filter failed. + // Build final "filteredReports" array. + NSUInteger reportCount = [(NSArray *)[reportSets objectAtIndex:0] count]; + NSMutableArray *combinedReports = [NSMutableArray arrayWithCapacity:reportCount]; + for (NSUInteger iReport = 0; iReport < reportCount; iReport++) { + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:filterCount]; + for (NSUInteger iSet = 0; iSet < filterCount; iSet++) { + NSString *key = keys[iSet]; + NSArray *reportSet = reportSets[iSet]; + if (iReport < reportSet.count) { + KSCrashReport *report = reportSet[iReport]; + dict[key] = report.dictionaryValue ?: report.stringValue ?: report.dataValue; + } + } + KSCrashReport *report = [KSCrashReport reportWithDictionary:dict]; + [combinedReports addObject:report]; + } + + kscrash_callCompletion(onCompletion, combinedReports, completed, filterError); + disposeOfCompletion(); + } copy]; weakFilterCompletion = filterCompletion; - + // Initial call with first filter to start everything going. id filter = [filters objectAtIndex:iFilter]; [filter filterReports:reports onCompletion:filterCompletion]; } - @end - @interface KSCrashReportFilterPipeline () -@property(nonatomic,readwrite,copy) NSArray>* filters; +@property(nonatomic, readwrite, copy) NSArray> *filters; @end - @implementation KSCrashReportFilterPipeline @synthesize filters = _filters; -+ (instancetype) filterWithFilters:(id) firstFilter, ... ++ (instancetype)filterWithFilters:(id)firstFilter, ... { ksva_list_to_nsarray(firstFilter, filters); return [[self class] filterWithFiltersArray:filters]; } -+ (instancetype) filterWithFiltersArray:(NSArray*) filters ++ (instancetype)filterWithFiltersArray:(NSArray *)filters { return [[self alloc] initWithFiltersArray:filters]; } -- (instancetype) initWithFilters:(id) firstFilter, ... +- (instancetype)initWithFilters:(id)firstFilter, ... { ksva_list_to_nsarray(firstFilter, filters); return [self initWithFiltersArray:filters]; } -- (instancetype) initWithFiltersArray:(NSArray*) filters +- (instancetype)initWithFiltersArray:(NSArray *)filters { - if((self = [super init])) - { - NSMutableArray* expandedFilters = [NSMutableArray array]; - for(id filter in filters) - { - if([filter isKindOfClass:[NSArray class]]) - { - [expandedFilters addObjectsFromArray:(NSArray*)filter]; - } - else - { + if ((self = [super init])) { + NSMutableArray *expandedFilters = [NSMutableArray array]; + for (id filter in filters) { + if ([filter isKindOfClass:[NSArray class]]) { + [expandedFilters addObjectsFromArray:(NSArray *)filter]; + } else { [expandedFilters addObject:filter]; } } @@ -285,73 +242,58 @@ - (instancetype) initWithFiltersArray:(NSArray*) filters return self; } -- (void) addFilter:(id) filter +- (void)addFilter:(id)filter { - self.filters = [@[filter] arrayByAddingObjectsFromArray:self.filters]; + self.filters = [@[ filter ] arrayByAddingObjectsFromArray:self.filters]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSArray* filters = self.filters; + NSArray *filters = self.filters; NSUInteger filterCount = [filters count]; - - if(filterCount == 0) - { - kscrash_callCompletion(onCompletion, reports, YES, nil); + + if (filterCount == 0) { + kscrash_callCompletion(onCompletion, reports, YES, nil); return; } - + __block NSUInteger iFilter = 0; __block KSCrashReportFilterCompletion filterCompletion; __block __weak KSCrashReportFilterCompletion weakFilterCompletion = nil; - dispatch_block_t disposeOfCompletion = [^ - { - // Release self-reference on the main thread. - dispatch_async(dispatch_get_main_queue(), ^ - { - filterCompletion = nil; - }); - } copy]; - filterCompletion = [^(NSArray* filteredReports, - BOOL completed, - NSError* filterError) - { - if(!completed || filteredReports == nil) - { - if(!completed) - { - kscrash_callCompletion(onCompletion, - filteredReports, - completed, - filterError); - } - else if(filteredReports == nil) - { - kscrash_callCompletion(onCompletion, filteredReports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"filteredReports was nil"]); - } - disposeOfCompletion(); - return; - } - - // Normal run until all filters exhausted or one - // filter fails to complete. - if(++iFilter < filterCount) - { - id filter = [filters objectAtIndex:iFilter]; - [filter filterReports:filteredReports onCompletion:weakFilterCompletion]; - return; - } - - // All filters complete, or a filter failed. - kscrash_callCompletion(onCompletion, filteredReports, completed, filterError); - disposeOfCompletion(); - } copy]; + dispatch_block_t disposeOfCompletion = [^{ + // Release self-reference on the main thread. + dispatch_async(dispatch_get_main_queue(), ^{ + filterCompletion = nil; + }); + } copy]; + filterCompletion = [^(NSArray *filteredReports, BOOL completed, NSError *filterError) { + if (!completed || filteredReports == nil) { + if (!completed) { + kscrash_callCompletion(onCompletion, filteredReports, completed, filterError); + } else if (filteredReports == nil) { + kscrash_callCompletion(onCompletion, filteredReports, NO, + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"filteredReports was nil"]); + } + disposeOfCompletion(); + return; + } + + // Normal run until all filters exhausted or one + // filter fails to complete. + if (++iFilter < filterCount) { + id filter = [filters objectAtIndex:iFilter]; + [filter filterReports:filteredReports onCompletion:weakFilterCompletion]; + return; + } + + // All filters complete, or a filter failed. + kscrash_callCompletion(onCompletion, filteredReports, completed, filterError); + disposeOfCompletion(); + } copy]; weakFilterCompletion = filterCompletion; - + // Initial call with first filter to start everything going. id filter = [filters objectAtIndex:iFilter]; [filter filterReports:reports onCompletion:filterCompletion]; @@ -359,11 +301,10 @@ - (void) filterReports:(NSArray*) reports @end - @interface KSCrashReportFilterConcatenate () -@property(nonatomic, readwrite, retain) NSString* separatorFmt; -@property(nonatomic, readwrite, retain) NSArray* keys; +@property(nonatomic, readwrite, retain) NSString *separatorFmt; +@property(nonatomic, readwrite, retain) NSArray *keys; @end @@ -372,62 +313,51 @@ @implementation KSCrashReportFilterConcatenate @synthesize separatorFmt = _separatorFmt; @synthesize keys = _keys; -+ (instancetype) filterWithSeparatorFmt:(NSString*) separatorFmt keys:(id) firstKey, ... ++ (instancetype)filterWithSeparatorFmt:(NSString *)separatorFmt keys:(id)firstKey, ... { ksva_list_to_nsarray(firstKey, keys); return [[self class] filterWithSeparatorFmt:separatorFmt keysArray:keys]; } -+ (instancetype) filterWithSeparatorFmt:(NSString*) separatorFmt keysArray:(NSArray*) keys ++ (instancetype)filterWithSeparatorFmt:(NSString *)separatorFmt keysArray:(NSArray *)keys { return [[self alloc] initWithSeparatorFmt:separatorFmt keysArray:keys]; } -- (instancetype) initWithSeparatorFmt:(NSString*) separatorFmt keys:(id) firstKey, ... +- (instancetype)initWithSeparatorFmt:(NSString *)separatorFmt keys:(id)firstKey, ... { ksva_list_to_nsarray(firstKey, keys); return [self initWithSeparatorFmt:separatorFmt keysArray:keys]; } -- (instancetype) initWithSeparatorFmt:(NSString*) separatorFmt keysArray:(NSArray*) keys +- (instancetype)initWithSeparatorFmt:(NSString *)separatorFmt keysArray:(NSArray *)keys { - if((self = [super init])) - { - NSMutableArray* realKeys = [NSMutableArray array]; - for(id key in keys) - { - if([key isKindOfClass:[NSArray class]]) - { - [realKeys addObjectsFromArray:(NSArray*)key]; - } - else - { + if ((self = [super init])) { + NSMutableArray *realKeys = [NSMutableArray array]; + for (id key in keys) { + if ([key isKindOfClass:[NSArray class]]) { + [realKeys addObjectsFromArray:(NSArray *)key]; + } else { [realKeys addObject:key]; } } - + self.separatorFmt = separatorFmt; self.keys = realKeys; } return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { BOOL firstEntry = YES; - NSMutableString* concatenated = [NSMutableString string]; - for(NSString* key in self.keys) - { - if(firstEntry) - { + NSMutableString *concatenated = [NSMutableString string]; + for (NSString *key in self.keys) { + if (firstEntry) { firstEntry = NO; - } - else - { + } else { [concatenated appendFormat:self.separatorFmt, key]; } id object = [report.dictionaryValue objectForKeyPath:key]; @@ -440,10 +370,9 @@ - (void) filterReports:(NSArray*) reports @end - @interface KSCrashReportFilterSubset () -@property(nonatomic, readwrite, retain) NSArray* keyPaths; +@property(nonatomic, readwrite, retain) NSArray *keyPaths; @end @@ -451,68 +380,58 @@ @implementation KSCrashReportFilterSubset @synthesize keyPaths = _keyPaths; -+ (instancetype) filterWithKeys:(id) firstKeyPath, ... ++ (instancetype)filterWithKeys:(id)firstKeyPath, ... { ksva_list_to_nsarray(firstKeyPath, keyPaths); return [[self class] filterWithKeysArray:keyPaths]; } -+ (instancetype) filterWithKeysArray:(NSArray*) keyPaths ++ (instancetype)filterWithKeysArray:(NSArray *)keyPaths { return [[self alloc] initWithKeysArray:keyPaths]; } -- (instancetype) initWithKeys:(id) firstKeyPath, ... +- (instancetype)initWithKeys:(id)firstKeyPath, ... { ksva_list_to_nsarray(firstKeyPath, keyPaths); return [self initWithKeysArray:keyPaths]; } -- (instancetype) initWithKeysArray:(NSArray*) keyPaths +- (instancetype)initWithKeysArray:(NSArray *)keyPaths { - if((self = [super init])) - { - NSMutableArray* realKeyPaths = [NSMutableArray array]; - for(id keyPath in keyPaths) - { - if([keyPath isKindOfClass:[NSArray class]]) - { - [realKeyPaths addObjectsFromArray:(NSArray*)keyPath]; - } - else - { + if ((self = [super init])) { + NSMutableArray *realKeyPaths = [NSMutableArray array]; + for (id keyPath in keyPaths) { + if ([keyPath isKindOfClass:[NSArray class]]) { + [realKeyPaths addObjectsFromArray:(NSArray *)keyPath]; + } else { [realKeyPaths addObject:keyPath]; } } - + self.keyPaths = realKeyPaths; } return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { NSDictionary *reportDict = report.dictionaryValue; - if(reportDict == nil) - { + if (reportDict == nil) { KSLOG_ERROR(@"Unexpected non-dictionary report: %@", report); continue; } - NSMutableDictionary* subset = [NSMutableDictionary dictionary]; - for(NSString* keyPath in self.keyPaths) - { + NSMutableDictionary *subset = [NSMutableDictionary dictionary]; + for (NSString *keyPath in self.keyPaths) { id object = [reportDict objectForKeyPath:keyPath]; - if(object == nil) - { + if (object == nil) { kscrash_callCompletion(onCompletion, filteredReports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"Report did not have key path %@", keyPath]); + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"Report did not have key path %@", keyPath]); return; } [subset setObject:object forKey:[keyPath lastPathComponent]]; @@ -525,28 +444,24 @@ - (void) filterReports:(NSArray*) reports @end - @implementation KSCrashReportFilterDataToString -+ (instancetype) filter ++ (instancetype)filter { return [[self alloc] init]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion)onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { - NSData* data = report.dataValue; - if(data == nil) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { + NSData *data = report.dataValue; + if (data == nil) { KSLOG_ERROR(@"Unexpected non-data report: %@", report); continue; } - NSString* converted = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSString *converted = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; [filteredReports addObject:[KSCrashReport reportWithString:converted]]; } @@ -555,38 +470,31 @@ - (void) filterReports:(NSArray*) reports @end - @implementation KSCrashReportFilterStringToData -+ (instancetype) filter ++ (instancetype)filter { return [[self alloc] init]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion)onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { - NSString* string = report.stringValue; - if(string == nil) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { + NSString *string = report.stringValue; + if (string == nil) { KSLOG_ERROR(@"Unexpected non-string report: %@", report); continue; } - NSData* converted = [string dataUsingEncoding:NSUTF8StringEncoding]; - if(converted == nil) - { + NSData *converted = [string dataUsingEncoding:NSUTF8StringEncoding]; + if (converted == nil) { kscrash_callCompletion(onCompletion, filteredReports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"Could not convert report to UTF-8"]); + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"Could not convert report to UTF-8"]); return; - } - else - { + } else { [filteredReports addObject:[KSCrashReport reportWithData:converted]]; } } diff --git a/Sources/KSCrashFilters/KSCrashReportFilterGZip.m b/Sources/KSCrashFilters/KSCrashReportFilterGZip.m index e15246a15..93d28d7b2 100644 --- a/Sources/KSCrashFilters/KSCrashReportFilterGZip.m +++ b/Sources/KSCrashFilters/KSCrashReportFilterGZip.m @@ -24,17 +24,16 @@ // THE SOFTWARE. // - #import "KSCrashReportFilterGZip.h" -#import "NSData+KSGZip.h" #import "KSCrashReport.h" +#import "NSData+KSGZip.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" @interface KSCrashReportFilterGZipCompress () -@property(nonatomic,readwrite,assign) NSInteger compressionLevel; +@property(nonatomic, readwrite, assign) NSInteger compressionLevel; @end @@ -42,43 +41,35 @@ @implementation KSCrashReportFilterGZipCompress @synthesize compressionLevel = _compressionLevel; -+ (instancetype) filterWithCompressionLevel:(NSInteger) compressionLevel ++ (instancetype)filterWithCompressionLevel:(NSInteger)compressionLevel { return [[self alloc] initWithCompressionLevel:compressionLevel]; } -- (instancetype) initWithCompressionLevel:(NSInteger) compressionLevel +- (instancetype)initWithCompressionLevel:(NSInteger)compressionLevel { - if((self = [super init])) - { + if ((self = [super init])) { self.compressionLevel = compressionLevel; } return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { - NSData* data = report.dataValue; - if(data == nil) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { + NSData *data = report.dataValue; + if (data == nil) { KSLOG_ERROR(@"Unexpected non-data report: %@", report); continue; } - NSError* error = nil; - NSData* compressedData = [data gzippedWithCompressionLevel:(int)self.compressionLevel - error:&error]; - if(compressedData == nil) - { + NSError *error = nil; + NSData *compressedData = [data gzippedWithCompressionLevel:(int)self.compressionLevel error:&error]; + if (compressedData == nil) { kscrash_callCompletion(onCompletion, filteredReports, NO, error); return; - } - else - { + } else { [filteredReports addObject:[KSCrashReport reportWithData:compressedData]]; } } @@ -88,36 +79,29 @@ - (void) filterReports:(NSArray*) reports @end - @implementation KSCrashReportFilterGZipDecompress -+ (instancetype) filter ++ (instancetype)filter { return [[self alloc] init]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { - NSData* data = report.dataValue; - if(data == nil) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { + NSData *data = report.dataValue; + if (data == nil) { KSLOG_ERROR(@"Unexpected non-data report: %@", report); continue; } - NSError* error = nil; - NSData* decompressedData = [data gunzippedWithError:&error]; - if(decompressedData == nil) - { + NSError *error = nil; + NSData *decompressedData = [data gunzippedWithError:&error]; + if (decompressedData == nil) { kscrash_callCompletion(onCompletion, filteredReports, NO, error); return; - } - else - { + } else { [filteredReports addObject:[KSCrashReport reportWithData:decompressedData]]; } } diff --git a/Sources/KSCrashFilters/KSCrashReportFilterJSON.m b/Sources/KSCrashFilters/KSCrashReportFilterJSON.m index d6c4c4d13..e0551cc26 100644 --- a/Sources/KSCrashFilters/KSCrashReportFilterJSON.m +++ b/Sources/KSCrashFilters/KSCrashReportFilterJSON.m @@ -24,63 +24,51 @@ // THE SOFTWARE. // - #import "KSCrashReportFilterJSON.h" #import "KSCrashReport.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" - @interface KSCrashReportFilterJSONEncode () -@property(nonatomic,readwrite,assign) KSJSONEncodeOption encodeOptions; +@property(nonatomic, readwrite, assign) KSJSONEncodeOption encodeOptions; @end - @implementation KSCrashReportFilterJSONEncode @synthesize encodeOptions = _encodeOptions; -+ (instancetype) filterWithOptions:(KSJSONEncodeOption) options ++ (instancetype)filterWithOptions:(KSJSONEncodeOption)options { return [[self alloc] initWithOptions:options]; } -- (instancetype) initWithOptions:(KSJSONEncodeOption) options +- (instancetype)initWithOptions:(KSJSONEncodeOption)options { - if((self = [super init])) - { + if ((self = [super init])) { self.encodeOptions = options; } return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { NSDictionary *reportDict = report.dictionaryValue; - if(reportDict == nil) - { + if (reportDict == nil) { KSLOG_ERROR(@"Unexpected non-dictionary report: %@", report); continue; } - NSError* error = nil; - NSData* jsonData = [KSJSONCodec encode:reportDict - options:self.encodeOptions - error:&error]; - if(jsonData == nil) - { + NSError *error = nil; + NSData *jsonData = [KSJSONCodec encode:reportDict options:self.encodeOptions error:&error]; + if (jsonData == nil) { kscrash_callCompletion(onCompletion, filteredReports, NO, error); return; - } - else - { + } else { [filteredReports addObject:[KSCrashReport reportWithData:jsonData]]; } } @@ -90,56 +78,45 @@ - (void) filterReports:(NSArray*) reports @end - @interface KSCrashReportFilterJSONDecode () -@property(nonatomic,readwrite,assign) KSJSONDecodeOption decodeOptions; +@property(nonatomic, readwrite, assign) KSJSONDecodeOption decodeOptions; @end - @implementation KSCrashReportFilterJSONDecode @synthesize decodeOptions = _encodeOptions; -+ (instancetype) filterWithOptions:(KSJSONDecodeOption) options ++ (instancetype)filterWithOptions:(KSJSONDecodeOption)options { return [[self alloc] initWithOptions:options]; } -- (instancetype) initWithOptions:(KSJSONDecodeOption) options +- (instancetype)initWithOptions:(KSJSONDecodeOption)options { - if((self = [super init])) - { + if ((self = [super init])) { self.decodeOptions = options; } return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { NSData *data = report.dataValue; - if(data == nil) - { + if (data == nil) { KSLOG_ERROR(@"Unexpected non-data report: %@", report); continue; } - NSError* error = nil; - NSDictionary* decodedReport = [KSJSONCodec decode:data - options:self.decodeOptions - error:&error]; - if(decodedReport == nil) - { + NSError *error = nil; + NSDictionary *decodedReport = [KSJSONCodec decode:data options:self.decodeOptions error:&error]; + if (decodedReport == nil) { kscrash_callCompletion(onCompletion, filteredReports, NO, error); return; - } - else - { + } else { [filteredReports addObject:[KSCrashReport reportWithDictionary:decodedReport]]; } } diff --git a/Sources/KSCrashFilters/KSCrashReportFilterSets.m b/Sources/KSCrashFilters/KSCrashReportFilterSets.m index 85eceabe7..22070267c 100644 --- a/Sources/KSCrashFilters/KSCrashReportFilterSets.m +++ b/Sources/KSCrashFilters/KSCrashReportFilterSets.m @@ -24,42 +24,34 @@ // THE SOFTWARE. // - #import "KSCrashReportFilterSets.h" +#import "KSCrashReportFields.h" #import "KSCrashReportFilterBasic.h" -#import "KSCrashReportFilterJSON.h" #import "KSCrashReportFilterGZip.h" -#import "KSCrashReportFields.h" +#import "KSCrashReportFilterJSON.h" @implementation KSCrashFilterSets -+ (id) appleFmtWithUserAndSystemData:(KSAppleReportStyle) reportStyle - compressed:(BOOL) compressed ++ (id)appleFmtWithUserAndSystemData:(KSAppleReportStyle)reportStyle compressed:(BOOL)compressed { id appleFilter = [KSCrashReportFilterAppleFmt filterWithReportStyle:reportStyle]; - id userSystemFilter = [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterSubset filterWithKeys: - KSCrashField_System, - KSCrashField_User, - nil], - [KSCrashReportFilterJSONEncode filterWithOptions:KSJSONEncodeOptionPretty | KSJSONEncodeOptionSorted], - [KSCrashReportFilterDataToString filter], - nil]; - - NSString* appleName = @"Apple Report"; - NSString* userSystemName = @"User & System Data"; - - NSMutableArray* filters = [NSMutableArray arrayWithObjects: - [KSCrashReportFilterCombine filterWithFiltersAndKeys: - appleFilter, appleName, - userSystemFilter, userSystemName, - nil], - [KSCrashReportFilterConcatenate filterWithSeparatorFmt:@"\n\n-------- %@ --------\n\n" keys: - appleName, userSystemName, nil], - nil]; - - if(compressed) - { + id userSystemFilter = [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterSubset filterWithKeys:KSCrashField_System, KSCrashField_User, nil], + [KSCrashReportFilterJSONEncode + filterWithOptions:KSJSONEncodeOptionPretty | KSJSONEncodeOptionSorted], + [KSCrashReportFilterDataToString filter], nil]; + + NSString *appleName = @"Apple Report"; + NSString *userSystemName = @"User & System Data"; + + NSMutableArray *filters = [NSMutableArray + arrayWithObjects:[KSCrashReportFilterCombine + filterWithFiltersAndKeys:appleFilter, appleName, userSystemFilter, userSystemName, nil], + [KSCrashReportFilterConcatenate filterWithSeparatorFmt:@"\n\n-------- %@ --------\n\n" + keys:appleName, userSystemName, nil], + nil]; + + if (compressed) { [filters addObject:[KSCrashReportFilterStringToData filter]]; [filters addObject:[KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1]]; } diff --git a/Sources/KSCrashFilters/KSCrashReportFilterStringify.m b/Sources/KSCrashFilters/KSCrashReportFilterStringify.m index 6267bb782..28f13d648 100644 --- a/Sources/KSCrashFilters/KSCrashReportFilterStringify.m +++ b/Sources/KSCrashFilters/KSCrashReportFilterStringify.m @@ -26,31 +26,27 @@ #import "KSCrashReportFilterStringify.h" #import "KSCrashReport.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" @implementation KSCrashReportFilterStringify -+ (instancetype) filter ++ (instancetype)filter { return [[self alloc] init]; } -- (NSString*) stringifyReport:(KSCrashReport*) report +- (NSString *)stringifyReport:(KSCrashReport *)report { - if(report.stringValue != nil) - { + if (report.stringValue != nil) { return report.stringValue; } - if(report.dataValue != nil) - { + if (report.dataValue != nil) { return [[NSString alloc] initWithData:report.dataValue encoding:NSUTF8StringEncoding]; } - if(report.dictionaryValue != nil) - { - if([NSJSONSerialization isValidJSONObject:report.dictionaryValue]) - { - NSData* data = [NSJSONSerialization dataWithJSONObject:report.dictionaryValue options:0 error:nil]; + if (report.dictionaryValue != nil) { + if ([NSJSONSerialization isValidJSONObject:report.dictionaryValue]) { + NSData *data = [NSJSONSerialization dataWithJSONObject:report.dictionaryValue options:0 error:nil]; return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } return [NSString stringWithFormat:@"%@", report.dictionaryValue]; @@ -58,16 +54,14 @@ - (NSString*) stringifyReport:(KSCrashReport*) report return [NSString stringWithFormat:@"%@", report]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSMutableArray* filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; - for(KSCrashReport* report in reports) - { + NSMutableArray *filteredReports = [NSMutableArray arrayWithCapacity:[reports count]]; + for (KSCrashReport *report in reports) { NSString *reportString = [self stringifyReport:report]; [filteredReports addObject:[KSCrashReport reportWithString:reportString]]; } - + kscrash_callCompletion(onCompletion, filteredReports, YES, nil); } diff --git a/Sources/KSCrashFilters/include/KSCrashReportFilterAlert.h b/Sources/KSCrashFilters/include/KSCrashReportFilterAlert.h index 0439bf4d8..61d45ac9b 100644 --- a/Sources/KSCrashFilters/include/KSCrashReportFilterAlert.h +++ b/Sources/KSCrashFilters/include/KSCrashReportFilterAlert.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import #import "KSCrashReportFilter.h" @@ -50,10 +49,10 @@ NS_SWIFT_NAME(CrashReportFilterAlert) * @param noAnswer The text to put in the "no" button. If nil, the filter will * proceed unconditionally. */ -+ (instancetype) filterWithTitle:(NSString*) title - message:(nullable NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(nullable NSString*) noAnswer; ++ (instancetype)filterWithTitle:(NSString *)title + message:(nullable NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(nullable NSString *)noAnswer; /** * @param title The title of the alert. @@ -62,10 +61,10 @@ NS_SWIFT_NAME(CrashReportFilterAlert) * @param noAnswer The text to put in the "no" button. If nil, the filter will * proceed unconditionally. */ -- (instancetype) initWithTitle:(NSString*) title - message:(nullable NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(nullable NSString*) noAnswer; +- (instancetype)initWithTitle:(NSString *)title + message:(nullable NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(nullable NSString *)noAnswer; @end diff --git a/Sources/KSCrashFilters/include/KSCrashReportFilterAppleFmt.h b/Sources/KSCrashFilters/include/KSCrashReportFilterAppleFmt.h index b0e5f247f..7e24518e2 100644 --- a/Sources/KSCrashFilters/include/KSCrashReportFilterAppleFmt.h +++ b/Sources/KSCrashFilters/include/KSCrashReportFilterAppleFmt.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashReportFilter.h" #import @@ -82,8 +81,7 @@ NS_ASSUME_NONNULL_BEGIN * If you DO care about line numbers, have the dsym file handy, and will be * symbolicating offline, use KSAppleReportStyleSymbolicatedSideBySide. */ -typedef NS_ENUM(NSInteger, KSAppleReportStyle) -{ +typedef NS_ENUM(NSInteger, KSAppleReportStyle) { /** Leave all stack trace entries unsymbolicated. */ KSAppleReportStyleUnsymbolicated, @@ -101,7 +99,6 @@ typedef NS_ENUM(NSInteger, KSAppleReportStyle) KSAppleReportStyleSymbolicated } NS_SWIFT_NAME(AppleReportStyle); - /** Converts to Apple format. * * Input: NSDictionary @@ -110,13 +107,13 @@ typedef NS_ENUM(NSInteger, KSAppleReportStyle) NS_SWIFT_NAME(CrashReportFilterAppleFmt) @interface KSCrashReportFilterAppleFmt : NSObject -+ (instancetype) filterWithReportStyle:(KSAppleReportStyle) reportStyle; ++ (instancetype)filterWithReportStyle:(KSAppleReportStyle)reportStyle; -- (instancetype) initWithReportStyle:(KSAppleReportStyle) reportStyle; +- (instancetype)initWithReportStyle:(KSAppleReportStyle)reportStyle; -- (NSString*)headerStringForSystemInfo:(NSDictionary*)system - reportID:(nullable NSString*)reportID - crashTime:(nullable NSDate*)crashTime; +- (NSString *)headerStringForSystemInfo:(NSDictionary *)system + reportID:(nullable NSString *)reportID + crashTime:(nullable NSDate *)crashTime; @end diff --git a/Sources/KSCrashFilters/include/KSCrashReportFilterBasic.h b/Sources/KSCrashFilters/include/KSCrashReportFilterBasic.h index d7f01ca54..bd265358c 100644 --- a/Sources/KSCrashFilters/include/KSCrashReportFilterBasic.h +++ b/Sources/KSCrashFilters/include/KSCrashReportFilterBasic.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashReportFilter.h" #import @@ -40,11 +39,10 @@ NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(CrashReportFilterPassthrough) @interface KSCrashReportFilterPassthrough : NSObject -+ (instancetype) filter; ++ (instancetype)filter; @end - /** * Passes reports to a series of subfilters, then stores the results of those operations * as keyed values in final master reports. @@ -61,7 +59,7 @@ NS_SWIFT_NAME(CrashReportFilterCombine) * Each "filter" can be id or an NSArray * of filters (which gets wrapped in a pipeline filter). */ -+ (instancetype) filterWithFiltersAndKeys:(nullable id) firstFilter, ... NS_REQUIRES_NIL_TERMINATION; ++ (instancetype)filterWithFiltersAndKeys:(nullable id)firstFilter, ... NS_REQUIRES_NIL_TERMINATION; /** Constructor. * @@ -72,7 +70,7 @@ NS_SWIFT_NAME(CrashReportFilterCombine) * used to store the output of its respective filter in the final * report dictionary. */ -+ (instancetype) filterWithFilters:(NSArray*) filters keys:(NSArray*) keys; ++ (instancetype)filterWithFilters:(NSArray *)filters keys:(NSArray *)keys; /** Initializer. * @@ -80,7 +78,7 @@ NS_SWIFT_NAME(CrashReportFilterCombine) * Each "filter" can be id or an NSArray * of filters (which gets wrapped in a pipeline filter). */ -- (instancetype) initWithFiltersAndKeys:(nullable id)firstFilter, ... NS_REQUIRES_NIL_TERMINATION; +- (instancetype)initWithFiltersAndKeys:(nullable id)firstFilter, ... NS_REQUIRES_NIL_TERMINATION; /** Initializer. * @@ -91,11 +89,10 @@ NS_SWIFT_NAME(CrashReportFilterCombine) * used to store the output of its respective filter in the final * report dictionary. */ -- (instancetype) initWithFilters:(NSArray*) filters keys:(NSArray*) keys; +- (instancetype)initWithFilters:(NSArray *)filters keys:(NSArray *)keys; @end - /** * A pipeline of filters. Reports get passed through each subfilter in order. * @@ -106,7 +103,7 @@ NS_SWIFT_NAME(CrashReportFilterPipeline) @interface KSCrashReportFilterPipeline : NSObject /** The filters in this pipeline. */ -@property(nonatomic,readonly,copy) NSArray>* filters; +@property(nonatomic, readonly, copy) NSArray> *filters; /** Constructor. * @@ -114,7 +111,7 @@ NS_SWIFT_NAME(CrashReportFilterPipeline) * Each "filter" can be an id or an NSArray * containing filters or locations of filters (which get wrapped in a pipeline filter). */ -+ (instancetype) filterWithFilters:(nullable id) firstFilter, ... NS_REQUIRES_NIL_TERMINATION; ++ (instancetype)filterWithFilters:(nullable id)firstFilter, ... NS_REQUIRES_NIL_TERMINATION; /** Constructor using an array of filters. * @@ -122,7 +119,7 @@ NS_SWIFT_NAME(CrashReportFilterPipeline) * the KSCrashReportFilter protocol or a location of filters. * Arrays of filters will be wrapped in a pipeline filter. */ -+ (instancetype) filterWithFiltersArray:(NSArray*) filters; ++ (instancetype)filterWithFiltersArray:(NSArray *)filters; /** Initializer. * @@ -130,7 +127,7 @@ NS_SWIFT_NAME(CrashReportFilterPipeline) * Each "filter" can be an id or an NSArray * containing filters or locations of filters (which get wrapped in a pipeline filter). */ -- (instancetype) initWithFilters:(nullable id) firstFilter, ... NS_REQUIRES_NIL_TERMINATION; +- (instancetype)initWithFilters:(nullable id)firstFilter, ... NS_REQUIRES_NIL_TERMINATION; /** Initializer using an array of filters. * @@ -138,7 +135,7 @@ NS_SWIFT_NAME(CrashReportFilterPipeline) * the KSCrashReportFilter protocol or a location of filters. * Arrays of filters will be wrapped in a pipeline filter. */ -- (instancetype) initWithFiltersArray:(NSArray*) filters; +- (instancetype)initWithFiltersArray:(NSArray *)filters; /** Adds a filter to the beginning of the pipeline. * @@ -146,11 +143,10 @@ NS_SWIFT_NAME(CrashReportFilterPipeline) * KSCrashReportFilter protocol. It will be inserted at the * beginning of the existing filters in the pipeline. */ -- (void) addFilter:(id) filter; +- (void)addFilter:(id)filter; @end - /** * Takes values by key from the report and concatenates their string representations. * @@ -166,8 +162,7 @@ NS_SWIFT_NAME(CrashReportFilterConcatenate) * %@ in the formatting text to include the key name as well. * @param firstKey Series of keys to extract from the source report. */ -+ (instancetype) filterWithSeparatorFmt:(NSString*) separatorFmt - keys:(id) firstKey, ... NS_REQUIRES_NIL_TERMINATION; ++ (instancetype)filterWithSeparatorFmt:(NSString *)separatorFmt keys:(id)firstKey, ... NS_REQUIRES_NIL_TERMINATION; /** Constructor using an array of keys. * @@ -176,8 +171,7 @@ NS_SWIFT_NAME(CrashReportFilterConcatenate) * @param keys An array of keys whose corresponding values will be concatenated * from the source report. */ -+ (instancetype) filterWithSeparatorFmt:(NSString*) separatorFmt - keysArray:(NSArray*) keys; ++ (instancetype)filterWithSeparatorFmt:(NSString *)separatorFmt keysArray:(NSArray *)keys; /** Initializer. * @@ -185,8 +179,7 @@ NS_SWIFT_NAME(CrashReportFilterConcatenate) * %@ in the formatting text to include the key name as well. * @param firstKey Series of keys to extract from the source report. */ -- (instancetype) initWithSeparatorFmt:(NSString*) separatorFmt - keys:(id) firstKey, ... NS_REQUIRES_NIL_TERMINATION; +- (instancetype)initWithSeparatorFmt:(NSString *)separatorFmt keys:(id)firstKey, ... NS_REQUIRES_NIL_TERMINATION; /** Initializer using an array of keys. * @@ -195,12 +188,10 @@ NS_SWIFT_NAME(CrashReportFilterConcatenate) * @param keys An array of keys whose corresponding values will be concatenated * from the source report. */ -- (instancetype) initWithSeparatorFmt:(NSString*) separatorFmt - keysArray:(NSArray*) keys; +- (instancetype)initWithSeparatorFmt:(NSString *)separatorFmt keysArray:(NSArray *)keys; @end - /** * Fetches subsets of data from the source reports. All other data is discarded. * @@ -214,31 +205,30 @@ NS_SWIFT_NAME(CrashReportFilterSubset) * * @param firstKeyPath Series of key paths to search in the source reports. */ -+ (instancetype) filterWithKeys:(id) firstKeyPath, ... NS_REQUIRES_NIL_TERMINATION; ++ (instancetype)filterWithKeys:(id)firstKeyPath, ... NS_REQUIRES_NIL_TERMINATION; /** Constructor using an array of key paths. * * @param keyPaths An array of key paths to search for in the source reports. * Each key path will extract a subset of data from the reports. */ -+ (instancetype) filterWithKeysArray:(NSArray*) keyPaths; ++ (instancetype)filterWithKeysArray:(NSArray *)keyPaths; /** Initializer. * * @param firstKeyPath Series of key paths to search in the source reports. */ -- (instancetype) initWithKeys:(id) firstKeyPath, ... NS_REQUIRES_NIL_TERMINATION; +- (instancetype)initWithKeys:(id)firstKeyPath, ... NS_REQUIRES_NIL_TERMINATION; /** Initializer using an array of key paths. * * @param keyPaths An array of key paths to search for in the source reports. * Each key path will extract a subset of data from the reports. */ -- (instancetype) initWithKeysArray:(NSArray*) keyPaths; +- (instancetype)initWithKeysArray:(NSArray *)keyPaths; @end - /** * Convert UTF-8 data to an NSString. * @@ -248,11 +238,10 @@ NS_SWIFT_NAME(CrashReportFilterSubset) NS_SWIFT_NAME(CrashReportFilterDataToString) @interface KSCrashReportFilterDataToString : NSObject -+ (instancetype) filter; ++ (instancetype)filter; @end - /** * Convert NSString to UTF-8 encoded NSData. * @@ -262,7 +251,7 @@ NS_SWIFT_NAME(CrashReportFilterDataToString) NS_SWIFT_NAME(CrashReportFilterStringToData) @interface KSCrashReportFilterStringToData : NSObject -+ (instancetype) filter; ++ (instancetype)filter; @end diff --git a/Sources/KSCrashFilters/include/KSCrashReportFilterGZip.h b/Sources/KSCrashFilters/include/KSCrashReportFilterGZip.h index f6c4ea1ae..efb48d965 100644 --- a/Sources/KSCrashFilters/include/KSCrashReportFilterGZip.h +++ b/Sources/KSCrashFilters/include/KSCrashReportFilterGZip.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashReportFilter.h" #import @@ -67,7 +66,7 @@ NS_SWIFT_NAME(CrashReportFilterGZipCompress) * - `KSCrashReportCompressionLevelDefault` (-1): Default compression level. * The compression level can be any integer value between 0 and 9. */ -+ (instancetype) filterWithCompressionLevel:(KSCrashReportCompressionLevel) compressionLevel; ++ (instancetype)filterWithCompressionLevel:(KSCrashReportCompressionLevel)compressionLevel; /** Initializer. * @@ -78,7 +77,7 @@ NS_SWIFT_NAME(CrashReportFilterGZipCompress) * - `KSCrashReportCompressionLevelDefault` (-1): Default compression level. * The compression level can be any integer value between 0 and 9. */ -- (instancetype) initWithCompressionLevel:(KSCrashReportCompressionLevel) compressionLevel; +- (instancetype)initWithCompressionLevel:(KSCrashReportCompressionLevel)compressionLevel; @end @@ -94,7 +93,7 @@ NS_SWIFT_NAME(CrashReportFilterGZipDecompress) * * Creates an instance of the filter for Gzip decompression. */ -+ (instancetype) filter; ++ (instancetype)filter; @end diff --git a/Sources/KSCrashFilters/include/KSCrashReportFilterJSON.h b/Sources/KSCrashFilters/include/KSCrashReportFilterJSON.h index 813f5f716..155b4a5f4 100644 --- a/Sources/KSCrashFilters/include/KSCrashReportFilterJSON.h +++ b/Sources/KSCrashFilters/include/KSCrashReportFilterJSON.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashReportFilter.h" #import "KSJSONCodecObjC.h" @@ -40,13 +39,12 @@ NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(CrashReportFilterJSONEncode) @interface KSCrashReportFilterJSONEncode : NSObject -+ (instancetype) filterWithOptions:(KSJSONEncodeOption) options; ++ (instancetype)filterWithOptions:(KSJSONEncodeOption)options; -- (instancetype) initWithOptions:(KSJSONEncodeOption) options; +- (instancetype)initWithOptions:(KSJSONEncodeOption)options; @end - /** Converts reports from JSON to dict. * * Input: NSData @@ -55,9 +53,9 @@ NS_SWIFT_NAME(CrashReportFilterJSONEncode) NS_SWIFT_NAME(CrashReportFilterJSONDecode) @interface KSCrashReportFilterJSONDecode : NSObject -+ (instancetype) filterWithOptions:(KSJSONDecodeOption) options; ++ (instancetype)filterWithOptions:(KSJSONDecodeOption)options; -- (instancetype) initWithOptions:(KSJSONDecodeOption) options; +- (instancetype)initWithOptions:(KSJSONDecodeOption)options; @end diff --git a/Sources/KSCrashFilters/include/KSCrashReportFilterSets.h b/Sources/KSCrashFilters/include/KSCrashReportFilterSets.h index cbdfb8480..40bf64bb4 100644 --- a/Sources/KSCrashFilters/include/KSCrashReportFilterSets.h +++ b/Sources/KSCrashFilters/include/KSCrashReportFilterSets.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashReportFilter.h" #import "KSCrashReportFilterAppleFmt.h" @@ -40,8 +39,7 @@ NS_SWIFT_NAME(CrashFilterSets) /** Create an Apple format filter that includes system and user data in JSON format. */ -+ (id) appleFmtWithUserAndSystemData:(KSAppleReportStyle) reportStyle - compressed:(BOOL) compressed; ++ (id)appleFmtWithUserAndSystemData:(KSAppleReportStyle)reportStyle compressed:(BOOL)compressed; @end diff --git a/Sources/KSCrashFilters/include/KSCrashReportFilterStringify.h b/Sources/KSCrashFilters/include/KSCrashReportFilterStringify.h index 48007eca4..7e05c1742 100644 --- a/Sources/KSCrashFilters/include/KSCrashReportFilterStringify.h +++ b/Sources/KSCrashFilters/include/KSCrashReportFilterStringify.h @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(CrashReportFilterStringify) @interface KSCrashReportFilterStringify : NSObject -+ (instancetype) filter; ++ (instancetype)filter; @end diff --git a/Sources/KSCrashInstallations/KSCrashInstallation+Alert.m b/Sources/KSCrashInstallations/KSCrashInstallation+Alert.m index d8d277567..e5d7f233a 100644 --- a/Sources/KSCrashInstallations/KSCrashInstallation+Alert.m +++ b/Sources/KSCrashInstallations/KSCrashInstallation+Alert.m @@ -22,34 +22,34 @@ // THE SOFTWARE. // -#import "KSCrashInstallation+Alert.h" #import "KSCrash.h" +#import "KSCrashInstallation+Alert.h" #import "KSCrashReportFilterAlert.h" @implementation KSCrashInstallation (Alert) -- (void) addConditionalAlertWithTitle:(NSString*) title - message:(NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(NSString*) noAnswer +- (void)addConditionalAlertWithTitle:(NSString *)title + message:(NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(NSString *)noAnswer { [self addPreFilter:[KSCrashReportFilterAlert filterWithTitle:title message:message yesAnswer:yesAnswer noAnswer:noAnswer]]; -// FIXME: Accessing config -// KSCrash* handler = [KSCrash sharedInstance]; -// if(handler.deleteBehaviorAfterSendAll == KSCDeleteOnSucess) -// { -// // Better to delete always, or else the user will keep getting nagged -// // until he presses "yes"! -// handler.deleteBehaviorAfterSendAll = KSCDeleteAlways; -// } + // FIXME: Accessing config + // KSCrash* handler = [KSCrash sharedInstance]; + // if(handler.deleteBehaviorAfterSendAll == KSCDeleteOnSucess) + // { + // // Better to delete always, or else the user will keep getting nagged + // // until he presses "yes"! + // handler.deleteBehaviorAfterSendAll = KSCDeleteAlways; + // } } -- (void) addUnconditionalAlertWithTitle:(NSString*) title - message:(NSString*) message - dismissButtonText:(NSString*) dismissButtonText +- (void)addUnconditionalAlertWithTitle:(NSString *)title + message:(NSString *)message + dismissButtonText:(NSString *)dismissButtonText { [self addPreFilter:[KSCrashReportFilterAlert filterWithTitle:title message:message diff --git a/Sources/KSCrashInstallations/KSCrashInstallation+Private.h b/Sources/KSCrashInstallations/KSCrashInstallation+Private.h index 5a6429276..428264d6c 100644 --- a/Sources/KSCrashInstallations/KSCrashInstallation+Private.h +++ b/Sources/KSCrashInstallations/KSCrashInstallation+Private.h @@ -24,35 +24,32 @@ // THE SOFTWARE. // - #import "KSCrashInstallation.h" - /** Implement a property to be used as a "key". */ -#define IMPLEMENT_REPORT_KEY_PROPERTY(NAME, NAMEUPPER) \ -@synthesize NAME##Key = _##NAME##Key; \ -- (void) set##NAMEUPPER##Key:(NSString*) value \ -{ \ - _##NAME##Key; \ - _##NAME##Key = value; \ - [self reportFieldForProperty:@#NAME setKey:value]; \ -} +#define IMPLEMENT_REPORT_KEY_PROPERTY(NAME, NAMEUPPER) \ + @synthesize NAME##Key = _##NAME##Key; \ + -(void)set##NAMEUPPER##Key : (NSString *)value \ + { \ + _##NAME##Key; \ + _##NAME##Key = value; \ + [self reportFieldForProperty:@ #NAME setKey:value]; \ + } /** Implement a property to be used as a "value". */ #define IMPLEMENT_REPORT_VALUE_PROPERTY(NAME, NAMEUPPER, TYPE) \ -@synthesize NAME = _##NAME; \ -- (void) set##NAMEUPPER:(TYPE) value \ -{ \ - _##NAME; \ - _##NAME = value; \ - [self reportFieldForProperty:@#NAME setValue:value]; \ -} + @synthesize NAME = _##NAME; \ + -(void)set##NAMEUPPER : (TYPE)value \ + { \ + _##NAME; \ + _##NAME = value; \ + [self reportFieldForProperty:@ #NAME setValue:value]; \ + } /** Implement a standard report property (with key and value properties) */ -#define IMPLEMENT_REPORT_PROPERTY(NAME, NAMEUPPER, TYPE) \ -IMPLEMENT_REPORT_VALUE_PROPERTY(NAME, NAMEUPPER, TYPE) \ -IMPLEMENT_REPORT_KEY_PROPERTY(NAME, NAMEUPPER) - +#define IMPLEMENT_REPORT_PROPERTY(NAME, NAMEUPPER, TYPE) \ + IMPLEMENT_REPORT_VALUE_PROPERTY(NAME, NAMEUPPER, TYPE) \ + IMPLEMENT_REPORT_KEY_PROPERTY(NAME, NAMEUPPER) @interface KSCrashInstallation () @@ -60,30 +57,30 @@ IMPLEMENT_REPORT_KEY_PROPERTY(NAME, NAMEUPPER) * * @param requiredProperties Properties that MUST be set when sending reports. */ -- (id) initWithRequiredProperties:(NSArray*) requiredProperties; +- (id)initWithRequiredProperties:(NSArray *)requiredProperties; /** Set the key to be used for the specified report property. * * @param propertyName The name of the property. * @param key The key to use. */ -- (void) reportFieldForProperty:(NSString*) propertyName setKey:(id) key; +- (void)reportFieldForProperty:(NSString *)propertyName setKey:(id)key; /** Set the value of the specified report property. * * @param propertyName The name of the property. * @param value The value to set. */ -- (void) reportFieldForProperty:(NSString*) propertyName setValue:(id) value; +- (void)reportFieldForProperty:(NSString *)propertyName setValue:(id)value; /** Create a new sink. Subclasses must implement this. */ -- (id) sink; +- (id)sink; /** Make an absolute key path if the specified path is not already absolute. */ -- (NSString*) makeKeyPath:(NSString*) keyPath; +- (NSString *)makeKeyPath:(NSString *)keyPath; /** Make an absolute key paths from the specified paths. */ -- (NSArray*) makeKeyPaths:(NSArray*) keyPaths; +- (NSArray *)makeKeyPaths:(NSArray *)keyPaths; @end diff --git a/Sources/KSCrashInstallations/KSCrashInstallation.m b/Sources/KSCrashInstallations/KSCrashInstallation.m index dc313df11..cc6045c16 100644 --- a/Sources/KSCrashInstallations/KSCrashInstallation.m +++ b/Sources/KSCrashInstallations/KSCrashInstallation.m @@ -24,50 +24,44 @@ // THE SOFTWARE. // - #import "KSCrashInstallation.h" -#import "KSCrashInstallation+Private.h" +#import +#import "KSCString.h" +#import "KSCrash.h" #import "KSCrashConfiguration.h" +#import "KSCrashInstallation+Private.h" #import "KSCrashReportFilterBasic.h" -#import "KSCrash.h" -#import "KSCString.h" #import "KSJSONCodecObjC.h" #import "KSLogger.h" #import "NSError+SimpleConstructor.h" -#import - /** Max number of properties that can be defined for writing to the report */ #define kMaxProperties 500 - -typedef struct -{ - const char* key; - const char* value; +typedef struct { + const char *key; + const char *value; } ReportField; -typedef struct -{ +typedef struct { KSReportWriteCallback userCrashCallback; int reportFieldsCount; - ReportField* reportFields[0]; + ReportField *reportFields[0]; } CrashHandlerData; +static CrashHandlerData *g_crashHandlerData; -static CrashHandlerData* g_crashHandlerData; +@interface KSCrashInstReportField : NSObject -@interface KSCrashInstReportField: NSObject +@property(nonatomic, readonly, assign) int index; +@property(nonatomic, readonly, assign) ReportField *field; -@property(nonatomic,readonly,assign) int index; -@property(nonatomic,readonly,assign) ReportField* field; +@property(nonatomic, readwrite, retain) NSString *key; +@property(nonatomic, readwrite, retain) id value; -@property(nonatomic,readwrite,retain) NSString* key; -@property(nonatomic,readwrite,retain) id value; - -@property(nonatomic,readwrite,retain) NSMutableData* fieldBacking; -@property(nonatomic,readwrite,retain) KSCString* keyBacking; -@property(nonatomic,readwrite,retain) KSCString* valueBacking; +@property(nonatomic, readwrite, retain) NSMutableData *fieldBacking; +@property(nonatomic, readwrite, retain) KSCString *keyBacking; +@property(nonatomic, readwrite, retain) KSCString *valueBacking; @end @@ -78,59 +72,53 @@ @implementation KSCrashInstReportField @synthesize value = _value; @synthesize fieldBacking = _fieldBacking; @synthesize keyBacking = _keyBacking; -@synthesize valueBacking= _valueBacking; +@synthesize valueBacking = _valueBacking; -+ (KSCrashInstReportField*) fieldWithIndex:(int) index ++ (KSCrashInstReportField *)fieldWithIndex:(int)index { - return [(KSCrashInstReportField*)[self alloc] initWithIndex:index]; + return [(KSCrashInstReportField *)[self alloc] initWithIndex:index]; } -- (id) initWithIndex:(int) index +- (id)initWithIndex:(int)index { - if((self = [super init])) - { + if ((self = [super init])) { _index = index; self.fieldBacking = [NSMutableData dataWithLength:sizeof(*self.field)]; } return self; } -- (ReportField*) field +- (ReportField *)field { - return (ReportField*)self.fieldBacking.mutableBytes; + return (ReportField *)self.fieldBacking.mutableBytes; } -- (void) setKey:(NSString*) key +- (void)setKey:(NSString *)key { _key = key; - if(key == nil) - { + if (key == nil) { self.keyBacking = nil; - } - else - { + } else { self.keyBacking = [KSCString stringWithString:key]; } self.field->key = self.keyBacking.bytes; } -- (void) setValue:(id) value +- (void)setValue:(id)value { - if(value == nil) - { + if (value == nil) { _value = nil; self.valueBacking = nil; return; } - - NSError* error = nil; - NSData* jsonData = [KSJSONCodec encode:value options:KSJSONEncodeOptionPretty | KSJSONEncodeOptionSorted error:&error]; - if(jsonData == nil) - { + + NSError *error = nil; + NSData *jsonData = [KSJSONCodec encode:value + options:KSJSONEncodeOptionPretty | KSJSONEncodeOptionSorted + error:&error]; + if (jsonData == nil) { KSLOG_ERROR(@"Could not set value %@ for property %@: %@", value, self.key, error); - } - else - { + } else { _value = value; self.valueBacking = [KSCString stringWithData:jsonData]; self.field->value = self.valueBacking.bytes; @@ -141,16 +129,15 @@ - (void) setValue:(id) value @interface KSCrashInstallation () -@property(nonatomic,readwrite,assign) int nextFieldIndex; -@property(nonatomic,readonly,assign) CrashHandlerData* crashHandlerData; -@property(nonatomic,readwrite,retain) NSMutableData* crashHandlerDataBacking; -@property(nonatomic,readwrite,retain) NSMutableDictionary* fields; -@property(nonatomic,readwrite,retain) NSArray* requiredProperties; -@property(nonatomic,readwrite,retain) KSCrashReportFilterPipeline* prependedFilters; +@property(nonatomic, readwrite, assign) int nextFieldIndex; +@property(nonatomic, readonly, assign) CrashHandlerData *crashHandlerData; +@property(nonatomic, readwrite, retain) NSMutableData *crashHandlerDataBacking; +@property(nonatomic, readwrite, retain) NSMutableDictionary *fields; +@property(nonatomic, readwrite, retain) NSArray *requiredProperties; +@property(nonatomic, readwrite, retain) KSCrashReportFilterPipeline *prependedFilters; @end - @implementation KSCrashInstallation @synthesize nextFieldIndex = _nextFieldIndex; @@ -159,19 +146,19 @@ @implementation KSCrashInstallation @synthesize requiredProperties = _requiredProperties; @synthesize prependedFilters = _prependedFilters; -- (id) init +- (id)init { [NSException raise:NSInternalInconsistencyException format:@"%@ does not support init. Subclasses must call initWithRequiredProperties:", [self class]]; return nil; } -- (id) initWithRequiredProperties:(NSArray*) requiredProperties +- (id)initWithRequiredProperties:(NSArray *)requiredProperties { - if((self = [super init])) - { - self.crashHandlerDataBacking = [NSMutableData dataWithLength:sizeof(*self.crashHandlerData) + - sizeof(*self.crashHandlerData->reportFields) * kMaxProperties]; + if ((self = [super init])) { + self.crashHandlerDataBacking = + [NSMutableData dataWithLength:sizeof(*self.crashHandlerData) + + sizeof(*self.crashHandlerData->reportFields) * kMaxProperties]; self.fields = [NSMutableDictionary dictionary]; self.requiredProperties = requiredProperties; self.prependedFilters = [KSCrashReportFilterPipeline filterWithFilters:nil]; @@ -179,30 +166,27 @@ - (id) initWithRequiredProperties:(NSArray*) requiredProperties return self; } -- (void) dealloc +- (void)dealloc { - KSCrash* handler = [KSCrash sharedInstance]; - @synchronized(handler) - { - if(g_crashHandlerData == self.crashHandlerData) - { + KSCrash *handler = [KSCrash sharedInstance]; + @synchronized(handler) { + if (g_crashHandlerData == self.crashHandlerData) { g_crashHandlerData = NULL; -// FIXME: Mutating the inner state -// handler.onCrash = NULL; + // FIXME: Mutating the inner state + // handler.onCrash = NULL; } } } -- (CrashHandlerData*) crashHandlerData +- (CrashHandlerData *)crashHandlerData { - return (CrashHandlerData*)self.crashHandlerDataBacking.mutableBytes; + return (CrashHandlerData *)self.crashHandlerDataBacking.mutableBytes; } -- (KSCrashInstReportField*) reportFieldForProperty:(NSString*) propertyName +- (KSCrashInstReportField *)reportFieldForProperty:(NSString *)propertyName { - KSCrashInstReportField* field = [self.fields objectForKey:propertyName]; - if(field == nil) - { + KSCrashInstReportField *field = [self.fields objectForKey:propertyName]; + if (field == nil) { field = [KSCrashInstReportField fieldWithIndex:self.nextFieldIndex]; self.nextFieldIndex++; self.crashHandlerData->reportFieldsCount = self.nextFieldIndex; @@ -212,47 +196,39 @@ - (KSCrashInstReportField*) reportFieldForProperty:(NSString*) propertyName return field; } -- (void) reportFieldForProperty:(NSString*) propertyName setKey:(id) key +- (void)reportFieldForProperty:(NSString *)propertyName setKey:(id)key { - KSCrashInstReportField* field = [self reportFieldForProperty:propertyName]; + KSCrashInstReportField *field = [self reportFieldForProperty:propertyName]; field.key = key; } -- (void) reportFieldForProperty:(NSString*) propertyName setValue:(id) value +- (void)reportFieldForProperty:(NSString *)propertyName setValue:(id)value { - KSCrashInstReportField* field = [self reportFieldForProperty:propertyName]; + KSCrashInstReportField *field = [self reportFieldForProperty:propertyName]; field.value = value; } -- (NSError*) validateProperties +- (NSError *)validateProperties { - NSMutableString* errors = [NSMutableString string]; - for(NSString* propertyName in self.requiredProperties) - { - NSString* nextError = nil; - @try - { + NSMutableString *errors = [NSMutableString string]; + for (NSString *propertyName in self.requiredProperties) { + NSString *nextError = nil; + @try { id value = [self valueForKey:propertyName]; - if(value == nil) - { + if (value == nil) { nextError = @"is nil"; } - } - @catch (NSException *exception) - { + } @catch (NSException *exception) { nextError = @"property not found"; } - if(nextError != nil) - { - if([errors length] > 0) - { + if (nextError != nil) { + if ([errors length] > 0) { [errors appendString:@", "]; } [errors appendFormat:@"%@ (%@)", propertyName, nextError]; } } - if([errors length] > 0) - { + if ([errors length] > 0) { return [NSError errorWithDomain:[[self class] description] code:0 description:@"Installation properties failed validation: %@", errors]; @@ -260,72 +236,62 @@ - (NSError*) validateProperties return nil; } -- (NSString*) makeKeyPath:(NSString*) keyPath +- (NSString *)makeKeyPath:(NSString *)keyPath { - if([keyPath length] == 0) - { + if ([keyPath length] == 0) { return keyPath; } BOOL isAbsoluteKeyPath = [keyPath length] > 0 && [keyPath characterAtIndex:0] == '/'; return isAbsoluteKeyPath ? keyPath : [@"user/" stringByAppendingString:keyPath]; } -- (NSArray*) makeKeyPaths:(NSArray*) keyPaths +- (NSArray *)makeKeyPaths:(NSArray *)keyPaths { - if([keyPaths count] == 0) - { + if ([keyPaths count] == 0) { return keyPaths; } - NSMutableArray* result = [NSMutableArray arrayWithCapacity:[keyPaths count]]; - for(NSString* keyPath in keyPaths) - { + NSMutableArray *result = [NSMutableArray arrayWithCapacity:[keyPaths count]]; + for (NSString *keyPath in keyPaths) { [result addObject:[self makeKeyPath:keyPath]]; } return result; } -- (KSReportWriteCallback) onCrash +- (KSReportWriteCallback)onCrash { - @synchronized(self) - { + @synchronized(self) { return self.crashHandlerData->userCrashCallback; } } -- (void) setOnCrash:(KSReportWriteCallback)onCrash +- (void)setOnCrash:(KSReportWriteCallback)onCrash { - @synchronized(self) - { + @synchronized(self) { self.crashHandlerData->userCrashCallback = onCrash; } } -- (void) installWithConfiguration:(KSCrashConfiguration*) configuration +- (void)installWithConfiguration:(KSCrashConfiguration *)configuration { - KSCrash* handler = [KSCrash sharedInstance]; - @synchronized(handler) - { + KSCrash *handler = [KSCrash sharedInstance]; + @synchronized(handler) { g_crashHandlerData = self.crashHandlerData; if (configuration == nil) { configuration = [[KSCrashConfiguration alloc] init]; } - configuration.crashNotifyCallback = ^(const struct KSCrashReportWriter * _Nonnull writer) { - CrashHandlerData* crashHandlerData = g_crashHandlerData; - if(crashHandlerData == NULL) - { + configuration.crashNotifyCallback = ^(const struct KSCrashReportWriter *_Nonnull writer) { + CrashHandlerData *crashHandlerData = g_crashHandlerData; + if (crashHandlerData == NULL) { return; } - for(int i = 0; i < crashHandlerData->reportFieldsCount; i++) - { - ReportField* field = crashHandlerData->reportFields[i]; - if(field->key != NULL && field->value != NULL) - { + for (int i = 0; i < crashHandlerData->reportFieldsCount; i++) { + ReportField *field = crashHandlerData->reportFields[i]; + if (field->key != NULL && field->value != NULL) { writer->addJSONElement(writer, field->key, field->value, true); } } - if(crashHandlerData->userCrashCallback != NULL) - { + if (crashHandlerData->userCrashCallback != NULL) { crashHandlerData->userCrashCallback(writer); } }; @@ -334,40 +300,38 @@ - (void) installWithConfiguration:(KSCrashConfiguration*) configuration } } -- (void) sendAllReportsWithCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)sendAllReportsWithCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSError* error = [self validateProperties]; - if(error != nil) - { - if(onCompletion != nil) - { + NSError *error = [self validateProperties]; + if (error != nil) { + if (onCompletion != nil) { onCompletion(nil, NO, error); } return; } id sink = [self sink]; - if(sink == nil) - { - onCompletion(nil, NO, [NSError errorWithDomain:[[self class] description] - code:0 - description:@"Sink was nil (subclasses must implement method \"sink\")"]); + if (sink == nil) { + onCompletion(nil, NO, + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"Sink was nil (subclasses must implement method \"sink\")"]); return; } - + sink = [KSCrashReportFilterPipeline filterWithFilters:self.prependedFilters, sink, nil]; - KSCrash* handler = [KSCrash sharedInstance]; + KSCrash *handler = [KSCrash sharedInstance]; handler.sink = sink; [handler sendAllReportsWithCompletion:onCompletion]; } -- (void) addPreFilter:(id) filter +- (void)addPreFilter:(id)filter { [self.prependedFilters addFilter:filter]; } -- (id) sink +- (id)sink { return nil; } diff --git a/Sources/KSCrashInstallations/KSCrashInstallationConsole.m b/Sources/KSCrashInstallations/KSCrashInstallationConsole.m index 478cf6495..5ed81c225 100644 --- a/Sources/KSCrashInstallations/KSCrashInstallationConsole.m +++ b/Sources/KSCrashInstallations/KSCrashInstallationConsole.m @@ -25,55 +25,48 @@ #import "KSCrashInstallationConsole.h" #import "KSCrashInstallation+Private.h" -#import "KSCrashReportSinkConsole.h" #import "KSCrashReportFilterAppleFmt.h" #import "KSCrashReportFilterBasic.h" #import "KSCrashReportFilterJSON.h" #import "KSCrashReportFilterStringify.h" +#import "KSCrashReportSinkConsole.h" @implementation KSCrashInstallationConsole @synthesize printAppleFormat = _printAppleFormat; -+ (instancetype) sharedInstance ++ (instancetype)sharedInstance { static KSCrashInstallationConsole *sharedInstance = nil; static dispatch_once_t onceToken; - + dispatch_once(&onceToken, ^{ sharedInstance = [[KSCrashInstallationConsole alloc] init]; }); return sharedInstance; } -- (id) init +- (id)init { - if((self = [super initWithRequiredProperties:nil])) - { + if ((self = [super initWithRequiredProperties:nil])) { self.printAppleFormat = NO; } return self; } -- (id) sink +- (id)sink { id formatFilter; - if(self.printAppleFormat) - { + if (self.printAppleFormat) { formatFilter = [KSCrashReportFilterAppleFmt filterWithReportStyle:KSAppleReportStyleSymbolicated]; - } - else - { - formatFilter = [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterJSONEncode filterWithOptions:KSJSONEncodeOptionPretty | KSJSONEncodeOptionSorted], - [KSCrashReportFilterStringify new], - nil]; + } else { + formatFilter = [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterJSONEncode + filterWithOptions:KSJSONEncodeOptionPretty | KSJSONEncodeOptionSorted], + [KSCrashReportFilterStringify new], nil]; } - return [KSCrashReportFilterPipeline filterWithFilters: - formatFilter, - [KSCrashReportSinkConsole new], - nil]; + return [KSCrashReportFilterPipeline filterWithFilters:formatFilter, [KSCrashReportSinkConsole new], nil]; } @end diff --git a/Sources/KSCrashInstallations/KSCrashInstallationEmail.m b/Sources/KSCrashInstallations/KSCrashInstallationEmail.m index 98a0e7070..f8f671076 100644 --- a/Sources/KSCrashInstallations/KSCrashInstallationEmail.m +++ b/Sources/KSCrashInstallations/KSCrashInstallationEmail.m @@ -24,20 +24,17 @@ // THE SOFTWARE. // - #import "KSCrashInstallationEmail.h" #import "KSCrashInstallation+Private.h" -#import "KSCrashReportSinkEMail.h" #import "KSCrashReportFilterAlert.h" - +#import "KSCrashReportSinkEMail.h" @interface KSCrashInstallationEmail () -@property(nonatomic,readwrite,retain) NSDictionary* defaultFilenameFormats; +@property(nonatomic, readwrite, retain) NSDictionary *defaultFilenameFormats; @end - @implementation KSCrashInstallationEmail @synthesize recipients = _recipients; @@ -47,58 +44,50 @@ @implementation KSCrashInstallationEmail @synthesize reportStyle = _reportStyle; @synthesize defaultFilenameFormats = _defaultFilenameFormats; -+ (instancetype) sharedInstance ++ (instancetype)sharedInstance { static KSCrashInstallationEmail *sharedInstance = nil; static dispatch_once_t onceToken; - + dispatch_once(&onceToken, ^{ sharedInstance = [[KSCrashInstallationEmail alloc] init]; }); return sharedInstance; } -- (id) init +- (id)init { - if((self = [super initWithRequiredProperties:[NSArray arrayWithObjects: - @"recipients", - @"subject", - @"filenameFmt", - nil]])) - { - NSString* bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + if ((self = [super + initWithRequiredProperties:[NSArray arrayWithObjects:@"recipients", @"subject", @"filenameFmt", nil]])) { + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; self.subject = [NSString stringWithFormat:@"Crash Report (%@)", bundleName]; - self.defaultFilenameFormats = [NSDictionary dictionaryWithObjectsAndKeys: - [NSString stringWithFormat:@"crash-report-%@-%%d.txt.gz", bundleName], - [NSNumber numberWithInt:KSCrashEmailReportStyleApple], - [NSString stringWithFormat:@"crash-report-%@-%%d.json.gz", bundleName], - [NSNumber numberWithInt:KSCrashEmailReportStyleJSON], - nil]; + self.defaultFilenameFormats = [NSDictionary + dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"crash-report-%@-%%d.txt.gz", bundleName], + [NSNumber numberWithInt:KSCrashEmailReportStyleApple], + [NSString stringWithFormat:@"crash-report-%@-%%d.json.gz", bundleName], + [NSNumber numberWithInt:KSCrashEmailReportStyleJSON], nil]; [self setReportStyle:KSCrashEmailReportStyleJSON useDefaultFilenameFormat:YES]; } return self; } -- (void) setReportStyle:(KSCrashEmailReportStyle)reportStyle -useDefaultFilenameFormat:(BOOL) useDefaultFilenameFormat +- (void)setReportStyle:(KSCrashEmailReportStyle)reportStyle useDefaultFilenameFormat:(BOOL)useDefaultFilenameFormat { self.reportStyle = reportStyle; - if(useDefaultFilenameFormat) - { + if (useDefaultFilenameFormat) { self.filenameFmt = [self.defaultFilenameFormats objectForKey:[NSNumber numberWithInt:(int)reportStyle]]; } } -- (id) sink +- (id)sink { - KSCrashReportSinkEMail* sink = [KSCrashReportSinkEMail sinkWithRecipients:self.recipients + KSCrashReportSinkEMail *sink = [KSCrashReportSinkEMail sinkWithRecipients:self.recipients subject:self.subject message:self.message filenameFmt:self.filenameFmt]; - - switch(self.reportStyle) - { + + switch (self.reportStyle) { case KSCrashEmailReportStyleApple: return [sink defaultCrashReportFilterSetAppleFmt]; case KSCrashEmailReportStyleJSON: diff --git a/Sources/KSCrashInstallations/KSCrashInstallationStandard.m b/Sources/KSCrashInstallations/KSCrashInstallationStandard.m index 4df9a9729..3c08b348f 100644 --- a/Sources/KSCrashInstallations/KSCrashInstallationStandard.m +++ b/Sources/KSCrashInstallations/KSCrashInstallationStandard.m @@ -24,36 +24,34 @@ // THE SOFTWARE. // - #import "KSCrashInstallationStandard.h" #import "KSCrashInstallation+Private.h" -#import "KSCrashReportSinkStandard.h" #import "KSCrashReportFilterBasic.h" - +#import "KSCrashReportSinkStandard.h" @implementation KSCrashInstallationStandard @synthesize url = _url; -+ (instancetype) sharedInstance ++ (instancetype)sharedInstance { static KSCrashInstallationStandard *sharedInstance = nil; static dispatch_once_t onceToken; - + dispatch_once(&onceToken, ^{ sharedInstance = [[KSCrashInstallationStandard alloc] init]; }); return sharedInstance; } -- (id) init +- (id)init { - return [super initWithRequiredProperties:[NSArray arrayWithObjects: @"url", nil]]; + return [super initWithRequiredProperties:[NSArray arrayWithObjects:@"url", nil]]; } -- (id) sink +- (id)sink { - KSCrashReportSinkStandard* sink = [KSCrashReportSinkStandard sinkWithURL:self.url]; + KSCrashReportSinkStandard *sink = [KSCrashReportSinkStandard sinkWithURL:self.url]; return [KSCrashReportFilterPipeline filterWithFilters:[sink defaultCrashReportFilterSet], nil]; } diff --git a/Sources/KSCrashInstallations/include/KSCrashInstallation+Alert.h b/Sources/KSCrashInstallations/include/KSCrashInstallation+Alert.h index e5caddc93..ed649ef50 100644 --- a/Sources/KSCrashInstallations/include/KSCrashInstallation+Alert.h +++ b/Sources/KSCrashInstallations/include/KSCrashInstallation+Alert.h @@ -38,10 +38,10 @@ NS_ASSUME_NONNULL_BEGIN * @param yesAnswer The text to display in the "yes" box. * @param noAnswer The text to display in the "no" box. */ -- (void) addConditionalAlertWithTitle:(NSString*) title - message:(nullable NSString*) message - yesAnswer:(NSString*) yesAnswer - noAnswer:(nullable NSString*) noAnswer; +- (void)addConditionalAlertWithTitle:(NSString *)title + message:(nullable NSString *)message + yesAnswer:(NSString *)yesAnswer + noAnswer:(nullable NSString *)noAnswer; /** Show an alert before sending any reports. Reports will be unconditionally sent * when the alert is dismissed. @@ -50,9 +50,9 @@ NS_ASSUME_NONNULL_BEGIN * @param message The message to show the user. * @param dismissButtonText The text to display in the dismiss button. */ -- (void) addUnconditionalAlertWithTitle:(NSString*) title - message:(nullable NSString*) message - dismissButtonText:(NSString*) dismissButtonText; +- (void)addUnconditionalAlertWithTitle:(NSString *)title + message:(nullable NSString *)message + dismissButtonText:(NSString *)dismissButtonText; @end diff --git a/Sources/KSCrashInstallations/include/KSCrashInstallation.h b/Sources/KSCrashInstallations/include/KSCrashInstallation.h index fd6d0b31f..45915ed4f 100644 --- a/Sources/KSCrashInstallations/include/KSCrashInstallation.h +++ b/Sources/KSCrashInstallations/include/KSCrashInstallation.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import #import "KSCrashReportFilter.h" #import "KSCrashReportWriter.h" @@ -49,7 +48,7 @@ NS_SWIFT_NAME(CrashInstallation) * WARNING: Only call async-safe functions from this function! DO NOT call * Swift/Objective-C methods!!! */ -@property(atomic,readwrite,assign,nullable) KSReportWriteCallback onCrash; +@property(atomic, readwrite, assign, nullable) KSReportWriteCallback onCrash; /** Install this crash handler with a specific configuration. * Call this method instead of `-[KSCrash installWithConfiguration:]` to set up the crash handler @@ -62,7 +61,7 @@ NS_SWIFT_NAME(CrashInstallation) * when using this method. The callback will be internally managed to ensure proper integration * with the backend. */ -- (void) installWithConfiguration:(nullable KSCrashConfiguration*) configuration; +- (void)installWithConfiguration:(nullable KSCrashConfiguration *)configuration; /** Convenience method to call -[KSCrash sendAllReportsWithCompletion:]. * This method will set the KSCrash sink and then send all outstanding reports. @@ -71,14 +70,14 @@ NS_SWIFT_NAME(CrashInstallation) * * @param onCompletion Called when sending is complete (nil = ignore). */ -- (void) sendAllReportsWithCompletion:(nullable KSCrashReportFilterCompletion) onCompletion; +- (void)sendAllReportsWithCompletion:(nullable KSCrashReportFilterCompletion)onCompletion; /** Add a filter that gets executed before all normal filters. * Prepended filters will be executed in the order in which they were added. * * @param filter the filter to prepend. */ -- (void) addPreFilter:(id) filter; +- (void)addPreFilter:(id)filter; @end diff --git a/Sources/KSCrashInstallations/include/KSCrashInstallationConsole.h b/Sources/KSCrashInstallations/include/KSCrashInstallationConsole.h index dc4faac44..a24638f3d 100644 --- a/Sources/KSCrashInstallations/include/KSCrashInstallationConsole.h +++ b/Sources/KSCrashInstallations/include/KSCrashInstallationConsole.h @@ -35,9 +35,9 @@ NS_ASSUME_NONNULL_BEGIN NS_SWIFT_NAME(CrashInstallationConsole) @interface KSCrashInstallationConsole : KSCrashInstallation -@property(nonatomic,readwrite) BOOL printAppleFormat; +@property(nonatomic, readwrite) BOOL printAppleFormat; -+ (instancetype) sharedInstance NS_SWIFT_NAME(shared()); ++ (instancetype)sharedInstance NS_SWIFT_NAME(shared()); @end diff --git a/Sources/KSCrashInstallations/include/KSCrashInstallationEmail.h b/Sources/KSCrashInstallations/include/KSCrashInstallationEmail.h index 13ec856d5..dacce0d7b 100644 --- a/Sources/KSCrashInstallations/include/KSCrashInstallationEmail.h +++ b/Sources/KSCrashInstallations/include/KSCrashInstallationEmail.h @@ -43,19 +43,19 @@ NS_SWIFT_NAME(CrashInstallationEmail) @interface KSCrashInstallationEmail : KSCrashInstallation /** List of email addresses to send to (mandatory) */ -@property(nonatomic,readwrite,copy) NSArray *recipients; +@property(nonatomic, readwrite, copy) NSArray *recipients; /** Email subject (mandatory). * * Default: "Crash Report (YourBundleID)" */ -@property(nonatomic,readwrite,copy) NSString* subject; +@property(nonatomic, readwrite, copy) NSString *subject; /** Message to accompany the reports (optional). * * Default: nil */ -@property(nonatomic,readwrite,copy,nullable) NSString* message; +@property(nonatomic, readwrite, copy, nullable) NSString *message; /** How to name the attachments (mandatory) * @@ -65,21 +65,20 @@ NS_SWIFT_NAME(CrashInstallationEmail) * * Default: "crash-report-YourBundleID-%d.txt.gz" */ -@property(nonatomic,readwrite,copy) NSString* filenameFmt; +@property(nonatomic, readwrite, copy) NSString *filenameFmt; /** Which report style to use. */ -@property(nonatomic,readwrite,assign) KSCrashEmailReportStyle reportStyle; +@property(nonatomic, readwrite, assign) KSCrashEmailReportStyle reportStyle; /** Use the specified report format. * * useDefaultFilenameFormat If true, also change the filename format to the default * suitable for the report format. */ -- (void) setReportStyle:(KSCrashEmailReportStyle)reportStyle -useDefaultFilenameFormat:(BOOL) useDefaultFilenameFormat; +- (void)setReportStyle:(KSCrashEmailReportStyle)reportStyle useDefaultFilenameFormat:(BOOL)useDefaultFilenameFormat; -+ (instancetype) sharedInstance NS_SWIFT_NAME(shared()); ++ (instancetype)sharedInstance NS_SWIFT_NAME(shared()); @end diff --git a/Sources/KSCrashInstallations/include/KSCrashInstallationStandard.h b/Sources/KSCrashInstallations/include/KSCrashInstallationStandard.h index 81833f74b..39ee027e4 100644 --- a/Sources/KSCrashInstallations/include/KSCrashInstallationStandard.h +++ b/Sources/KSCrashInstallations/include/KSCrashInstallationStandard.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashInstallation.h" #import @@ -35,9 +34,9 @@ NS_SWIFT_NAME(CrashInstallationStandard) @interface KSCrashInstallationStandard : KSCrashInstallation /** The URL to connect to. */ -@property(nonatomic,readwrite,strong) NSURL* url; +@property(nonatomic, readwrite, strong) NSURL *url; -+ (instancetype) sharedInstance NS_SWIFT_NAME(shared()); ++ (instancetype)sharedInstance NS_SWIFT_NAME(shared()); @end diff --git a/Sources/KSCrashRecording/KSCrash+Private.h b/Sources/KSCrashRecording/KSCrash+Private.h index c1ff0fac9..555b771cc 100644 --- a/Sources/KSCrashRecording/KSCrash+Private.h +++ b/Sources/KSCrashRecording/KSCrash+Private.h @@ -29,10 +29,10 @@ #import "KSCrash.h" -@interface KSCrash() +@interface KSCrash () -@property (nonatomic, readwrite, assign) NSUncaughtExceptionHandler *uncaughtExceptionHandler; -@property (nonatomic, readwrite, assign) NSUncaughtExceptionHandler *currentSnapshotUserReportedExceptionHandler; +@property(nonatomic, readwrite, assign) NSUncaughtExceptionHandler *uncaughtExceptionHandler; +@property(nonatomic, readwrite, assign) NSUncaughtExceptionHandler *currentSnapshotUserReportedExceptionHandler; @end diff --git a/Sources/KSCrashRecording/KSCrash.m b/Sources/KSCrashRecording/KSCrash.m index 102b3147d..eef7c8e35 100644 --- a/Sources/KSCrashRecording/KSCrash.m +++ b/Sources/KSCrashRecording/KSCrash.m @@ -24,24 +24,23 @@ // THE SOFTWARE. // - #import "KSCrash.h" #import "KSCrash+Private.h" -#import "KSCrashConfiguration+Private.h" #import "KSCrashC.h" +#import "KSCrashConfiguration+Private.h" #import "KSCrashDoctor.h" -#import "KSCrashReportFields.h" -#import "KSCrashMonitor_AppState.h" -#import "KSJSONCodecObjC.h" -#import "NSError+SimpleConstructor.h" #import "KSCrashMonitorContext.h" -#import "KSCrashMonitor_System.h" -#import "KSSystemCapabilities.h" +#import "KSCrashMonitor_AppState.h" #import "KSCrashMonitor_Memory.h" +#import "KSCrashMonitor_System.h" #import "KSCrashReport.h" +#import "KSCrashReportFields.h" +#import "KSJSONCodecObjC.h" +#import "KSSystemCapabilities.h" +#import "NSError+SimpleConstructor.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" #include @@ -49,58 +48,50 @@ #import #endif - // ============================================================================ #pragma mark - Globals - // ============================================================================ @interface KSCrash () -@property(nonatomic,readwrite,retain) NSString* bundleName; -@property(nonatomic,readwrite,retain) NSString* basePath; -@property(nonatomic,strong) KSCrashConfiguration* configuration; +@property(nonatomic, readwrite, retain) NSString *bundleName; +@property(nonatomic, readwrite, retain) NSString *basePath; +@property(nonatomic, strong) KSCrashConfiguration *configuration; @end static NSString *gCustomBasePath = nil; static BOOL gIsSharedInstanceCreated = NO; -static NSString* getBundleName(void) +static NSString *getBundleName(void) { - NSString* bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; - if(bundleName == nil) - { + NSString *bundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; + if (bundleName == nil) { bundleName = @"Unknown"; } return bundleName; } -static NSString* getBasePath(void) +static NSString *getBasePath(void) { - if(gCustomBasePath != nil) - { + if (gCustomBasePath != nil) { return gCustomBasePath; } - NSArray* directories = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, - NSUserDomainMask, - YES); - if([directories count] == 0) - { + NSArray *directories = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + if ([directories count] == 0) { KSLOG_ERROR(@"Could not locate cache directory path."); return nil; } - NSString* cachePath = [directories objectAtIndex:0]; - if([cachePath length] == 0) - { + NSString *cachePath = [directories objectAtIndex:0]; + if ([cachePath length] == 0) { KSLOG_ERROR(@"Could not locate cache directory path."); return nil; } - NSString* pathEnd = [@"KSCrash" stringByAppendingPathComponent:getBundleName()]; + NSString *pathEnd = [@"KSCrash" stringByAppendingPathComponent:getBundleName()]; return [cachePath stringByAppendingPathComponent:pathEnd]; } - @implementation KSCrash // ============================================================================ @@ -129,24 +120,22 @@ + (void)initialize } } -+ (void) setBasePath:(NSString*) basePath; ++ (void)setBasePath:(NSString *)basePath; { - if(basePath == gCustomBasePath || [basePath isEqualToString:gCustomBasePath]) - { + if (basePath == gCustomBasePath || [basePath isEqualToString:gCustomBasePath]) { return; } - if(gIsSharedInstanceCreated) - { + if (gIsSharedInstanceCreated) { KSLOG_WARN(@"A shared instance of KSCrash is already created. Can't change the base path to: %@", basePath); } gCustomBasePath = [basePath copy]; } -+ (instancetype) sharedInstance ++ (instancetype)sharedInstance { static KSCrash *sharedInstance = nil; static dispatch_once_t onceToken; - + dispatch_once(&onceToken, ^{ sharedInstance = [[KSCrash alloc] initWithBasePath:getBasePath()]; gIsSharedInstanceCreated = YES; @@ -154,14 +143,12 @@ + (instancetype) sharedInstance return sharedInstance; } -- (instancetype) initWithBasePath:(NSString*) basePath +- (instancetype)initWithBasePath:(NSString *)basePath { - if((self = [super init])) - { + if ((self = [super init])) { self.bundleName = getBundleName(); self.basePath = basePath; - if(self.basePath == nil) - { + if (self.basePath == nil) { KSLOG_ERROR(@"Failed to initialize crash handler. Crash reporting disabled."); return nil; } @@ -173,18 +160,16 @@ - (instancetype) initWithBasePath:(NSString*) basePath #pragma mark - API - // ============================================================================ -- (NSDictionary* )userInfo +- (NSDictionary *)userInfo { const char *userInfoJSON = kscrash_getUserInfoJSON(); - if (userInfoJSON != NULL) - { + if (userInfoJSON != NULL) { NSError *error = nil; NSData *jsonData = [NSData dataWithBytes:userInfoJSON length:strlen(userInfoJSON)]; NSDictionary *userInfoDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; - free((void *)userInfoJSON); // Free the allocated memory + free((void *)userInfoJSON); // Free the allocated memory - if (error != nil) - { + if (error != nil) { KSLOG_ERROR(@"Error parsing JSON: %@", error.localizedDescription); return nil; } @@ -193,17 +178,15 @@ - (NSDictionary* )userInfo return nil; } -- (void) setUserInfo:(NSDictionary*) userInfo +- (void)setUserInfo:(NSDictionary *)userInfo { NSError *error = nil; NSData *userInfoJSON = nil; - if (userInfo != nil) - { + if (userInfo != nil) { userInfoJSON = [NSJSONSerialization dataWithJSONObject:userInfo options:NSJSONWritingSortedKeys error:&error]; - if (error != nil) - { + if (error != nil) { KSLOG_ERROR(@"Could not serialize user info: %@", error.localizedDescription); return; } @@ -223,14 +206,15 @@ - (void)setReportsMemoryTerminations:(BOOL)reportsMemoryTerminations ksmemory_set_fatal_reports_enabled(reportsMemoryTerminations); } -- (NSDictionary*) systemInfo +- (NSDictionary *)systemInfo { - KSCrash_MonitorContext fakeEvent = {0}; + KSCrash_MonitorContext fakeEvent = { 0 }; kscm_system_getAPI()->addContextualInfoToEvent(&fakeEvent); - NSMutableDictionary* dict = [NSMutableDictionary new]; + NSMutableDictionary *dict = [NSMutableDictionary new]; -#define COPY_STRING(A) if (fakeEvent.System.A) dict[@#A] = [NSString stringWithUTF8String:fakeEvent.System.A] -#define COPY_PRIMITIVE(A) dict[@#A] = @(fakeEvent.System.A) +#define COPY_STRING(A) \ + if (fakeEvent.System.A) dict[@ #A] = [NSString stringWithUTF8String:fakeEvent.System.A] +#define COPY_PRIMITIVE(A) dict[@ #A] = @(fakeEvent.System.A) COPY_STRING(systemName); COPY_STRING(systemVersion); COPY_STRING(machine); @@ -238,7 +222,7 @@ - (NSDictionary*) systemInfo COPY_STRING(kernelVersion); COPY_STRING(osVersion); COPY_PRIMITIVE(isJailbroken); - COPY_STRING(bootTime); // this field is populated in an optional monitor + COPY_STRING(bootTime); // this field is populated in an optional monitor COPY_STRING(appStartTime); COPY_STRING(executablePath); COPY_STRING(executableName); @@ -258,7 +242,7 @@ - (NSDictionary*) systemInfo COPY_PRIMITIVE(parentProcessID); COPY_STRING(deviceAppHash); COPY_STRING(buildType); - COPY_PRIMITIVE(storageSize); // this field is populated in an optional monitor + COPY_PRIMITIVE(storageSize); // this field is populated in an optional monitor COPY_PRIMITIVE(memorySize); COPY_PRIMITIVE(freeMemory); COPY_PRIMITIVE(usableMemory); @@ -266,7 +250,7 @@ - (NSDictionary*) systemInfo return [dict copy]; } -- (BOOL) installWithConfiguration:(KSCrashConfiguration*) configuration +- (BOOL)installWithConfiguration:(KSCrashConfiguration *)configuration { self.configuration = [configuration copy] ?: [KSCrashConfiguration new]; kscrash_install(self.bundleName.UTF8String, self.basePath.UTF8String, [self.configuration toCConfiguration]); @@ -274,73 +258,62 @@ - (BOOL) installWithConfiguration:(KSCrashConfiguration*) configuration return true; } -- (void) sendAllReportsWithCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)sendAllReportsWithCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSArray* reports = [self allReports]; - + NSArray *reports = [self allReports]; + KSLOG_INFO(@"Sending %d crash reports", [reports count]); - + [self sendReports:reports - onCompletion:^(NSArray* filteredReports, BOOL completed, NSError* error) - { - KSLOG_DEBUG(@"Process finished with completion: %d", completed); - if(error != nil) - { - KSLOG_ERROR(@"Failed to send reports: %@", error); - } - if((self.configuration.deleteBehaviorAfterSendAll == KSCDeleteOnSucess && completed) || - self.configuration.deleteBehaviorAfterSendAll == KSCDeleteAlways) - { - kscrash_deleteAllReports(); - } - kscrash_callCompletion(onCompletion, filteredReports, completed, error); - }]; -} - -- (void) deleteAllReports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + KSLOG_DEBUG(@"Process finished with completion: %d", completed); + if (error != nil) { + KSLOG_ERROR(@"Failed to send reports: %@", error); + } + if ((self.configuration.deleteBehaviorAfterSendAll == KSCDeleteOnSucess && completed) || + self.configuration.deleteBehaviorAfterSendAll == KSCDeleteAlways) { + kscrash_deleteAllReports(); + } + kscrash_callCompletion(onCompletion, filteredReports, completed, error); + }]; +} + +- (void)deleteAllReports { kscrash_deleteAllReports(); } -- (void) deleteReportWithID:(int64_t) reportID +- (void)deleteReportWithID:(int64_t)reportID { kscrash_deleteReportWithID(reportID); } -- (void) reportUserException:(NSString*) name - reason:(NSString*) reason - language:(NSString*) language - lineOfCode:(NSString*) lineOfCode - stackTrace:(NSArray*) stackTrace - logAllThreads:(BOOL) logAllThreads - terminateProgram:(BOOL) terminateProgram -{ - const char* cName = [name cStringUsingEncoding:NSUTF8StringEncoding]; - const char* cReason = [reason cStringUsingEncoding:NSUTF8StringEncoding]; - const char* cLanguage = [language cStringUsingEncoding:NSUTF8StringEncoding]; - const char* cLineOfCode = [lineOfCode cStringUsingEncoding:NSUTF8StringEncoding]; - const char* cStackTrace = NULL; - - if(stackTrace != nil) - { - NSError* error = nil; - NSData* jsonData = [KSJSONCodec encode:stackTrace options:0 error:&error]; - if(jsonData == nil || error != nil) - { +- (void)reportUserException:(NSString *)name + reason:(NSString *)reason + language:(NSString *)language + lineOfCode:(NSString *)lineOfCode + stackTrace:(NSArray *)stackTrace + logAllThreads:(BOOL)logAllThreads + terminateProgram:(BOOL)terminateProgram +{ + const char *cName = [name cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cReason = [reason cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cLanguage = [language cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cLineOfCode = [lineOfCode cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cStackTrace = NULL; + + if (stackTrace != nil) { + NSError *error = nil; + NSData *jsonData = [KSJSONCodec encode:stackTrace options:0 error:&error]; + if (jsonData == nil || error != nil) { KSLOG_ERROR(@"Error encoding stack trace to JSON: %@", error); // Don't return, since we can still record other useful information. } - NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; cStackTrace = [jsonString cStringUsingEncoding:NSUTF8StringEncoding]; } - - kscrash_reportUserException(cName, - cReason, - cLanguage, - cLineOfCode, - cStackTrace, - logAllThreads, - terminateProgram); + + kscrash_reportUserException(cName, cReason, cLanguage, cLineOfCode, cStackTrace, logAllThreads, terminateProgram); } // ============================================================================ @@ -348,10 +321,7 @@ - (void) reportUserException:(NSString*) name // ============================================================================ #define SYNTHESIZE_CRASH_STATE_PROPERTY(TYPE, NAME) \ -- (TYPE) NAME \ -{ \ - return kscrashstate_currentState()->NAME; \ -} + -(TYPE)NAME { return kscrashstate_currentState()->NAME; } SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, activeDurationSinceLastCrash) SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, backgroundDurationSinceLastCrash) @@ -362,92 +332,82 @@ - (TYPE) NAME \ SYNTHESIZE_CRASH_STATE_PROPERTY(NSInteger, sessionsSinceLaunch) SYNTHESIZE_CRASH_STATE_PROPERTY(BOOL, crashedLastLaunch) -- (NSInteger) reportCount +- (NSInteger)reportCount { return kscrash_getReportCount(); } -- (void) sendReports:(NSArray*) reports onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)sendReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - if([reports count] == 0) - { + if ([reports count] == 0) { kscrash_callCompletion(onCompletion, reports, YES, nil); return; } - - if(self.sink == nil) - { + + if (self.sink == nil) { kscrash_callCompletion(onCompletion, reports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"No sink set. Crash reports not sent."]); + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"No sink set. Crash reports not sent."]); return; } - + [self.sink filterReports:reports - onCompletion:^(NSArray* filteredReports, BOOL completed, NSError* error) - { - kscrash_callCompletion(onCompletion, filteredReports, completed, error); - }]; + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + kscrash_callCompletion(onCompletion, filteredReports, completed, error); + }]; } -- (NSData*) loadCrashReportJSONWithID:(int64_t) reportID +- (NSData *)loadCrashReportJSONWithID:(int64_t)reportID { - char* report = kscrash_readReport(reportID); - if(report != NULL) - { + char *report = kscrash_readReport(reportID); + if (report != NULL) { return [NSData dataWithBytesNoCopy:report length:strlen(report) freeWhenDone:YES]; } return nil; } -- (void) doctorReport:(NSMutableDictionary*) report +- (void)doctorReport:(NSMutableDictionary *)report { - NSMutableDictionary* crashReport = report[KSCrashField_Crash]; - if(crashReport != nil) - { + NSMutableDictionary *crashReport = report[KSCrashField_Crash]; + if (crashReport != nil) { crashReport[KSCrashField_Diagnosis] = [[KSCrashDoctor doctor] diagnoseCrash:report]; } crashReport = report[KSCrashField_RecrashReport][KSCrashField_Crash]; - if(crashReport != nil) - { + if (crashReport != nil) { crashReport[KSCrashField_Diagnosis] = [[KSCrashDoctor doctor] diagnoseCrash:report]; } } -- (NSArray*)reportIDs +- (NSArray *)reportIDs { int reportCount = kscrash_getReportCount(); int64_t reportIDsC[reportCount]; reportCount = kscrash_getReportIDs(reportIDsC, reportCount); - NSMutableArray* reportIDs = [NSMutableArray arrayWithCapacity:(NSUInteger)reportCount]; - for(int i = 0; i < reportCount; i++) - { + NSMutableArray *reportIDs = [NSMutableArray arrayWithCapacity:(NSUInteger)reportCount]; + for (int i = 0; i < reportCount; i++) { [reportIDs addObject:[NSNumber numberWithLongLong:reportIDsC[i]]]; } return [reportIDs copy]; } -- (KSCrashReport*) reportForID:(int64_t) reportID +- (KSCrashReport *)reportForID:(int64_t)reportID { - NSData* jsonData = [self loadCrashReportJSONWithID:reportID]; - if(jsonData == nil) - { + NSData *jsonData = [self loadCrashReportJSONWithID:reportID]; + if (jsonData == nil) { return nil; } - NSError* error = nil; - NSMutableDictionary* crashReport = [KSJSONCodec decode:jsonData - options:KSJSONDecodeOptionIgnoreNullInArray | - KSJSONDecodeOptionIgnoreNullInObject | - KSJSONDecodeOptionKeepPartialObject - error:&error]; - if(error != nil) - { + NSError *error = nil; + NSMutableDictionary *crashReport = + [KSJSONCodec decode:jsonData + options:KSJSONDecodeOptionIgnoreNullInArray | KSJSONDecodeOptionIgnoreNullInObject | + KSJSONDecodeOptionKeepPartialObject + error:&error]; + if (error != nil) { KSLOG_ERROR(@"Encountered error loading crash report %" PRIx64 ": %@", reportID, error); } - if(crashReport == nil) - { + if (crashReport == nil) { KSLOG_ERROR(@"Could not load crash report"); return nil; } @@ -456,21 +416,19 @@ - (KSCrashReport*) reportForID:(int64_t) reportID return [KSCrashReport reportWithDictionary:crashReport]; } -- (NSArray*) allReports +- (NSArray *)allReports { int reportCount = kscrash_getReportCount(); int64_t reportIDs[reportCount]; reportCount = kscrash_getReportIDs(reportIDs, reportCount); - NSMutableArray* reports = [NSMutableArray arrayWithCapacity:(NSUInteger)reportCount]; - for(int i = 0; i < reportCount; i++) - { - KSCrashReport* report = [self reportForID:reportIDs[i]]; - if(report != nil) - { + NSMutableArray *reports = [NSMutableArray arrayWithCapacity:(NSUInteger)reportCount]; + for (int i = 0; i < reportCount; i++) { + KSCrashReport *report = [self reportForID:reportIDs[i]]; + if (report != nil) { [reports addObject:report]; } } - + return reports; } @@ -478,26 +436,24 @@ - (KSCrashReport*) reportForID:(int64_t) reportID #pragma mark - Utility - // ============================================================================ -- (NSMutableData*) nullTerminated:(NSData*) data +- (NSMutableData *)nullTerminated:(NSData *)data { - if(data == nil) - { + if (data == nil) { return NULL; } - NSMutableData* mutable = [NSMutableData dataWithData:data]; + NSMutableData *mutable = [NSMutableData dataWithData:data]; [mutable appendBytes:"\0" length:1]; return mutable; } - // ============================================================================ #pragma mark - Notifications - // ============================================================================ -+ (void) subscribeToNotifications ++ (void)subscribeToNotifications { #if KSCRASH_HAS_UIAPPLICATION - NSNotificationCenter* nCenter = [NSNotificationCenter defaultCenter]; + NSNotificationCenter *nCenter = [NSNotificationCenter defaultCenter]; [nCenter addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification @@ -520,7 +476,7 @@ + (void) subscribeToNotifications object:nil]; #endif #if KSCRASH_HAS_NSEXTENSION - NSNotificationCenter* nCenter = [NSNotificationCenter defaultCenter]; + NSNotificationCenter *nCenter = [NSNotificationCenter defaultCenter]; [nCenter addObserver:self selector:@selector(applicationDidBecomeActive) name:NSExtensionHostDidBecomeActiveNotification @@ -540,39 +496,38 @@ + (void) subscribeToNotifications #endif } -+ (void) classDidBecomeLoaded ++ (void)classDidBecomeLoaded { kscrash_notifyObjCLoad(); } -+ (void) applicationDidBecomeActive ++ (void)applicationDidBecomeActive { kscrash_notifyAppActive(true); } -+ (void) applicationWillResignActive ++ (void)applicationWillResignActive { kscrash_notifyAppActive(false); } -+ (void) applicationDidEnterBackground ++ (void)applicationDidEnterBackground { kscrash_notifyAppInForeground(false); } -+ (void) applicationWillEnterForeground ++ (void)applicationWillEnterForeground { kscrash_notifyAppInForeground(true); } -+ (void) applicationWillTerminate ++ (void)applicationWillTerminate { kscrash_notifyAppTerminate(); } @end - //! Project version number for KSCrashFramework. const double KSCrashFrameworkVersionNumber = 2.0000; diff --git a/Sources/KSCrashRecording/KSCrashAppMemory+Private.h b/Sources/KSCrashRecording/KSCrashAppMemory+Private.h index 37dce4d06..17756755c 100644 --- a/Sources/KSCrashRecording/KSCrashAppMemory+Private.h +++ b/Sources/KSCrashRecording/KSCrashAppMemory+Private.h @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN pressure:(KSCrashAppMemoryState)pressure NS_DESIGNATED_INITIALIZER; @end -typedef KSCrashAppMemory * _Nonnull (^KSCrashAppMemoryProvider)(void); +typedef KSCrashAppMemory *_Nonnull (^KSCrashAppMemoryProvider)(void); FOUNDATION_EXPORT void __KSCrashAppMemorySetProvider(KSCrashAppMemoryProvider provider); NS_ASSUME_NONNULL_END diff --git a/Sources/KSCrashRecording/KSCrashAppMemory.m b/Sources/KSCrashRecording/KSCrashAppMemory.m index a7388f64d..5083abc3a 100644 --- a/Sources/KSCrashRecording/KSCrashAppMemory.m +++ b/Sources/KSCrashRecording/KSCrashAppMemory.m @@ -8,7 +8,8 @@ @implementation KSCrashAppMemory - (instancetype)initWithFootprint:(uint64_t)footprint remaining:(uint64_t)remaining - pressure:(KSCrashAppMemoryState)pressure { + pressure:(KSCrashAppMemoryState)pressure +{ if (self = [super init]) { _footprint = footprint; _remaining = remaining; @@ -17,37 +18,40 @@ - (instancetype)initWithFootprint:(uint64_t)footprint return self; } -- (BOOL)isEqual:(id)object { +- (BOOL)isEqual:(id)object +{ if (![object isKindOfClass:self.class]) { return NO; } KSCrashAppMemory *comp = (KSCrashAppMemory *)object; - return comp.footprint == self.footprint && comp.remaining == self.remaining && - comp.pressure == self.pressure; + return comp.footprint == self.footprint && comp.remaining == self.remaining && comp.pressure == self.pressure; } -- (uint64_t)limit { +- (uint64_t)limit +{ return _footprint + _remaining; } -- (KSCrashAppMemoryState)level { +- (KSCrashAppMemoryState)level +{ double usedRatio = (double)self.footprint / (double)self.limit; - + return usedRatio < 0.25 ? KSCrashAppMemoryStateNormal - : usedRatio < 0.50 ? KSCrashAppMemoryStateWarn - : usedRatio < 0.75 ? KSCrashAppMemoryStateUrgent - : usedRatio < 0.95 ? KSCrashAppMemoryStateCritical - : KSCrashAppMemoryStateTerminal; + : usedRatio < 0.50 ? KSCrashAppMemoryStateWarn + : usedRatio < 0.75 ? KSCrashAppMemoryStateUrgent + : usedRatio < 0.95 ? KSCrashAppMemoryStateCritical + : KSCrashAppMemoryStateTerminal; } -- (BOOL)isOutOfMemory { - return self.level >= KSCrashAppMemoryStateCritical || - self.pressure >= KSCrashAppMemoryStateCritical; +- (BOOL)isOutOfMemory +{ + return self.level >= KSCrashAppMemoryStateCritical || self.pressure >= KSCrashAppMemoryStateCritical; } @end -const char *KSCrashAppMemoryStateToString(KSCrashAppMemoryState state) { +const char *KSCrashAppMemoryStateToString(KSCrashAppMemoryState state) +{ switch (state) { case KSCrashAppMemoryStateNormal: return "normal"; @@ -63,34 +67,33 @@ - (BOOL)isOutOfMemory { assert(state <= KSCrashAppMemoryStateTerminal); } -KSCrashAppMemoryState KSCrashAppMemoryStateFromString(NSString *const string) { +KSCrashAppMemoryState KSCrashAppMemoryStateFromString(NSString *const string) +{ if ([string isEqualToString:@"normal"]) { return KSCrashAppMemoryStateNormal; } - + if ([string isEqualToString:@"warn"]) { return KSCrashAppMemoryStateWarn; } - + if ([string isEqualToString:@"urgent"]) { return KSCrashAppMemoryStateUrgent; } - + if ([string isEqualToString:@"critical"]) { return KSCrashAppMemoryStateCritical; } - + if ([string isEqualToString:@"terminal"]) { return KSCrashAppMemoryStateTerminal; } - + return KSCrashAppMemoryStateNormal; } -NSNotificationName const KSCrashAppMemoryLevelChangedNotification = -@"KSCrashAppMemoryLevelChangedNotification"; -NSNotificationName const KSCrashAppMemoryPressureChangedNotification = -@"KSCrashAppMemoryPressureChangedNotification"; +NSNotificationName const KSCrashAppMemoryLevelChangedNotification = @"KSCrashAppMemoryLevelChangedNotification"; +NSNotificationName const KSCrashAppMemoryPressureChangedNotification = @"KSCrashAppMemoryPressureChangedNotification"; NSString *const KSCrashAppMemoryNewValueKey = @"KSCrashAppMemoryNewValueKey"; NSString *const KSCrashAppMemoryOldValueKey = @"KSCrashAppMemoryOldValueKey"; diff --git a/Sources/KSCrashRecording/KSCrashAppMemoryTracker.m b/Sources/KSCrashRecording/KSCrashAppMemoryTracker.m index 7950ade12..c03565297 100644 --- a/Sources/KSCrashRecording/KSCrashAppMemoryTracker.m +++ b/Sources/KSCrashRecording/KSCrashAppMemoryTracker.m @@ -14,25 +14,25 @@ /** The memory tracker takes care of centralizing the knowledge around memory. It does the following: - + 1- Wraps memory pressure. This is more useful than `didReceiveMemoryWarning` as it vends different levels of pressure caused by the app as well as the rest of the OS. - + 2- Vends a memory level. This is pretty novel. It vends levels of where the app is wihtin the memory limit. - + Some useful info. - + Memory Pressure is mostly useful when the app is in the background. It helps understand how much `pressure` is on the app due to external concerns. Using this data, we can make informed decisions around the reasons the app might have been terminated. - + Memory Level is useful in the foreground as well as background. It indicates where the app is within its memory limit. That limit being calculated by the addition of `remaining` and `footprint`. Using this data, we can also make informed decisions around foreground and background memory terminations, aka. OOMs. - + See: https://github.com/naftaly/Footprint */ @@ -48,7 +48,7 @@ @interface KSCrashAppMemoryTracker () { dispatch_queue_t _heartbeatQueue; dispatch_source_t _pressureSource; dispatch_source_t _limitSource; - + os_unfair_lock _lock; uint64_t _footprint; KSCrashAppMemoryState _pressure; @@ -58,11 +58,11 @@ @interface KSCrashAppMemoryTracker () { @implementation KSCrashAppMemoryTracker -- (instancetype)init { +- (instancetype)init +{ if (self = [super init]) { _lock = OS_UNFAIR_LOCK_INIT; - _heartbeatQueue = dispatch_queue_create_with_target( - "com.kscrash.memory.heartbeat", DISPATCH_QUEUE_SERIAL, + _heartbeatQueue = dispatch_queue_create_with_target("com.kscrash.memory.heartbeat", DISPATCH_QUEUE_SERIAL, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)); _level = KSCrashAppMemoryStateNormal; _pressure = KSCrashAppMemoryStateNormal; @@ -70,38 +70,37 @@ - (instancetype)init { return self; } -- (void)dealloc { +- (void)dealloc +{ [self stop]; } -- (void)start { +- (void)start +{ // kill the old ones if (_pressureSource || _limitSource) { [self stop]; } - + // memory pressure uintptr_t mask = DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL; - _pressureSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, mask, - dispatch_get_main_queue()); - + _pressureSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, mask, dispatch_get_main_queue()); + __weak __typeof(self) weakMe = self; - + dispatch_source_set_event_handler(_pressureSource, ^{ [weakMe _memoryPressureChanged:YES]; }); dispatch_activate(_pressureSource); - + // memory limit (level) _limitSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _heartbeatQueue); dispatch_source_set_event_handler(_limitSource, ^{ [weakMe _heartbeat:YES]; }); - dispatch_source_set_timer(_limitSource, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC, - NSEC_PER_SEC / 10); + dispatch_source_set_timer(_limitSource, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC, NSEC_PER_SEC / 10); dispatch_activate(_limitSource); - - + #if KSCRASH_HAS_UIAPPLICATION // We won't always hit this depending on how the system is setup in the app, // but at least we can try. @@ -114,17 +113,19 @@ - (void)start { } #if KSCRASH_HAS_UIAPPLICATION -- (void)_appDidFinishLaunching { +- (void)_appDidFinishLaunching +{ [self _handleMemoryChange:[self currentAppMemory] type:KSCrashAppMemoryTrackerChangeTypeNone]; } #endif -- (void)stop { +- (void)stop +{ if (_pressureSource) { dispatch_source_cancel(_pressureSource); _pressureSource = nil; } - + if (_limitSource) { dispatch_source_cancel(_limitSource); _limitSource = nil; @@ -139,7 +140,7 @@ - (void)stop { if (err != KERN_SUCCESS) { return nil; } - + #if TARGET_OS_SIMULATOR // in simulator, remaining is always 0. So let's fake it. // How about a limit of 3GB. @@ -148,43 +149,43 @@ - (void)stop { #else uint64_t remaining = info.limit_bytes_remaining; #endif - - return [[KSCrashAppMemory alloc] initWithFootprint:info.phys_footprint - remaining:remaining - pressure:pressure]; + + return [[KSCrashAppMemory alloc] initWithFootprint:info.phys_footprint remaining:remaining pressure:pressure]; } -- (nullable KSCrashAppMemory *)currentAppMemory { +- (nullable KSCrashAppMemory *)currentAppMemory +{ return gMemoryProvider ? gMemoryProvider() : _ProvideCrashAppMemory(_pressure); } -- (void)_handleMemoryChange:(KSCrashAppMemory *)memory type:(KSCrashAppMemoryTrackerChangeType)changes { +- (void)_handleMemoryChange:(KSCrashAppMemory *)memory type:(KSCrashAppMemoryTrackerChangeType)changes +{ [self.delegate appMemoryTracker:self memory:memory changed:changes]; } // in case of unsigned values // ie: MAX(x,y) - MIN(x,y) -#define _KSABS_DIFF(x,y) x > y ? x - y : y - x +#define _KSABS_DIFF(x, y) x > y ? x - y : y - x -- (void)_heartbeat:(BOOL)sendObservers { - +- (void)_heartbeat:(BOOL)sendObservers +{ // This handles the memory limit. KSCrashAppMemory *memory = [self currentAppMemory]; - + KSCrashAppMemoryState newLevel = memory.level; uint64_t newFootprint = memory.footprint; - + KSCrashAppMemoryState oldLevel; BOOL footprintChanged = NO; { os_unfair_lock_lock(&_lock); - + oldLevel = _level; _level = newLevel; - + // the amount footprint needs to change for any footprint notifs. - const uint64_t kKSCrashFootprintMinChange = 1 << 20; // 1 MiB - + const uint64_t kKSCrashFootprintMinChange = 1 << 20; // 1 MiB + // For the footprint, we don't need very granular changes, // changing a few bytes here or there won't mke a difference, // we're looking for anything larger. @@ -192,33 +193,32 @@ - (void)_heartbeat:(BOOL)sendObservers { _footprint = newFootprint; footprintChanged = YES; } - + os_unfair_lock_unlock(&_lock); } - - KSCrashAppMemoryTrackerChangeType changes = (newLevel != oldLevel) ? KSCrashAppMemoryTrackerChangeTypeLevel : KSCrashAppMemoryTrackerChangeTypeNone; - + + KSCrashAppMemoryTrackerChangeType changes = + (newLevel != oldLevel) ? KSCrashAppMemoryTrackerChangeTypeLevel : KSCrashAppMemoryTrackerChangeTypeNone; + if (footprintChanged) { changes |= KSCrashAppMemoryTrackerChangeTypeFootprint; } - + if (changes != KSCrashAppMemoryTrackerChangeTypeNone) { [self _handleMemoryChange:memory type:changes]; } - + if (newLevel != oldLevel && sendObservers) { - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] - postNotificationName:KSCrashAppMemoryLevelChangedNotification - object:self - userInfo:@{ - KSCrashAppMemoryNewValueKey : @(newLevel), - KSCrashAppMemoryOldValueKey : @(oldLevel) - }]; + [[NSNotificationCenter defaultCenter] postNotificationName:KSCrashAppMemoryLevelChangedNotification + object:self + userInfo:@{ + KSCrashAppMemoryNewValueKey : @(newLevel), + KSCrashAppMemoryOldValueKey : @(oldLevel) + }]; }); #if TARGET_OS_SIMULATOR - + // On the simulator, if we're at a terminal level // let's fake an OOM by sending a SIGKILL signal // @@ -241,7 +241,8 @@ - (void)_heartbeat:(BOOL)sendObservers { } } -- (void)_memoryPressureChanged:(BOOL)sendObservers { +- (void)_memoryPressureChanged:(BOOL)sendObservers +{ // This handles system based memory pressure. KSCrashAppMemoryState newPressure = KSCrashAppMemoryStateNormal; dispatch_source_memorypressure_flags_t flags = dispatch_source_get_data(_pressureSource); @@ -249,16 +250,16 @@ - (void)_memoryPressureChanged:(BOOL)sendObservers { case DISPATCH_MEMORYPRESSURE_NORMAL: newPressure = KSCrashAppMemoryStateNormal; break; - + case DISPATCH_MEMORYPRESSURE_WARN: newPressure = KSCrashAppMemoryStateWarn; break; - + case DISPATCH_MEMORYPRESSURE_CRITICAL: newPressure = KSCrashAppMemoryStateCritical; break; } - + KSCrashAppMemoryState oldPressure; { os_unfair_lock_lock(&_lock); @@ -266,21 +267,20 @@ - (void)_memoryPressureChanged:(BOOL)sendObservers { _pressure = newPressure; os_unfair_lock_unlock(&_lock); } - + if (oldPressure != newPressure && sendObservers) { - [self _handleMemoryChange:[self currentAppMemory] - type:KSCrashAppMemoryTrackerChangeTypePressure]; - [[NSNotificationCenter defaultCenter] - postNotificationName:KSCrashAppMemoryPressureChangedNotification - object:self - userInfo:@{ - KSCrashAppMemoryNewValueKey : @(newPressure), - KSCrashAppMemoryOldValueKey : @(oldPressure) - }]; + [self _handleMemoryChange:[self currentAppMemory] type:KSCrashAppMemoryTrackerChangeTypePressure]; + [[NSNotificationCenter defaultCenter] postNotificationName:KSCrashAppMemoryPressureChangedNotification + object:self + userInfo:@{ + KSCrashAppMemoryNewValueKey : @(newPressure), + KSCrashAppMemoryOldValueKey : @(oldPressure) + }]; } } -- (KSCrashAppMemoryState)pressure { +- (KSCrashAppMemoryState)pressure +{ KSCrashAppMemoryState state; { os_unfair_lock_lock(&_lock); @@ -290,7 +290,8 @@ - (KSCrashAppMemoryState)pressure { return state; } -- (KSCrashAppMemoryState)level { +- (KSCrashAppMemoryState)level +{ KSCrashAppMemoryState state; { os_unfair_lock_lock(&_lock); diff --git a/Sources/KSCrashRecording/KSCrashAppStateTracker.m b/Sources/KSCrashRecording/KSCrashAppStateTracker.m index fe20e7b82..f785718c8 100644 --- a/Sources/KSCrashRecording/KSCrashAppStateTracker.m +++ b/Sources/KSCrashRecording/KSCrashAppStateTracker.m @@ -34,17 +34,27 @@ #import #endif -const char *ksapp_transitionStateToString(KSCrashAppTransitionState state) { +const char *ksapp_transitionStateToString(KSCrashAppTransitionState state) +{ switch (state) { - case KSCrashAppTransitionStateStartup: return "startup"; - case KSCrashAppTransitionStateStartupPrewarm: return "prewarm"; - case KSCrashAppTransitionStateActive: return "active"; - case KSCrashAppTransitionStateLaunching: return "launching"; - case KSCrashAppTransitionStateBackground: return "background"; - case KSCrashAppTransitionStateTerminating: return "terminating"; - case KSCrashAppTransitionStateExiting: return "exiting"; - case KSCrashAppTransitionStateDeactivating: return "deactivating"; - case KSCrashAppTransitionStateForegrounding: return "foregrounding"; + case KSCrashAppTransitionStateStartup: + return "startup"; + case KSCrashAppTransitionStateStartupPrewarm: + return "prewarm"; + case KSCrashAppTransitionStateActive: + return "active"; + case KSCrashAppTransitionStateLaunching: + return "launching"; + case KSCrashAppTransitionStateBackground: + return "background"; + case KSCrashAppTransitionStateTerminating: + return "terminating"; + case KSCrashAppTransitionStateExiting: + return "exiting"; + case KSCrashAppTransitionStateDeactivating: + return "deactivating"; + case KSCrashAppTransitionStateForegrounding: + return "foregrounding"; } return "unknown"; } @@ -57,7 +67,7 @@ bool ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionState state) case KSCrashAppTransitionStateTerminating: case KSCrashAppTransitionStateExiting: return NO; - + case KSCrashAppTransitionStateStartup: case KSCrashAppTransitionStateLaunching: case KSCrashAppTransitionStateForegrounding: @@ -70,10 +80,10 @@ bool ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionState state) @interface KSCrashAppStateTrackerBlockObserver : NSObject -@property (nonatomic, copy) KSCrashAppStateTrackerObserverBlock block; -@property (nonatomic, weak) id object; +@property(nonatomic, copy) KSCrashAppStateTrackerObserverBlock block; +@property(nonatomic, weak) id object; -@property (nonatomic, weak) KSCrashAppStateTracker *tracker; +@property(nonatomic, weak) KSCrashAppStateTracker *tracker; - (BOOL)shouldReap; @@ -81,13 +91,14 @@ - (BOOL)shouldReap; @implementation KSCrashAppStateTrackerBlockObserver -- (void)appStateTracker:(nonnull KSCrashAppStateTracker *)tracker didTransitionToState:(KSCrashAppTransitionState)transitionState +- (void)appStateTracker:(nonnull KSCrashAppStateTracker *)tracker + didTransitionToState:(KSCrashAppTransitionState)transitionState { KSCrashAppStateTrackerObserverBlock block = self.block; if (block) { block(transitionState); } - + id object = self.object; if (object) { [object appStateTracker:self.tracker didTransitionToState:transitionState]; @@ -102,10 +113,9 @@ - (BOOL)shouldReap @end @interface KSCrashAppStateTracker () { - NSNotificationCenter *_center; NSArray> *_registrations; - + // transition state and observers protected by the lock os_unfair_lock _lock; KSCrashAppTransitionState _transitionState; @@ -144,7 +154,7 @@ - (instancetype)initWithNotificationCenter:(NSNotificationCenter *)notificationC _observers = [NSMutableArray array]; _center = notificationCenter; _registrations = nil; - + BOOL isPrewarm = [NSProcessInfo.processInfo.environment[@"ActivePrewarm"] boolValue]; _transitionState = isPrewarm ? KSCrashAppTransitionStateStartupPrewarm : KSCrashAppTransitionStateStartup; } @@ -205,7 +215,7 @@ - (void)addObserver:(id)observer - (void)removeObserver:(id)observer { os_unfair_lock_lock(&_lock); - + // Observers added with a block if ([observer isKindOfClass:KSCrashAppStateTrackerBlockObserver.class]) { KSCrashAppStateTrackerBlockObserver *obs = (KSCrashAppStateTrackerBlockObserver *)observer; @@ -213,12 +223,12 @@ - (void)removeObserver:(id)observer obs.object = nil; [self _locked_reapObserversOrObject:nil]; } - + // observers added with an object else { [self _locked_reapObserversOrObject:observer]; } - + os_unfair_lock_unlock(&_lock); } @@ -244,17 +254,14 @@ - (void)_setTransitionState:(KSCrashAppTransitionState)transitionState } os_unfair_lock_unlock(&_lock); } - + for (id obs in observers) { [obs appStateTracker:self didTransitionToState:transitionState]; } } #define OBSERVE(center, name, block) \ -[center addObserverForName:name \ -object:nil \ -queue:nil \ -usingBlock:^(NSNotification *notification)block] \ + [center addObserverForName:name object:nil queue:nil usingBlock:^(NSNotification * notification) block] - (void)_exitCalled { @@ -270,42 +277,36 @@ - (void)start if (_registrations) { return; } - - __weak typeof(self)weakMe = self; - + + __weak typeof(self) weakMe = self; + // Register a normal `exit` callback so we don't think it's an OOM. atexit_b(^{ [weakMe _exitCalled]; }); - + #if KSCRASH_HAS_UIAPPLICATION - + // register all normal lifecycle events // in the future, we could also look at scene lifecycle // events but in reality, we don't actually need to, // it could just give us more granularity. _registrations = @[ - - OBSERVE(_center, UIApplicationDidFinishLaunchingNotification, { - [weakMe _setTransitionState:KSCrashAppTransitionStateLaunching]; - }), - OBSERVE(_center, UIApplicationWillEnterForegroundNotification, { - [weakMe _setTransitionState:KSCrashAppTransitionStateForegrounding]; - }), - OBSERVE(_center, UIApplicationDidBecomeActiveNotification, { - [weakMe _setTransitionState:KSCrashAppTransitionStateActive]; - }), - OBSERVE(_center, UIApplicationWillResignActiveNotification, { - [weakMe _setTransitionState:KSCrashAppTransitionStateDeactivating]; - }), - OBSERVE(_center, UIApplicationDidEnterBackgroundNotification, { - [weakMe _setTransitionState:KSCrashAppTransitionStateBackground]; - }), - OBSERVE(_center, UIApplicationWillTerminateNotification, { - [weakMe _setTransitionState:KSCrashAppTransitionStateTerminating]; - }), + + OBSERVE(_center, UIApplicationDidFinishLaunchingNotification, + { [weakMe _setTransitionState:KSCrashAppTransitionStateLaunching]; }), + OBSERVE(_center, UIApplicationWillEnterForegroundNotification, + { [weakMe _setTransitionState:KSCrashAppTransitionStateForegrounding]; }), + OBSERVE(_center, UIApplicationDidBecomeActiveNotification, + { [weakMe _setTransitionState:KSCrashAppTransitionStateActive]; }), + OBSERVE(_center, UIApplicationWillResignActiveNotification, + { [weakMe _setTransitionState:KSCrashAppTransitionStateDeactivating]; }), + OBSERVE(_center, UIApplicationDidEnterBackgroundNotification, + { [weakMe _setTransitionState:KSCrashAppTransitionStateBackground]; }), + OBSERVE(_center, UIApplicationWillTerminateNotification, + { [weakMe _setTransitionState:KSCrashAppTransitionStateTerminating]; }), ]; - + #else // on other platforms that don't have UIApplication // we simply state that the app is active in order to report OOMs. diff --git a/Sources/KSCrashRecording/KSCrashC.c b/Sources/KSCrashRecording/KSCrashC.c index 9a7232140..8c287c758 100644 --- a/Sources/KSCrashRecording/KSCrashC.c +++ b/Sources/KSCrashRecording/KSCrashC.c @@ -24,40 +24,38 @@ // THE SOFTWARE. // - #include "KSCrashC.h" #include "KSCrashCachedData.h" -#include "KSCrashReportC.h" -#include "KSCrashReportFixer.h" -#include "KSCrashReportStore.h" +#include "KSCrashMonitorContext.h" #include "KSCrashMonitorType.h" -#include "KSCrashMonitor_MachException.h" -#include "KSCrashMonitor_Signal.h" -#include "KSCrashMonitor_NSException.h" +#include "KSCrashMonitor_AppState.h" #include "KSCrashMonitor_CPPException.h" #include "KSCrashMonitor_Deadlock.h" -#include "KSCrashMonitor_User.h" +#include "KSCrashMonitor_MachException.h" #include "KSCrashMonitor_Memory.h" +#include "KSCrashMonitor_NSException.h" +#include "KSCrashMonitor_Signal.h" +#include "KSCrashMonitor_System.h" +#include "KSCrashMonitor_User.h" +#include "KSCrashMonitor_Zombie.h" +#include "KSCrashReportC.h" +#include "KSCrashReportFixer.h" +#include "KSCrashReportStore.h" #include "KSFileUtils.h" #include "KSObjC.h" #include "KSString.h" -#include "KSCrashMonitor_System.h" -#include "KSCrashMonitor_Zombie.h" -#include "KSCrashMonitor_AppState.h" -#include "KSCrashMonitorContext.h" #include "KSSystemCapabilities.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - +// #define KSLogger_LocalLevel TRACE #include #include #include #include -typedef enum -{ +#include "KSLogger.h" + +typedef enum { KSApplicationStateNone, KSApplicationStateDidBecomeActive, KSApplicationStateWillResignActiveActive, @@ -68,19 +66,17 @@ typedef enum static const struct KSCrashMonitorMapping { KSCrashMonitorType type; - KSCrashMonitorAPI* (*getAPI)(void); -} g_monitorMappings[] = { - {KSCrashMonitorTypeMachException, kscm_machexception_getAPI}, - {KSCrashMonitorTypeSignal, kscm_signal_getAPI}, - {KSCrashMonitorTypeCPPException, kscm_cppexception_getAPI}, - {KSCrashMonitorTypeNSException, kscm_nsexception_getAPI}, - {KSCrashMonitorTypeMainThreadDeadlock, kscm_deadlock_getAPI}, - {KSCrashMonitorTypeUserReported, kscm_user_getAPI}, - {KSCrashMonitorTypeSystem, kscm_system_getAPI}, - {KSCrashMonitorTypeApplicationState, kscm_appstate_getAPI}, - {KSCrashMonitorTypeZombie, kscm_zombie_getAPI}, - {KSCrashMonitorTypeMemoryTermination, kscm_memory_getAPI} -}; + KSCrashMonitorAPI *(*getAPI)(void); +} g_monitorMappings[] = { { KSCrashMonitorTypeMachException, kscm_machexception_getAPI }, + { KSCrashMonitorTypeSignal, kscm_signal_getAPI }, + { KSCrashMonitorTypeCPPException, kscm_cppexception_getAPI }, + { KSCrashMonitorTypeNSException, kscm_nsexception_getAPI }, + { KSCrashMonitorTypeMainThreadDeadlock, kscm_deadlock_getAPI }, + { KSCrashMonitorTypeUserReported, kscm_user_getAPI }, + { KSCrashMonitorTypeSystem, kscm_system_getAPI }, + { KSCrashMonitorTypeApplicationState, kscm_appstate_getAPI }, + { KSCrashMonitorTypeZombie, kscm_zombie_getAPI }, + { KSCrashMonitorTypeMemoryTermination, kscm_memory_getAPI } }; static const size_t g_monitorMappingCount = sizeof(g_monitorMappings) / sizeof(g_monitorMappings[0]); @@ -103,12 +99,11 @@ static KSApplicationState g_lastApplicationState = KSApplicationStateNone; #pragma mark - Utility - // ============================================================================ -static void printPreviousLog(const char* filePath) +static void printPreviousLog(const char *filePath) { - char* data; + char *data; int length; - if(ksfu_readEntireFile(filePath, &data, &length, 0)) - { + if (ksfu_readEntireFile(filePath, &data, &length, 0)) { printf("\nvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Previous Log vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\n"); printf("%s\n", data); free(data); @@ -120,8 +115,7 @@ static void printPreviousLog(const char* filePath) static void notifyOfBeforeInstallationState(void) { KSLOG_DEBUG("Notifying of pre-installation state"); - switch (g_lastApplicationState) - { + switch (g_lastApplicationState) { case KSApplicationStateDidBecomeActive: return kscrash_notifyAppActive(true); case KSApplicationStateWillResignActiveActive: @@ -145,7 +139,7 @@ static void notifyOfBeforeInstallationState(void) * * This function gets passed as a callback to a crash handler. */ -static void onCrash(struct KSCrash_MonitorContext* monitorContext) +static void onCrash(struct KSCrash_MonitorContext *monitorContext) { if (monitorContext->currentSnapshotUserReported == false) { KSLOG_DEBUG("Updating application state to note crash."); @@ -153,23 +147,17 @@ static void onCrash(struct KSCrash_MonitorContext* monitorContext) } monitorContext->consoleLogPath = g_shouldAddConsoleLogToReport ? g_consoleLogPath : NULL; - if(monitorContext->crashedDuringCrashHandling) - { + if (monitorContext->crashedDuringCrashHandling) { kscrashreport_writeRecrashReport(monitorContext, g_lastCrashReportFilePath); - } - else if (monitorContext->reportPath) - { + } else if (monitorContext->reportPath) { kscrashreport_writeStandardReport(monitorContext, monitorContext->reportPath); - } - else - { + } else { char crashReportFilePath[KSFU_MAX_PATH_LENGTH]; int64_t reportID = kscrs_getNextCrashReport(crashReportFilePath); strncpy(g_lastCrashReportFilePath, crashReportFilePath, sizeof(g_lastCrashReportFilePath)); kscrashreport_writeStandardReport(monitorContext, crashReportFilePath); - if(g_reportWrittenCallback) - { + if (g_reportWrittenCallback) { g_reportWrittenCallback(reportID); } } @@ -179,19 +167,13 @@ static void setMonitors(KSCrashMonitorType monitorTypes) { g_monitoring = monitorTypes; - if (g_installed) - { - for (size_t i = 0; i < g_monitorMappingCount; i++) - { - KSCrashMonitorAPI* api = g_monitorMappings[i].getAPI(); - if (api != NULL) - { - if (monitorTypes & g_monitorMappings[i].type) - { + if (g_installed) { + for (size_t i = 0; i < g_monitorMappingCount; i++) { + KSCrashMonitorAPI *api = g_monitorMappings[i].getAPI(); + if (api != NULL) { + if (monitorTypes & g_monitorMappings[i].type) { kscm_addMonitor(api); - } - else - { + } else { kscm_removeMonitor(api); } } @@ -199,10 +181,9 @@ static void setMonitors(KSCrashMonitorType monitorTypes) } } -void handleConfiguration(KSCrashCConfiguration* configuration) +void handleConfiguration(KSCrashCConfiguration *configuration) { - if (configuration->userInfoJSON != NULL) - { + if (configuration->userInfoJSON != NULL) { kscrashreport_setUserInfoJSON(configuration->userInfoJSON); } #if KSCRASH_HAS_OBJC @@ -211,9 +192,8 @@ void handleConfiguration(KSCrashCConfiguration* configuration) ksccd_setSearchQueueNames(configuration->enableQueueNameSearch); kscrashreport_setIntrospectMemory(configuration->enableMemoryIntrospection); - if (configuration->doNotIntrospectClasses.strings != NULL) - { - kscrashreport_setDoNotIntrospectClasses(configuration->doNotIntrospectClasses.strings, + if (configuration->doNotIntrospectClasses.strings != NULL) { + kscrashreport_setDoNotIntrospectClasses(configuration->doNotIntrospectClasses.strings, configuration->doNotIntrospectClasses.length); } @@ -223,8 +203,7 @@ void handleConfiguration(KSCrashCConfiguration* configuration) g_shouldPrintPreviousLog = configuration->printPreviousLogOnStartup; kscrs_setMaxReportCount(configuration->maxReportCount); - if (configuration->enableSwapCxaThrow) - { + if (configuration->enableSwapCxaThrow) { kscm_enableSwapCxaThrow(); } } @@ -232,12 +211,11 @@ void handleConfiguration(KSCrashCConfiguration* configuration) #pragma mark - API - // ============================================================================ -void kscrash_install(const char* appName, const char* const installPath, KSCrashCConfiguration configuration) +void kscrash_install(const char *appName, const char *const installPath, KSCrashCConfiguration configuration) { KSLOG_DEBUG("Installing crash reporter."); - if(g_installed) - { + if (g_installed) { KSLOG_DEBUG("Crash reporter already installed."); return; } @@ -253,17 +231,16 @@ void kscrash_install(const char* appName, const char* const installPath, KSCrash snprintf(path, sizeof(path), "%s/Data", installPath); ksfu_makePath(path); ksmemory_initialize(path); - + snprintf(path, sizeof(path), "%s/Data/CrashState.json", installPath); kscrashstate_initialize(path); snprintf(g_consoleLogPath, sizeof(g_consoleLogPath), "%s/Data/ConsoleLog.txt", installPath); - if(g_shouldPrintPreviousLog) - { + if (g_shouldPrintPreviousLog) { printPreviousLog(g_consoleLogPath); } kslog_setLogFilename(g_consoleLogPath, true); - + ksccd_init(60); kscm_setEventCallback(onCrash); @@ -275,125 +252,84 @@ void kscrash_install(const char* appName, const char* const installPath, KSCrash notifyOfBeforeInstallationState(); } -void kscrash_setUserInfoJSON(const char* const userInfoJSON) -{ - kscrashreport_setUserInfoJSON(userInfoJSON); -} +void kscrash_setUserInfoJSON(const char *const userInfoJSON) { kscrashreport_setUserInfoJSON(userInfoJSON); } -const char* kscrash_getUserInfoJSON(void) -{ - return kscrashreport_getUserInfoJSON(); -} +const char *kscrash_getUserInfoJSON(void) { return kscrashreport_getUserInfoJSON(); } -void kscrash_reportUserException(const char* name, - const char* reason, - const char* language, - const char* lineOfCode, - const char* stackTrace, - bool logAllThreads, - bool terminateProgram) +void kscrash_reportUserException(const char *name, const char *reason, const char *language, const char *lineOfCode, + const char *stackTrace, bool logAllThreads, bool terminateProgram) { - kscm_reportUserException(name, - reason, - language, - lineOfCode, - stackTrace, - logAllThreads, - terminateProgram); - if(g_shouldAddConsoleLogToReport) - { + kscm_reportUserException(name, reason, language, lineOfCode, stackTrace, logAllThreads, terminateProgram); + if (g_shouldAddConsoleLogToReport) { kslog_clearLogFile(); } } -void kscrash_notifyObjCLoad(void) -{ - kscrashstate_notifyObjCLoad(); -} +void kscrash_notifyObjCLoad(void) { kscrashstate_notifyObjCLoad(); } void kscrash_notifyAppActive(bool isActive) { - if (g_installed) - { + if (g_installed) { kscrashstate_notifyAppActive(isActive); } - g_lastApplicationState = isActive - ? KSApplicationStateDidBecomeActive - : KSApplicationStateWillResignActiveActive; + g_lastApplicationState = isActive ? KSApplicationStateDidBecomeActive : KSApplicationStateWillResignActiveActive; } void kscrash_notifyAppInForeground(bool isInForeground) { - if (g_installed) - { + if (g_installed) { kscrashstate_notifyAppInForeground(isInForeground); } - g_lastApplicationState = isInForeground - ? KSApplicationStateWillEnterForeground - : KSApplicationStateDidEnterBackground; + g_lastApplicationState = + isInForeground ? KSApplicationStateWillEnterForeground : KSApplicationStateDidEnterBackground; } void kscrash_notifyAppTerminate(void) { - if (g_installed) - { + if (g_installed) { kscrashstate_notifyAppTerminate(); } g_lastApplicationState = KSApplicationStateWillTerminate; } -void kscrash_notifyAppCrash(void) -{ - kscrashstate_notifyAppCrash(); -} +void kscrash_notifyAppCrash(void) { kscrashstate_notifyAppCrash(); } -int kscrash_getReportCount(void) -{ - return kscrs_getReportCount(); -} +int kscrash_getReportCount(void) { return kscrs_getReportCount(); } -int kscrash_getReportIDs(int64_t* reportIDs, int count) -{ - return kscrs_getReportIDs(reportIDs, count); -} +int kscrash_getReportIDs(int64_t *reportIDs, int count) { return kscrs_getReportIDs(reportIDs, count); } -char* kscrash_readReportAtPath(const char* path) +char *kscrash_readReportAtPath(const char *path) { - if(!path) - { + if (!path) { return NULL; } - - char* rawReport = kscrs_readReportAtPath(path); - if(rawReport == NULL) - { + + char *rawReport = kscrs_readReportAtPath(path); + if (rawReport == NULL) { return NULL; } - - char* fixedReport = kscrf_fixupCrashReport(rawReport); + + char *fixedReport = kscrf_fixupCrashReport(rawReport); free(rawReport); return fixedReport; } -char* kscrash_readReport(int64_t reportID) +char *kscrash_readReport(int64_t reportID) { - if(reportID <= 0) - { + if (reportID <= 0) { KSLOG_ERROR("Report ID was %" PRIx64, reportID); return NULL; } - char* rawReport = kscrs_readReport(reportID); - if(rawReport == NULL) - { + char *rawReport = kscrs_readReport(reportID); + if (rawReport == NULL) { KSLOG_ERROR("Failed to load report ID %" PRIx64, reportID); return NULL; } - char* fixedReport = kscrf_fixupCrashReport(rawReport); - if(fixedReport == NULL) - { + char *fixedReport = kscrf_fixupCrashReport(rawReport); + if (fixedReport == NULL) { KSLOG_ERROR("Failed to fixup report ID %" PRIx64, reportID); } @@ -401,17 +337,11 @@ char* kscrash_readReport(int64_t reportID) return fixedReport; } -int64_t kscrash_addUserReport(const char* report, int reportLength) +int64_t kscrash_addUserReport(const char *report, int reportLength) { return kscrs_addUserReport(report, reportLength); } -void kscrash_deleteAllReports(void) -{ - kscrs_deleteAllReports(); -} +void kscrash_deleteAllReports(void) { kscrs_deleteAllReports(); } -void kscrash_deleteReportWithID(int64_t reportID) -{ - kscrs_deleteReportWithID(reportID); -} +void kscrash_deleteReportWithID(int64_t reportID) { kscrs_deleteReportWithID(reportID); } diff --git a/Sources/KSCrashRecording/KSCrashCachedData.c b/Sources/KSCrashRecording/KSCrashCachedData.c index 3fc996926..e52688250 100644 --- a/Sources/KSCrashRecording/KSCrashCachedData.c +++ b/Sources/KSCrashRecording/KSCrashCachedData.c @@ -22,34 +22,32 @@ // THE SOFTWARE. // - #include "KSCrashCachedData.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - -#include +// #define KSLogger_LocalLevel TRACE #include +#include #include #include -#include #include +#include #include +#include "KSLogger.h" #define SWAP_POINTERS(A, B) \ -{ \ - void* temp = A; \ - A = B; \ - B = temp; \ -} + { \ + void *temp = A; \ + A = B; \ + B = temp; \ + } static int g_pollingIntervalInSeconds; static pthread_t g_cacheThread; -static KSThread* g_allMachThreads; -static KSThread* g_allPThreads; -static const char** g_allThreadNames; -static const char** g_allQueueNames; +static KSThread *g_allMachThreads; +static KSThread *g_allPThreads; +static const char **g_allThreadNames; +static const char **g_allQueueNames; static int g_allThreadsCount; static _Atomic(int) g_semaphoreCount; static bool g_searchQueueNames = false; @@ -59,16 +57,15 @@ static void updateThreadList(void) { const task_t thisTask = mach_task_self(); int oldThreadsCount = g_allThreadsCount; - KSThread* allMachThreads = NULL; - KSThread* allPThreads = NULL; - static const char** allThreadNames; - static const char** allQueueNames; + KSThread *allMachThreads = NULL; + KSThread *allPThreads = NULL; + static const char **allThreadNames; + static const char **allQueueNames; mach_msg_type_number_t allThreadsCount; thread_act_array_t threads; kern_return_t kr; - if((kr = task_threads(thisTask, &threads, &allThreadsCount)) != KERN_SUCCESS) - { + if ((kr = task_threads(thisTask, &threads, &allThreadsCount)) != KERN_SUCCESS) { KSLOG_ERROR("task_threads: %s", mach_error_string(kr)); return; } @@ -77,24 +74,21 @@ static void updateThreadList(void) allPThreads = calloc(allThreadsCount, sizeof(*allPThreads)); allThreadNames = calloc(allThreadsCount, sizeof(*allThreadNames)); allQueueNames = calloc(allThreadsCount, sizeof(*allQueueNames)); - - for(mach_msg_type_number_t i = 0; i < allThreadsCount; i++) - { + + for (mach_msg_type_number_t i = 0; i < allThreadsCount; i++) { char buffer[1000]; thread_t thread = threads[i]; pthread_t pthread = pthread_from_mach_thread_np(thread); allMachThreads[i] = (KSThread)thread; allPThreads[i] = (KSThread)pthread; - if(pthread != 0 && pthread_getname_np(pthread, buffer, sizeof(buffer)) == 0 && buffer[0] != 0) - { + if (pthread != 0 && pthread_getname_np(pthread, buffer, sizeof(buffer)) == 0 && buffer[0] != 0) { allThreadNames[i] = strdup(buffer); } - if(g_searchQueueNames && ksthread_getQueueName((KSThread)thread, buffer, sizeof(buffer)) && buffer[0] != 0) - { + if (g_searchQueueNames && ksthread_getQueueName((KSThread)thread, buffer, sizeof(buffer)) && buffer[0] != 0) { allQueueNames[i] = strdup(buffer); } } - + g_allThreadsCount = g_allThreadsCount < (int)allThreadsCount ? g_allThreadsCount : (int)allThreadsCount; SWAP_POINTERS(g_allMachThreads, allMachThreads); SWAP_POINTERS(g_allPThreads, allPThreads); @@ -102,59 +96,47 @@ static void updateThreadList(void) SWAP_POINTERS(g_allQueueNames, allQueueNames); g_allThreadsCount = (int)allThreadsCount; - if(allMachThreads != NULL) - { + if (allMachThreads != NULL) { free(allMachThreads); } - if(allPThreads != NULL) - { + if (allPThreads != NULL) { free(allPThreads); } - if(allThreadNames != NULL) - { - for(int i = 0; i < oldThreadsCount; i++) - { - const char* name = allThreadNames[i]; - if(name != NULL) - { - free((void*)name); + if (allThreadNames != NULL) { + for (int i = 0; i < oldThreadsCount; i++) { + const char *name = allThreadNames[i]; + if (name != NULL) { + free((void *)name); } } free(allThreadNames); } - if(allQueueNames != NULL) - { - for(int i = 0; i < oldThreadsCount; i++) - { - const char* name = allQueueNames[i]; - if(name != NULL) - { - free((void*)name); + if (allQueueNames != NULL) { + for (int i = 0; i < oldThreadsCount; i++) { + const char *name = allQueueNames[i]; + if (name != NULL) { + free((void *)name); } } free(allQueueNames); } - - for(mach_msg_type_number_t i = 0; i < allThreadsCount; i++) - { + + for (mach_msg_type_number_t i = 0; i < allThreadsCount; i++) { mach_port_deallocate(thisTask, threads[i]); } vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * allThreadsCount); } -static void* monitorCachedData(__unused void* const userData) +static void *monitorCachedData(__unused void *const userData) { static int quickPollCount = 4; usleep(1); - for(;;) - { - if(g_semaphoreCount <= 0) - { + for (;;) { + if (g_semaphoreCount <= 0) { updateThreadList(); } unsigned pollintInterval = (unsigned)g_pollingIntervalInSeconds; - if(quickPollCount > 0) - { + if (quickPollCount > 0) { // Lots can happen in the first few seconds of operation. quickPollCount--; pollintInterval = 1; @@ -167,19 +149,15 @@ static void* monitorCachedData(__unused void* const userData) void ksccd_init(int pollingIntervalInSeconds) { if (g_hasThreadStarted == true) { - return ; + return; } g_hasThreadStarted = true; g_pollingIntervalInSeconds = pollingIntervalInSeconds; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - int error = pthread_create(&g_cacheThread, - &attr, - &monitorCachedData, - "KSCrash Cached Data Monitor"); - if(error != 0) - { + int error = pthread_create(&g_cacheThread, &attr, &monitorCachedData, "KSCrash Cached Data Monitor"); + if (error != 0) { KSLOG_ERROR("pthread_create_suspended_np: %s", strerror(error)); } pthread_attr_destroy(&attr); @@ -187,8 +165,7 @@ void ksccd_init(int pollingIntervalInSeconds) void ksccd_freeze(void) { - if(g_semaphoreCount++ <= 0) - { + if (g_semaphoreCount++ <= 0) { // Sleep just in case the cached data thread is in the middle of an update. usleep(1); } @@ -196,35 +173,27 @@ void ksccd_freeze(void) void ksccd_unfreeze(void) { - if(--g_semaphoreCount < 0) - { + if (--g_semaphoreCount < 0) { // Handle extra calls to unfreeze somewhat gracefully. g_semaphoreCount++; } } -void ksccd_setSearchQueueNames(bool searchQueueNames) -{ - g_searchQueueNames = searchQueueNames; -} +void ksccd_setSearchQueueNames(bool searchQueueNames) { g_searchQueueNames = searchQueueNames; } -KSThread* ksccd_getAllThreads(int* threadCount) +KSThread *ksccd_getAllThreads(int *threadCount) { - if(threadCount != NULL) - { + if (threadCount != NULL) { *threadCount = g_allThreadsCount; } return g_allMachThreads; } -const char* ksccd_getThreadName(KSThread thread) +const char *ksccd_getThreadName(KSThread thread) { - if(g_allThreadNames != NULL) - { - for(int i = 0; i < g_allThreadsCount; i++) - { - if(g_allMachThreads[i] == thread) - { + if (g_allThreadNames != NULL) { + for (int i = 0; i < g_allThreadsCount; i++) { + if (g_allMachThreads[i] == thread) { return g_allThreadNames[i]; } } @@ -232,14 +201,11 @@ const char* ksccd_getThreadName(KSThread thread) return NULL; } -const char* ksccd_getQueueName(KSThread thread) +const char *ksccd_getQueueName(KSThread thread) { - if(g_allQueueNames != NULL) - { - for(int i = 0; i < g_allThreadsCount; i++) - { - if(g_allMachThreads[i] == thread) - { + if (g_allQueueNames != NULL) { + for (int i = 0; i < g_allThreadsCount; i++) { + if (g_allMachThreads[i] == thread) { return g_allQueueNames[i]; } } diff --git a/Sources/KSCrashRecording/KSCrashCachedData.h b/Sources/KSCrashRecording/KSCrashCachedData.h index 0becbd6f9..abbb70167 100644 --- a/Sources/KSCrashRecording/KSCrashCachedData.h +++ b/Sources/KSCrashRecording/KSCrashCachedData.h @@ -22,11 +22,9 @@ // THE SOFTWARE. // - /* Maintains a cache of difficult-to-retrieve data. */ - #include "KSThread.h" void ksccd_init(int pollingIntervalInSeconds); @@ -36,8 +34,8 @@ void ksccd_unfreeze(void); void ksccd_setSearchQueueNames(bool searchQueueNames); -KSThread* ksccd_getAllThreads(int* threadCount); +KSThread *ksccd_getAllThreads(int *threadCount); -const char* ksccd_getThreadName(KSThread thread); +const char *ksccd_getThreadName(KSThread thread); -const char* ksccd_getQueueName(KSThread thread); +const char *ksccd_getQueueName(KSThread thread); diff --git a/Sources/KSCrashRecording/KSCrashConfiguration+Private.h b/Sources/KSCrashRecording/KSCrashConfiguration+Private.h index 0ba50ce72..050749481 100644 --- a/Sources/KSCrashRecording/KSCrashConfiguration+Private.h +++ b/Sources/KSCrashRecording/KSCrashConfiguration+Private.h @@ -27,10 +27,10 @@ #ifndef KSCrashConfiguration_Private_h #define KSCrashConfiguration_Private_h -#import "KSCrashConfiguration.h" #import "KSCrashCConfiguration.h" +#import "KSCrashConfiguration.h" -@interface KSCrashConfiguration() +@interface KSCrashConfiguration () - (KSCrashCConfiguration)toCConfiguration; diff --git a/Sources/KSCrashRecording/KSCrashConfiguration.m b/Sources/KSCrashRecording/KSCrashConfiguration.m index 19d648912..7c554beae 100644 --- a/Sources/KSCrashRecording/KSCrashConfiguration.m +++ b/Sources/KSCrashRecording/KSCrashConfiguration.m @@ -33,23 +33,18 @@ @implementation KSCrashConfiguration - (instancetype)init { self = [super init]; - if (self) - { + if (self) { KSCrashCConfiguration cConfig = KSCrashCConfiguration_Default(); _monitors = cConfig.monitors; - if (cConfig.userInfoJSON != NULL) - { + if (cConfig.userInfoJSON != NULL) { NSData *data = [NSData dataWithBytes:cConfig.userInfoJSON length:strlen(cConfig.userInfoJSON)]; NSError *error = nil; _userInfoJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; - if (error) - { + if (error) { _userInfoJSON = nil; // Handle the error appropriately } - } - else - { + } else { _userInfoJSON = nil; } @@ -94,44 +89,43 @@ - (KSCrashCConfiguration)toCConfiguration return config; } -- (const char**)createCStringArrayFromNSArray:(NSArray*)nsArray +- (const char **)createCStringArrayFromNSArray:(NSArray *)nsArray { if (!nsArray) return NULL; - const char** cArray = malloc(sizeof(char*) * [nsArray count]); - for (NSUInteger i = 0; i < [nsArray count]; i++) - { + const char **cArray = malloc(sizeof(char *) * [nsArray count]); + for (NSUInteger i = 0; i < [nsArray count]; i++) { cArray[i] = strdup([nsArray[i] UTF8String]); } return cArray; } -- (const char*)jsonStringFromDictionary:(NSDictionary*)dictionary +- (const char *)jsonStringFromDictionary:(NSDictionary *)dictionary { - NSError* error; - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error]; - if (!jsonData) - { + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error]; + if (!jsonData) { NSLog(@"Error converting dictionary to JSON: %@", error.localizedDescription); return NULL; } - const char* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding].UTF8String; + const char *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding].UTF8String; return strdup(jsonString); // strdup to ensure it's a copy that's safe to free later } #pragma mark - NSCopying -- (nonnull id)copyWithZone:(nullable NSZone*)zone +- (nonnull id)copyWithZone:(nullable NSZone *)zone { - KSCrashConfiguration* copy = [[KSCrashConfiguration allocWithZone:zone] init]; + KSCrashConfiguration *copy = [[KSCrashConfiguration allocWithZone:zone] init]; copy.monitors = self.monitors; copy.userInfoJSON = [self.userInfoJSON copyWithZone:zone]; copy.deadlockWatchdogInterval = self.deadlockWatchdogInterval; copy.enableQueueNameSearch = self.enableQueueNameSearch; copy.enableMemoryIntrospection = self.enableMemoryIntrospection; - copy.doNotIntrospectClasses = self.doNotIntrospectClasses - ? [[NSArray allocWithZone:zone] initWithArray:self.doNotIntrospectClasses copyItems:YES] - : nil; + copy.doNotIntrospectClasses = self.doNotIntrospectClasses + ? [[NSArray allocWithZone:zone] initWithArray:self.doNotIntrospectClasses + copyItems:YES] + : nil; copy.crashNotifyCallback = [self.crashNotifyCallback copy]; copy.reportWrittenCallback = [self.reportWrittenCallback copy]; copy.addConsoleLogToReport = self.addConsoleLogToReport; diff --git a/Sources/KSCrashRecording/KSCrashDoctor.h b/Sources/KSCrashRecording/KSCrashDoctor.h index abac9373c..76f37bb49 100644 --- a/Sources/KSCrashRecording/KSCrashDoctor.h +++ b/Sources/KSCrashRecording/KSCrashDoctor.h @@ -10,8 +10,8 @@ @interface KSCrashDoctor : NSObject -+ (KSCrashDoctor*) doctor; ++ (KSCrashDoctor *)doctor; -- (NSString*) diagnoseCrash:(NSDictionary*) crashReport; +- (NSString *)diagnoseCrash:(NSDictionary *)crashReport; @end diff --git a/Sources/KSCrashRecording/KSCrashDoctor.m b/Sources/KSCrashRecording/KSCrashDoctor.m index 461b2c124..54e1fcef3 100644 --- a/Sources/KSCrashRecording/KSCrashDoctor.m +++ b/Sources/KSCrashRecording/KSCrashDoctor.m @@ -7,26 +7,19 @@ // #import "KSCrashDoctor.h" -#import "KSCrashReportFields.h" #import "KSCrashMonitor_System.h" +#import "KSCrashReportFields.h" +typedef enum { CPUFamilyUnknown, CPUFamilyArm, CPUFamilyX86, CPUFamilyX86_64 } CPUFamily; -typedef enum -{ - CPUFamilyUnknown, - CPUFamilyArm, - CPUFamilyX86, - CPUFamilyX86_64 -} CPUFamily; - -@interface KSCrashDoctorParam: NSObject +@interface KSCrashDoctorParam : NSObject -@property(nonatomic, readwrite, retain) NSString* className; -@property(nonatomic, readwrite, retain) NSString* previousClassName; -@property(nonatomic, readwrite, retain) NSString* type; +@property(nonatomic, readwrite, retain) NSString *className; +@property(nonatomic, readwrite, retain) NSString *previousClassName; +@property(nonatomic, readwrite, retain) NSString *type; @property(nonatomic, readwrite, assign) BOOL isInstance; @property(nonatomic, readwrite, assign) uintptr_t address; -@property(nonatomic, readwrite, retain) NSString* value; +@property(nonatomic, readwrite, retain) NSString *value; @end @@ -41,10 +34,10 @@ @implementation KSCrashDoctorParam @end -@interface KSCrashDoctorFunctionCall: NSObject +@interface KSCrashDoctorFunctionCall : NSObject -@property(nonatomic, readwrite, retain) NSString* name; -@property(nonatomic, readwrite, retain) NSArray* params; +@property(nonatomic, readwrite, retain) NSString *name; +@property(nonatomic, readwrite, retain) NSArray *params; @end @@ -53,68 +46,49 @@ @implementation KSCrashDoctorFunctionCall @synthesize name = _name; @synthesize params = _params; -- (NSString*) descriptionForObjCCall +- (NSString *)descriptionForObjCCall { - if(![self.name isEqualToString:@"objc_msgSend"]) - { + if (![self.name isEqualToString:@"objc_msgSend"]) { return nil; } - KSCrashDoctorParam* receiverParam = [self.params objectAtIndex:0]; - NSString* receiver = receiverParam.previousClassName; - if(receiver == nil) - { + KSCrashDoctorParam *receiverParam = [self.params objectAtIndex:0]; + NSString *receiver = receiverParam.previousClassName; + if (receiver == nil) { receiver = receiverParam.className; - if(receiver == nil) - { + if (receiver == nil) { receiver = @"id"; } } - KSCrashDoctorParam* selectorParam = [self.params objectAtIndex:1]; - if(![selectorParam.type isEqualToString:KSCrashMemType_String]) - { + KSCrashDoctorParam *selectorParam = [self.params objectAtIndex:1]; + if (![selectorParam.type isEqualToString:KSCrashMemType_String]) { return nil; } - NSArray* splitSelector = [selectorParam.value componentsSeparatedByString:@":"]; + NSArray *splitSelector = [selectorParam.value componentsSeparatedByString:@":"]; int paramCount = (int)splitSelector.count - 1; - NSMutableString* string = [NSMutableString stringWithFormat:@"-[%@ %@", receiver, [splitSelector objectAtIndex:0]]; - for(int paramNum = 0; paramNum < paramCount; paramNum++) - { + NSMutableString *string = [NSMutableString stringWithFormat:@"-[%@ %@", receiver, [splitSelector objectAtIndex:0]]; + for (int paramNum = 0; paramNum < paramCount; paramNum++) { [string appendString:@":"]; - if(paramNum < 2) - { - KSCrashDoctorParam* param = [self.params objectAtIndex:(NSUInteger)paramNum + 2]; - if(param.value != nil) - { - if([param.type isEqualToString:KSCrashMemType_String]) - { + if (paramNum < 2) { + KSCrashDoctorParam *param = [self.params objectAtIndex:(NSUInteger)paramNum + 2]; + if (param.value != nil) { + if ([param.type isEqualToString:KSCrashMemType_String]) { [string appendFormat:@"\"%@\"", param.value]; - } - else - { + } else { [string appendString:param.value]; } - } - else if(param.previousClassName != nil) - { + } else if (param.previousClassName != nil) { [string appendString:param.previousClassName]; - } - else if(param.className != nil) - { + } else if (param.className != nil) { [string appendFormat:@"%@ (%@)", param.className, param.isInstance ? @"instance" : @"class"]; - } - else - { + } else { [string appendString:@"?"]; } - } - else - { + } else { [string appendString:@"?"]; } - if(paramNum < paramCount - 1) - { + if (paramNum < paramCount - 1) { [string appendString:@" "]; } } @@ -123,38 +97,31 @@ - (NSString*) descriptionForObjCCall return string; } -- (NSString*) descriptionWithParamCount:(int) paramCount +- (NSString *)descriptionWithParamCount:(int)paramCount { - NSString* objCCall = [self descriptionForObjCCall]; - if(objCCall != nil) - { + NSString *objCCall = [self descriptionForObjCCall]; + if (objCCall != nil) { return objCCall; } - if(paramCount > (int)self.params.count) - { + if (paramCount > (int)self.params.count) { paramCount = (int)self.params.count; } - NSMutableString* str = [NSMutableString string]; + NSMutableString *str = [NSMutableString string]; [str appendFormat:@"Function: %@\n", self.name]; - for(int i = 0; i < paramCount; i++) - { - KSCrashDoctorParam* param = [self.params objectAtIndex:(NSUInteger)i]; + for (int i = 0; i < paramCount; i++) { + KSCrashDoctorParam *param = [self.params objectAtIndex:(NSUInteger)i]; [str appendFormat:@"Param %d: ", i + 1]; - if(param.className != nil) - { + if (param.className != nil) { [str appendFormat:@"%@ (%@) ", param.className, param.isInstance ? @"instance" : @"class"]; } - if(param.value != nil) - { + if (param.value != nil) { [str appendFormat:@"%@ ", param.value]; } - if(param.previousClassName != nil) - { + if (param.previousClassName != nil) { [str appendFormat:@"(was %@)", param.previousClassName]; } - if(i < paramCount - 1) - { + if (i < paramCount - 1) { [str appendString:@"\n"]; } } @@ -163,50 +130,46 @@ - (NSString*) descriptionWithParamCount:(int) paramCount @end - - @implementation KSCrashDoctor -+ (KSCrashDoctor*) doctor ++ (KSCrashDoctor *)doctor { return [[self alloc] init]; } -- (NSDictionary*) recrashReport:(NSDictionary*) report +- (NSDictionary *)recrashReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_RecrashReport]; } -- (NSDictionary*) systemReport:(NSDictionary*) report +- (NSDictionary *)systemReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_System]; } -- (NSDictionary*) crashReport:(NSDictionary*) report +- (NSDictionary *)crashReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_Crash]; } -- (NSDictionary*) infoReport:(NSDictionary*) report +- (NSDictionary *)infoReport:(NSDictionary *)report { return [report objectForKey:KSCrashField_Report]; } -- (NSDictionary*) errorReport:(NSDictionary*) report +- (NSDictionary *)errorReport:(NSDictionary *)report { return [[self crashReport:report] objectForKey:KSCrashField_Error]; } -- (CPUFamily) cpuFamily:(NSDictionary*) report +- (CPUFamily)cpuFamily:(NSDictionary *)report { - NSDictionary* system = [self systemReport:report]; - NSString* cpuArch = [system objectForKey:KSCrashField_CPUArch]; - if([cpuArch rangeOfString:@"arm"].location == 0) - { + NSDictionary *system = [self systemReport:report]; + NSString *cpuArch = [system objectForKey:KSCrashField_CPUArch]; + if ([cpuArch rangeOfString:@"arm"].location == 0) { return CPUFamilyArm; } - if([cpuArch rangeOfString:@"i"].location == 0 && [cpuArch rangeOfString:@"86"].location == 2) - { + if ([cpuArch rangeOfString:@"i"].location == 0 && [cpuArch rangeOfString:@"86"].location == 2) { return CPUFamilyX86; } if ([cpuArch rangeOfString:@"x86_64" options:NSCaseInsensitiveSearch].location != NSNotFound) { @@ -215,14 +178,11 @@ - (CPUFamily) cpuFamily:(NSDictionary*) report return CPUFamilyUnknown; } -- (NSString*) registerNameForFamily:(CPUFamily) family paramIndex:(int) index +- (NSString *)registerNameForFamily:(CPUFamily)family paramIndex:(int)index { - switch (family) - { - case CPUFamilyArm: - { - switch(index) - { + switch (family) { + case CPUFamilyArm: { + switch (index) { case 0: return @"r0"; case 1: @@ -233,10 +193,8 @@ - (NSString*) registerNameForFamily:(CPUFamily) family paramIndex:(int) index return @"r3"; } } - case CPUFamilyX86: - { - switch(index) - { + case CPUFamilyX86: { + switch (index) { case 0: return @"edi"; case 1: @@ -247,10 +205,8 @@ - (NSString*) registerNameForFamily:(CPUFamily) family paramIndex:(int) index return @"ecx"; } } - case CPUFamilyX86_64: - { - switch(index) - { + case CPUFamilyX86_64: { + switch (index) { case 0: return @"rdi"; case 1: @@ -267,138 +223,121 @@ - (NSString*) registerNameForFamily:(CPUFamily) family paramIndex:(int) index return nil; } -- (NSString*) mainExecutableNameForReport:(NSDictionary*) report +- (NSString *)mainExecutableNameForReport:(NSDictionary *)report { - NSDictionary* info = [self infoReport:report]; + NSDictionary *info = [self infoReport:report]; return [info objectForKey:KSCrashField_ProcessName]; } -- (NSDictionary*) crashedThreadReport:(NSDictionary*) report +- (NSDictionary *)crashedThreadReport:(NSDictionary *)report { - NSDictionary* crashReport = [self crashReport:report]; - NSDictionary* crashedThread = [crashReport objectForKey:KSCrashField_CrashedThread]; - if(crashedThread != nil) - { + NSDictionary *crashReport = [self crashReport:report]; + NSDictionary *crashedThread = [crashReport objectForKey:KSCrashField_CrashedThread]; + if (crashedThread != nil) { return crashedThread; } - for(NSDictionary* thread in [crashReport objectForKey:KSCrashField_Threads]) - { - if([[thread objectForKey:KSCrashField_Crashed] boolValue]) - { + for (NSDictionary *thread in [crashReport objectForKey:KSCrashField_Threads]) { + if ([[thread objectForKey:KSCrashField_Crashed] boolValue]) { return thread; } } return nil; } -- (NSArray*) backtraceFromThreadReport:(NSDictionary*) threadReport +- (NSArray *)backtraceFromThreadReport:(NSDictionary *)threadReport { - NSDictionary* backtrace = [threadReport objectForKey:KSCrashField_Backtrace]; + NSDictionary *backtrace = [threadReport objectForKey:KSCrashField_Backtrace]; return [backtrace objectForKey:KSCrashField_Contents]; } -- (NSDictionary*) basicRegistersFromThreadReport:(NSDictionary*) threadReport +- (NSDictionary *)basicRegistersFromThreadReport:(NSDictionary *)threadReport { - NSDictionary* registers = [threadReport objectForKey:KSCrashField_Registers]; - NSDictionary* basic = [registers objectForKey:KSCrashField_Basic]; + NSDictionary *registers = [threadReport objectForKey:KSCrashField_Registers]; + NSDictionary *basic = [registers objectForKey:KSCrashField_Basic]; return basic; } -- (NSDictionary*) lastInAppStackEntry:(NSDictionary*) report +- (NSDictionary *)lastInAppStackEntry:(NSDictionary *)report { - NSString* executableName = [self mainExecutableNameForReport:report]; - NSDictionary* crashedThread = [self crashedThreadReport:report]; - NSArray* backtrace = [self backtraceFromThreadReport:crashedThread]; - for(NSDictionary* entry in backtrace) - { - NSString* objectName = [entry objectForKey:KSCrashField_ObjectName]; - if([objectName isEqualToString:executableName]) - { + NSString *executableName = [self mainExecutableNameForReport:report]; + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSArray *backtrace = [self backtraceFromThreadReport:crashedThread]; + for (NSDictionary *entry in backtrace) { + NSString *objectName = [entry objectForKey:KSCrashField_ObjectName]; + if ([objectName isEqualToString:executableName]) { return entry; } } return nil; } -- (NSDictionary*) lastStackEntry:(NSDictionary*) report +- (NSDictionary *)lastStackEntry:(NSDictionary *)report { - NSDictionary* crashedThread = [self crashedThreadReport:report]; - NSArray* backtrace = [self backtraceFromThreadReport:crashedThread]; - if([backtrace count] > 0) - { + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSArray *backtrace = [self backtraceFromThreadReport:crashedThread]; + if ([backtrace count] > 0) { return [backtrace objectAtIndex:0]; } return nil; } -- (BOOL) isInvalidAddress:(NSDictionary*) errorReport +- (BOOL)isInvalidAddress:(NSDictionary *)errorReport { - NSDictionary* machError = [errorReport objectForKey:KSCrashField_Mach]; - if(machError != nil) - { - NSString* exceptionName = [machError objectForKey:KSCrashField_ExceptionName]; + NSDictionary *machError = [errorReport objectForKey:KSCrashField_Mach]; + if (machError != nil) { + NSString *exceptionName = [machError objectForKey:KSCrashField_ExceptionName]; return [exceptionName isEqualToString:@"EXC_BAD_ACCESS"]; } - NSDictionary* signal = [errorReport objectForKey:KSCrashField_Signal]; - NSString* sigName = [signal objectForKey:KSCrashField_Name]; + NSDictionary *signal = [errorReport objectForKey:KSCrashField_Signal]; + NSString *sigName = [signal objectForKey:KSCrashField_Name]; return [sigName isEqualToString:@"SIGSEGV"]; } -- (BOOL) isMathError:(NSDictionary*) errorReport +- (BOOL)isMathError:(NSDictionary *)errorReport { - NSDictionary* machError = [errorReport objectForKey:KSCrashField_Mach]; - if(machError != nil) - { - NSString* exceptionName = [machError objectForKey:KSCrashField_ExceptionName]; + NSDictionary *machError = [errorReport objectForKey:KSCrashField_Mach]; + if (machError != nil) { + NSString *exceptionName = [machError objectForKey:KSCrashField_ExceptionName]; return [exceptionName isEqualToString:@"EXC_ARITHMETIC"]; } - NSDictionary* signal = [errorReport objectForKey:KSCrashField_Signal]; - NSString* sigName = [signal objectForKey:KSCrashField_Name]; + NSDictionary *signal = [errorReport objectForKey:KSCrashField_Signal]; + NSString *sigName = [signal objectForKey:KSCrashField_Name]; return [sigName isEqualToString:@"SIGFPE"]; } -- (BOOL) isMemoryCorruption:(NSDictionary*) report +- (BOOL)isMemoryCorruption:(NSDictionary *)report { - NSDictionary* crashedThread = [self crashedThreadReport:report]; - NSArray* notableAddresses = [crashedThread objectForKey:KSCrashField_NotableAddresses]; - for(NSDictionary* address in [notableAddresses objectEnumerator]) - { - NSString* type = [address objectForKey:KSCrashField_Type]; - if([type isEqualToString:@"string"]) - { - NSString* value = [address objectForKey:KSCrashField_Value]; - if([value rangeOfString:@"autorelease pool page"].location != NSNotFound && - [value rangeOfString:@"corrupted"].location != NSNotFound) - { + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSArray *notableAddresses = [crashedThread objectForKey:KSCrashField_NotableAddresses]; + for (NSDictionary *address in [notableAddresses objectEnumerator]) { + NSString *type = [address objectForKey:KSCrashField_Type]; + if ([type isEqualToString:@"string"]) { + NSString *value = [address objectForKey:KSCrashField_Value]; + if ([value rangeOfString:@"autorelease pool page"].location != NSNotFound && + [value rangeOfString:@"corrupted"].location != NSNotFound) { return YES; } - if([value rangeOfString:@"incorrect checksum for freed object"].location != NSNotFound) - { + if ([value rangeOfString:@"incorrect checksum for freed object"].location != NSNotFound) { return YES; } } } - NSArray* backtrace = [self backtraceFromThreadReport:crashedThread]; - for(NSDictionary* entry in backtrace) - { - NSString* objectName = [entry objectForKey:KSCrashField_ObjectName]; - NSString* symbolName = [entry objectForKey:KSCrashField_SymbolName]; - if([symbolName isEqualToString:@"objc_autoreleasePoolPush"]) - { + NSArray *backtrace = [self backtraceFromThreadReport:crashedThread]; + for (NSDictionary *entry in backtrace) { + NSString *objectName = [entry objectForKey:KSCrashField_ObjectName]; + NSString *symbolName = [entry objectForKey:KSCrashField_SymbolName]; + if ([symbolName isEqualToString:@"objc_autoreleasePoolPush"]) { return YES; } - if([symbolName isEqualToString:@"free_list_checksum_botch"]) - { + if ([symbolName isEqualToString:@"free_list_checksum_botch"]) { return YES; } - if([symbolName isEqualToString:@"szone_malloc_should_clear"]) - { + if ([symbolName isEqualToString:@"szone_malloc_should_clear"]) { return YES; } - if([symbolName isEqualToString:@"lookUpMethod"] && [objectName isEqualToString:@"libobjc.A.dylib"]) - { + if ([symbolName isEqualToString:@"lookUpMethod"] && [objectName isEqualToString:@"libobjc.A.dylib"]) { return YES; } } @@ -406,50 +345,39 @@ - (BOOL) isMemoryCorruption:(NSDictionary*) report return NO; } -- (KSCrashDoctorFunctionCall*) lastFunctionCall:(NSDictionary*) report +- (KSCrashDoctorFunctionCall *)lastFunctionCall:(NSDictionary *)report { - KSCrashDoctorFunctionCall* function = [[KSCrashDoctorFunctionCall alloc] init]; - NSDictionary* lastStackEntry = [self lastStackEntry:report]; + KSCrashDoctorFunctionCall *function = [[KSCrashDoctorFunctionCall alloc] init]; + NSDictionary *lastStackEntry = [self lastStackEntry:report]; function.name = [lastStackEntry objectForKey:KSCrashField_SymbolName]; - NSDictionary* crashedThread = [self crashedThreadReport:report]; - NSDictionary* notableAddresses = [crashedThread objectForKey:KSCrashField_NotableAddresses]; + NSDictionary *crashedThread = [self crashedThreadReport:report]; + NSDictionary *notableAddresses = [crashedThread objectForKey:KSCrashField_NotableAddresses]; CPUFamily family = [self cpuFamily:report]; - NSDictionary* registers = [self basicRegistersFromThreadReport:crashedThread]; - NSArray* regNames = [NSArray arrayWithObjects: - [self registerNameForFamily:family paramIndex:0], - [self registerNameForFamily:family paramIndex:1], - [self registerNameForFamily:family paramIndex:2], - [self registerNameForFamily:family paramIndex:3], - nil]; - NSMutableArray* params = [NSMutableArray arrayWithCapacity:4]; - for(NSString* regName in regNames) - { - KSCrashDoctorParam* param = [[KSCrashDoctorParam alloc] init]; + NSDictionary *registers = [self basicRegistersFromThreadReport:crashedThread]; + NSArray *regNames = [NSArray arrayWithObjects:[self registerNameForFamily:family paramIndex:0], + [self registerNameForFamily:family paramIndex:1], + [self registerNameForFamily:family paramIndex:2], + [self registerNameForFamily:family paramIndex:3], nil]; + NSMutableArray *params = [NSMutableArray arrayWithCapacity:4]; + for (NSString *regName in regNames) { + KSCrashDoctorParam *param = [[KSCrashDoctorParam alloc] init]; param.address = (uintptr_t)[[registers objectForKey:regName] unsignedLongLongValue]; - NSDictionary* notableAddress = [notableAddresses objectForKey:regName]; - if(notableAddress == nil) - { - param.value = [NSString stringWithFormat:@"%p", (void*)param.address]; - } - else - { + NSDictionary *notableAddress = [notableAddresses objectForKey:regName]; + if (notableAddress == nil) { + param.value = [NSString stringWithFormat:@"%p", (void *)param.address]; + } else { param.type = [notableAddress objectForKey:KSCrashField_Type]; - NSString* className = [notableAddress objectForKey:KSCrashField_Class]; - NSString* previousClass = [notableAddress objectForKey:KSCrashField_LastDeallocObject]; - NSString* value = [notableAddress objectForKey:KSCrashField_Value]; + NSString *className = [notableAddress objectForKey:KSCrashField_Class]; + NSString *previousClass = [notableAddress objectForKey:KSCrashField_LastDeallocObject]; + NSString *value = [notableAddress objectForKey:KSCrashField_Value]; - if([param.type isEqualToString:KSCrashMemType_String]) - { + if ([param.type isEqualToString:KSCrashMemType_String]) { param.value = value; - } - else if([param.type isEqualToString:KSCrashMemType_Object]) - { + } else if ([param.type isEqualToString:KSCrashMemType_Object]) { param.className = className; param.isInstance = YES; - } - else if([param.type isEqualToString:KSCrashMemType_Class]) - { + } else if ([param.type isEqualToString:KSCrashMemType_Class]) { param.className = className; param.isInstance = NO; } @@ -463,42 +391,40 @@ - (KSCrashDoctorFunctionCall*) lastFunctionCall:(NSDictionary*) report return function; } -- (NSString*) zombieCall:(KSCrashDoctorFunctionCall*) functionCall +- (NSString *)zombieCall:(KSCrashDoctorFunctionCall *)functionCall { - if([functionCall.name isEqualToString:@"objc_msgSend"] && functionCall.params.count > 0 && [[functionCall.params objectAtIndex:0] previousClassName] != nil) - { + if ([functionCall.name isEqualToString:@"objc_msgSend"] && functionCall.params.count > 0 && + [[functionCall.params objectAtIndex:0] previousClassName] != nil) { return [functionCall descriptionWithParamCount:4]; - } - else if([functionCall.name isEqualToString:@"objc_retain"] && functionCall.params.count > 0 && [[functionCall.params objectAtIndex:0] previousClassName] != nil) - { + } else if ([functionCall.name isEqualToString:@"objc_retain"] && functionCall.params.count > 0 && + [[functionCall.params objectAtIndex:0] previousClassName] != nil) { return [functionCall descriptionWithParamCount:1]; } return nil; } -- (BOOL) isStackOverflow:(NSDictionary*) crashedThreadReport +- (BOOL)isStackOverflow:(NSDictionary *)crashedThreadReport { - NSDictionary* stack = [crashedThreadReport objectForKey:KSCrashField_Stack]; + NSDictionary *stack = [crashedThreadReport objectForKey:KSCrashField_Stack]; return [[stack objectForKey:KSCrashField_Overflow] boolValue]; } -- (BOOL) isDeadlock:(NSDictionary*) report +- (BOOL)isDeadlock:(NSDictionary *)report { - NSDictionary* errorReport = [self errorReport:report]; - NSString* crashType = [errorReport objectForKey:KSCrashField_Type]; + NSDictionary *errorReport = [self errorReport:report]; + NSString *crashType = [errorReport objectForKey:KSCrashField_Type]; return [KSCrashExcType_Deadlock isEqualToString:crashType]; } -- (NSString*) appendOriginatingCall:(NSString*) string callName:(NSString*) callName +- (NSString *)appendOriginatingCall:(NSString *)string callName:(NSString *)callName { - if(callName != nil && ![callName isEqualToString:@"main"]) - { + if (callName != nil && ![callName isEqualToString:@"main"]) { return [string stringByAppendingFormat:@"\nOriginated at or in a subcall of %@", callName]; } return string; } -- (BOOL) isGracefulTerminationRequest:(NSDictionary *)report +- (BOOL)isGracefulTerminationRequest:(NSDictionary *)report { return [report[KSCrashField_Signal][KSCrashField_Signal] integerValue] == SIGTERM; } @@ -508,84 +434,80 @@ - (BOOL)isMemoryTermination:(NSDictionary *)report return [report[KSCrashField_Type] isEqualToString:KSCrashExcType_MemoryTermination]; } -- (NSString*) diagnoseCrash:(NSDictionary*) report +- (NSString *)diagnoseCrash:(NSDictionary *)report { - @try - { - NSString* lastFunctionName = [[self lastInAppStackEntry:report] objectForKey:KSCrashField_SymbolName]; - NSDictionary* crashedThreadReport = [self crashedThreadReport:report]; - NSDictionary* errorReport = [self errorReport:report]; - - if([self isDeadlock:report]) - { + @try { + NSString *lastFunctionName = [[self lastInAppStackEntry:report] objectForKey:KSCrashField_SymbolName]; + NSDictionary *crashedThreadReport = [self crashedThreadReport:report]; + NSDictionary *errorReport = [self errorReport:report]; + + if ([self isDeadlock:report]) { return [NSString stringWithFormat:@"Main thread deadlocked in %@", lastFunctionName]; } - - if([self isStackOverflow:crashedThreadReport]) - { + + if ([self isStackOverflow:crashedThreadReport]) { return [NSString stringWithFormat:@"Stack overflow in %@", lastFunctionName]; } - NSString* crashType = [errorReport objectForKey:KSCrashField_Type]; - if([crashType isEqualToString:KSCrashExcType_NSException]) - { - NSDictionary* exception = [errorReport objectForKey:KSCrashField_NSException]; - NSString* name = [exception objectForKey:KSCrashField_Name]; - NSString* reason = [exception objectForKey:KSCrashField_Reason]? [exception objectForKey:KSCrashField_Reason]:[errorReport objectForKey:KSCrashField_Reason]; - return [self appendOriginatingCall:[NSString stringWithFormat:@"Application threw exception %@: %@", - name, reason] - callName:lastFunctionName]; + NSString *crashType = [errorReport objectForKey:KSCrashField_Type]; + if ([crashType isEqualToString:KSCrashExcType_NSException]) { + NSDictionary *exception = [errorReport objectForKey:KSCrashField_NSException]; + NSString *name = [exception objectForKey:KSCrashField_Name]; + NSString *reason = [exception objectForKey:KSCrashField_Reason] + ? [exception objectForKey:KSCrashField_Reason] + : [errorReport objectForKey:KSCrashField_Reason]; + return [self + appendOriginatingCall:[NSString stringWithFormat:@"Application threw exception %@: %@", name, reason] + callName:lastFunctionName]; } - if([self isMemoryCorruption:report]) - { + if ([self isMemoryCorruption:report]) { return @"Rogue memory write has corrupted memory."; } - if([self isMathError:errorReport]) - { - return [self appendOriginatingCall:[NSString stringWithFormat:@"Math error (usually caused from division by 0)."] - callName:lastFunctionName]; + if ([self isMathError:errorReport]) { + return [self + appendOriginatingCall:[NSString stringWithFormat:@"Math error (usually caused from division by 0)."] + callName:lastFunctionName]; } - KSCrashDoctorFunctionCall* functionCall = [self lastFunctionCall:report]; - NSString* zombieCall = [self zombieCall:functionCall]; - if(zombieCall != nil) - { + KSCrashDoctorFunctionCall *functionCall = [self lastFunctionCall:report]; + NSString *zombieCall = [self zombieCall:functionCall]; + if (zombieCall != nil) { return [self appendOriginatingCall:[NSString stringWithFormat:@"Possible zombie in call: %@", zombieCall] callName:lastFunctionName]; } - if([self isInvalidAddress:errorReport]) - { + if ([self isInvalidAddress:errorReport]) { uintptr_t address = (uintptr_t)[[errorReport objectForKey:KSCrashField_Address] unsignedLongLongValue]; - if(address == 0) - { - return [self appendOriginatingCall:@"Attempted to dereference null pointer." - callName:lastFunctionName]; + if (address == 0) { + return [self appendOriginatingCall:@"Attempted to dereference null pointer." callName:lastFunctionName]; } - return [self appendOriginatingCall:[NSString stringWithFormat:@"Attempted to dereference garbage pointer %p.", (void*)address] - callName:lastFunctionName]; + return + [self appendOriginatingCall:[NSString stringWithFormat:@"Attempted to dereference garbage pointer %p.", + (void *)address] + callName:lastFunctionName]; } - - if([self isGracefulTerminationRequest:errorReport]) { + + if ([self isGracefulTerminationRequest:errorReport]) { return @"The OS request the app be gracefully terminated."; } - + if ([self isMemoryTermination:errorReport]) { return @"The app was terminated due to running out of memory (OOM)."; } - + return nil; - } - @catch (NSException* e) - { - NSArray* symbols = [e callStackSymbols]; - if(symbols) - { - return [NSString stringWithFormat:@"No diagnosis due to exception %@:\n%@\nPlease file a bug report to the KSCrash project.", e, symbols]; + } @catch (NSException *e) { + NSArray *symbols = [e callStackSymbols]; + if (symbols) { + return [NSString + stringWithFormat: + @"No diagnosis due to exception %@:\n%@\nPlease file a bug report to the KSCrash project.", e, + symbols]; } - return [NSString stringWithFormat:@"No diagnosis due to exception %@\nPlease file a bug report to the KSCrash project.", e]; + return [NSString + stringWithFormat:@"No diagnosis due to exception %@\nPlease file a bug report to the KSCrash project.", e]; } } diff --git a/Sources/KSCrashRecording/KSCrashReport.m b/Sources/KSCrashRecording/KSCrashReport.m index ac87fbdd8..09b4d35ce 100644 --- a/Sources/KSCrashRecording/KSCrashReport.m +++ b/Sources/KSCrashRecording/KSCrashReport.m @@ -28,14 +28,13 @@ @implementation KSCrashReport -- (instancetype) initWithValueType:(KSCrashReportValueType) valueType - dictionaryValue:(nullable NSDictionary*) dictionaryValue - stringValue:(nullable NSString*) stringValue - dataValue:(nullable NSData*) dataValue +- (instancetype)initWithValueType:(KSCrashReportValueType)valueType + dictionaryValue:(nullable NSDictionary *)dictionaryValue + stringValue:(nullable NSString *)stringValue + dataValue:(nullable NSData *)dataValue { self = [super init]; - if(self != nil) - { + if (self != nil) { _valueType = valueType; _dictionaryValue = [dictionaryValue copy]; _stringValue = [stringValue copy]; @@ -44,7 +43,7 @@ - (instancetype) initWithValueType:(KSCrashReportValueType) valueType return self; } -+ (instancetype) reportWithDictionary:(NSDictionary*) dictionaryValue ++ (instancetype)reportWithDictionary:(NSDictionary *)dictionaryValue { return [[KSCrashReport alloc] initWithValueType:KSCrashReportValueTypeDictionary dictionaryValue:dictionaryValue @@ -52,7 +51,7 @@ + (instancetype) reportWithDictionary:(NSDictionary*) dictionaryV dataValue:nil]; } -+ (instancetype) reportWithString:(NSString*) stringValue ++ (instancetype)reportWithString:(NSString *)stringValue { return [[KSCrashReport alloc] initWithValueType:KSCrashReportValueTypeString dictionaryValue:nil @@ -60,7 +59,7 @@ + (instancetype) reportWithString:(NSString*) stringValue dataValue:nil]; } -+ (instancetype) reportWithData:(NSData*) dataValue ++ (instancetype)reportWithData:(NSData *)dataValue { return [[KSCrashReport alloc] initWithValueType:KSCrashReportValueTypeData dictionaryValue:nil @@ -68,25 +67,21 @@ + (instancetype) reportWithData:(NSData*) dataValue dataValue:dataValue]; } -- (BOOL) isEqual:(id) object +- (BOOL)isEqual:(id)object { - if([object isKindOfClass:[KSCrashReport class]] == NO) - { + if ([object isKindOfClass:[KSCrashReport class]] == NO) { return NO; } KSCrashReport *other = object; #define SAME_OR_EQUAL(GETTER) ((self.GETTER) == (other.GETTER) || [(self.GETTER) isEqual:(other.GETTER)]) - return self.valueType == other.valueType - && SAME_OR_EQUAL(stringValue) - && SAME_OR_EQUAL(dictionaryValue) - && SAME_OR_EQUAL(dataValue); + return self.valueType == other.valueType && SAME_OR_EQUAL(stringValue) && SAME_OR_EQUAL(dictionaryValue) && + SAME_OR_EQUAL(dataValue); #undef SAME_OR_EQUAL } -- (NSString*) description +- (NSString *)description { - switch(self.valueType) - { + switch (self.valueType) { case KSCrashReportValueTypeDictionary: return [self.dictionaryValue description]; case KSCrashReportValueTypeString: diff --git a/Sources/KSCrashRecording/KSCrashReportC.c b/Sources/KSCrashRecording/KSCrashReportC.c index 2deb13b5d..130364a06 100644 --- a/Sources/KSCrashRecording/KSCrashReportC.c +++ b/Sources/KSCrashRecording/KSCrashReportC.c @@ -24,52 +24,49 @@ // THE SOFTWARE. // - #include "KSCrashReportC.h" -#include "KSString.h" -#include "KSCrashReportFields.h" -#include "KSCrashReportWriter.h" -#include "KSDynamicLinker.h" -#include "KSFileUtils.h" -#include "KSJSONCodec.h" #include "KSCPU.h" -#include "KSMemory.h" -#include "KSMach.h" -#include "KSThread.h" -#include "KSObjC.h" -#include "KSSignalInfo.h" +#include "KSCrashCachedData.h" #include "KSCrashMonitorHelper.h" -#include "KSCrashMonitor_MachException.h" -#include "KSCrashMonitor_Signal.h" +#include "KSCrashMonitor_AppState.h" #include "KSCrashMonitor_CPPException.h" -#include "KSCrashMonitor_NSException.h" #include "KSCrashMonitor_Deadlock.h" -#include "KSCrashMonitor_User.h" +#include "KSCrashMonitor_MachException.h" #include "KSCrashMonitor_Memory.h" -#include "KSCrashMonitor_Deadlock.h" +#include "KSCrashMonitor_NSException.h" +#include "KSCrashMonitor_Signal.h" #include "KSCrashMonitor_System.h" -#include "KSCrashMonitor_AppState.h" +#include "KSCrashMonitor_User.h" #include "KSCrashMonitor_Zombie.h" -#include "KSString.h" +#include "KSCrashReportFields.h" #include "KSCrashReportVersion.h" +#include "KSCrashReportWriter.h" +#include "KSDate.h" +#include "KSDynamicLinker.h" +#include "KSFileUtils.h" +#include "KSJSONCodec.h" +#include "KSMach.h" +#include "KSMemory.h" +#include "KSObjC.h" +#include "KSSignalInfo.h" #include "KSStackCursor_Backtrace.h" #include "KSStackCursor_MachineContext.h" +#include "KSString.h" #include "KSSystemCapabilities.h" -#include "KSCrashCachedData.h" -#include "KSDate.h" - -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" +#include "KSThread.h" +// #define KSLogger_LocalLevel TRACE #include #include #include #include #include #include -#include #include +#include + +#include "KSLogger.h" // ============================================================================ #pragma mark - Constants - @@ -90,97 +87,86 @@ /** The minimum length for a valid string. */ #define kMinStringLength 4 - // ============================================================================ #pragma mark - JSON Encoding - // ============================================================================ -#define getJsonContext(REPORT_WRITER) ((KSJSONEncodeContext*)((REPORT_WRITER)->context)) +#define getJsonContext(REPORT_WRITER) ((KSJSONEncodeContext *)((REPORT_WRITER)->context)) /** Used for writing hex string values. */ -static const char g_hexNybbles[] = -{ - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; +static const char g_hexNybbles[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; // ============================================================================ #pragma mark - Runtime Config - // ============================================================================ -typedef struct -{ +typedef struct { /** If YES, introspect memory contents during a crash. * Any Objective-C objects or C strings near the stack pointer or referenced by * cpu registers or exceptions will be recorded in the crash report, along with * their contents. */ bool enabled; - + /** List of classes that should never be introspected. * Whenever a class in this list is encountered, only the class name will be recorded. */ - const char** restrictedClasses; + const char **restrictedClasses; int restrictedClassesCount; } KSCrash_IntrospectionRules; -static const char* g_userInfoJSON; +static const char *g_userInfoJSON; static pthread_mutex_t g_userInfoMutex = PTHREAD_MUTEX_INITIALIZER; static KSCrash_IntrospectionRules g_introspectionRules; static KSReportWriteCallback g_userSectionWriteCallback; - #pragma mark Callbacks -static void addBooleanElement(const KSCrashReportWriter* const writer, const char* const key, const bool value) +static void addBooleanElement(const KSCrashReportWriter *const writer, const char *const key, const bool value) { ksjson_addBooleanElement(getJsonContext(writer), key, value); } -static void addFloatingPointElement(const KSCrashReportWriter* const writer, const char* const key, const double value) +static void addFloatingPointElement(const KSCrashReportWriter *const writer, const char *const key, const double value) { ksjson_addFloatingPointElement(getJsonContext(writer), key, value); } -static void addIntegerElement(const KSCrashReportWriter* const writer, const char* const key, const int64_t value) +static void addIntegerElement(const KSCrashReportWriter *const writer, const char *const key, const int64_t value) { ksjson_addIntegerElement(getJsonContext(writer), key, value); } -static void addUIntegerElement(const KSCrashReportWriter* const writer, const char* const key, const uint64_t value) +static void addUIntegerElement(const KSCrashReportWriter *const writer, const char *const key, const uint64_t value) { ksjson_addUIntegerElement(getJsonContext(writer), key, value); } -static void addStringElement(const KSCrashReportWriter* const writer, const char* const key, const char* const value) +static void addStringElement(const KSCrashReportWriter *const writer, const char *const key, const char *const value) { ksjson_addStringElement(getJsonContext(writer), key, value, KSJSON_SIZE_AUTOMATIC); } -static void addTextFileElement(const KSCrashReportWriter* const writer, const char* const key, const char* const filePath) +static void addTextFileElement(const KSCrashReportWriter *const writer, const char *const key, + const char *const filePath) { const int fd = open(filePath, O_RDONLY); - if(fd < 0) - { + if (fd < 0) { KSLOG_ERROR("Could not open file %s: %s", filePath, strerror(errno)); return; } - if(ksjson_beginStringElement(getJsonContext(writer), key) != KSJSON_OK) - { + if (ksjson_beginStringElement(getJsonContext(writer), key) != KSJSON_OK) { KSLOG_ERROR("Could not start string element"); goto done; } char buffer[512]; int bytesRead; - for(bytesRead = (int)read(fd, buffer, sizeof(buffer)); - bytesRead > 0; - bytesRead = (int)read(fd, buffer, sizeof(buffer))) - { - if(ksjson_appendStringElement(getJsonContext(writer), buffer, bytesRead) != KSJSON_OK) - { + for (bytesRead = (int)read(fd, buffer, sizeof(buffer)); bytesRead > 0; + bytesRead = (int)read(fd, buffer, sizeof(buffer))) { + if (ksjson_appendStringElement(getJsonContext(writer), buffer, bytesRead) != KSJSON_OK) { KSLOG_ERROR("Could not append string element"); goto done; } @@ -191,145 +177,110 @@ static void addTextFileElement(const KSCrashReportWriter* const writer, const ch close(fd); } -static void addDataElement(const KSCrashReportWriter* const writer, - const char* const key, - const char* const value, +static void addDataElement(const KSCrashReportWriter *const writer, const char *const key, const char *const value, const int length) { ksjson_addDataElement(getJsonContext(writer), key, value, length); } -static void beginDataElement(const KSCrashReportWriter* const writer, const char* const key) +static void beginDataElement(const KSCrashReportWriter *const writer, const char *const key) { ksjson_beginDataElement(getJsonContext(writer), key); } -static void appendDataElement(const KSCrashReportWriter* const writer, const char* const value, const int length) +static void appendDataElement(const KSCrashReportWriter *const writer, const char *const value, const int length) { ksjson_appendDataElement(getJsonContext(writer), value, length); } -static void endDataElement(const KSCrashReportWriter* const writer) -{ - ksjson_endDataElement(getJsonContext(writer)); -} +static void endDataElement(const KSCrashReportWriter *const writer) { ksjson_endDataElement(getJsonContext(writer)); } -static void addUUIDElement(const KSCrashReportWriter* const writer, const char* const key, const unsigned char* const value) +static void addUUIDElement(const KSCrashReportWriter *const writer, const char *const key, + const unsigned char *const value) { - if(value == NULL) - { + if (value == NULL) { ksjson_addNullElement(getJsonContext(writer), key); - } - else - { + } else { char uuidBuffer[37]; - const unsigned char* src = value; - char* dst = uuidBuffer; - for(int i = 0; i < 4; i++) - { - *dst++ = g_hexNybbles[(*src>>4)&15]; - *dst++ = g_hexNybbles[(*src++)&15]; + const unsigned char *src = value; + char *dst = uuidBuffer; + for (int i = 0; i < 4; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; } *dst++ = '-'; - for(int i = 0; i < 2; i++) - { - *dst++ = g_hexNybbles[(*src>>4)&15]; - *dst++ = g_hexNybbles[(*src++)&15]; + for (int i = 0; i < 2; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; } *dst++ = '-'; - for(int i = 0; i < 2; i++) - { - *dst++ = g_hexNybbles[(*src>>4)&15]; - *dst++ = g_hexNybbles[(*src++)&15]; + for (int i = 0; i < 2; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; } *dst++ = '-'; - for(int i = 0; i < 2; i++) - { - *dst++ = g_hexNybbles[(*src>>4)&15]; - *dst++ = g_hexNybbles[(*src++)&15]; + for (int i = 0; i < 2; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; } *dst++ = '-'; - for(int i = 0; i < 6; i++) - { - *dst++ = g_hexNybbles[(*src>>4)&15]; - *dst++ = g_hexNybbles[(*src++)&15]; + for (int i = 0; i < 6; i++) { + *dst++ = g_hexNybbles[(*src >> 4) & 15]; + *dst++ = g_hexNybbles[(*src++) & 15]; } ksjson_addStringElement(getJsonContext(writer), key, uuidBuffer, (int)(dst - uuidBuffer)); } } -static void addJSONElement(const KSCrashReportWriter* const writer, - const char* const key, - const char* const jsonElement, - bool closeLastContainer) +static void addJSONElement(const KSCrashReportWriter *const writer, const char *const key, + const char *const jsonElement, bool closeLastContainer) { - int jsonResult = ksjson_addJSONElement(getJsonContext(writer), - key, - jsonElement, - (int)strlen(jsonElement), - closeLastContainer); - if(jsonResult != KSJSON_OK) - { + int jsonResult = + ksjson_addJSONElement(getJsonContext(writer), key, jsonElement, (int)strlen(jsonElement), closeLastContainer); + if (jsonResult != KSJSON_OK) { char errorBuff[100]; - snprintf(errorBuff, - sizeof(errorBuff), - "Invalid JSON data: %s", - ksjson_stringForError(jsonResult)); + snprintf(errorBuff, sizeof(errorBuff), "Invalid JSON data: %s", ksjson_stringForError(jsonResult)); ksjson_beginObject(getJsonContext(writer), key); - ksjson_addStringElement(getJsonContext(writer), - KSCrashField_Error, - errorBuff, - KSJSON_SIZE_AUTOMATIC); - ksjson_addStringElement(getJsonContext(writer), - KSCrashField_JSONData, - jsonElement, - KSJSON_SIZE_AUTOMATIC); + ksjson_addStringElement(getJsonContext(writer), KSCrashField_Error, errorBuff, KSJSON_SIZE_AUTOMATIC); + ksjson_addStringElement(getJsonContext(writer), KSCrashField_JSONData, jsonElement, KSJSON_SIZE_AUTOMATIC); ksjson_endContainer(getJsonContext(writer)); } } -static void addJSONElementFromFile(const KSCrashReportWriter* const writer, - const char* const key, - const char* const filePath, - bool closeLastContainer) +static void addJSONElementFromFile(const KSCrashReportWriter *const writer, const char *const key, + const char *const filePath, bool closeLastContainer) { ksjson_addJSONFromFile(getJsonContext(writer), key, filePath, closeLastContainer); } -static void beginObject(const KSCrashReportWriter* const writer, const char* const key) +static void beginObject(const KSCrashReportWriter *const writer, const char *const key) { ksjson_beginObject(getJsonContext(writer), key); } -static void beginArray(const KSCrashReportWriter* const writer, const char* const key) +static void beginArray(const KSCrashReportWriter *const writer, const char *const key) { ksjson_beginArray(getJsonContext(writer), key); } -static void endContainer(const KSCrashReportWriter* const writer) -{ - ksjson_endContainer(getJsonContext(writer)); -} - +static void endContainer(const KSCrashReportWriter *const writer) { ksjson_endContainer(getJsonContext(writer)); } -static void addTextLinesFromFile(const KSCrashReportWriter* const writer, const char* const key, const char* const filePath) +static void addTextLinesFromFile(const KSCrashReportWriter *const writer, const char *const key, + const char *const filePath) { char readBuffer[1024]; KSBufferedReader reader; - if(!ksfu_openBufferedReader(&reader, filePath, readBuffer, sizeof(readBuffer))) - { + if (!ksfu_openBufferedReader(&reader, filePath, readBuffer, sizeof(readBuffer))) { return; } char buffer[1024]; beginArray(writer, key); { - for(;;) - { + for (;;) { int length = sizeof(buffer); ksfu_readBufferedReaderUntilChar(&reader, '\n', buffer, &length); - if(length <= 0) - { + if (length <= 0) { break; } buffer[length - 1] = '\0'; @@ -340,14 +291,13 @@ static void addTextLinesFromFile(const KSCrashReportWriter* const writer, const ksfu_closeBufferedReader(&reader); } -static int addJSONData(const char* restrict const data, const int length, void* restrict userData) +static int addJSONData(const char *restrict const data, const int length, void *restrict userData) { - KSBufferedWriter* writer = (KSBufferedWriter*)userData; + KSBufferedWriter *writer = (KSBufferedWriter *)userData; const bool success = ksfu_writeBufferedWriter(writer, data, length); return success ? KSJSON_OK : KSJSON_ERROR_CANNOT_ADD_DATA; } - // ============================================================================ #pragma mark - Utility - // ============================================================================ @@ -358,21 +308,18 @@ static int addJSONData(const char* restrict const data, const int length, void* * * @return true if the address points to a string. */ -static bool isValidString(const void* const address) +static bool isValidString(const void *const address) { - if((void*)address == NULL) - { + if ((void *)address == NULL) { return false; } char buffer[500]; - if((uintptr_t)address+sizeof(buffer) < (uintptr_t)address) - { + if ((uintptr_t)address + sizeof(buffer) < (uintptr_t)address) { // Wrapped around the address range. return false; } - if(!ksmem_copySafely(address, buffer, sizeof(buffer))) - { + if (!ksmem_copySafely(address, buffer, sizeof(buffer))) { return false; } return ksstring_isNullTerminatedUTF8String(buffer, kMinStringLength, sizeof(buffer)); @@ -393,13 +340,11 @@ static bool isValidString(const void* const address) * * @return True if the cursor was filled. */ -static bool getStackCursor(const KSCrash_MonitorContext* const crash, - const struct KSMachineContext* const machineContext, - KSStackCursor *cursor) +static bool getStackCursor(const KSCrash_MonitorContext *const crash, + const struct KSMachineContext *const machineContext, KSStackCursor *cursor) { - if(ksmc_getThreadFromContext(machineContext) == ksmc_getThreadFromContext(crash->offendingMachineContext)) - { - *cursor = *((KSStackCursor*)crash->stackCursor); + if (ksmc_getThreadFromContext(machineContext) == ksmc_getThreadFromContext(crash->offendingMachineContext)) { + *cursor = *((KSStackCursor *)crash->stackCursor); return true; } @@ -407,7 +352,6 @@ static bool getStackCursor(const KSCrash_MonitorContext* const crash, return true; } - // ============================================================================ #pragma mark - Report Writing - // ============================================================================ @@ -423,10 +367,8 @@ static bool getStackCursor(const KSCrash_MonitorContext* const crash, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeMemoryContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t address, - int* limit); +static void writeMemoryContents(const KSCrashReportWriter *const writer, const char *const key, const uintptr_t address, + int *limit); /** Write a string to the report. * This will only print the first child of the array. @@ -439,15 +381,12 @@ static void writeMemoryContents(const KSCrashReportWriter* const writer, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeNSStringContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t objectAddress, - __unused int* limit) +static void writeNSStringContents(const KSCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) { - const void* object = (const void*)objectAddress; + const void *object = (const void *)objectAddress; char buffer[200]; - if(ksobjc_copyStringContents(object, buffer, sizeof(buffer))) - { + if (ksobjc_copyStringContents(object, buffer, sizeof(buffer))) { writer->addStringElement(writer, key, buffer); } } @@ -463,15 +402,12 @@ static void writeNSStringContents(const KSCrashReportWriter* const writer, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeURLContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t objectAddress, - __unused int* limit) +static void writeURLContents(const KSCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) { - const void* object = (const void*)objectAddress; + const void *object = (const void *)objectAddress; char buffer[200]; - if(ksobjc_copyStringContents(object, buffer, sizeof(buffer))) - { + if (ksobjc_copyStringContents(object, buffer, sizeof(buffer))) { writer->addStringElement(writer, key, buffer); } } @@ -487,12 +423,10 @@ static void writeURLContents(const KSCrashReportWriter* const writer, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeDateContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t objectAddress, - __unused int* limit) +static void writeDateContents(const KSCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) { - const void* object = (const void*)objectAddress; + const void *object = (const void *)objectAddress; writer->addFloatingPointElement(writer, key, ksobjc_dateContents(object)); } @@ -507,12 +441,10 @@ static void writeDateContents(const KSCrashReportWriter* const writer, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeNumberContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t objectAddress, - __unused int* limit) +static void writeNumberContents(const KSCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, __unused int *limit) { - const void* object = (const void*)objectAddress; + const void *object = (const void *)objectAddress; writer->addFloatingPointElement(writer, key, ksobjc_numberAsFloat(object)); } @@ -527,15 +459,12 @@ static void writeNumberContents(const KSCrashReportWriter* const writer, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeArrayContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t objectAddress, - int* limit) +static void writeArrayContents(const KSCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, int *limit) { - const void* object = (const void*)objectAddress; + const void *object = (const void *)objectAddress; uintptr_t firstObject; - if(ksobjc_arrayContents(object, &firstObject, 1) == 1) - { + if (ksobjc_arrayContents(object, &firstObject, 1) == 1) { writeMemoryContents(writer, key, firstObject, limit); } } @@ -550,13 +479,11 @@ static void writeArrayContents(const KSCrashReportWriter* const writer, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeUnknownObjectContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t objectAddress, - int* limit) +static void writeUnknownObjectContents(const KSCrashReportWriter *const writer, const char *const key, + const uintptr_t objectAddress, int *limit) { (*limit)--; - const void* object = (const void*)objectAddress; + const void *object = (const void *)objectAddress; KSObjCIvar ivars[10]; int8_t s8; int16_t s16; @@ -571,25 +498,19 @@ static void writeUnknownObjectContents(const KSCrashReportWriter* const writer, float f32; double f64; bool b; - void* pointer; - - + void *pointer; + writer->beginObject(writer, key); { - if(ksobjc_isTaggedPointer(object)) - { + if (ksobjc_isTaggedPointer(object)) { writer->addIntegerElement(writer, "tagged_payload", (int64_t)ksobjc_taggedPointerPayload(object)); - } - else - { - const void* class = ksobjc_isaPointer(object); - int ivarCount = ksobjc_ivarList(class, ivars, sizeof(ivars)/sizeof(*ivars)); + } else { + const void *class = ksobjc_isaPointer(object); + int ivarCount = ksobjc_ivarList(class, ivars, sizeof(ivars) / sizeof(*ivars)); *limit -= ivarCount; - for(int i = 0; i < ivarCount; i++) - { - KSObjCIvar* ivar = &ivars[i]; - switch(ivar->type[0]) - { + for (int i = 0; i < ivarCount; i++) { + KSObjCIvar *ivar = &ivars[i]; + switch (ivar->type[0]) { case 'c': ksobjc_ivarValue(object, ivar->index, &s8); writer->addIntegerElement(writer, ivar->name, s8); @@ -658,14 +579,11 @@ static void writeUnknownObjectContents(const KSCrashReportWriter* const writer, writer->endContainer(writer); } -static bool isRestrictedClass(const char* name) +static bool isRestrictedClass(const char *name) { - if(g_introspectionRules.restrictedClasses != NULL) - { - for(int i = 0; i < g_introspectionRules.restrictedClassesCount; i++) - { - if(ksstring_safeStrcmp(name, g_introspectionRules.restrictedClasses[i]) == 0) - { + if (g_introspectionRules.restrictedClasses != NULL) { + for (int i = 0; i < g_introspectionRules.restrictedClassesCount; i++) { + if (ksstring_safeStrcmp(name, g_introspectionRules.restrictedClasses[i]) == 0) { return true; } } @@ -673,41 +591,33 @@ static bool isRestrictedClass(const char* name) return false; } -static void writeZombieIfPresent(const KSCrashReportWriter* const writer, - const char* const key, +static void writeZombieIfPresent(const KSCrashReportWriter *const writer, const char *const key, const uintptr_t address) { #if KSCRASH_HAS_OBJC - const void* object = (const void*)address; - const char* zombieClassName = kszombie_className(object); - if(zombieClassName != NULL) - { + const void *object = (const void *)address; + const char *zombieClassName = kszombie_className(object); + if (zombieClassName != NULL) { writer->addStringElement(writer, key, zombieClassName); } #endif } -static bool writeObjCObject(const KSCrashReportWriter* const writer, - const uintptr_t address, - int* limit) +static bool writeObjCObject(const KSCrashReportWriter *const writer, const uintptr_t address, int *limit) { #if KSCRASH_HAS_OBJC - const void* object = (const void*)address; - switch(ksobjc_objectType(object)) - { + const void *object = (const void *)address; + switch (ksobjc_objectType(object)) { case KSObjCTypeClass: writer->addStringElement(writer, KSCrashField_Type, KSCrashMemType_Class); writer->addStringElement(writer, KSCrashField_Class, ksobjc_className(object)); return true; - case KSObjCTypeObject: - { + case KSObjCTypeObject: { writer->addStringElement(writer, KSCrashField_Type, KSCrashMemType_Object); - const char* className = ksobjc_objectClassName(object); + const char *className = ksobjc_objectClassName(object); writer->addStringElement(writer, KSCrashField_Class, className); - if(!isRestrictedClass(className)) - { - switch(ksobjc_objectClassType(object)) - { + if (!isRestrictedClass(className)) { + switch (ksobjc_objectClassType(object)) { case KSObjCClassTypeString: writeNSStringContents(writer, KSCrashField_Value, address, limit); return true; @@ -718,8 +628,7 @@ static bool writeObjCObject(const KSCrashReportWriter* const writer, writeDateContents(writer, KSCrashField_Value, address, limit); return true; case KSObjCClassTypeArray: - if(*limit > 0) - { + if (*limit > 0) { writeArrayContents(writer, KSCrashField_FirstObject, address, limit); } return true; @@ -729,14 +638,12 @@ static bool writeObjCObject(const KSCrashReportWriter* const writer, case KSObjCClassTypeDictionary: case KSObjCClassTypeException: // TODO: Implement these. - if(*limit > 0) - { + if (*limit > 0) { writeUnknownObjectContents(writer, KSCrashField_Ivars, address, limit); } return true; case KSObjCClassTypeUnknown: - if(*limit > 0) - { + if (*limit > 0) { writeUnknownObjectContents(writer, KSCrashField_Ivars, address, limit); } return true; @@ -746,7 +653,7 @@ static bool writeObjCObject(const KSCrashReportWriter* const writer, } case KSObjCTypeBlock: writer->addStringElement(writer, KSCrashField_Type, KSCrashMemType_Block); - const char* className = ksobjc_objectClassName(object); + const char *className = ksobjc_objectClassName(object); writer->addStringElement(writer, KSCrashField_Class, className); return true; case KSObjCTypeUnknown: @@ -768,30 +675,22 @@ static bool writeObjCObject(const KSCrashReportWriter* const writer, * * @param limit How many more subreferenced objects to write, if any. */ -static void writeMemoryContents(const KSCrashReportWriter* const writer, - const char* const key, - const uintptr_t address, - int* limit) +static void writeMemoryContents(const KSCrashReportWriter *const writer, const char *const key, const uintptr_t address, + int *limit) { (*limit)--; - const void* object = (const void*)address; + const void *object = (const void *)address; writer->beginObject(writer, key); { writer->addUIntegerElement(writer, KSCrashField_Address, address); writeZombieIfPresent(writer, KSCrashField_LastDeallocObject, address); - if(!writeObjCObject(writer, address, limit)) - { - if(object == NULL) - { + if (!writeObjCObject(writer, address, limit)) { + if (object == NULL) { writer->addStringElement(writer, KSCrashField_Type, KSCrashMemType_NullPointer); - } - else if(isValidString(object)) - { + } else if (isValidString(object)) { writer->addStringElement(writer, KSCrashField_Type, KSCrashMemType_String); - writer->addStringElement(writer, KSCrashField_Value, (const char*)object); - } - else - { + writer->addStringElement(writer, KSCrashField_Value, (const char *)object); + } else { writer->addStringElement(writer, KSCrashField_Type, KSCrashMemType_Unknown); } } @@ -801,16 +700,13 @@ static void writeMemoryContents(const KSCrashReportWriter* const writer, static bool isValidPointer(const uintptr_t address) { - if(address == (uintptr_t)NULL) - { + if (address == (uintptr_t)NULL) { return false; } #if KSCRASH_HAS_OBJC - if(ksobjc_isTaggedPointer((const void*)address)) - { - if(!ksobjc_isValidTaggedPointer((const void*)address)) - { + if (ksobjc_isTaggedPointer((const void *)address)) { + if (!ksobjc_isValidTaggedPointer((const void *)address)) { return false; } } @@ -821,27 +717,23 @@ static bool isValidPointer(const uintptr_t address) static bool isNotableAddress(const uintptr_t address) { - if(!isValidPointer(address)) - { + if (!isValidPointer(address)) { return false; } - - const void* object = (const void*)address; + + const void *object = (const void *)address; #if KSCRASH_HAS_OBJC - if(kszombie_className(object) != NULL) - { + if (kszombie_className(object) != NULL) { return true; } - if(ksobjc_objectType(object) != KSObjCTypeUnknown) - { + if (ksobjc_objectType(object) != KSObjCTypeUnknown) { return true; } #endif - if(isValidString(object)) - { + if (isValidString(object)) { return true; } @@ -857,12 +749,10 @@ static bool isNotableAddress(const uintptr_t address) * * @param address The memory address. */ -static void writeMemoryContentsIfNotable(const KSCrashReportWriter* const writer, - const char* const key, +static void writeMemoryContentsIfNotable(const KSCrashReportWriter *const writer, const char *const key, const uintptr_t address) { - if(isNotableAddress(address)) - { + if (isNotableAddress(address)) { int limit = kDefaultMemorySearchDepth; writeMemoryContents(writer, key, address, &limit); } @@ -876,16 +766,14 @@ static void writeMemoryContentsIfNotable(const KSCrashReportWriter* const writer * * @param string The string to search. */ -static void writeAddressReferencedByString(const KSCrashReportWriter* const writer, - const char* const key, - const char* string) +static void writeAddressReferencedByString(const KSCrashReportWriter *const writer, const char *const key, + const char *string) { uint64_t address = 0; - if(string == NULL || !ksstring_extractHexValue(string, (int)strlen(string), &address)) - { + if (string == NULL || !ksstring_extractHexValue(string, (int)strlen(string), &address)) { return; } - + int limit = kDefaultMemorySearchDepth; writeMemoryContents(writer, key, (uintptr_t)address, &limit); } @@ -900,30 +788,28 @@ static void writeAddressReferencedByString(const KSCrashReportWriter* const writ * * @param stackCursor The stack cursor to read from. */ -static void writeBacktrace(const KSCrashReportWriter* const writer, - const char* const key, - KSStackCursor* stackCursor) +static void writeBacktrace(const KSCrashReportWriter *const writer, const char *const key, KSStackCursor *stackCursor) { writer->beginObject(writer, key); { writer->beginArray(writer, KSCrashField_Contents); { - while(stackCursor->advanceCursor(stackCursor)) - { + while (stackCursor->advanceCursor(stackCursor)) { writer->beginObject(writer, NULL); { - if(stackCursor->symbolicate(stackCursor)) - { - if(stackCursor->stackEntry.imageName != NULL) - { - writer->addStringElement(writer, KSCrashField_ObjectName, ksfu_lastPathEntry(stackCursor->stackEntry.imageName)); + if (stackCursor->symbolicate(stackCursor)) { + if (stackCursor->stackEntry.imageName != NULL) { + writer->addStringElement(writer, KSCrashField_ObjectName, + ksfu_lastPathEntry(stackCursor->stackEntry.imageName)); } - writer->addUIntegerElement(writer, KSCrashField_ObjectAddr, stackCursor->stackEntry.imageAddress); - if(stackCursor->stackEntry.symbolName != NULL) - { - writer->addStringElement(writer, KSCrashField_SymbolName, stackCursor->stackEntry.symbolName); + writer->addUIntegerElement(writer, KSCrashField_ObjectAddr, + stackCursor->stackEntry.imageAddress); + if (stackCursor->stackEntry.symbolName != NULL) { + writer->addStringElement(writer, KSCrashField_SymbolName, + stackCursor->stackEntry.symbolName); } - writer->addUIntegerElement(writer, KSCrashField_SymbolAddr, stackCursor->stackEntry.symbolAddress); + writer->addUIntegerElement(writer, KSCrashField_SymbolAddr, + stackCursor->stackEntry.symbolAddress); } writer->addUIntegerElement(writer, KSCrashField_InstructionAddr, stackCursor->stackEntry.address); } @@ -935,7 +821,6 @@ static void writeBacktrace(const KSCrashReportWriter* const writer, } writer->endContainer(writer); } - #pragma mark Stack @@ -949,21 +834,19 @@ static void writeBacktrace(const KSCrashReportWriter* const writer, * * @param isStackOverflow If true, the stack has overflowed. */ -static void writeStackContents(const KSCrashReportWriter* const writer, - const char* const key, - const struct KSMachineContext* const machineContext, - const bool isStackOverflow) +static void writeStackContents(const KSCrashReportWriter *const writer, const char *const key, + const struct KSMachineContext *const machineContext, const bool isStackOverflow) { uintptr_t sp = kscpu_stackPointer(machineContext); - if((void*)sp == NULL) - { + if ((void *)sp == NULL) { return; } - uintptr_t lowAddress = sp + (uintptr_t)(kStackContentsPushedDistance * (int)sizeof(sp) * kscpu_stackGrowDirection() * -1); - uintptr_t highAddress = sp + (uintptr_t)(kStackContentsPoppedDistance * (int)sizeof(sp) * kscpu_stackGrowDirection()); - if(highAddress < lowAddress) - { + uintptr_t lowAddress = + sp + (uintptr_t)(kStackContentsPushedDistance * (int)sizeof(sp) * kscpu_stackGrowDirection() * -1); + uintptr_t highAddress = + sp + (uintptr_t)(kStackContentsPoppedDistance * (int)sizeof(sp) * kscpu_stackGrowDirection()); + if (highAddress < lowAddress) { uintptr_t tmp = lowAddress; lowAddress = highAddress; highAddress = tmp; @@ -977,12 +860,9 @@ static void writeStackContents(const KSCrashReportWriter* const writer, writer->addBooleanElement(writer, KSCrashField_Overflow, isStackOverflow); uint8_t stackBuffer[kStackContentsTotalDistance * sizeof(sp)]; int copyLength = (int)(highAddress - lowAddress); - if(ksmem_copySafely((void*)lowAddress, stackBuffer, copyLength)) - { - writer->addDataElement(writer, KSCrashField_Contents, (void*)stackBuffer, copyLength); - } - else - { + if (ksmem_copySafely((void *)lowAddress, stackBuffer, copyLength)) { + writer->addDataElement(writer, KSCrashField_Contents, (void *)stackBuffer, copyLength); + } else { writer->addStringElement(writer, KSCrashField_Error, "Stack contents not accessible"); } } @@ -999,38 +879,32 @@ static void writeStackContents(const KSCrashReportWriter* const writer, * * @param forwardDistance The distance past the end of the stack to check. */ -static void writeNotableStackContents(const KSCrashReportWriter* const writer, - const struct KSMachineContext* const machineContext, - const int backDistance, +static void writeNotableStackContents(const KSCrashReportWriter *const writer, + const struct KSMachineContext *const machineContext, const int backDistance, const int forwardDistance) { uintptr_t sp = kscpu_stackPointer(machineContext); - if((void*)sp == NULL) - { + if ((void *)sp == NULL) { return; } uintptr_t lowAddress = sp + (uintptr_t)(backDistance * (int)sizeof(sp) * kscpu_stackGrowDirection() * -1); uintptr_t highAddress = sp + (uintptr_t)(forwardDistance * (int)sizeof(sp) * kscpu_stackGrowDirection()); - if(highAddress < lowAddress) - { + if (highAddress < lowAddress) { uintptr_t tmp = lowAddress; lowAddress = highAddress; highAddress = tmp; } uintptr_t contentsAsPointer; char nameBuffer[40]; - for(uintptr_t address = lowAddress; address < highAddress; address += sizeof(address)) - { - if(ksmem_copySafely((void*)address, &contentsAsPointer, sizeof(contentsAsPointer))) - { - sprintf(nameBuffer, "stack@%p", (void*)address); + for (uintptr_t address = lowAddress; address < highAddress; address += sizeof(address)) { + if (ksmem_copySafely((void *)address, &contentsAsPointer, sizeof(contentsAsPointer))) { + sprintf(nameBuffer, "stack@%p", (void *)address); writeMemoryContentsIfNotable(writer, nameBuffer, contentsAsPointer); } } } - #pragma mark Registers /** Write the contents of all regular registers to the report. @@ -1041,25 +915,21 @@ static void writeNotableStackContents(const KSCrashReportWriter* const writer, * * @param machineContext The context to retrieve the registers from. */ -static void writeBasicRegisters(const KSCrashReportWriter* const writer, - const char* const key, - const struct KSMachineContext* const machineContext) +static void writeBasicRegisters(const KSCrashReportWriter *const writer, const char *const key, + const struct KSMachineContext *const machineContext) { char registerNameBuff[30]; - const char* registerName; + const char *registerName; writer->beginObject(writer, key); { const int numRegisters = kscpu_numRegisters(); - for(int reg = 0; reg < numRegisters; reg++) - { + for (int reg = 0; reg < numRegisters; reg++) { registerName = kscpu_registerName(reg); - if(registerName == NULL) - { + if (registerName == NULL) { snprintf(registerNameBuff, sizeof(registerNameBuff), "r%d", reg); registerName = registerNameBuff; } - writer->addUIntegerElement(writer, registerName, - kscpu_registerValue(machineContext, reg)); + writer->addUIntegerElement(writer, registerName, kscpu_registerValue(machineContext, reg)); } } writer->endContainer(writer); @@ -1073,25 +943,21 @@ static void writeBasicRegisters(const KSCrashReportWriter* const writer, * * @param machineContext The context to retrieve the registers from. */ -static void writeExceptionRegisters(const KSCrashReportWriter* const writer, - const char* const key, - const struct KSMachineContext* const machineContext) +static void writeExceptionRegisters(const KSCrashReportWriter *const writer, const char *const key, + const struct KSMachineContext *const machineContext) { char registerNameBuff[30]; - const char* registerName; + const char *registerName; writer->beginObject(writer, key); { const int numRegisters = kscpu_numExceptionRegisters(); - for(int reg = 0; reg < numRegisters; reg++) - { + for (int reg = 0; reg < numRegisters; reg++) { registerName = kscpu_exceptionRegisterName(reg); - if(registerName == NULL) - { + if (registerName == NULL) { snprintf(registerNameBuff, sizeof(registerNameBuff), "r%d", reg); registerName = registerNameBuff; } - writer->addUIntegerElement(writer,registerName, - kscpu_exceptionRegisterValue(machineContext, reg)); + writer->addUIntegerElement(writer, registerName, kscpu_exceptionRegisterValue(machineContext, reg)); } } writer->endContainer(writer); @@ -1105,15 +971,13 @@ static void writeExceptionRegisters(const KSCrashReportWriter* const writer, * * @param machineContext The context to retrieve the registers from. */ -static void writeRegisters(const KSCrashReportWriter* const writer, - const char* const key, - const struct KSMachineContext* const machineContext) +static void writeRegisters(const KSCrashReportWriter *const writer, const char *const key, + const struct KSMachineContext *const machineContext) { writer->beginObject(writer, key); { writeBasicRegisters(writer, KSCrashField_Basic, machineContext); - if(ksmc_hasValidExceptionRegisters(machineContext)) - { + if (ksmc_hasValidExceptionRegisters(machineContext)) { writeExceptionRegisters(writer, KSCrashField_Exception, machineContext); } } @@ -1126,23 +990,19 @@ static void writeRegisters(const KSCrashReportWriter* const writer, * * @param machineContext The context to retrieve the registers from. */ -static void writeNotableRegisters(const KSCrashReportWriter* const writer, - const struct KSMachineContext* const machineContext) +static void writeNotableRegisters(const KSCrashReportWriter *const writer, + const struct KSMachineContext *const machineContext) { char registerNameBuff[30]; - const char* registerName; + const char *registerName; const int numRegisters = kscpu_numRegisters(); - for(int reg = 0; reg < numRegisters; reg++) - { + for (int reg = 0; reg < numRegisters; reg++) { registerName = kscpu_registerName(reg); - if(registerName == NULL) - { + if (registerName == NULL) { snprintf(registerNameBuff, sizeof(registerNameBuff), "r%d", reg); registerName = registerNameBuff; } - writeMemoryContentsIfNotable(writer, - registerName, - (uintptr_t)kscpu_registerValue(machineContext, reg)); + writeMemoryContentsIfNotable(writer, registerName, (uintptr_t)kscpu_registerValue(machineContext, reg)); } } @@ -1156,16 +1016,13 @@ static void writeNotableRegisters(const KSCrashReportWriter* const writer, * * @param machineContext The context to retrieve the registers from. */ -static void writeNotableAddresses(const KSCrashReportWriter* const writer, - const char* const key, - const struct KSMachineContext* const machineContext) +static void writeNotableAddresses(const KSCrashReportWriter *const writer, const char *const key, + const struct KSMachineContext *const machineContext) { writer->beginObject(writer, key); { writeNotableRegisters(writer, machineContext); - writeNotableStackContents(writer, - machineContext, - kStackNotableSearchBackDistance, + writeNotableStackContents(writer, machineContext, kStackNotableSearchBackDistance, kStackNotableSearchForwardDistance); } writer->endContainer(writer); @@ -1183,12 +1040,9 @@ static void writeNotableAddresses(const KSCrashReportWriter* const writer, * * @param shouldWriteNotableAddresses If true, write any notable addresses found. */ -static void writeThread(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const crash, - const struct KSMachineContext* const machineContext, - const int threadIndex, - const bool shouldWriteNotableAddresses) +static void writeThread(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const crash, const struct KSMachineContext *const machineContext, + const int threadIndex, const bool shouldWriteNotableAddresses) { bool isCrashedThread = ksmc_isCrashedContext(machineContext); KSThread thread = ksmc_getThreadFromContext(machineContext); @@ -1199,32 +1053,26 @@ static void writeThread(const KSCrashReportWriter* const writer, writer->beginObject(writer, key); { - if(hasBacktrace) - { + if (hasBacktrace) { writeBacktrace(writer, KSCrashField_Backtrace, &stackCursor); } - if(ksmc_canHaveCPUState(machineContext)) - { + if (ksmc_canHaveCPUState(machineContext)) { writeRegisters(writer, KSCrashField_Registers, machineContext); } writer->addIntegerElement(writer, KSCrashField_Index, threadIndex); - const char* name = ksccd_getThreadName(thread); - if(name != NULL) - { + const char *name = ksccd_getThreadName(thread); + if (name != NULL) { writer->addStringElement(writer, KSCrashField_Name, name); } name = ksccd_getQueueName(thread); - if(name != NULL) - { + if (name != NULL) { writer->addStringElement(writer, KSCrashField_DispatchQueue, name); } writer->addBooleanElement(writer, KSCrashField_Crashed, isCrashedThread); writer->addBooleanElement(writer, KSCrashField_CurrentThread, thread == ksthread_self()); - if(isCrashedThread) - { + if (isCrashedThread) { writeStackContents(writer, KSCrashField_Stack, machineContext, stackCursor.state.hasGivenUp); - if(shouldWriteNotableAddresses) - { + if (shouldWriteNotableAddresses) { writeNotableAddresses(writer, KSCrashField_NotableAddresses, machineContext); } } @@ -1240,12 +1088,10 @@ static void writeThread(const KSCrashReportWriter* const writer, * * @param crash The crash handler context. */ -static void writeAllThreads(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const crash, - bool writeNotableAddresses) +static void writeAllThreads(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const crash, bool writeNotableAddresses) { - const struct KSMachineContext* const context = crash->offendingMachineContext; + const struct KSMachineContext *const context = crash->offendingMachineContext; KSThread offendingThread = ksmc_getThreadFromContext(context); int threadCount = ksmc_getThreadCount(context); KSMC_NEW_CONTEXT(machineContext); @@ -1254,15 +1100,11 @@ static void writeAllThreads(const KSCrashReportWriter* const writer, writer->beginArray(writer, key); { KSLOG_DEBUG("Writing %d threads.", threadCount); - for(int i = 0; i < threadCount; i++) - { + for (int i = 0; i < threadCount; i++) { KSThread thread = ksmc_getThreadAtIndex(context, i); - if(thread == offendingThread) - { + if (thread == offendingThread) { writeThread(writer, NULL, crash, context, i, writeNotableAddresses); - } - else - { + } else { ksmc_getContextForThread(thread, machineContext, false); writeThread(writer, NULL, crash, machineContext, i, writeNotableAddresses); } @@ -1281,13 +1123,10 @@ static void writeAllThreads(const KSCrashReportWriter* const writer, * * @param index Which image to write about. */ -static void writeBinaryImage(const KSCrashReportWriter* const writer, - const char* const key, - const int index) +static void writeBinaryImage(const KSCrashReportWriter *const writer, const char *const key, const int index) { - KSBinaryImage image = {0}; - if(!ksdl_getBinaryImage(index, &image)) - { + KSBinaryImage image = { 0 }; + if (!ksdl_getBinaryImage(index, &image)) { return; } @@ -1303,20 +1142,16 @@ static void writeBinaryImage(const KSCrashReportWriter* const writer, writer->addUIntegerElement(writer, KSCrashField_ImageMajorVersion, image.majorVersion); writer->addUIntegerElement(writer, KSCrashField_ImageMinorVersion, image.minorVersion); writer->addUIntegerElement(writer, KSCrashField_ImageRevisionVersion, image.revisionVersion); - if(image.crashInfoMessage != NULL) - { + if (image.crashInfoMessage != NULL) { writer->addStringElement(writer, KSCrashField_ImageCrashInfoMessage, image.crashInfoMessage); } - if(image.crashInfoMessage2 != NULL) - { + if (image.crashInfoMessage2 != NULL) { writer->addStringElement(writer, KSCrashField_ImageCrashInfoMessage2, image.crashInfoMessage2); } - if(image.crashInfoBacktrace != NULL) - { + if (image.crashInfoBacktrace != NULL) { writer->addStringElement(writer, KSCrashField_ImageCrashInfoBacktrace, image.crashInfoBacktrace); } - if(image.crashInfoSignature != NULL) - { + if (image.crashInfoSignature != NULL) { writer->addStringElement(writer, KSCrashField_ImageCrashInfoSignature, image.crashInfoSignature); } } @@ -1329,14 +1164,13 @@ static void writeBinaryImage(const KSCrashReportWriter* const writer, * * @param key The object key, if needed. */ -static void writeBinaryImages(const KSCrashReportWriter* const writer, const char* const key) +static void writeBinaryImages(const KSCrashReportWriter *const writer, const char *const key) { const int imageCount = ksdl_imageCount(); writer->beginArray(writer, key); { - for(int iImg = 0; iImg < imageCount; iImg++) - { + for (int iImg = 0; iImg < imageCount; iImg++) { writeBinaryImage(writer, NULL, iImg); } } @@ -1349,9 +1183,8 @@ static void writeBinaryImages(const KSCrashReportWriter* const writer, const cha * * @param key The object key, if needed. */ -static void writeMemoryInfo(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const monitorContext) +static void writeMemoryInfo(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const monitorContext) { writer->beginObject(writer, key); { @@ -1362,7 +1195,7 @@ static void writeMemoryInfo(const KSCrashReportWriter* const writer, writer->endContainer(writer); } -static inline bool isCrashOfMonitorType(const KSCrash_MonitorContext* const crash, const KSCrashMonitorAPI* monitorAPI) +static inline bool isCrashOfMonitorType(const KSCrash_MonitorContext *const crash, const KSCrashMonitorAPI *monitorAPI) { return ksstring_safeStrcmp(crash->monitorId, kscm_getMonitorId(monitorAPI)) == 0; } @@ -1375,25 +1208,22 @@ static inline bool isCrashOfMonitorType(const KSCrash_MonitorContext* const cras * * @param crash The crash handler context. */ -static void writeError(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const crash) +static void writeError(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const crash) { writer->beginObject(writer, key); { #if KSCRASH_HOST_APPLE writer->beginObject(writer, KSCrashField_Mach); { - const char* machExceptionName = ksmach_exceptionName(crash->mach.type); - const char* machCodeName = crash->mach.code == 0 ? NULL : ksmach_kernelReturnCodeName(crash->mach.code); + const char *machExceptionName = ksmach_exceptionName(crash->mach.type); + const char *machCodeName = crash->mach.code == 0 ? NULL : ksmach_kernelReturnCodeName(crash->mach.code); writer->addUIntegerElement(writer, KSCrashField_Exception, (unsigned)crash->mach.type); - if(machExceptionName != NULL) - { + if (machExceptionName != NULL) { writer->addStringElement(writer, KSCrashField_ExceptionName, machExceptionName); } writer->addUIntegerElement(writer, KSCrashField_Code, (unsigned)crash->mach.code); - if(machCodeName != NULL) - { + if (machCodeName != NULL) { writer->addStringElement(writer, KSCrashField_CodeName, machCodeName); } writer->addUIntegerElement(writer, KSCrashField_Subcode, (size_t)crash->mach.subcode); @@ -1402,29 +1232,25 @@ static void writeError(const KSCrashReportWriter* const writer, #endif writer->beginObject(writer, KSCrashField_Signal); { - const char* sigName = kssignal_signalName(crash->signal.signum); - const char* sigCodeName = kssignal_signalCodeName(crash->signal.signum, crash->signal.sigcode); + const char *sigName = kssignal_signalName(crash->signal.signum); + const char *sigCodeName = kssignal_signalCodeName(crash->signal.signum, crash->signal.sigcode); writer->addUIntegerElement(writer, KSCrashField_Signal, (unsigned)crash->signal.signum); - if(sigName != NULL) - { + if (sigName != NULL) { writer->addStringElement(writer, KSCrashField_Name, sigName); } writer->addUIntegerElement(writer, KSCrashField_Code, (unsigned)crash->signal.sigcode); - if(sigCodeName != NULL) - { + if (sigCodeName != NULL) { writer->addStringElement(writer, KSCrashField_CodeName, sigCodeName); } } writer->endContainer(writer); writer->addUIntegerElement(writer, KSCrashField_Address, crash->faultAddress); - if(crash->crashReason != NULL) - { + if (crash->crashReason != NULL) { writer->addStringElement(writer, KSCrashField_Reason, crash->crashReason); } - if (isCrashOfMonitorType(crash, kscm_nsexception_getAPI())) - { + if (isCrashOfMonitorType(crash, kscm_nsexception_getAPI())) { writer->addStringElement(writer, KSCrashField_Type, KSCrashExcType_NSException); writer->beginObject(writer, KSCrashField_NSException); { @@ -1433,30 +1259,20 @@ static void writeError(const KSCrashReportWriter* const writer, writeAddressReferencedByString(writer, KSCrashField_ReferencedObject, crash->crashReason); } writer->endContainer(writer); - } - else if (isCrashOfMonitorType(crash, kscm_machexception_getAPI())) - { + } else if (isCrashOfMonitorType(crash, kscm_machexception_getAPI())) { writer->addStringElement(writer, KSCrashField_Type, KSCrashExcType_Mach); - } - else if (isCrashOfMonitorType(crash, kscm_signal_getAPI())) - { + } else if (isCrashOfMonitorType(crash, kscm_signal_getAPI())) { writer->addStringElement(writer, KSCrashField_Type, KSCrashExcType_Signal); - } - else if (isCrashOfMonitorType(crash, kscm_cppexception_getAPI())) - { + } else if (isCrashOfMonitorType(crash, kscm_cppexception_getAPI())) { writer->addStringElement(writer, KSCrashField_Type, KSCrashExcType_CPPException); writer->beginObject(writer, KSCrashField_CPPException); { writer->addStringElement(writer, KSCrashField_Name, crash->CPPException.name); } writer->endContainer(writer); - } - else if (isCrashOfMonitorType(crash, kscm_deadlock_getAPI())) - { + } else if (isCrashOfMonitorType(crash, kscm_deadlock_getAPI())) { writer->addStringElement(writer, KSCrashField_Type, KSCrashExcType_Deadlock); - } - else if (isCrashOfMonitorType(crash, kscm_memory_getAPI())) - { + } else if (isCrashOfMonitorType(crash, kscm_memory_getAPI())) { writer->addStringElement(writer, KSCrashField_Type, KSCrashExcType_MemoryTermination); writer->beginObject(writer, KSCrashField_MemoryTermination); { @@ -1464,36 +1280,27 @@ static void writeError(const KSCrashReportWriter* const writer, writer->addStringElement(writer, KSCrashField_MemoryLevel, crash->AppMemory.level); } writer->endContainer(writer); - } - else if (isCrashOfMonitorType(crash, kscm_user_getAPI())) - { + } else if (isCrashOfMonitorType(crash, kscm_user_getAPI())) { writer->addStringElement(writer, KSCrashField_Type, KSCrashExcType_User); writer->beginObject(writer, KSCrashField_UserReported); { writer->addStringElement(writer, KSCrashField_Name, crash->userException.name); - if (crash->userException.language != NULL) - { + if (crash->userException.language != NULL) { writer->addStringElement(writer, KSCrashField_Language, crash->userException.language); } - if (crash->userException.lineOfCode != NULL) - { + if (crash->userException.lineOfCode != NULL) { writer->addStringElement(writer, KSCrashField_LineOfCode, crash->userException.lineOfCode); } - if (crash->userException.customStackTrace != NULL) - { + if (crash->userException.customStackTrace != NULL) { writer->addJSONElement(writer, KSCrashField_Backtrace, crash->userException.customStackTrace, true); } } writer->endContainer(writer); - } - else if (isCrashOfMonitorType(crash, kscm_system_getAPI()) || - isCrashOfMonitorType(crash, kscm_appstate_getAPI()) || - isCrashOfMonitorType(crash, kscm_zombie_getAPI())) - { + } else if (isCrashOfMonitorType(crash, kscm_system_getAPI()) || + isCrashOfMonitorType(crash, kscm_appstate_getAPI()) || + isCrashOfMonitorType(crash, kscm_zombie_getAPI())) { KSLOG_ERROR("Crash monitor type %s shouldn't be able to cause events!", crash->monitorId); - } - else - { + } else { KSLOG_WARN("Unknown crash monitor type: %s", crash->monitorId); } } @@ -1508,23 +1315,29 @@ static void writeError(const KSCrashReportWriter* const writer, * * @param monitorContext The event monitor context. */ -static void writeAppStats(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const monitorContext) +static void writeAppStats(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const monitorContext) { writer->beginObject(writer, key); { writer->addBooleanElement(writer, KSCrashField_AppActive, monitorContext->AppState.applicationIsActive); writer->addBooleanElement(writer, KSCrashField_AppInFG, monitorContext->AppState.applicationIsInForeground); - writer->addIntegerElement(writer, KSCrashField_LaunchesSinceCrash, monitorContext->AppState.launchesSinceLastCrash); - writer->addIntegerElement(writer, KSCrashField_SessionsSinceCrash, monitorContext->AppState.sessionsSinceLastCrash); - writer->addFloatingPointElement(writer, KSCrashField_ActiveTimeSinceCrash, monitorContext->AppState.activeDurationSinceLastCrash); - writer->addFloatingPointElement(writer, KSCrashField_BGTimeSinceCrash, monitorContext->AppState.backgroundDurationSinceLastCrash); - - writer->addIntegerElement(writer, KSCrashField_SessionsSinceLaunch, monitorContext->AppState.sessionsSinceLaunch); - writer->addFloatingPointElement(writer, KSCrashField_ActiveTimeSinceLaunch, monitorContext->AppState.activeDurationSinceLaunch); - writer->addFloatingPointElement(writer, KSCrashField_BGTimeSinceLaunch, monitorContext->AppState.backgroundDurationSinceLaunch); + writer->addIntegerElement(writer, KSCrashField_LaunchesSinceCrash, + monitorContext->AppState.launchesSinceLastCrash); + writer->addIntegerElement(writer, KSCrashField_SessionsSinceCrash, + monitorContext->AppState.sessionsSinceLastCrash); + writer->addFloatingPointElement(writer, KSCrashField_ActiveTimeSinceCrash, + monitorContext->AppState.activeDurationSinceLastCrash); + writer->addFloatingPointElement(writer, KSCrashField_BGTimeSinceCrash, + monitorContext->AppState.backgroundDurationSinceLastCrash); + + writer->addIntegerElement(writer, KSCrashField_SessionsSinceLaunch, + monitorContext->AppState.sessionsSinceLaunch); + writer->addFloatingPointElement(writer, KSCrashField_ActiveTimeSinceLaunch, + monitorContext->AppState.activeDurationSinceLaunch); + writer->addFloatingPointElement(writer, KSCrashField_BGTimeSinceLaunch, + monitorContext->AppState.backgroundDurationSinceLaunch); } writer->endContainer(writer); } @@ -1535,20 +1348,19 @@ static void writeAppStats(const KSCrashReportWriter* const writer, * * @param key The object key, if needed. */ -static void writeProcessState(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const monitorContext) +static void writeProcessState(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const monitorContext) { writer->beginObject(writer, key); { - if(monitorContext->ZombieException.address != 0) - { + if (monitorContext->ZombieException.address != 0) { writer->beginObject(writer, KSCrashField_LastDeallocedNSException); { writer->addUIntegerElement(writer, KSCrashField_Address, monitorContext->ZombieException.address); writer->addStringElement(writer, KSCrashField_Name, monitorContext->ZombieException.name); writer->addStringElement(writer, KSCrashField_Reason, monitorContext->ZombieException.reason); - writeAddressReferencedByString(writer, KSCrashField_ReferencedObject, monitorContext->ZombieException.reason); + writeAddressReferencedByString(writer, KSCrashField_ReferencedObject, + monitorContext->ZombieException.reason); } writer->endContainer(writer); } @@ -1566,11 +1378,8 @@ static void writeProcessState(const KSCrashReportWriter* const writer, * * @param reportID The report ID. */ -static void writeReportInfo(const KSCrashReportWriter* const writer, - const char* const key, - const char* const type, - const char* const reportID, - const char* const processName) +static void writeReportInfo(const KSCrashReportWriter *const writer, const char *const key, const char *const type, + const char *const reportID, const char *const processName) { writer->beginObject(writer, key); { @@ -1583,14 +1392,11 @@ static void writeReportInfo(const KSCrashReportWriter* const writer, writer->endContainer(writer); } -static void writeRecrash(const KSCrashReportWriter* const writer, - const char* const key, - const char* crashReportPath) +static void writeRecrash(const KSCrashReportWriter *const writer, const char *const key, const char *crashReportPath) { writer->addJSONFileElement(writer, key, crashReportPath, true); } - #pragma mark Setup /** Prepare a report writer for use. @@ -1599,7 +1405,7 @@ static void writeRecrash(const KSCrashReportWriter* const writer, * * @param context JSON writer contextual information. */ -static void prepareReportWriter(KSCrashReportWriter* const writer, KSJSONEncodeContext* const context) +static void prepareReportWriter(KSCrashReportWriter *const writer, KSJSONEncodeContext *const context) { writer->addBooleanElement = addBooleanElement; writer->addFloatingPointElement = addFloatingPointElement; @@ -1621,12 +1427,11 @@ static void prepareReportWriter(KSCrashReportWriter* const writer, KSJSONEncodeC writer->context = context; } - // ============================================================================ #pragma mark - Main API - // ============================================================================ -void kscrashreport_writeRecrashReport(const KSCrash_MonitorContext* const monitorContext, const char* const path) +void kscrashreport_writeRecrashReport(const KSCrash_MonitorContext *const monitorContext, const char *const path) { char writeBuffer[1024]; KSBufferedWriter bufferedWriter; @@ -1635,12 +1440,10 @@ void kscrashreport_writeRecrashReport(const KSCrash_MonitorContext* const monito strncpy(tempPath + strlen(tempPath) - 5, ".old", 5); KSLOG_INFO("Writing recrash report to %s", path); - if(rename(path, tempPath) < 0) - { + if (rename(path, tempPath) < 0) { KSLOG_ERROR("Could not rename %s to %s: %s", path, tempPath, strerror(errno)); } - if(!ksfu_openBufferedWriter(&bufferedWriter, path, writeBuffer, sizeof(writeBuffer))) - { + if (!ksfu_openBufferedWriter(&bufferedWriter, path, writeBuffer, sizeof(writeBuffer))) { return; } @@ -1649,7 +1452,7 @@ void kscrashreport_writeRecrashReport(const KSCrash_MonitorContext* const monito KSJSONEncodeContext jsonContext; jsonContext.userData = &bufferedWriter; KSCrashReportWriter concreteWriter; - KSCrashReportWriter* writer = &concreteWriter; + KSCrashReportWriter *writer = &concreteWriter; prepareReportWriter(writer, &jsonContext); ksjson_beginEncode(getJsonContext(writer), true, addJSONData, &bufferedWriter); @@ -1658,14 +1461,10 @@ void kscrashreport_writeRecrashReport(const KSCrash_MonitorContext* const monito { writeRecrash(writer, KSCrashField_RecrashReport, tempPath); ksfu_flushBufferedWriter(&bufferedWriter); - if(remove(tempPath) < 0) - { + if (remove(tempPath) < 0) { KSLOG_ERROR("Could not remove %s: %s", tempPath, strerror(errno)); } - writeReportInfo(writer, - KSCrashField_Report, - KSCrashReportType_Minimal, - monitorContext->eventID, + writeReportInfo(writer, KSCrashField_Report, KSCrashReportType_Minimal, monitorContext->eventID, monitorContext->System.processName); ksfu_flushBufferedWriter(&bufferedWriter); @@ -1675,12 +1474,8 @@ void kscrashreport_writeRecrashReport(const KSCrash_MonitorContext* const monito ksfu_flushBufferedWriter(&bufferedWriter); int threadIndex = ksmc_indexOfThread(monitorContext->offendingMachineContext, ksmc_getThreadFromContext(monitorContext->offendingMachineContext)); - writeThread(writer, - KSCrashField_CrashedThread, - monitorContext, - monitorContext->offendingMachineContext, - threadIndex, - false); + writeThread(writer, KSCrashField_CrashedThread, monitorContext, monitorContext->offendingMachineContext, + threadIndex, false); ksfu_flushBufferedWriter(&bufferedWriter); } writer->endContainer(writer); @@ -1692,9 +1487,8 @@ void kscrashreport_writeRecrashReport(const KSCrash_MonitorContext* const monito ksccd_unfreeze(); } -static void writeAppMemoryInfo(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const monitorContext) +static void writeAppMemoryInfo(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const monitorContext) { writer->beginObject(writer, key); { @@ -1708,9 +1502,8 @@ static void writeAppMemoryInfo(const KSCrashReportWriter* const writer, writer->endContainer(writer); } -static void writeSystemInfo(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const monitorContext) +static void writeSystemInfo(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const monitorContext) { writer->beginObject(writer, key); { @@ -1748,51 +1541,43 @@ static void writeSystemInfo(const KSCrashReportWriter* const writer, writeAppMemoryInfo(writer, KSCrashField_AppMemory, monitorContext); } writer->endContainer(writer); - } -static void writeDebugInfo(const KSCrashReportWriter* const writer, - const char* const key, - const KSCrash_MonitorContext* const monitorContext) +static void writeDebugInfo(const KSCrashReportWriter *const writer, const char *const key, + const KSCrash_MonitorContext *const monitorContext) { writer->beginObject(writer, key); { - if(monitorContext->consoleLogPath != NULL) - { + if (monitorContext->consoleLogPath != NULL) { addTextLinesFromFile(writer, KSCrashField_ConsoleLog, monitorContext->consoleLogPath); } } writer->endContainer(writer); - } -void kscrashreport_writeStandardReport(const KSCrash_MonitorContext* const monitorContext, const char* const path) +void kscrashreport_writeStandardReport(const KSCrash_MonitorContext *const monitorContext, const char *const path) { KSLOG_INFO("Writing crash report to %s", path); char writeBuffer[1024]; KSBufferedWriter bufferedWriter; - if(!ksfu_openBufferedWriter(&bufferedWriter, path, writeBuffer, sizeof(writeBuffer))) - { + if (!ksfu_openBufferedWriter(&bufferedWriter, path, writeBuffer, sizeof(writeBuffer))) { return; } ksccd_freeze(); - + KSJSONEncodeContext jsonContext; jsonContext.userData = &bufferedWriter; KSCrashReportWriter concreteWriter; - KSCrashReportWriter* writer = &concreteWriter; + KSCrashReportWriter *writer = &concreteWriter; prepareReportWriter(writer, &jsonContext); ksjson_beginEncode(getJsonContext(writer), true, addJSONData, &bufferedWriter); writer->beginObject(writer, KSCrashField_Report); { - writeReportInfo(writer, - KSCrashField_Report, - KSCrashReportType_Standard, - monitorContext->eventID, + writeReportInfo(writer, KSCrashField_Report, KSCrashReportType_Standard, monitorContext->eventID, monitorContext->System.processName); ksfu_flushBufferedWriter(&bufferedWriter); @@ -1800,7 +1585,7 @@ void kscrashreport_writeStandardReport(const KSCrash_MonitorContext* const monit writeBinaryImages(writer, KSCrashField_BinaryImages); ksfu_flushBufferedWriter(&bufferedWriter); } - + writeProcessState(writer, KSCrashField_ProcessState, monitorContext); ksfu_flushBufferedWriter(&bufferedWriter); @@ -1811,25 +1596,18 @@ void kscrashreport_writeStandardReport(const KSCrash_MonitorContext* const monit { writeError(writer, KSCrashField_Error, monitorContext); ksfu_flushBufferedWriter(&bufferedWriter); - writeAllThreads(writer, - KSCrashField_Threads, - monitorContext, - g_introspectionRules.enabled); + writeAllThreads(writer, KSCrashField_Threads, monitorContext, g_introspectionRules.enabled); ksfu_flushBufferedWriter(&bufferedWriter); } writer->endContainer(writer); - if(g_userInfoJSON != NULL) - { + if (g_userInfoJSON != NULL) { addJSONElement(writer, KSCrashField_User, g_userInfoJSON, false); ksfu_flushBufferedWriter(&bufferedWriter); - } - else - { + } else { writer->beginObject(writer, KSCrashField_User); } - if(g_userSectionWriteCallback != NULL) - { + if (g_userSectionWriteCallback != NULL) { ksfu_flushBufferedWriter(&bufferedWriter); if (monitorContext->currentSnapshotUserReported == false) { g_userSectionWriteCallback(writer); @@ -1841,40 +1619,34 @@ void kscrashreport_writeStandardReport(const KSCrash_MonitorContext* const monit writeDebugInfo(writer, KSCrashField_Debug, monitorContext); } writer->endContainer(writer); - + ksjson_endEncode(getJsonContext(writer)); ksfu_closeBufferedWriter(&bufferedWriter); ksccd_unfreeze(); } - -void kscrashreport_setUserInfoJSON(const char* const userInfoJSON) +void kscrashreport_setUserInfoJSON(const char *const userInfoJSON) { KSLOG_TRACE("Setting userInfoJSON to %p", userInfoJSON); pthread_mutex_lock(&g_userInfoMutex); - if (g_userInfoJSON != NULL) - { - free((void*)g_userInfoJSON); + if (g_userInfoJSON != NULL) { + free((void *)g_userInfoJSON); } - if (userInfoJSON == NULL) - { + if (userInfoJSON == NULL) { g_userInfoJSON = NULL; - } - else - { + } else { g_userInfoJSON = strdup(userInfoJSON); } pthread_mutex_unlock(&g_userInfoMutex); } -const char* kscrashreport_getUserInfoJSON(void) +const char *kscrashreport_getUserInfoJSON(void) { - const char* userInfoJSONCopy = NULL; + const char *userInfoJSONCopy = NULL; pthread_mutex_lock(&g_userInfoMutex); - if (g_userInfoJSON != NULL) - { + if (g_userInfoJSON != NULL) { userInfoJSONCopy = strdup(g_userInfoJSON); } pthread_mutex_unlock(&g_userInfoMutex); @@ -1887,37 +1659,32 @@ void kscrashreport_setIntrospectMemory(bool shouldIntrospectMemory) g_introspectionRules.enabled = shouldIntrospectMemory; } -void kscrashreport_setDoNotIntrospectClasses(const char** doNotIntrospectClasses, int length) +void kscrashreport_setDoNotIntrospectClasses(const char **doNotIntrospectClasses, int length) { - const char** oldClasses = g_introspectionRules.restrictedClasses; + const char **oldClasses = g_introspectionRules.restrictedClasses; int oldClassesLength = g_introspectionRules.restrictedClassesCount; - const char** newClasses = NULL; + const char **newClasses = NULL; int newClassesLength = 0; - - if(doNotIntrospectClasses != NULL && length > 0) - { + + if (doNotIntrospectClasses != NULL && length > 0) { newClassesLength = length; newClasses = malloc(sizeof(*newClasses) * (unsigned)newClassesLength); - if(newClasses == NULL) - { + if (newClasses == NULL) { KSLOG_ERROR("Could not allocate memory"); return; } - - for(int i = 0; i < newClassesLength; i++) - { + + for (int i = 0; i < newClassesLength; i++) { newClasses[i] = strdup(doNotIntrospectClasses[i]); } } - + g_introspectionRules.restrictedClasses = newClasses; g_introspectionRules.restrictedClassesCount = newClassesLength; - - if(oldClasses != NULL) - { - for(int i = 0; i < oldClassesLength; i++) - { - free((void*)oldClasses[i]); + + if (oldClasses != NULL) { + for (int i = 0; i < oldClassesLength; i++) { + free((void *)oldClasses[i]); } free(oldClasses); } diff --git a/Sources/KSCrashRecording/KSCrashReportC.h b/Sources/KSCrashRecording/KSCrashReportC.h index 793a55f41..ae2de3ef8 100644 --- a/Sources/KSCrashRecording/KSCrashReportC.h +++ b/Sources/KSCrashRecording/KSCrashReportC.h @@ -24,19 +24,17 @@ // THE SOFTWARE. // - /* Writes a crash report to disk. */ - #ifndef HDR_KSCrashReport_h #define HDR_KSCrashReport_h -#import "KSCrashReportWriter.h" -#import "KSCrashMonitorContext.h" - #include +#import "KSCrashMonitorContext.h" +#import "KSCrashReportWriter.h" + #ifdef __cplusplus extern "C" { #endif @@ -44,12 +42,12 @@ extern "C" { // ============================================================================ #pragma mark - Configuration - // ============================================================================ - + /** Set custom user information to be stored in the report. * * @param userInfoJSON The user information, in JSON format. */ -void kscrashreport_setUserInfoJSON(const char* const userInfoJSON); +void kscrashreport_setUserInfoJSON(const char *const userInfoJSON); /** Get a copy of the custom user information stored in the report. * @@ -57,7 +55,7 @@ void kscrashreport_setUserInfoJSON(const char* const userInfoJSON); * or NULL if no information is set. * The caller is responsible for freeing the returned string. */ -const char* kscrashreport_getUserInfoJSON(void); +const char *kscrashreport_getUserInfoJSON(void); /** Configure whether to introspect any interesting memory locations. * This can find things like strings or Objective-C classes. @@ -71,7 +69,7 @@ void kscrashreport_setIntrospectMemory(bool shouldIntrospectMemory); * @param doNotIntrospectClasses Array of class names. * @param length Length of the array. */ -void kscrashreport_setDoNotIntrospectClasses(const char** doNotIntrospectClasses, int length); +void kscrashreport_setDoNotIntrospectClasses(const char **doNotIntrospectClasses, int length); /** Set the function to call when writing the user section of the report. * This allows the user to add more fields to the user section at the time of the crash. @@ -81,11 +79,10 @@ void kscrashreport_setDoNotIntrospectClasses(const char** doNotIntrospectClasses */ void kscrashreport_setUserSectionWriteCallback(const KSReportWriteCallback userSectionWriteCallback); - // ============================================================================ #pragma mark - Main API - // ============================================================================ - + /** Write a standard crash report to a file. * * @param monitorContext Contextual information about the crash and environment. @@ -93,8 +90,7 @@ void kscrashreport_setUserSectionWriteCallback(const KSReportWriteCallback userS * * @param path The file to write to. */ -void kscrashreport_writeStandardReport(const struct KSCrash_MonitorContext* const monitorContext, - const char* path); +void kscrashreport_writeStandardReport(const struct KSCrash_MonitorContext *const monitorContext, const char *path); /** Write a minimal crash report to a file. * @@ -103,12 +99,10 @@ void kscrashreport_writeStandardReport(const struct KSCrash_MonitorContext* cons * * @param path The file to write to. */ -void kscrashreport_writeRecrashReport(const struct KSCrash_MonitorContext* const monitorContext, - const char* path); - +void kscrashreport_writeRecrashReport(const struct KSCrash_MonitorContext *const monitorContext, const char *path); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashReport_h +#endif // HDR_KSCrashReport_h diff --git a/Sources/KSCrashRecording/KSCrashReportFixer.c b/Sources/KSCrashRecording/KSCrashReportFixer.c index 8e53160d6..79b75cfcf 100644 --- a/Sources/KSCrashRecording/KSCrashReportFixer.c +++ b/Sources/KSCrashRecording/KSCrashReportFixer.c @@ -25,117 +25,105 @@ // #include "KSCrashReportFields.h" -#include "KSSystemCapabilities.h" -#include "KSJSONCodec.h" #include "KSDemangle_CPP.h" +#include "KSJSONCodec.h" +#include "KSSystemCapabilities.h" #if KSCRASH_HAS_SWIFT #include "KSDemangle_Swift.h" #endif -#include "KSDate.h" -#include "KSLogger.h" - #include #include +#include "KSDate.h" +#include "KSLogger.h" + #define MAX_DEPTH 100 #define MAX_NAME_LENGTH 100 #define REPORT_VERSION_COMPONENTS_COUNT 3 -static const char* datePaths[][MAX_DEPTH] = -{ - {"", KSCrashField_Report, KSCrashField_Timestamp}, - {"", KSCrashField_RecrashReport, KSCrashField_Report, KSCrashField_Timestamp}, +static const char *datePaths[][MAX_DEPTH] = { + { "", KSCrashField_Report, KSCrashField_Timestamp }, + { "", KSCrashField_RecrashReport, KSCrashField_Report, KSCrashField_Timestamp }, }; static int datePathsCount = sizeof(datePaths) / sizeof(*datePaths); -static const char* demanglePaths[][MAX_DEPTH] = -{ - {"", KSCrashField_Crash, KSCrashField_Threads, "", KSCrashField_Backtrace, KSCrashField_Contents, "", KSCrashField_SymbolName}, - {"", KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Threads, "", KSCrashField_Backtrace, KSCrashField_Contents, "", KSCrashField_SymbolName}, - {"", KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, KSCrashField_Name}, - {"", KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, KSCrashField_Name}, +static const char *demanglePaths[][MAX_DEPTH] = { + { "", KSCrashField_Crash, KSCrashField_Threads, "", KSCrashField_Backtrace, KSCrashField_Contents, "", + KSCrashField_SymbolName }, + { "", KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Threads, "", KSCrashField_Backtrace, + KSCrashField_Contents, "", KSCrashField_SymbolName }, + { "", KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, KSCrashField_Name }, + { "", KSCrashField_RecrashReport, KSCrashField_Crash, KSCrashField_Error, KSCrashField_CPPException, + KSCrashField_Name }, }; static int demanglePathsCount = sizeof(demanglePaths) / sizeof(*demanglePaths); -static const char* versionPaths[][MAX_DEPTH] = -{ - {"", KSCrashField_Report, KSCrashField_Version}, - {"", KSCrashField_RecrashReport, KSCrashField_Report, KSCrashField_Version}, +static const char *versionPaths[][MAX_DEPTH] = { + { "", KSCrashField_Report, KSCrashField_Version }, + { "", KSCrashField_RecrashReport, KSCrashField_Report, KSCrashField_Version }, }; static int versionPathsCount = sizeof(versionPaths) / sizeof(*versionPaths); -typedef struct -{ - KSJSONEncodeContext* encodeContext; +typedef struct { + KSJSONEncodeContext *encodeContext; int reportVersionComponents[REPORT_VERSION_COMPONENTS_COUNT]; char objectPath[MAX_DEPTH][MAX_NAME_LENGTH]; int currentDepth; - char* outputPtr; + char *outputPtr; int outputBytesLeft; } FixupContext; -static bool increaseDepth(FixupContext* context, const char* name) +static bool increaseDepth(FixupContext *context, const char *name) { - if(context->currentDepth >= MAX_DEPTH) - { + if (context->currentDepth >= MAX_DEPTH) { return false; } - if(name == NULL) - { + if (name == NULL) { *context->objectPath[context->currentDepth] = '\0'; - } - else - { + } else { strncpy(context->objectPath[context->currentDepth], name, sizeof(context->objectPath[context->currentDepth])); } context->currentDepth++; return true; } -static bool decreaseDepth(FixupContext* context) +static bool decreaseDepth(FixupContext *context) { - if(context->currentDepth <= 0) - { + if (context->currentDepth <= 0) { return false; } context->currentDepth--; return true; } -static bool matchesPath(FixupContext* context, const char** path, const char* finalName) +static bool matchesPath(FixupContext *context, const char **path, const char *finalName) { - if(finalName == NULL) - { + if (finalName == NULL) { finalName = ""; } - for(int i = 0;i < context->currentDepth; i++) - { - if(strncmp(context->objectPath[i], path[i], MAX_NAME_LENGTH) != 0) - { + for (int i = 0; i < context->currentDepth; i++) { + if (strncmp(context->objectPath[i], path[i], MAX_NAME_LENGTH) != 0) { return false; } } - if(strncmp(finalName, path[context->currentDepth], MAX_NAME_LENGTH) != 0) - { + if (strncmp(finalName, path[context->currentDepth], MAX_NAME_LENGTH) != 0) { return false; } return true; } -static bool matchesAPath(FixupContext* context, const char* name, const char* paths[][MAX_DEPTH], int pathsCount) +static bool matchesAPath(FixupContext *context, const char *name, const char *paths[][MAX_DEPTH], int pathsCount) { - for(int i = 0; i < pathsCount; i++) - { - if(matchesPath(context, paths[i], name)) - { + for (int i = 0; i < pathsCount; i++) { + if (matchesPath(context, paths[i], name)) { return true; } } return false; } -static bool matchesMinVersion(FixupContext* context, int major, int minor, int patch) +static bool matchesMinVersion(FixupContext *context, int major, int minor, int patch) { // Works only for report version 3.1.0 and above. See KSCrashReportVersion.h bool result = false; @@ -146,106 +134,85 @@ static bool matchesMinVersion(FixupContext* context, int major, int minor, int p return result; } -static bool shouldDemangle(FixupContext* context, const char* name) +static bool shouldDemangle(FixupContext *context, const char *name) { return matchesAPath(context, name, demanglePaths, demanglePathsCount); } -static bool shouldFixDate(FixupContext* context, const char* name) +static bool shouldFixDate(FixupContext *context, const char *name) { return matchesAPath(context, name, datePaths, datePathsCount); } -static bool shouldSaveVersion(FixupContext* context, const char* name) +static bool shouldSaveVersion(FixupContext *context, const char *name) { return matchesAPath(context, name, versionPaths, versionPathsCount); } -static int onBooleanElement(const char* const name, - const bool value, - void* const userData) +static int onBooleanElement(const char *const name, const bool value, void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; return ksjson_addBooleanElement(context->encodeContext, name, value); } -static int onFloatingPointElement(const char* const name, - const double value, - void* const userData) +static int onFloatingPointElement(const char *const name, const double value, void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; return ksjson_addFloatingPointElement(context->encodeContext, name, value); } -static int onIntegerElement(const char* const name, - const int64_t value, - void* const userData) +static int onIntegerElement(const char *const name, const int64_t value, void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; int result = KSJSON_OK; - if(shouldFixDate(context, name)) - { + if (shouldFixDate(context, name)) { char buffer[28]; - if(matchesMinVersion(context, 3, 3, 0)) - { + if (matchesMinVersion(context, 3, 3, 0)) { ksdate_utcStringFromMicroseconds(value, buffer); - } - else - { + } else { ksdate_utcStringFromTimestamp((time_t)value, buffer); } result = ksjson_addStringElement(context->encodeContext, name, buffer, (int)strlen(buffer)); - } - else - { + } else { result = ksjson_addIntegerElement(context->encodeContext, name, value); } return result; } -static int onNullElement(const char* const name, - void* const userData) +static int onNullElement(const char *const name, void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; return ksjson_addNullElement(context->encodeContext, name); } -static int onStringElement(const char* const name, - const char* const value, - void* const userData) +static int onStringElement(const char *const name, const char *const value, void *const userData) { - FixupContext* context = (FixupContext*)userData; - const char* stringValue = value; - char* demangled = NULL; - if(shouldDemangle(context, name)) - { + FixupContext *context = (FixupContext *)userData; + const char *stringValue = value; + char *demangled = NULL; + if (shouldDemangle(context, name)) { demangled = ksdm_demangleCPP(value); #if KSCRASH_HAS_SWIFT - if(demangled == NULL) - { + if (demangled == NULL) { demangled = ksdm_demangleSwift(value); } #endif - if(demangled != NULL) - { + if (demangled != NULL) { stringValue = demangled; } } int result = ksjson_addStringElement(context->encodeContext, name, stringValue, (int)strlen(stringValue)); - if(demangled != NULL) - { + if (demangled != NULL) { free(demangled); } - if(shouldSaveVersion(context, name)) - { + if (shouldSaveVersion(context, name)) { memset(context->reportVersionComponents, 0, sizeof(context->reportVersionComponents)); int versionPartsIndex = 0; - char* mutableValue = strdup(value); - char* versionPart = strtok(mutableValue, "."); - while(versionPart != NULL && versionPartsIndex < REPORT_VERSION_COMPONENTS_COUNT) - { + char *mutableValue = strdup(value); + char *versionPart = strtok(mutableValue, "."); + while (versionPart != NULL && versionPartsIndex < REPORT_VERSION_COMPONENTS_COUNT) { context->reportVersionComponents[versionPartsIndex++] = atoi(versionPart); versionPart = strtok(NULL, "."); } @@ -254,70 +221,62 @@ static int onStringElement(const char* const name, return result; } -static int onBeginObject(const char* const name, - void* const userData) +static int onBeginObject(const char *const name, void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; int result = ksjson_beginObject(context->encodeContext, name); - if(!increaseDepth(context, name)) - { + if (!increaseDepth(context, name)) { return KSJSON_ERROR_DATA_TOO_LONG; } return result; } -static int onBeginArray(const char* const name, - void* const userData) +static int onBeginArray(const char *const name, void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; int result = ksjson_beginArray(context->encodeContext, name); - if(!increaseDepth(context, name)) - { + if (!increaseDepth(context, name)) { return KSJSON_ERROR_DATA_TOO_LONG; } return result; } -static int onEndContainer(void* const userData) +static int onEndContainer(void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; int result = ksjson_endContainer(context->encodeContext); - if(!decreaseDepth(context)) - { + if (!decreaseDepth(context)) { // Do something; } return result; } -static int onEndData(__unused void* const userData) +static int onEndData(__unused void *const userData) { - FixupContext* context = (FixupContext*)userData; + FixupContext *context = (FixupContext *)userData; return ksjson_endEncode(context->encodeContext); } -static int addJSONData(const char* data, int length, void* userData) +static int addJSONData(const char *data, int length, void *userData) { - FixupContext* context = (FixupContext*)userData; - if(length > context->outputBytesLeft) - { + FixupContext *context = (FixupContext *)userData; + if (length > context->outputBytesLeft) { return KSJSON_ERROR_DATA_TOO_LONG; } memcpy(context->outputPtr, data, length); context->outputPtr += length; context->outputBytesLeft -= length; - + return KSJSON_OK; } -char* kscrf_fixupCrashReport(const char* crashReport) +char *kscrf_fixupCrashReport(const char *crashReport) { - if(crashReport == NULL) - { + if (crashReport == NULL) { return NULL; } - KSJSONDecodeCallbacks callbacks = - { + KSJSONDecodeCallbacks callbacks = { .onBeginArray = onBeginArray, .onBeginObject = onBeginObject, .onBooleanElement = onBooleanElement, @@ -329,28 +288,27 @@ char* kscrf_fixupCrashReport(const char* crashReport) .onStringElement = onStringElement, }; int stringBufferLength = 10000; - char* stringBuffer = malloc((unsigned)stringBufferLength); + char *stringBuffer = malloc((unsigned)stringBufferLength); int crashReportLength = (int)strlen(crashReport); int fixedReportLength = (int)(crashReportLength * 1.5); - char* fixedReport = malloc((unsigned)fixedReportLength); + char *fixedReport = malloc((unsigned)fixedReportLength); KSJSONEncodeContext encodeContext; - FixupContext fixupContext = - { + FixupContext fixupContext = { .encodeContext = &encodeContext, - .reportVersionComponents = {0}, + .reportVersionComponents = { 0 }, .currentDepth = 0, .outputPtr = fixedReport, .outputBytesLeft = fixedReportLength, }; - + ksjson_beginEncode(&encodeContext, true, addJSONData, &fixupContext); - + int errorOffset = 0; - int result = ksjson_decode(crashReport, (int)strlen(crashReport), stringBuffer, stringBufferLength, &callbacks, &fixupContext, &errorOffset); + int result = ksjson_decode(crashReport, (int)strlen(crashReport), stringBuffer, stringBufferLength, &callbacks, + &fixupContext, &errorOffset); *fixupContext.outputPtr = '\0'; free(stringBuffer); - if(result != KSJSON_OK) - { + if (result != KSJSON_OK) { KSLOG_ERROR("Could not decode report: %s", ksjson_stringForError(result)); free(fixedReport); return NULL; diff --git a/Sources/KSCrashRecording/KSCrashReportFixer.h b/Sources/KSCrashRecording/KSCrashReportFixer.h index ba8d96459..22b333c9d 100644 --- a/Sources/KSCrashRecording/KSCrashReportFixer.h +++ b/Sources/KSCrashRecording/KSCrashReportFixer.h @@ -31,7 +31,6 @@ extern "C" { #endif - /** Fixes up fields in a crash report that could not be fixed up at crash time. * Some fields, such a mangled fields and dates, cannot be fixed up at crash time * because the function calls needed to do it are not async-safe. @@ -41,11 +40,10 @@ extern "C" { * @return A fixed up crash report. * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on the returned value. */ -char* kscrf_fixupCrashReport(const char* crashReport); - +char *kscrf_fixupCrashReport(const char *crashReport); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashReportFixer_h +#endif // HDR_KSCrashReportFixer_h diff --git a/Sources/KSCrashRecording/KSCrashReportStore.c b/Sources/KSCrashRecording/KSCrashReportStore.c index 78d3ff49e..901d085c4 100644 --- a/Sources/KSCrashRecording/KSCrashReportStore.c +++ b/Sources/KSCrashRecording/KSCrashReportStore.c @@ -25,8 +25,6 @@ // #include "KSCrashReportStore.h" -#include "KSLogger.h" -#include "KSFileUtils.h" #include #include @@ -38,46 +36,41 @@ #include #include +#include "KSFileUtils.h" +#include "KSLogger.h" static int g_maxReportCount = 5; // Have to use max 32-bit atomics because of MIPS. static _Atomic(uint32_t) g_nextUniqueIDLow; static int64_t g_nextUniqueIDHigh; -static const char* g_appName; -static const char* g_reportsPath; -static const char* g_installPath; +static const char *g_appName; +static const char *g_reportsPath; +static const char *g_installPath; static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; -static int compareInt64(const void* a, const void* b) +static int compareInt64(const void *a, const void *b) { - int64_t diff = *(int64_t*)a - *(int64_t*)b; - if(diff < 0) - { + int64_t diff = *(int64_t *)a - *(int64_t *)b; + if (diff < 0) { return -1; - } - else if(diff > 0) - { + } else if (diff > 0) { return 1; } return 0; } -static inline int64_t getNextUniqueID(void) -{ - return g_nextUniqueIDHigh + g_nextUniqueIDLow++; -} +static inline int64_t getNextUniqueID(void) { return g_nextUniqueIDHigh + g_nextUniqueIDLow++; } -static void getCrashReportPathByID(int64_t id, char* pathBuffer) +static void getCrashReportPathByID(int64_t id, char *pathBuffer) { snprintf(pathBuffer, KSCRS_MAX_PATH_LENGTH, "%s/%s-report-%016llx.json", g_reportsPath, g_appName, id); - } -static int64_t getReportIDFromFilename(const char* filename) +static int64_t getReportIDFromFilename(const char *filename) { char scanFormat[100]; sprintf(scanFormat, "%s-report-%%" PRIx64 ".json", g_appName); - + int64_t reportID = 0; sscanf(filename, scanFormat, &reportID); return reportID; @@ -86,45 +79,38 @@ static int64_t getReportIDFromFilename(const char* filename) static int getReportCount(void) { int count = 0; - DIR* dir = opendir(g_reportsPath); - if(dir == NULL) - { + DIR *dir = opendir(g_reportsPath); + if (dir == NULL) { KSLOG_ERROR("Could not open directory %s", g_reportsPath); goto done; } - struct dirent* ent; - while((ent = readdir(dir)) != NULL) - { - if(getReportIDFromFilename(ent->d_name) > 0) - { + struct dirent *ent; + while ((ent = readdir(dir)) != NULL) { + if (getReportIDFromFilename(ent->d_name) > 0) { count++; } } done: - if(dir != NULL) - { + if (dir != NULL) { closedir(dir); } return count; } -static int getReportIDs(int64_t* reportIDs, int count) +static int getReportIDs(int64_t *reportIDs, int count) { int index = 0; - DIR* dir = opendir(g_reportsPath); - if(dir == NULL) - { + DIR *dir = opendir(g_reportsPath); + if (dir == NULL) { KSLOG_ERROR("Could not open directory %s", g_reportsPath); goto done; } - struct dirent* ent; - while((ent = readdir(dir)) != NULL && index < count) - { + struct dirent *ent; + while ((ent = readdir(dir)) != NULL && index < count) { int64_t reportID = getReportIDFromFilename(ent->d_name); - if(reportID > 0) - { + if (reportID > 0) { reportIDs[index++] = reportID; } } @@ -132,8 +118,7 @@ static int getReportIDs(int64_t* reportIDs, int count) qsort(reportIDs, (unsigned)count, sizeof(reportIDs[0]), compareInt64); done: - if(dir != NULL) - { + if (dir != NULL) { closedir(dir); } return index; @@ -142,18 +127,16 @@ static int getReportIDs(int64_t* reportIDs, int count) static void pruneReports(void) { int reportCount = getReportCount(); - if(reportCount > g_maxReportCount) - { + if (reportCount > g_maxReportCount) { int64_t reportIDs[reportCount]; reportCount = getReportIDs(reportIDs, reportCount); - - for(int i = 0; i < reportCount - g_maxReportCount; i++) - { + + for (int i = 0; i < reportCount - g_maxReportCount; i++) { kscrs_deleteReportWithID(reportIDs[i]); } } } - +// clang-format off static void initializeIDs(void) { time_t rawTime; @@ -170,11 +153,11 @@ static void initializeIDs(void) g_nextUniqueIDHigh = baseID & ~(int64_t)0xffffffff; g_nextUniqueIDLow = (uint32_t)(baseID & 0xffffffff); } - +// clang-format on // Public API -void kscrs_initialize(const char* appName, const char* installPath, const char* reportsPath) +void kscrs_initialize(const char *appName, const char *installPath, const char *reportsPath) { pthread_mutex_lock(&g_mutex); g_appName = strdup(appName); @@ -187,11 +170,10 @@ void kscrs_initialize(const char* appName, const char* installPath, const char* pthread_mutex_unlock(&g_mutex); } -int64_t kscrs_getNextCrashReport(char* crashReportPathBuffer) +int64_t kscrs_getNextCrashReport(char *crashReportPathBuffer) { int64_t nextID = getNextUniqueID(); - if(crashReportPathBuffer) - { + if (crashReportPathBuffer) { getCrashReportPathByID(nextID, crashReportPathBuffer); } return nextID; @@ -205,7 +187,7 @@ int kscrs_getReportCount(void) return count; } -int kscrs_getReportIDs(int64_t* reportIDs, int count) +int kscrs_getReportIDs(int64_t *reportIDs, int count) { pthread_mutex_lock(&g_mutex); count = getReportIDs(reportIDs, count); @@ -213,27 +195,27 @@ int kscrs_getReportIDs(int64_t* reportIDs, int count) return count; } -char* kscrs_readReportAtPath(const char *path) +char *kscrs_readReportAtPath(const char *path) { pthread_mutex_lock(&g_mutex); - char* result; + char *result; ksfu_readEntireFile(path, &result, NULL, 2000000); pthread_mutex_unlock(&g_mutex); return result; } -char* kscrs_readReport(int64_t reportID) +char *kscrs_readReport(int64_t reportID) { pthread_mutex_lock(&g_mutex); char path[KSCRS_MAX_PATH_LENGTH]; getCrashReportPathByID(reportID, path); - char* result; + char *result; ksfu_readEntireFile(path, &result, NULL, 2000000); pthread_mutex_unlock(&g_mutex); return result; } -int64_t kscrs_addUserReport(const char* report, int reportLength) +int64_t kscrs_addUserReport(const char *report, int reportLength) { pthread_mutex_lock(&g_mutex); int64_t currentID = getNextUniqueID(); @@ -241,26 +223,22 @@ int64_t kscrs_addUserReport(const char* report, int reportLength) getCrashReportPathByID(currentID, crashReportPath); int fd = open(crashReportPath, O_WRONLY | O_CREAT, 0644); - if(fd < 0) - { + if (fd < 0) { KSLOG_ERROR("Could not open file %s: %s", crashReportPath, strerror(errno)); goto done; } int bytesWritten = (int)write(fd, report, (unsigned)reportLength); - if(bytesWritten < 0) - { + if (bytesWritten < 0) { KSLOG_ERROR("Could not write to file %s: %s", crashReportPath, strerror(errno)); goto done; - } - else if(bytesWritten < reportLength) - { - KSLOG_ERROR("Expected to write %d bytes to file %s, but only wrote %d", crashReportPath, reportLength, bytesWritten); + } else if (bytesWritten < reportLength) { + KSLOG_ERROR("Expected to write %d bytes to file %s, but only wrote %d", crashReportPath, reportLength, + bytesWritten); } done: - if(fd >= 0) - { + if (fd >= 0) { close(fd); } pthread_mutex_unlock(&g_mutex); @@ -282,7 +260,4 @@ void kscrs_deleteReportWithID(int64_t reportID) ksfu_removeFile(path, true); } -void kscrs_setMaxReportCount(int maxReportCount) -{ - g_maxReportCount = maxReportCount; -} +void kscrs_setMaxReportCount(int maxReportCount) { g_maxReportCount = maxReportCount; } diff --git a/Sources/KSCrashRecording/KSCrashReportStore.h b/Sources/KSCrashRecording/KSCrashReportStore.h index df55ad562..a99abab19 100644 --- a/Sources/KSCrashRecording/KSCrashReportStore.h +++ b/Sources/KSCrashRecording/KSCrashReportStore.h @@ -41,7 +41,7 @@ extern "C" { * @param installPath Full path to directory where the crash system writes files. * @param reportsPath Full path to directory where the reports are to be stored (path will be created if needed). */ -void kscrs_initialize(const char* appName, const char* installPath, const char* reportsPath); +void kscrs_initialize(const char *appName, const char *installPath, const char *reportsPath); /** Get the next crash report to be generated. * Max length for paths is KSCRS_MAX_PATH_LENGTH @@ -50,7 +50,7 @@ void kscrs_initialize(const char* appName, const char* installPath, const char* * * @return the report ID of the next report. */ -int64_t kscrs_getNextCrashReport(char* crashReportPathBuffer); +int64_t kscrs_getNextCrashReport(char *crashReportPathBuffer); /** Get the number of reports on disk. */ @@ -63,7 +63,7 @@ int kscrs_getReportCount(void); * * @return The number of report IDs that were placed in the array. */ -int kscrs_getReportIDs(int64_t* reportIDs, int count); +int kscrs_getReportIDs(int64_t *reportIDs, int count); /** Read a report. * @@ -72,8 +72,8 @@ int kscrs_getReportIDs(int64_t* reportIDs, int count); * @return The NULL terminated report, or NULL if not found. * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on the returned value. */ -char* kscrs_readReport(int64_t reportID); -char* kscrs_readReportAtPath(const char *path); +char *kscrs_readReport(int64_t reportID); +char *kscrs_readReportAtPath(const char *path); /** Add a custom report to the store. * @@ -82,7 +82,7 @@ char* kscrs_readReportAtPath(const char *path); * * @return the new report's ID. */ -int64_t kscrs_addUserReport(const char* report, int reportLength); +int64_t kscrs_addUserReport(const char *report, int reportLength); /** Delete all reports on disk. */ @@ -98,10 +98,10 @@ void kscrs_deleteReportWithID(int64_t reportID); * * @param maxReportCount The maximum number of reports. */ - void kscrs_setMaxReportCount(int maxReportCount); +void kscrs_setMaxReportCount(int maxReportCount); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashReportStore_h +#endif // HDR_KSCrashReportStore_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitorContextHelper.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitorContextHelper.h index e054a2d7e..d0864977a 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitorContextHelper.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitorContextHelper.h @@ -27,15 +27,15 @@ #ifndef KSCrashMonitorContextHelper_h #define KSCrashMonitorContextHelper_h -#include "KSCrashMonitorContext.h" #include "KSCrashMonitor.h" +#include "KSCrashMonitorContext.h" #include "KSCrashMonitorHelper.h" #ifdef __cplusplus extern "C" { #endif -static void inline ksmc_fillMonitorContext(KSCrash_MonitorContext* monitorContext, KSCrashMonitorAPI* monitorApi) +static void inline ksmc_fillMonitorContext(KSCrash_MonitorContext *monitorContext, KSCrashMonitorAPI *monitorApi) { if (monitorContext) { monitorContext->monitorId = kscm_getMonitorId(monitorApi); diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.c b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.c index b74565ef1..383f270c1 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.c +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.c @@ -24,16 +24,13 @@ // THE SOFTWARE. // - #include "KSCrashMonitor_AppState.h" +#include "KSCrashMonitorContext.h" #include "KSFileUtils.h" #include "KSJSONCodec.h" -#include "KSCrashMonitorContext.h" - -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" +// #define KSLogger_LocalLevel TRACE #include #include #include @@ -42,6 +39,7 @@ #include #include +#include "KSLogger.h" // ============================================================================ #pragma mark - Constants - @@ -62,7 +60,7 @@ // ============================================================================ /** Location where stat file is stored. */ -static const char* g_stateFilePath; +static const char *g_stateFilePath; /** Current state. */ static KSCrash_AppState g_state; @@ -73,52 +71,43 @@ static volatile bool g_isEnabled = false; #pragma mark - JSON Encoding - // ============================================================================ -static int onBooleanElement(const char* const name, const bool value, void* const userData) +static int onBooleanElement(const char *const name, const bool value, void *const userData) { - KSCrash_AppState* state = userData; + KSCrash_AppState *state = userData; - if(strcmp(name, kKeyCrashedLastLaunch) == 0) - { + if (strcmp(name, kKeyCrashedLastLaunch) == 0) { state->crashedLastLaunch = value; } return KSJSON_OK; } -static int onFloatingPointElement(const char* const name, const double value, void* const userData) +static int onFloatingPointElement(const char *const name, const double value, void *const userData) { - KSCrash_AppState* state = userData; + KSCrash_AppState *state = userData; - if(strcmp(name, kKeyActiveDurationSinceLastCrash) == 0) - { + if (strcmp(name, kKeyActiveDurationSinceLastCrash) == 0) { state->activeDurationSinceLastCrash = value; } - if(strcmp(name, kKeyBackgroundDurationSinceLastCrash) == 0) - { + if (strcmp(name, kKeyBackgroundDurationSinceLastCrash) == 0) { state->backgroundDurationSinceLastCrash = value; } return KSJSON_OK; } -static int onIntegerElement(const char* const name, const int64_t value, void* const userData) +static int onIntegerElement(const char *const name, const int64_t value, void *const userData) { - KSCrash_AppState* state = userData; + KSCrash_AppState *state = userData; - if(strcmp(name, kKeyFormatVersion) == 0) - { - if(value != kFormatVersion) - { + if (strcmp(name, kKeyFormatVersion) == 0) { + if (value != kFormatVersion) { KSLOG_ERROR("Expected version 1 but got %" PRId64, value); return KSJSON_ERROR_INVALID_DATA; } - } - else if(strcmp(name, kKeyLaunchesSinceLastCrash) == 0) - { + } else if (strcmp(name, kKeyLaunchesSinceLastCrash) == 0) { state->launchesSinceLastCrash = (int)value; - } - else if(strcmp(name, kKeySessionsSinceLastCrash) == 0) - { + } else if (strcmp(name, kKeySessionsSinceLastCrash) == 0) { state->sessionsSinceLastCrash = (int)value; } @@ -126,49 +115,31 @@ static int onIntegerElement(const char* const name, const int64_t value, void* c return onFloatingPointElement(name, value, userData); } -static int onNullElement(__unused const char* const name, __unused void* const userData) -{ - return KSJSON_OK; -} +static int onNullElement(__unused const char *const name, __unused void *const userData) { return KSJSON_OK; } -static int onStringElement(__unused const char* const name, - __unused const char* const value, - __unused void* const userData) +static int onStringElement(__unused const char *const name, __unused const char *const value, + __unused void *const userData) { return KSJSON_OK; } -static int onBeginObject(__unused const char* const name, __unused void* const userData) -{ - return KSJSON_OK; -} +static int onBeginObject(__unused const char *const name, __unused void *const userData) { return KSJSON_OK; } -static int onBeginArray(__unused const char* const name, __unused void* const userData) -{ - return KSJSON_OK; -} +static int onBeginArray(__unused const char *const name, __unused void *const userData) { return KSJSON_OK; } -static int onEndContainer(__unused void* const userData) -{ - return KSJSON_OK; -} - -static int onEndData(__unused void* const userData) -{ - return KSJSON_OK; -} +static int onEndContainer(__unused void *const userData) { return KSJSON_OK; } +static int onEndData(__unused void *const userData) { return KSJSON_OK; } /** Callback for adding JSON data. */ -static int addJSONData(const char* const data, const int length, void* const userData) +static int addJSONData(const char *const data, const int length, void *const userData) { - const int fd = *((int*)userData); + const int fd = *((int *)userData); const bool success = ksfu_writeBytesToFD(fd, data, length); return success ? KSJSON_OK : KSJSON_ERROR_CANNOT_ADD_DATA; } - // ============================================================================ #pragma mark - Utility - // ============================================================================ @@ -180,10 +151,7 @@ static double getCurrentTime(void) return tv.tv_sec + (double)tv.tv_usec / 1000000.0; } -static double timeSince(double timeInSeconds) -{ - return getCurrentTime() - timeInSeconds; -} +static double timeSince(double timeInSeconds) { return getCurrentTime() - timeInSeconds; } /** Load the persistent state portion of a crash context. * @@ -191,21 +159,19 @@ static double timeSince(double timeInSeconds) * * @return true if the operation was successful. */ -static bool loadState(const char* const path) +static bool loadState(const char *const path) { // Stop if the file doesn't exist. // This is expected on the first run of the app. const int fd = open(path, O_RDONLY); - if(fd < 0) - { + if (fd < 0) { return false; } close(fd); - char* data; + char *data; int length; - if(!ksfu_readEntireFile(path, &data, &length, 50000)) - { + if (!ksfu_readEntireFile(path, &data, &length, 50000)) { KSLOG_ERROR("%s: Could not load file", path); return false; } @@ -224,18 +190,11 @@ static bool loadState(const char* const path) int errorOffset = 0; char stringBuffer[1000]; - const int result = ksjson_decode(data, - (int)length, - stringBuffer, - sizeof(stringBuffer), - &callbacks, - &g_state, - &errorOffset); + const int result = + ksjson_decode(data, (int)length, stringBuffer, sizeof(stringBuffer), &callbacks, &g_state, &errorOffset); free(data); - if(result != KSJSON_OK) - { - KSLOG_ERROR("%s, offset %d: %s", - path, errorOffset, ksjson_stringForError(result)); + if (result != KSJSON_OK) { + KSLOG_ERROR("%s, offset %d: %s", path, errorOffset, ksjson_stringForError(result)); return false; } return true; @@ -247,73 +206,51 @@ static bool loadState(const char* const path) * * @return true if the operation was successful. */ -static bool saveState(const char* const path) +static bool saveState(const char *const path) { int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644); - if(fd < 0) - { - KSLOG_ERROR("Could not open file %s for writing: %s", - path, - strerror(errno)); + if (fd < 0) { + KSLOG_ERROR("Could not open file %s for writing: %s", path, strerror(errno)); return false; } KSJSONEncodeContext JSONContext; - ksjson_beginEncode(&JSONContext, - true, - addJSONData, - &fd); + ksjson_beginEncode(&JSONContext, true, addJSONData, &fd); int result; - if((result = ksjson_beginObject(&JSONContext, NULL)) != KSJSON_OK) - { + if ((result = ksjson_beginObject(&JSONContext, NULL)) != KSJSON_OK) { goto done; } - if((result = ksjson_addIntegerElement(&JSONContext, - kKeyFormatVersion, - kFormatVersion)) != KSJSON_OK) - { + if ((result = ksjson_addIntegerElement(&JSONContext, kKeyFormatVersion, kFormatVersion)) != KSJSON_OK) { goto done; } // Record this launch crashed state into "crashed last launch" field. - if((result = ksjson_addBooleanElement(&JSONContext, - kKeyCrashedLastLaunch, - g_state.crashedThisLaunch)) != KSJSON_OK) - { + if ((result = ksjson_addBooleanElement(&JSONContext, kKeyCrashedLastLaunch, g_state.crashedThisLaunch)) != + KSJSON_OK) { goto done; } - if((result = ksjson_addFloatingPointElement(&JSONContext, - kKeyActiveDurationSinceLastCrash, - g_state.activeDurationSinceLastCrash)) != KSJSON_OK) - { + if ((result = ksjson_addFloatingPointElement(&JSONContext, kKeyActiveDurationSinceLastCrash, + g_state.activeDurationSinceLastCrash)) != KSJSON_OK) { goto done; } - if((result = ksjson_addFloatingPointElement(&JSONContext, - kKeyBackgroundDurationSinceLastCrash, - g_state.backgroundDurationSinceLastCrash)) != KSJSON_OK) - { + if ((result = ksjson_addFloatingPointElement(&JSONContext, kKeyBackgroundDurationSinceLastCrash, + g_state.backgroundDurationSinceLastCrash)) != KSJSON_OK) { goto done; } - if((result = ksjson_addIntegerElement(&JSONContext, - kKeyLaunchesSinceLastCrash, - g_state.launchesSinceLastCrash)) != KSJSON_OK) - { + if ((result = ksjson_addIntegerElement(&JSONContext, kKeyLaunchesSinceLastCrash, g_state.launchesSinceLastCrash)) != + KSJSON_OK) { goto done; } - if((result = ksjson_addIntegerElement(&JSONContext, - kKeySessionsSinceLastCrash, - g_state.sessionsSinceLastCrash)) != KSJSON_OK) - { + if ((result = ksjson_addIntegerElement(&JSONContext, kKeySessionsSinceLastCrash, g_state.sessionsSinceLastCrash)) != + KSJSON_OK) { goto done; } result = ksjson_endEncode(&JSONContext); done: close(fd); - if(result != KSJSON_OK) - { - KSLOG_ERROR("%s: %s", - path, ksjson_stringForError(result)); + if (result != KSJSON_OK) { + KSLOG_ERROR("%s: %s", path, ksjson_stringForError(result)); return false; } return true; @@ -323,18 +260,16 @@ static void updateAppState(void) { const double duration = timeSince(g_state.appStateTransitionTime); g_state.appStateTransitionTime = getCurrentTime(); - - if(g_state.applicationIsActive) - { + + if (g_state.applicationIsActive) { KSLOG_TRACE("Updating activeDurationSinceLaunch: %f and activeDurationSinceLastCrash: %f with duration: %f", g_state.activeDurationSinceLaunch, g_state.activeDurationSinceLastCrash, duration); g_state.activeDurationSinceLaunch += duration; g_state.activeDurationSinceLastCrash += duration; - } - else if(!g_state.applicationIsInForeground) - { - KSLOG_TRACE("Updating backgroundDurationSinceLaunch: %f and backgroundDurationSinceLastCrash: %f with duration: %f", - g_state.backgroundDurationSinceLaunch, g_state.backgroundDurationSinceLastCrash, duration); + } else if (!g_state.applicationIsInForeground) { + KSLOG_TRACE( + "Updating backgroundDurationSinceLaunch: %f and backgroundDurationSinceLastCrash: %f with duration: %f", + g_state.backgroundDurationSinceLaunch, g_state.backgroundDurationSinceLastCrash, duration); g_state.backgroundDurationSinceLaunch += duration; g_state.backgroundDurationSinceLastCrash += duration; } @@ -344,7 +279,7 @@ static void updateAppState(void) #pragma mark - API - // ============================================================================ -void kscrashstate_initialize(const char* const stateFilePath) +void kscrashstate_initialize(const char *const stateFilePath) { g_stateFilePath = strdup(stateFilePath); loadState(g_stateFilePath); @@ -352,20 +287,18 @@ void kscrashstate_initialize(const char* const stateFilePath) bool kscrashstate_reset(void) { - if(g_isEnabled) - { + if (g_isEnabled) { g_state.sessionsSinceLaunch = 1; g_state.activeDurationSinceLaunch = 0; g_state.backgroundDurationSinceLaunch = 0; - if(g_state.crashedLastLaunch) - { + if (g_state.crashedLastLaunch) { g_state.activeDurationSinceLastCrash = 0; g_state.backgroundDurationSinceLastCrash = 0; g_state.launchesSinceLastCrash = 0; g_state.sessionsSinceLastCrash = 0; } g_state.crashedThisLaunch = false; - + // Simulate first transition to foreground g_state.launchesSinceLastCrash++; g_state.sessionsSinceLastCrash++; @@ -387,16 +320,12 @@ void kscrashstate_notifyObjCLoad(void) void kscrashstate_notifyAppActive(const bool isActive) { - if(g_isEnabled) - { + if (g_isEnabled) { g_state.applicationIsActive = isActive; - if(isActive) - { + if (isActive) { KSLOG_TRACE("Updating transition time from: %f to: %f", g_state.appStateTransitionTime, getCurrentTime()); g_state.appStateTransitionTime = getCurrentTime(); - } - else - { + } else { double duration = timeSince(g_state.appStateTransitionTime); KSLOG_TRACE("Updating activeDurationSinceLaunch: %f and activeDurationSinceLastCrash: %f with duration: %f", g_state.activeDurationSinceLaunch, g_state.activeDurationSinceLastCrash, duration); @@ -408,23 +337,20 @@ void kscrashstate_notifyAppActive(const bool isActive) void kscrashstate_notifyAppInForeground(const bool isInForeground) { - if(g_isEnabled) - { - const char* const stateFilePath = g_stateFilePath; + if (g_isEnabled) { + const char *const stateFilePath = g_stateFilePath; g_state.applicationIsInForeground = isInForeground; - if(isInForeground) - { + if (isInForeground) { double duration = getCurrentTime() - g_state.appStateTransitionTime; - KSLOG_TRACE("Updating backgroundDurationSinceLaunch: %f and backgroundDurationSinceLastCrash: %f with duration: %f", - g_state.backgroundDurationSinceLaunch, g_state.backgroundDurationSinceLastCrash, duration); + KSLOG_TRACE( + "Updating backgroundDurationSinceLaunch: %f and backgroundDurationSinceLastCrash: %f with duration: %f", + g_state.backgroundDurationSinceLaunch, g_state.backgroundDurationSinceLastCrash, duration); g_state.backgroundDurationSinceLaunch += duration; g_state.backgroundDurationSinceLastCrash += duration; g_state.sessionsSinceLastCrash++; g_state.sessionsSinceLaunch++; - } - else - { + } else { g_state.appStateTransitionTime = getCurrentTime(); saveState(stateFilePath); } @@ -433,9 +359,8 @@ void kscrashstate_notifyAppInForeground(const bool isInForeground) void kscrashstate_notifyAppTerminate(void) { - if(g_isEnabled) - { - const char* const stateFilePath = g_stateFilePath; + if (g_isEnabled) { + const char *const stateFilePath = g_stateFilePath; updateAppState(); saveState(stateFilePath); } @@ -444,47 +369,33 @@ void kscrashstate_notifyAppTerminate(void) void kscrashstate_notifyAppCrash(void) { KSLOG_TRACE("Trying to update AppState. g_isEnabled: %d", g_isEnabled); - if(g_isEnabled) - { - const char* const stateFilePath = g_stateFilePath; + if (g_isEnabled) { + const char *const stateFilePath = g_stateFilePath; updateAppState(); g_state.crashedThisLaunch = true; saveState(stateFilePath); } } -const KSCrash_AppState* const kscrashstate_currentState(void) -{ - return &g_state; -} +const KSCrash_AppState *const kscrashstate_currentState(void) { return &g_state; } -static const char* monitorId(void) -{ - return "ApplicationState"; -} +static const char *monitorId(void) { return "ApplicationState"; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { kscrashstate_reset(); } } } -static bool isEnabled(void) -{ - return g_isEnabled; -} - +static bool isEnabled(void) { return g_isEnabled; } -static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(KSCrash_MonitorContext *eventContext) { - if(g_isEnabled) - { + if (g_isEnabled) { updateAppState(); eventContext->AppState.activeDurationSinceLastCrash = g_state.activeDurationSinceLastCrash; eventContext->AppState.activeDurationSinceLaunch = g_state.activeDurationSinceLaunch; @@ -501,14 +412,11 @@ static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) } } -KSCrashMonitorAPI* kscm_appstate_getAPI(void) +KSCrashMonitorAPI *kscm_appstate_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent - }; + static KSCrashMonitorAPI api = { .monitorId = monitorId, + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; return &api; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.h index 4ccaeb37f..0614338bf 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_AppState.h @@ -24,74 +24,70 @@ // THE SOFTWARE. // - /* Manages persistent state information useful for crash reporting such as * number of sessions, session length, etc. */ - #ifndef HDR_KSCrashMonitor_AppState_h #define HDR_KSCrashMonitor_AppState_h -#include "KSCrashMonitor.h" - #include +#include "KSCrashMonitor.h" + #ifdef __cplusplus extern "C" { #endif -typedef struct -{ +typedef struct { // Saved data - + /** Total active time elapsed since the last crash. */ double activeDurationSinceLastCrash; - + /** Total time backgrounded elapsed since the last crash. */ double backgroundDurationSinceLastCrash; - + /** Number of app launches since the last crash. */ int launchesSinceLastCrash; - + /** Number of sessions (launch, resume from suspend) since last crash. */ int sessionsSinceLastCrash; - + /** Total active time elapsed since launch. */ double activeDurationSinceLaunch; - + /** Total time backgrounded elapsed since launch. */ double backgroundDurationSinceLaunch; - + /** Number of sessions (launch, resume from suspend) since app launch. */ int sessionsSinceLaunch; - + /** If true, the application crashed on the previous launch. */ bool crashedLastLaunch; - + // Live data - + /** If true, the application crashed on this launch. */ bool crashedThisLaunch; - + /** Timestamp for when the app state was last changed (active<->inactive, * background<->foreground) */ double appStateTransitionTime; - + /** If true, the application is currently active. */ bool applicationIsActive; - + /** If true, the application is currently in the foreground. */ bool applicationIsInForeground; - + } KSCrash_AppState; - /** Initialize the state monitor. * * @param stateFilePath Where to store on-disk representation of state. */ -void kscrashstate_initialize(const char* stateFilePath); +void kscrashstate_initialize(const char *stateFilePath); /** Reset the crash state. */ @@ -124,15 +120,14 @@ void kscrashstate_notifyAppCrash(void); /** Read-only access into the current state. */ -const KSCrash_AppState* const kscrashstate_currentState(void); +const KSCrash_AppState *const kscrashstate_currentState(void); /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_appstate_getAPI(void); - +KSCrashMonitorAPI *kscm_appstate_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_AppState_h +#endif // HDR_KSCrashMonitor_AppState_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.cpp b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.cpp index 5e54bff1a..57bbb882f 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.cpp +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.cpp @@ -24,35 +24,32 @@ #include "KSCrashMonitor_CPPException.h" -#include "KSCrashMonitorContextHelper.h" #include "KSCrashMonitorContext.h" +#include "KSCrashMonitorContextHelper.h" #include "KSID.h" -#include "KSThread.h" #include "KSMachineContext.h" #include "KSStackCursor_SelfThread.h" +#include "KSThread.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - -#include "KSCxaThrowSwapper.h" - +// #define KSLogger_LocalLevel TRACE #include #include #include #include #include -#include + #include +#include +#include "KSCxaThrowSwapper.h" +#include "KSLogger.h" #define STACKTRACE_BUFFER_LENGTH 30 #define DESCRIPTION_BUFFER_LENGTH 1000 - // Compiler hints for "if" statements -#define likely_if(x) if(__builtin_expect(x,1)) -#define unlikely_if(x) if(__builtin_expect(x,0)) - +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) // ============================================================================ #pragma mark - Globals - @@ -80,40 +77,34 @@ static KSStackCursor g_stackCursor; #pragma mark - Callbacks - // ============================================================================ -static void captureStackTrace(void*, std::type_info* tinfo, void (*)(void*)) __attribute__((disable_tail_calls)) +static void captureStackTrace(void *, std::type_info *tinfo, void (*)(void *)) __attribute__((disable_tail_calls)) { - if (tinfo != nullptr && strcmp(tinfo->name(), "NSException") == 0) - { + if (tinfo != nullptr && strcmp(tinfo->name(), "NSException") == 0) { return; } - if(g_captureNextStackTrace) - { + if (g_captureNextStackTrace) { kssc_initSelfThread(&g_stackCursor, 2); } - __asm__ __volatile__(""); // thwart tail-call optimization + __asm__ __volatile__(""); // thwart tail-call optimization } -typedef void (*cxa_throw_type)(void*, std::type_info*, void (*)(void*)); +typedef void (*cxa_throw_type)(void *, std::type_info *, void (*)(void *)); -extern "C" +extern "C" { +void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void *)) __attribute__((weak)); + +void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void *)) + __attribute__((disable_tail_calls)) { - void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)) __attribute__ ((weak)); - - void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)) __attribute__((disable_tail_calls)) - { - static cxa_throw_type orig_cxa_throw = NULL; - if (g_cxaSwapEnabled == false) - { - captureStackTrace(thrown_exception, tinfo, dest); - } - unlikely_if(orig_cxa_throw == NULL) - { - orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw"); - } - orig_cxa_throw(thrown_exception, tinfo, dest); - __asm__ __volatile__(""); // thwart tail-call optimization - __builtin_unreachable(); + static cxa_throw_type orig_cxa_throw = NULL; + if (g_cxaSwapEnabled == false) { + captureStackTrace(thrown_exception, tinfo, dest); } + unlikely_if(orig_cxa_throw == NULL) { orig_cxa_throw = (cxa_throw_type)dlsym(RTLD_NEXT, "__cxa_throw"); } + orig_cxa_throw(thrown_exception, tinfo, dest); + __asm__ __volatile__(""); // thwart tail-call optimization + __builtin_unreachable(); +} } static void CPPExceptionTerminate(void) @@ -122,56 +113,46 @@ static void CPPExceptionTerminate(void) mach_msg_type_number_t numThreads = 0; ksmc_suspendEnvironment(&threads, &numThreads); KSLOG_DEBUG("Trapped c++ exception"); - const char* name = NULL; - std::type_info* tinfo = __cxxabiv1::__cxa_current_exception_type(); - if(tinfo != NULL) - { + const char *name = NULL; + std::type_info *tinfo = __cxxabiv1::__cxa_current_exception_type(); + if (tinfo != NULL) { name = tinfo->name(); } - - if(name == NULL || strcmp(name, "NSException") != 0) - { + + if (name == NULL || strcmp(name, "NSException") != 0) { kscm_notifyFatalExceptionCaptured(false); - KSCrash_MonitorContext* crashContext = &g_monitorContext; + KSCrash_MonitorContext *crashContext = &g_monitorContext; memset(crashContext, 0, sizeof(*crashContext)); char descriptionBuff[DESCRIPTION_BUFFER_LENGTH]; - const char* description = descriptionBuff; + const char *description = descriptionBuff; descriptionBuff[0] = 0; KSLOG_DEBUG("Discovering what kind of exception was thrown."); g_captureNextStackTrace = false; - try - { + try { throw; - } - catch(std::exception& exc) - { + } catch (std::exception &exc) { strncpy(descriptionBuff, exc.what(), sizeof(descriptionBuff)); } -#define CATCH_VALUE(TYPE, PRINTFTYPE) \ -catch(TYPE value)\ -{ \ - snprintf(descriptionBuff, sizeof(descriptionBuff), "%" #PRINTFTYPE, value); \ -} - CATCH_VALUE(char, d) - CATCH_VALUE(short, d) - CATCH_VALUE(int, d) - CATCH_VALUE(long, ld) - CATCH_VALUE(long long, lld) - CATCH_VALUE(unsigned char, u) - CATCH_VALUE(unsigned short, u) - CATCH_VALUE(unsigned int, u) - CATCH_VALUE(unsigned long, lu) +#define CATCH_VALUE(TYPE, PRINTFTYPE) \ + catch (TYPE value) { snprintf(descriptionBuff, sizeof(descriptionBuff), "%" #PRINTFTYPE, value); \ + } + CATCH_VALUE(char, d) + CATCH_VALUE(short, d) + CATCH_VALUE(int, d) + CATCH_VALUE(long, ld) + CATCH_VALUE(long long, lld) + CATCH_VALUE(unsigned char, u) + CATCH_VALUE(unsigned short, u) + CATCH_VALUE(unsigned int, u) + CATCH_VALUE(unsigned long, lu) CATCH_VALUE(unsigned long long, llu) - CATCH_VALUE(float, f) - CATCH_VALUE(double, f) - CATCH_VALUE(long double, Lf) - CATCH_VALUE(char*, s) - catch(...) - { - description = NULL; - } + CATCH_VALUE(float, f) + CATCH_VALUE(double, f) + CATCH_VALUE(long double, Lf) + CATCH_VALUE(char *, s) + catch (...) { description = NULL; } g_captureNextStackTrace = g_isEnabled; // TODO: Should this be done here? Maybe better in the exception handler? @@ -189,9 +170,7 @@ catch(TYPE value)\ crashContext->offendingMachineContext = machineContext; kscm_handleException(crashContext); - } - else - { + } else { KSLOG_DEBUG("Detected NSException. Letting the current NSException handler deal with it."); } ksmc_resumeEnvironment(threads, numThreads); @@ -200,7 +179,6 @@ catch(TYPE value)\ g_originalTerminateHandler(); } - // ============================================================================ #pragma mark - Public API - // ============================================================================ @@ -208,65 +186,46 @@ catch(TYPE value)\ static void initialize() { static bool isInitialized = false; - if(!isInitialized) - { + if (!isInitialized) { isInitialized = true; kssc_initCursor(&g_stackCursor, NULL, NULL); } } -static const char* monitorId() -{ - return "CPPException"; -} +static const char *monitorId() { return "CPPException"; } -static KSCrashMonitorFlag monitorFlags() -{ - return KSCrashMonitorFlagFatal; -} +static KSCrashMonitorFlag monitorFlags() { return KSCrashMonitorFlagFatal; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { initialize(); ksid_generate(g_eventID); g_originalTerminateHandler = std::set_terminate(CPPExceptionTerminate); - } - else - { + } else { std::set_terminate(g_originalTerminateHandler); } g_captureNextStackTrace = isEnabled; } } -static bool isEnabled() -{ - return g_isEnabled; -} +static bool isEnabled() { return g_isEnabled; } extern "C" void kscm_enableSwapCxaThrow(void) { - if (g_cxaSwapEnabled != true) - { + if (g_cxaSwapEnabled != true) { ksct_swap(captureStackTrace); g_cxaSwapEnabled = true; } } -extern "C" KSCrashMonitorAPI* kscm_cppexception_getAPI() +extern "C" KSCrashMonitorAPI *kscm_cppexception_getAPI() { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .monitorFlags = monitorFlags, - .setEnabled = setEnabled, - .isEnabled = isEnabled + static KSCrashMonitorAPI api = { + .monitorId = monitorId, .monitorFlags = monitorFlags, .setEnabled = setEnabled, .isEnabled = isEnabled }; return &api; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.h index bbb9287a0..ccf741c06 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_CPPException.h @@ -37,11 +37,10 @@ void kscm_enableSwapCxaThrow(void); /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_cppexception_getAPI(void); - +KSCrashMonitorAPI *kscm_cppexception_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_CPPException_h +#endif // HDR_KSCrashMonitor_CPPException_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.h index 697a91b66..c09133754 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.h @@ -27,7 +27,6 @@ /* Catches deadlocks in threads and queues. */ - #ifndef HDR_KSCrashMonitor_Deadlock_h #define HDR_KSCrashMonitor_Deadlock_h @@ -35,12 +34,10 @@ extern "C" { #endif +#include #include "KSCrashMonitor.h" -#include - - /** Set the interval between watchdog checks on the main thread. * Default is 5 seconds. * @@ -50,11 +47,10 @@ void kscm_setDeadlockHandlerWatchdogInterval(double value); /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_deadlock_getAPI(void); - +KSCrashMonitorAPI *kscm_deadlock_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_Deadlock_h +#endif // HDR_KSCrashMonitor_Deadlock_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.m b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.m index d44af5bd6..49008bd11 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.m +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Deadlock.m @@ -26,20 +26,18 @@ #import "KSCrashMonitor_Deadlock.h" +#import #import "KSCrashMonitorContext.h" #import "KSCrashMonitorContextHelper.h" #import "KSID.h" -#import "KSThread.h" #import "KSStackCursor_MachineContext.h" -#import +#import "KSThread.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" - #define kIdleInterval 5.0f - @class KSCrashDeadlockMonitor; // ============================================================================ @@ -51,7 +49,7 @@ static KSCrash_MonitorContext g_monitorContext; /** Thread which monitors other threads. */ -static KSCrashDeadlockMonitor* g_monitor; +static KSCrashDeadlockMonitor *g_monitor; static KSThread g_mainQueueThread; @@ -62,9 +60,9 @@ #pragma mark - X - // ============================================================================ -@interface KSCrashDeadlockMonitor: NSObject +@interface KSCrashDeadlockMonitor : NSObject -@property(nonatomic, readwrite, retain) NSThread* monitorThread; +@property(nonatomic, readwrite, retain) NSThread *monitorThread; @property(atomic, readwrite, assign) BOOL awaitingResponse; @end @@ -74,10 +72,9 @@ @implementation KSCrashDeadlockMonitor @synthesize monitorThread = _monitorThread; @synthesize awaitingResponse = _awaitingResponse; -- (id) init +- (id)init { - if((self = [super init])) - { + if ((self = [super init])) { // target (self) is retained until selector (runMonitor) exits. self.monitorThread = [[NSThread alloc] initWithTarget:self selector:@selector(runMonitor) object:nil]; self.monitorThread.name = @"KSCrash Deadlock Detection Thread"; @@ -86,27 +83,26 @@ - (id) init return self; } -- (void) cancel +- (void)cancel { [self.monitorThread cancel]; } -- (void) watchdogPulse +- (void)watchdogPulse { __block id blockSelf = self; self.awaitingResponse = YES; - dispatch_async(dispatch_get_main_queue(), ^ - { - [blockSelf watchdogAnswer]; - }); + dispatch_async(dispatch_get_main_queue(), ^{ + [blockSelf watchdogAnswer]; + }); } -- (void) watchdogAnswer +- (void)watchdogAnswer { self.awaitingResponse = NO; } -- (void) handleDeadlock +- (void)handleDeadlock { thread_act_array_t threads = NULL; mach_msg_type_number_t numThreads = 0; @@ -121,14 +117,14 @@ - (void) handleDeadlock ksid_generate(eventID); KSLOG_DEBUG(@"Filling out context."); - KSCrash_MonitorContext* crashContext = &g_monitorContext; + KSCrash_MonitorContext *crashContext = &g_monitorContext; memset(crashContext, 0, sizeof(*crashContext)); ksmc_fillMonitorContext(crashContext, kscm_deadlock_getAPI()); crashContext->eventID = eventID; crashContext->registersAreValid = false; crashContext->offendingMachineContext = machineContext; crashContext->stackCursor = &stackCursor; - + kscm_handleException(crashContext); ksmc_resumeEnvironment(threads, numThreads); @@ -136,30 +132,24 @@ - (void) handleDeadlock abort(); } -- (void) runMonitor +- (void)runMonitor { BOOL cancelled = NO; - do - { + do { // Only do a watchdog check if the watchdog interval is > 0. // If the interval is <= 0, just idle until the user changes it. @autoreleasepool { NSTimeInterval sleepInterval = g_watchdogInterval; BOOL runWatchdogCheck = sleepInterval > 0; - if(!runWatchdogCheck) - { + if (!runWatchdogCheck) { sleepInterval = kIdleInterval; } [NSThread sleepForTimeInterval:sleepInterval]; cancelled = self.monitorThread.isCancelled; - if(!cancelled && runWatchdogCheck) - { - if(self.awaitingResponse) - { + if (!cancelled && runWatchdogCheck) { + if (self.awaitingResponse) { [self handleDeadlock]; - } - else - { + } else { [self watchdogPulse]; } } @@ -176,36 +166,27 @@ - (void) runMonitor static void initialize(void) { static bool isInitialized = false; - if(!isInitialized) - { + if (!isInitialized) { isInitialized = true; - dispatch_async(dispatch_get_main_queue(), ^{g_mainQueueThread = ksthread_self();}); + dispatch_async(dispatch_get_main_queue(), ^{ + g_mainQueueThread = ksthread_self(); + }); } } -static const char* monitorId(void) -{ - return "MainThreadDeadlock"; -} +static const char *monitorId(void) { return "MainThreadDeadlock"; } -static KSCrashMonitorFlag monitorFlags(void) -{ - return KSCrashMonitorFlagFatal; -} +static KSCrashMonitorFlag monitorFlags(void) { return KSCrashMonitorFlagFatal; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { KSLOG_DEBUG(@"Creating new deadlock monitor."); initialize(); g_monitor = [[KSCrashDeadlockMonitor alloc] init]; - } - else - { + } else { KSLOG_DEBUG(@"Stopping deadlock monitor."); [g_monitor cancel]; g_monitor = nil; @@ -213,24 +194,14 @@ static void setEnabled(bool isEnabled) } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -KSCrashMonitorAPI* kscm_deadlock_getAPI(void) +KSCrashMonitorAPI *kscm_deadlock_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .monitorFlags = monitorFlags, - .setEnabled = setEnabled, - .isEnabled = isEnabled + static KSCrashMonitorAPI api = { + .monitorId = monitorId, .monitorFlags = monitorFlags, .setEnabled = setEnabled, .isEnabled = isEnabled }; return &api; } -void kscm_setDeadlockHandlerWatchdogInterval(double value) -{ - g_watchdogInterval = value; -} +void kscm_setDeadlockHandlerWatchdogInterval(double value) { g_watchdogInterval = value; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.c b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.c index dc86c1f1c..1c6dd8970 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.c +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.c @@ -25,17 +25,18 @@ // #include "KSCrashMonitor_MachException.h" -#include "KSCrashMonitorHelper.h" + +#include "KSCPU.h" +#include "KSCrashMonitorContext.h" #include "KSCrashMonitorContextHelper.h" +#include "KSCrashMonitorHelper.h" #include "KSCrashMonitor_Signal.h" -#include "KSCrashMonitorContext.h" -#include "KSCPU.h" #include "KSID.h" -#include "KSThread.h" -#include "KSSystemCapabilities.h" #include "KSStackCursor_MachineContext.h" +#include "KSSystemCapabilities.h" +#include "KSThread.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" #if KSCRASH_HAS_MACH @@ -48,13 +49,13 @@ #pragma mark - Constants - // ============================================================================ -static const char* kThreadPrimary = "KSCrash Exception Handler (Primary)"; -static const char* kThreadSecondary = "KSCrash Exception Handler (Secondary)"; +static const char *kThreadPrimary = "KSCrash Exception Handler (Primary)"; +static const char *kThreadSecondary = "KSCrash Exception Handler (Secondary)"; #if __LP64__ - #define MACH_ERROR_CODE_MASK 0xFFFFFFFFFFFFFFFF +#define MACH_ERROR_CODE_MASK 0xFFFFFFFFFFFFFFFF #else - #define MACH_ERROR_CODE_MASK 0xFFFFFFFF +#define MACH_ERROR_CODE_MASK 0xFFFFFFFF #endif // ============================================================================ @@ -64,15 +65,14 @@ static const char* kThreadSecondary = "KSCrash Exception Handler (Secondary)"; /** A mach exception message (according to ux_exception.c, xnu-1699.22.81). */ #pragma pack(4) -typedef struct -{ +typedef struct { /** Mach header. */ - mach_msg_header_t header; + mach_msg_header_t header; // Start of the kernel processed data. /** Basic message body data. */ - mach_msg_body_t body; + mach_msg_body_t body; /** The thread that raised the exception. */ mach_msg_port_descriptor_t thread; @@ -83,13 +83,13 @@ typedef struct // End of the kernel processed data. /** Network Data Representation. */ - NDR_record_t NDR; + NDR_record_t NDR; /** The exception that was raised. */ - exception_type_t exception; + exception_type_t exception; /** The number of codes. */ - mach_msg_type_number_t codeCount; + mach_msg_type_number_t codeCount; /** Exception code and subcode. */ // ux_exception.c defines this as mach_exception_data_t for some reason. @@ -99,23 +99,22 @@ typedef struct mach_exception_data_type_t code[0]; /** Padding to avoid RCV_TOO_LARGE. */ - char padding[512]; + char padding[512]; } MachExceptionMessage; #pragma pack() /** A mach reply message (according to ux_exception.c, xnu-1699.22.81). */ #pragma pack(4) -typedef struct -{ +typedef struct { /** Mach header. */ mach_msg_header_t header; /** Network Data Representation. */ - NDR_record_t NDR; + NDR_record_t NDR; /** Return code. */ - kern_return_t returnCode; + kern_return_t returnCode; } MachReplyMessage; #pragma pack() @@ -133,13 +132,12 @@ static bool g_isHandlingCrash = false; /** Holds exception port info regarding the previously installed exception * handlers. */ -static struct -{ - exception_mask_t masks[EXC_TYPES_COUNT]; - exception_handler_t ports[EXC_TYPES_COUNT]; - exception_behavior_t behaviors[EXC_TYPES_COUNT]; - thread_state_flavor_t flavors[EXC_TYPES_COUNT]; - mach_msg_type_number_t count; +static struct { + exception_mask_t masks[EXC_TYPES_COUNT]; + exception_handler_t ports[EXC_TYPES_COUNT]; + exception_behavior_t behaviors[EXC_TYPES_COUNT]; + thread_state_flavor_t flavors[EXC_TYPES_COUNT]; + mach_msg_type_number_t count; } g_previousExceptionPorts; /** Our exception port. */ @@ -165,8 +163,7 @@ static char g_secondaryEventID[37]; static void restoreExceptionPorts(void) { KSLOG_DEBUG("Restoring original exception ports."); - if(g_previousExceptionPorts.count == 0) - { + if (g_previousExceptionPorts.count == 0) { KSLOG_DEBUG("Original exception ports were already restored."); return; } @@ -175,18 +172,12 @@ static void restoreExceptionPorts(void) kern_return_t kr; // Reinstall old exception ports. - for(mach_msg_type_number_t i = 0; i < g_previousExceptionPorts.count; i++) - { + for (mach_msg_type_number_t i = 0; i < g_previousExceptionPorts.count; i++) { KSLOG_TRACE("Restoring port index %d", i); - kr = task_set_exception_ports(thisTask, - g_previousExceptionPorts.masks[i], - g_previousExceptionPorts.ports[i], - g_previousExceptionPorts.behaviors[i], - g_previousExceptionPorts.flavors[i]); - if(kr != KERN_SUCCESS) - { - KSLOG_ERROR("task_set_exception_ports: %s", - mach_error_string(kr)); + kr = task_set_exception_ports(thisTask, g_previousExceptionPorts.masks[i], g_previousExceptionPorts.ports[i], + g_previousExceptionPorts.behaviors[i], g_previousExceptionPorts.flavors[i]); + if (kr != KERN_SUCCESS) { + KSLOG_ERROR("task_set_exception_ports: %s", mach_error_string(kr)); } } KSLOG_DEBUG("Exception ports restored."); @@ -194,13 +185,12 @@ static void restoreExceptionPorts(void) } #define EXC_UNIX_BAD_SYSCALL 0x10000 /* SIGSYS */ -#define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ -#define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ +#define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ +#define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ static int signalForMachException(exception_type_t exception, mach_exception_code_t code) { - switch(exception) - { + switch (exception) { case EXC_ARITHMETIC: return SIGFPE; case EXC_BAD_ACCESS: @@ -211,10 +201,8 @@ static int signalForMachException(exception_type_t exception, mach_exception_cod return SIGTRAP; case EXC_EMULATION: return SIGEMT; - case EXC_SOFTWARE: - { - switch (code) - { + case EXC_SOFTWARE: { + switch (code) { case EXC_UNIX_BAD_SYSCALL: return SIGSYS; case EXC_UNIX_BAD_PIPE: @@ -232,8 +220,7 @@ static int signalForMachException(exception_type_t exception, mach_exception_cod static exception_type_t machExceptionForSignal(int sigNum) { - switch(sigNum) - { + switch (sigNum) { case SIGFPE: return EXC_ARITHMETIC; case SIGSEGV: @@ -267,35 +254,27 @@ static exception_type_t machExceptionForSignal(int sigNum) * Wait for an exception message, uninstall our exception port, record the * exception information, and write a report. */ -static void* handleExceptions(void* const userData) +static void *handleExceptions(void *const userData) { - MachExceptionMessage exceptionMessage = {{0}}; - MachReplyMessage replyMessage = {{0}}; - char* eventID = g_primaryEventID; + MachExceptionMessage exceptionMessage = { { 0 } }; + MachReplyMessage replyMessage = { { 0 } }; + char *eventID = g_primaryEventID; - const char* threadName = (const char*) userData; + const char *threadName = (const char *)userData; pthread_setname_np(threadName); - if(threadName == kThreadSecondary) - { + if (threadName == kThreadSecondary) { KSLOG_DEBUG("This is the secondary thread. Suspending."); thread_suspend((thread_t)ksthread_self()); eventID = g_secondaryEventID; } - for(;;) - { + for (;;) { KSLOG_DEBUG("Waiting for mach exception"); // Wait for a message. - kern_return_t kr = mach_msg(&exceptionMessage.header, - MACH_RCV_MSG, - 0, - sizeof(exceptionMessage), - g_exceptionPort, - MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - if(kr == KERN_SUCCESS) - { + kern_return_t kr = mach_msg(&exceptionMessage.header, MACH_RCV_MSG, 0, sizeof(exceptionMessage), + g_exceptionPort, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if (kr == KERN_SUCCESS) { break; } @@ -303,10 +282,9 @@ static void* handleExceptions(void* const userData) KSLOG_ERROR("mach_msg: %s", mach_error_string(kr)); } - KSLOG_DEBUG("Trapped mach exception code 0x%llx, subcode 0x%llx", - exceptionMessage.code[0], exceptionMessage.code[1]); - if(g_isEnabled) - { + KSLOG_DEBUG("Trapped mach exception code 0x%llx, subcode 0x%llx", exceptionMessage.code[0], + exceptionMessage.code[1]); + if (g_isEnabled) { thread_act_array_t threads = NULL; mach_msg_type_number_t numThreads = 0; ksmc_suspendEnvironment(&threads, &numThreads); @@ -315,42 +293,33 @@ static void* handleExceptions(void* const userData) KSLOG_DEBUG("Exception handler is installed. Continuing exception handling."); - // Switch to the secondary thread if necessary, or uninstall the handler // to avoid a death loop. - if(ksthread_self() == g_primaryMachThread) - { + if (ksthread_self() == g_primaryMachThread) { KSLOG_DEBUG("This is the primary exception thread. Activating secondary thread."); -// TODO: This was put here to avoid a freeze. Does secondary thread ever fire? + // TODO: This was put here to avoid a freeze. Does secondary thread ever fire? restoreExceptionPorts(); - if(thread_resume(g_secondaryMachThread) != KERN_SUCCESS) - { + if (thread_resume(g_secondaryMachThread) != KERN_SUCCESS) { KSLOG_DEBUG("Could not activate secondary thread. Restoring original exception ports."); } - } - else - { - KSLOG_DEBUG("This is the secondary exception thread.");// Restoring original exception ports."); -// restoreExceptionPorts(); + } else { + KSLOG_DEBUG("This is the secondary exception thread."); // Restoring original exception ports."); + // restoreExceptionPorts(); } // Fill out crash information KSLOG_DEBUG("Fetching machine state."); KSMC_NEW_CONTEXT(machineContext); - KSCrash_MonitorContext* crashContext = &g_monitorContext; + KSCrash_MonitorContext *crashContext = &g_monitorContext; crashContext->offendingMachineContext = machineContext; kssc_initCursor(&g_stackCursor, NULL, NULL); - if(ksmc_getContextForThread(exceptionMessage.thread.name, machineContext, true)) - { + if (ksmc_getContextForThread(exceptionMessage.thread.name, machineContext, true)) { kssc_initWithMachineContext(&g_stackCursor, KSSC_MAX_STACK_DEPTH, machineContext); - KSLOG_TRACE("Fault address %p, instruction address %p", - kscpu_faultAddress(machineContext), kscpu_instructionAddress(machineContext)); - if(exceptionMessage.exception == EXC_BAD_ACCESS) - { + KSLOG_TRACE("Fault address %p, instruction address %p", kscpu_faultAddress(machineContext), + kscpu_instructionAddress(machineContext)); + if (exceptionMessage.exception == EXC_BAD_ACCESS) { crashContext->faultAddress = kscpu_faultAddress(machineContext); - } - else - { + } else { crashContext->faultAddress = kscpu_instructionAddress(machineContext); } } @@ -362,8 +331,7 @@ static void* handleExceptions(void* const userData) crashContext->mach.type = exceptionMessage.exception; crashContext->mach.code = exceptionMessage.code[0] & (int64_t)MACH_ERROR_CODE_MASK; crashContext->mach.subcode = exceptionMessage.code[1] & (int64_t)MACH_ERROR_CODE_MASK; - if(crashContext->mach.code == KERN_PROTECTION_FAILURE && crashContext->isStackOverflow) - { + if (crashContext->mach.code == KERN_PROTECTION_FAILURE && crashContext->isStackOverflow) { // A stack overflow should return KERN_INVALID_ADDRESS, but // when a stack blasts through the guard pages at the top of the stack, // it generates KERN_PROTECTION_FAILURE. Correct for this. @@ -385,18 +353,12 @@ static void* handleExceptions(void* const userData) replyMessage.NDR = exceptionMessage.NDR; replyMessage.returnCode = KERN_FAILURE; - mach_msg(&replyMessage.header, - MACH_SEND_MSG, - sizeof(replyMessage), - 0, - MACH_PORT_NULL, - MACH_MSG_TIMEOUT_NONE, + mach_msg(&replyMessage.header, MACH_SEND_MSG, sizeof(replyMessage), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); return NULL; } - // ============================================================================ #pragma mark - API - // ============================================================================ @@ -412,29 +374,21 @@ static void uninstallExceptionHandler(void) thread_t thread_self = (thread_t)ksthread_self(); - if(g_primaryPThread != 0 && g_primaryMachThread != thread_self) - { + if (g_primaryPThread != 0 && g_primaryMachThread != thread_self) { KSLOG_DEBUG("Canceling primary exception thread."); - if(g_isHandlingCrash) - { + if (g_isHandlingCrash) { thread_terminate(g_primaryMachThread); - } - else - { + } else { pthread_cancel(g_primaryPThread); } g_primaryMachThread = 0; g_primaryPThread = 0; } - if(g_secondaryPThread != 0 && g_secondaryMachThread != thread_self) - { + if (g_secondaryPThread != 0 && g_secondaryMachThread != thread_self) { KSLOG_DEBUG("Canceling secondary exception thread."); - if(g_isHandlingCrash) - { + if (g_isHandlingCrash) { thread_terminate(g_secondaryMachThread); - } - else - { + } else { pthread_cancel(g_secondaryPThread); } g_secondaryMachThread = 0; @@ -456,58 +410,38 @@ static bool installExceptionHandler(void) int error; const task_t thisTask = mach_task_self(); - exception_mask_t mask = EXC_MASK_BAD_ACCESS | - EXC_MASK_BAD_INSTRUCTION | - EXC_MASK_ARITHMETIC | - EXC_MASK_SOFTWARE | - EXC_MASK_BREAKPOINT; + exception_mask_t mask = + EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT; KSLOG_DEBUG("Backing up original exception ports."); - kr = task_get_exception_ports(thisTask, - mask, - g_previousExceptionPorts.masks, - &g_previousExceptionPorts.count, - g_previousExceptionPorts.ports, - g_previousExceptionPorts.behaviors, + kr = task_get_exception_ports(thisTask, mask, g_previousExceptionPorts.masks, &g_previousExceptionPorts.count, + g_previousExceptionPorts.ports, g_previousExceptionPorts.behaviors, g_previousExceptionPorts.flavors); - if(kr != KERN_SUCCESS) - { + if (kr != KERN_SUCCESS) { KSLOG_ERROR("task_get_exception_ports: %s", mach_error_string(kr)); goto failed; } - if(g_exceptionPort == MACH_PORT_NULL) - { + if (g_exceptionPort == MACH_PORT_NULL) { KSLOG_DEBUG("Allocating new port with receive rights."); - kr = mach_port_allocate(thisTask, - MACH_PORT_RIGHT_RECEIVE, - &g_exceptionPort); - if(kr != KERN_SUCCESS) - { + kr = mach_port_allocate(thisTask, MACH_PORT_RIGHT_RECEIVE, &g_exceptionPort); + if (kr != KERN_SUCCESS) { KSLOG_ERROR("mach_port_allocate: %s", mach_error_string(kr)); goto failed; } KSLOG_DEBUG("Adding send rights to port."); - kr = mach_port_insert_right(thisTask, - g_exceptionPort, - g_exceptionPort, - MACH_MSG_TYPE_MAKE_SEND); - if(kr != KERN_SUCCESS) - { + kr = mach_port_insert_right(thisTask, g_exceptionPort, g_exceptionPort, MACH_MSG_TYPE_MAKE_SEND); + if (kr != KERN_SUCCESS) { KSLOG_ERROR("mach_port_insert_right: %s", mach_error_string(kr)); goto failed; } } KSLOG_DEBUG("Installing port as exception handler."); - kr = task_set_exception_ports(thisTask, - mask, - g_exceptionPort, - (int)(EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), + kr = task_set_exception_ports(thisTask, mask, g_exceptionPort, (int)(EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), THREAD_STATE_NONE); - if(kr != KERN_SUCCESS) - { + if (kr != KERN_SUCCESS) { KSLOG_ERROR("task_set_exception_ports: %s", mach_error_string(kr)); goto failed; } @@ -516,12 +450,8 @@ static bool installExceptionHandler(void) pthread_attr_init(&attr); attributes_created = true; pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - error = pthread_create(&g_secondaryPThread, - &attr, - &handleExceptions, - (void*)kThreadSecondary); - if(error != 0) - { + error = pthread_create(&g_secondaryPThread, &attr, &handleExceptions, (void *)kThreadSecondary); + if (error != 0) { KSLOG_ERROR("pthread_create_suspended_np: %s", strerror(error)); goto failed; } @@ -529,12 +459,8 @@ static bool installExceptionHandler(void) ksmc_addReservedThread(g_secondaryMachThread); KSLOG_DEBUG("Creating primary exception thread."); - error = pthread_create(&g_primaryPThread, - &attr, - &handleExceptions, - (void*)kThreadPrimary); - if(error != 0) - { + error = pthread_create(&g_primaryPThread, &attr, &handleExceptions, (void *)kThreadPrimary); + if (error != 0) { KSLOG_ERROR("pthread_create: %s", strerror(error)); goto failed; } @@ -545,76 +471,57 @@ static bool installExceptionHandler(void) KSLOG_DEBUG("Mach exception handler installed."); return true; - failed: KSLOG_DEBUG("Failed to install mach exception handler."); - if(attributes_created) - { + if (attributes_created) { pthread_attr_destroy(&attr); } uninstallExceptionHandler(); return false; } -static const char* monitorId(void) -{ - return "MachException"; -} +static const char *monitorId(void) { return "MachException"; } static KSCrashMonitorFlag monitorFlags(void) { - return KSCrashMonitorFlagFatal | - KSCrashMonitorFlagAsyncSafe | - KSCrashMonitorFlagDebuggerUnsafe; + return KSCrashMonitorFlagFatal | KSCrashMonitorFlagAsyncSafe | KSCrashMonitorFlagDebuggerUnsafe; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { ksid_generate(g_primaryEventID); ksid_generate(g_secondaryEventID); - if(!installExceptionHandler()) - { + if (!installExceptionHandler()) { return; } - } - else - { + } else { uninstallExceptionHandler(); } } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -static void addContextualInfoToEvent(struct KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(struct KSCrash_MonitorContext *eventContext) { - const char* signalName = kscm_getMonitorId(kscm_signal_getAPI()); + const char *signalName = kscm_getMonitorId(kscm_signal_getAPI()); - if(signalName && strcmp(eventContext->monitorId, signalName) == 0) - { + if (signalName && strcmp(eventContext->monitorId, signalName) == 0) { eventContext->mach.type = machExceptionForSignal(eventContext->signal.signum); - } - else if(strcmp(eventContext->monitorId, monitorId()) != 0) - { + } else if (strcmp(eventContext->monitorId, monitorId()) != 0) { eventContext->mach.type = EXC_CRASH; } } #endif -KSCrashMonitorAPI* kscm_machexception_getAPI(void) +KSCrashMonitorAPI *kscm_machexception_getAPI(void) { #if KSCRASH_HAS_MACH - static KSCrashMonitorAPI api = - { + static KSCrashMonitorAPI api = { .monitorId = monitorId, .monitorFlags = monitorFlags, diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.h index 204f25922..24244519f 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_MachException.h @@ -24,29 +24,26 @@ // THE SOFTWARE. // - /* Catches mach exceptions. */ - #ifndef HDR_KSCrashMonitor_MachException_h #define HDR_KSCrashMonitor_MachException_h -#include "KSCrashMonitor.h" #include +#include "KSCrashMonitor.h" + #ifdef __cplusplus extern "C" { #endif - /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_machexception_getAPI(void); - +KSCrashMonitorAPI *kscm_machexception_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_MachException_h +#endif // HDR_KSCrashMonitor_MachException_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.h index 94b3b7f6f..97b769df8 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.h @@ -24,16 +24,14 @@ // THE SOFTWARE. // - /* Monitor memory and records data for OOMs. */ - #ifndef KSCrashMonitor_Memory_h #define KSCrashMonitor_Memory_h -#include "KSCrashMonitor.h" #include "KSCrashAppTransitionState.h" +#include "KSCrashMonitor.h" #ifdef __cplusplus extern "C" { @@ -49,42 +47,41 @@ extern const uint8_t KSCrash_Memory_NonFatalReportLevelNone; App Memory */ typedef struct KSCrash_Memory { - /** magic header */ int32_t magic; - + /** current version of the struct */ int8_t version; - + /** timestamp in microseconds */ int64_t timestamp; - + /** amount of app memory used */ uint64_t footprint; - + /** amount of app memory remaining */ uint64_t remaining; - + /** high water mark for footprint (footprint + remaining)*/ uint64_t limit; - + /** memory pressure `KSCrashAppMemoryPressure` */ uint8_t pressure; - + /** memory level `KSCrashAppMemoryLevel` (KSCrashAppMemory.level) */ uint8_t level; - + /** transition state of the app */ KSCrashAppTransitionState state; - + /** The process for this data had a fatal exception/event of some type */ bool fatal; - + } KSCrash_Memory; /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_memory_getAPI(void); +KSCrashMonitorAPI *kscm_memory_getAPI(void); /** Initialize the memory monitor. * @@ -128,4 +125,4 @@ bool ksmemory_get_fatal_reports_enabled(void); } #endif -#endif // KSCrashMonitor_Memory_h +#endif // KSCrashMonitor_Memory_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.m b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.m index b320b90e3..3f0841df4 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.m +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Memory.m @@ -25,21 +25,21 @@ // #import "KSCrashMonitor_Memory.h" -#import "KSSystemCapabilities.h" -#import "KSCrashMonitorContextHelper.h" #import "KSCrash.h" +#import "KSCrashAppMemory.h" +#import "KSCrashAppMemoryTracker.h" +#import "KSCrashAppStateTracker.h" #import "KSCrashC.h" #import "KSCrashMonitorContext.h" -#import "KSCrashAppMemory.h" -#import "KSID.h" -#import "KSStackCursor.h" -#import "KSStackCursor_SelfThread.h" -#import "KSStackCursor_MachineContext.h" +#import "KSCrashMonitorContextHelper.h" #import "KSCrashReportFields.h" #import "KSDate.h" #import "KSFileUtils.h" -#import "KSCrashAppStateTracker.h" -#import "KSCrashAppMemoryTracker.h" +#import "KSID.h" +#import "KSStackCursor.h" +#import "KSStackCursor_MachineContext.h" +#import "KSStackCursor_SelfThread.h" +#import "KSSystemCapabilities.h" #import #import @@ -68,12 +68,12 @@ static void setEnabled(bool isEnabled); static bool isEnabled(void); static NSURL *kscm_memory_oom_breadcrumb_URL(void); -static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext); +static void addContextualInfoToEvent(KSCrash_MonitorContext *eventContext); static NSDictionary *kscm_memory_serialize(KSCrash_Memory *const memory); static void kscm_memory_check_for_oom_in_previous_session(void); static void notifyPostSystemEnable(void); -static void ksmemory_read(const char* path); -static void ksmemory_map(const char* path); +static void ksmemory_read(const char *path); +static void ksmemory_map(const char *path); // ============================================================================ #pragma mark - Globals - @@ -107,8 +107,9 @@ static os_unfair_lock g_memoryLock = OS_UNFAIR_LOCK_INIT; static KSCrash_Memory *g_memory = NULL; -static KSCrash_Memory _ks_memory_copy(void) { - KSCrash_Memory copy = {0}; +static KSCrash_Memory _ks_memory_copy(void) +{ + KSCrash_Memory copy = { 0 }; { os_unfair_lock_lock(&g_memoryLock); if (g_memory) { @@ -119,7 +120,8 @@ static KSCrash_Memory _ks_memory_copy(void) { return copy; } -static void _ks_memory_update(void (^block)(KSCrash_Memory *mem)) { +static void _ks_memory_update(void (^block)(KSCrash_Memory *mem)) +{ if (!block) { return; } @@ -130,9 +132,10 @@ static void _ks_memory_update(void (^block)(KSCrash_Memory *mem)) { os_unfair_lock_unlock(&g_memoryLock); } -static void _ks_memory_update_from_app_memory(KSCrashAppMemory *const memory) { +static void _ks_memory_update_from_app_memory(KSCrashAppMemory *const memory) +{ _ks_memory_update(^(KSCrash_Memory *mem) { - *mem = (KSCrash_Memory){ + *mem = (KSCrash_Memory) { .magic = KSCrash_Memory_Magic, .version = KSCrash_Memory_CurrentVersion, .footprint = memory.footprint, @@ -185,42 +188,39 @@ - (void)_updateMappedMemoryFrom:(KSCrashAppMemory *)memory _ks_memory_update_from_app_memory(memory); } -- (void)appMemoryTracker:(KSCrashAppMemoryTracker *)tracker memory:(KSCrashAppMemory *)memory changed:(KSCrashAppMemoryTrackerChangeType)changes +- (void)appMemoryTracker:(KSCrashAppMemoryTracker *)tracker + memory:(KSCrashAppMemory *)memory + changed:(KSCrashAppMemoryTrackerChangeType)changes { if (changes & KSCrashAppMemoryTrackerChangeTypeFootprint) { [self _updateMappedMemoryFrom:memory]; } - - if ((changes & KSCrashAppMemoryTrackerChangeTypeLevel) && - memory.level >= g_MinimumNonFatalReportingLevel) { + if ((changes & KSCrashAppMemoryTrackerChangeTypeLevel) && memory.level >= g_MinimumNonFatalReportingLevel) { NSString *level = @(KSCrashAppMemoryStateToString(memory.level)).uppercaseString; NSString *reason = [NSString stringWithFormat:@"Memory Level Is %@", level]; - + [[KSCrash sharedInstance] reportUserException:@"Memory Level" reason:reason language:@"" lineOfCode:@"0" - stackTrace:@[@"__MEMORY_LEVEL__NON_FATAL__"] + stackTrace:@[ @"__MEMORY_LEVEL__NON_FATAL__" ] logAllThreads:NO terminateProgram:NO]; } - - if ((changes & KSCrashAppMemoryTrackerChangeTypePressure) && - memory.pressure >= g_MinimumNonFatalReportingLevel) { + if ((changes & KSCrashAppMemoryTrackerChangeTypePressure) && memory.pressure >= g_MinimumNonFatalReportingLevel) { NSString *pressure = @(KSCrashAppMemoryStateToString(memory.pressure)).uppercaseString; NSString *reason = [NSString stringWithFormat:@"Memory Pressure Is %@", pressure]; - + [[KSCrash sharedInstance] reportUserException:@"Memory Pressure" reason:reason language:@"" lineOfCode:@"0" - stackTrace:@[@"__MEMORY_PRESSURE__NON_FATAL__"] + stackTrace:@[ @"__MEMORY_PRESSURE__NON_FATAL__" ] logAllThreads:NO terminateProgram:NO]; } - } @end @@ -229,31 +229,25 @@ - (void)appMemoryTracker:(KSCrashAppMemoryTracker *)tracker memory:(KSCrashAppMe #pragma mark - API - // ============================================================================ -static const char* monitorId(void) -{ - return "MemoryTermination"; -} +static const char *monitorId(void) { return "MemoryTermination"; } static void setEnabled(bool isEnabled) { - if (isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { g_memoryTracker = [[_KSCrashMonitor_MemoryTracker alloc] init]; - + ksmemory_map(g_memoryURL.path.UTF8String); - g_appStateObserver = [KSCrashAppStateTracker.sharedInstance addObserverWithBlock:^(KSCrashAppTransitionState transitionState) { - _ks_memory_update(^(KSCrash_Memory *mem) { - mem->state = transitionState; - }); - }]; - - } - else - { + g_appStateObserver = [KSCrashAppStateTracker.sharedInstance + addObserverWithBlock:^(KSCrashAppTransitionState transitionState) { + _ks_memory_update(^(KSCrash_Memory *mem) { + mem->state = transitionState; + }); + }]; + + } else { g_memoryTracker = nil; [KSCrashAppStateTracker.sharedInstance removeObserver:g_appStateObserver]; g_appStateObserver = nil; @@ -261,19 +255,17 @@ static void setEnabled(bool isEnabled) } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -static NSURL *kscm_memory_oom_breadcrumb_URL(void) { +static NSURL *kscm_memory_oom_breadcrumb_URL(void) +{ return [g_dataURL URLByAppendingPathComponent:@"oom_breadcrumb_report.json"]; } -static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(KSCrash_MonitorContext *eventContext) { bool asyncSafeOnly = eventContext->requiresAsyncSafety; - + // we'll use this when reading this back on the next run // to know if an OOM is even possible. if (asyncSafeOnly) { @@ -283,9 +275,8 @@ static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) mem->fatal = eventContext->handlingCrash; }); } - - if (g_isEnabled) - { + + if (g_isEnabled) { KSCrash_Memory memCopy = asyncSafeOnly ? *g_memory : _ks_memory_copy(); eventContext->AppMemory.footprint = memCopy.footprint; eventContext->AppMemory.pressure = KSCrashAppMemoryStateToString((KSCrashAppMemoryState)memCopy.pressure); @@ -300,13 +291,13 @@ static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) static NSDictionary *kscm_memory_serialize(KSCrash_Memory *const memory) { return @{ - KSCrashField_MemoryFootprint: @(memory->footprint), - KSCrashField_MemoryRemaining: @(memory->remaining), - KSCrashField_MemoryLimit: @(memory->limit), - KSCrashField_MemoryPressure: @(KSCrashAppMemoryStateToString((KSCrashAppMemoryState)memory->pressure)), - KSCrashField_MemoryLevel: @(KSCrashAppMemoryStateToString((KSCrashAppMemoryState)memory->level)), - KSCrashField_Timestamp: @(memory->timestamp), - KSCrashField_AppTransitionState: @(ksapp_transitionStateToString(memory->state)), + KSCrashField_MemoryFootprint : @(memory->footprint), + KSCrashField_MemoryRemaining : @(memory->remaining), + KSCrashField_MemoryLimit : @(memory->limit), + KSCrashField_MemoryPressure : @(KSCrashAppMemoryStateToString((KSCrashAppMemoryState)memory->pressure)), + KSCrashField_MemoryLevel : @(KSCrashAppMemoryStateToString((KSCrashAppMemoryState)memory->level)), + KSCrashField_Timestamp : @(memory->timestamp), + KSCrashField_AppTransitionState : @(ksapp_transitionStateToString(memory->state)), }; } @@ -324,30 +315,30 @@ static void kscm_memory_check_for_oom_in_previous_session(void) // indicates a crash, we should process that on startup and ignore // and indication of an OOM. bool userPerceivedOOM = NO; - if (g_FatalReportsEnabled && - ksmemory_previous_session_was_terminated_due_to_memory(&userPerceivedOOM)) - { - + if (g_FatalReportsEnabled && ksmemory_previous_session_was_terminated_due_to_memory(&userPerceivedOOM)) { // We only report an OOM that the user might have seen. // Ignore this check if we want to report all OOM, foreground and background. if (userPerceivedOOM) { NSURL *url = kscm_memory_oom_breadcrumb_URL(); const char *reportContents = kscrash_readReportAtPath(url.path.UTF8String); if (reportContents) { - NSData *data = [NSData dataWithBytes:reportContents length:strlen(reportContents)]; - NSMutableDictionary *json = [[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:nil] mutableCopy]; - + NSMutableDictionary *json = + [[NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves + error:nil] mutableCopy]; + if (json) { json[KSCrashField_System][KSCrashField_AppMemory] = kscm_memory_serialize(&g_previousSessionMemory); json[KSCrashField_Report][KSCrashField_Timestamp] = @(g_previousSessionMemory.timestamp); - json[KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_MemoryTermination] =kscm_memory_serialize(&g_previousSessionMemory); + json[KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_MemoryTermination] = + kscm_memory_serialize(&g_previousSessionMemory); json[KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_Mach] = nil; json[KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_Signal] = @{ - KSCrashField_Signal: @(SIGKILL), - KSCrashField_Name: @"SIGKILL", + KSCrashField_Signal : @(SIGKILL), + KSCrashField_Name : @"SIGKILL", }; - + data = [NSJSONSerialization dataWithJSONObject:json options:NSJSONWritingPrettyPrinted error:nil]; kscrash_addUserReport((const char *)data.bytes, (int)data.length); } @@ -355,7 +346,7 @@ static void kscm_memory_check_for_oom_in_previous_session(void) } } } - + // remove the old breadcrumb oom file unlink(kscm_memory_oom_breadcrumb_URL().path.UTF8String); } @@ -369,23 +360,21 @@ static void notifyPostSystemEnable(void) return; } g_hasPostEnable = 1; - + // Usually we'd do something like this `setEnabled`, // but in this case not all monitors are ready in `seEnabled` // so we simply do it after everything is enabled. - + kscm_memory_check_for_oom_in_previous_session(); - if (g_isEnabled) - { + if (g_isEnabled) { ksmemory_write_possible_oom(); } } -KSCrashMonitorAPI* kscm_memory_getAPI(void) +KSCrashMonitorAPI *kscm_memory_getAPI(void) { - static KSCrashMonitorAPI api = - { + static KSCrashMonitorAPI api = { .monitorId = monitorId, .setEnabled = setEnabled, .isEnabled = isEnabled, @@ -399,17 +388,17 @@ static void notifyPostSystemEnable(void) Read the previous sessions memory data, and unlinks the file to remove any trace of it. */ -static void ksmemory_read(const char* path) +static void ksmemory_read(const char *path) { int fd = open(path, O_RDONLY); if (fd == -1) { unlink(path); return; } - + size_t size = sizeof(KSCrash_Memory); KSCrash_Memory memory = {}; - + // This will fail is we don't receive exactly _size_. // In the future, we need to read and allow getting back something // that is not exactly _size_, then check the version to see @@ -419,27 +408,27 @@ static void ksmemory_read(const char* path) unlink(path); return; } - + // get rid of the file, we don't want it anymore. close(fd); unlink(path); - + // validate some of the data before doing anything with it. - + // check magic if (memory.magic != KSCrash_Memory_Magic) { return; } - + // check version if (memory.version == 0 || memory.version > KSCrash_Memory_CurrentVersion) { return; } - + // --- // START KSCrash_Memory_Version_1_0 // --- - + // check the timestamp, let's say it's valid for the last week // do we really want crash reports older than a week anyway?? const uint64_t kUS_in_day = 8.64e+10; @@ -448,7 +437,7 @@ static void ksmemory_read(const char* path) if (memory.timestamp <= 0 || memory.timestamp == INT64_MAX || memory.timestamp < now - kUS_in_week) { return; } - + // check pressure and level are in ranges if (memory.level > KSCrashAppMemoryStateTerminal) { return; @@ -456,12 +445,12 @@ static void ksmemory_read(const char* path) if (memory.pressure > KSCrashAppMemoryStateTerminal) { return; } - + // check app transition state if (memory.state > KSCrashAppTransitionStateExiting) { return; } - + // if we're at max, we likely overflowed or set a negative value, // in any case, we're counting this as a possible error and bailing. if (memory.footprint == UINT64_MAX) { @@ -473,16 +462,16 @@ static void ksmemory_read(const char* path) if (memory.limit == UINT64_MAX) { return; } - + // Footprint and remaining should always = limit if (memory.footprint + memory.remaining != memory.limit) { return; } - + // --- // END KSCrash_Memory_Version_1_0 // --- - + g_previousSessionMemory = memory; } @@ -491,13 +480,13 @@ static void ksmemory_read(const char* path) in memory as a structure and the kernel will ensure it is on disk. This is also crash resistant. */ -static void ksmemory_map(const char* path) +static void ksmemory_map(const char *path) { void *ptr = ksfu_mmap(path, sizeof(KSCrash_Memory)); if (!ptr) { return; } - + g_memory = (KSCrash_Memory *)ptr; _ks_memory_update_from_app_memory(g_memoryTracker.memory); } @@ -505,7 +494,7 @@ static void ksmemory_map(const char* path) /** What we're doing here is writing a file out that can be reused on restart if the data shows us there was a memory issue. - + If an OOM did happen, we'll modify this file (see `kscm_memory_check_for_oom_in_previous_session`), then write it back out using the normal writing procedure to write reports. This @@ -521,10 +510,10 @@ static void ksmemory_write_possible_oom(void) ksmc_getContextForThread(ksthread_self(), machineContext, false); KSStackCursor stackCursor; kssc_initWithMachineContext(&stackCursor, KSSC_MAX_STACK_DEPTH, machineContext); - - char eventID[37] = {0}; + + char eventID[37] = { 0 }; ksid_generate(eventID); - + KSCrash_MonitorContext context; memset(&context, 0, sizeof(context)); ksmc_fillMonitorContext(&context, kscm_memory_getAPI()); @@ -532,10 +521,10 @@ static void ksmemory_write_possible_oom(void) context.registersAreValid = false; context.offendingMachineContext = machineContext; context.currentSnapshotUserReported = true; - + // we don't need all the images, we have no stack context.omitBinaryImages = true; - + // _reportPath_ only valid within this scope context.reportPath = reportPath; @@ -561,33 +550,21 @@ bool ksmemory_previous_session_was_terminated_due_to_memory(bool *userPerceptibl if (g_previousSessionMemory.fatal) { return NO; } - + // We might care if the user might have seen the OOM if (userPerceptible) { *userPerceptible = ksapp_transitionStateIsUserPerceptible(g_previousSessionMemory.state); } - + // level or pressure is critical++ return g_previousSessionMemory.level >= KSCrashAppMemoryStateCritical || - g_previousSessionMemory.pressure >= KSCrashAppMemoryStateCritical; + g_previousSessionMemory.pressure >= KSCrashAppMemoryStateCritical; } -void ksmemory_set_nonfatal_report_level(uint8_t level) -{ - g_MinimumNonFatalReportingLevel = level; -} +void ksmemory_set_nonfatal_report_level(uint8_t level) { g_MinimumNonFatalReportingLevel = level; } -uint8_t ksmemory_get_nonfatal_report_level(void) -{ - return g_MinimumNonFatalReportingLevel; -} +uint8_t ksmemory_get_nonfatal_report_level(void) { return g_MinimumNonFatalReportingLevel; } -void ksmemory_set_fatal_reports_enabled(bool enabled) -{ - g_FatalReportsEnabled = enabled; -} +void ksmemory_set_fatal_reports_enabled(bool enabled) { g_FatalReportsEnabled = enabled; } -bool ksmemory_get_fatal_reports_enabled(void) -{ - return g_FatalReportsEnabled; -} +bool ksmemory_get_fatal_reports_enabled(void) { return g_FatalReportsEnabled; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.h index ec166dd1d..2e0311c30 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.h @@ -24,11 +24,9 @@ // THE SOFTWARE. // - /* Catches Objective-C exceptions. */ - #ifndef HDR_KSCrashMonitor_NSException_h #define HDR_KSCrashMonitor_NSException_h @@ -38,14 +36,12 @@ extern "C" { #endif - /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_nsexception_getAPI(void); - +KSCrashMonitorAPI *kscm_nsexception_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_NSException_h +#endif // HDR_KSCrashMonitor_NSException_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.m b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.m index eede45797..64d44d7f7 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.m +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_NSException.m @@ -26,19 +26,18 @@ #import "KSCrashMonitor_NSException.h" -#import "KSCrash.h" +#import #import "KSCrash+Private.h" -#import "KSCrashMonitorContextHelper.h" -#import "KSStackCursor_Backtrace.h" +#import "KSCrash.h" #include "KSCrashMonitorContext.h" +#import "KSCrashMonitorContextHelper.h" #include "KSID.h" +#import "KSStackCursor_Backtrace.h" #include "KSThread.h" -#import -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" - // ============================================================================ #pragma mark - Globals - // ============================================================================ @@ -48,7 +47,7 @@ static KSCrash_MonitorContext g_monitorContext; /** The exception handler that was in place before we installed ours. */ -static NSUncaughtExceptionHandler* g_previousUncaughtExceptionHandler; +static NSUncaughtExceptionHandler *g_previousUncaughtExceptionHandler; // ============================================================================ #pragma mark - Callbacks - @@ -60,21 +59,20 @@ * @param exception The exception that was raised. */ -static void handleException(NSException* exception, BOOL currentSnapshotUserReported) { +static void handleException(NSException *exception, BOOL currentSnapshotUserReported) +{ KSLOG_DEBUG(@"Trapped exception %@", exception); - if(g_isEnabled) - { + if (g_isEnabled) { thread_act_array_t threads = NULL; mach_msg_type_number_t numThreads = 0; ksmc_suspendEnvironment(&threads, &numThreads); kscm_notifyFatalExceptionCaptured(false); KSLOG_DEBUG(@"Filling out context."); - NSArray* addresses = [exception callStackReturnAddresses]; + NSArray *addresses = [exception callStackReturnAddresses]; NSUInteger numFrames = addresses.count; - uintptr_t* callstack = malloc(numFrames * sizeof(*callstack)); - for(NSUInteger i = 0; i < numFrames; i++) - { + uintptr_t *callstack = malloc(numFrames * sizeof(*callstack)); + for (NSUInteger i = 0; i < numFrames; i++) { callstack[i] = (uintptr_t)[addresses[i] unsignedLongLongValue]; } @@ -85,7 +83,7 @@ static void handleException(NSException* exception, BOOL currentSnapshotUserRepo KSStackCursor cursor; kssc_initWithBacktrace(&cursor, callstack, (int)numFrames, 0); - KSCrash_MonitorContext* crashContext = &g_monitorContext; + KSCrash_MonitorContext *crashContext = &g_monitorContext; memset(crashContext, 0, sizeof(*crashContext)); ksmc_fillMonitorContext(crashContext, kscm_nsexception_getAPI()); crashContext->eventID = eventID; @@ -105,21 +103,16 @@ static void handleException(NSException* exception, BOOL currentSnapshotUserRepo if (currentSnapshotUserReported) { ksmc_resumeEnvironment(threads, numThreads); } - if (g_previousUncaughtExceptionHandler != NULL) - { + if (g_previousUncaughtExceptionHandler != NULL) { KSLOG_DEBUG(@"Calling original exception handler."); g_previousUncaughtExceptionHandler(exception); } } } -static void handleCurrentSnapshotUserReportedException(NSException* exception) { - handleException(exception, true); -} +static void handleCurrentSnapshotUserReportedException(NSException *exception) { handleException(exception, true); } -static void handleUncaughtException(NSException* exception) { - handleException(exception, false); -} +static void handleUncaughtException(NSException *exception) { handleException(exception, false); } // ============================================================================ #pragma mark - API - @@ -127,50 +120,34 @@ static void handleUncaughtException(NSException* exception) { static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { KSLOG_DEBUG(@"Backing up original handler."); g_previousUncaughtExceptionHandler = NSGetUncaughtExceptionHandler(); - + KSLOG_DEBUG(@"Setting new handler."); NSSetUncaughtExceptionHandler(&handleUncaughtException); KSCrash.sharedInstance.uncaughtExceptionHandler = &handleUncaughtException; - KSCrash.sharedInstance.currentSnapshotUserReportedExceptionHandler = &handleCurrentSnapshotUserReportedException; - } - else - { + KSCrash.sharedInstance.currentSnapshotUserReportedExceptionHandler = + &handleCurrentSnapshotUserReportedException; + } else { KSLOG_DEBUG(@"Restoring original handler."); NSSetUncaughtExceptionHandler(g_previousUncaughtExceptionHandler); } } } -static const char* monitorId(void) -{ - return "NSException"; -} +static const char *monitorId(void) { return "NSException"; } -static KSCrashMonitorFlag monitorFlags(void) -{ - return KSCrashMonitorFlagFatal; -} +static KSCrashMonitorFlag monitorFlags(void) { return KSCrashMonitorFlagFatal; } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -KSCrashMonitorAPI* kscm_nsexception_getAPI(void) +KSCrashMonitorAPI *kscm_nsexception_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .monitorFlags = monitorFlags, - .setEnabled = setEnabled, - .isEnabled = isEnabled + static KSCrashMonitorAPI api = { + .monitorId = monitorId, .monitorFlags = monitorFlags, .setEnabled = setEnabled, .isEnabled = isEnabled }; return &api; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.c b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.c index 788f47562..cd893d71b 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.c +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.c @@ -25,17 +25,18 @@ // #include "KSCrashMonitor_Signal.h" + +#include "KSCrashMonitorContext.h" #include "KSCrashMonitorContextHelper.h" -#include "KSCrashMonitor_MachException.h" #include "KSCrashMonitorHelper.h" -#include "KSCrashMonitorContext.h" +#include "KSCrashMonitor_MachException.h" #include "KSID.h" -#include "KSSignalInfo.h" #include "KSMachineContext.h" -#include "KSSystemCapabilities.h" +#include "KSSignalInfo.h" #include "KSStackCursor_MachineContext.h" +#include "KSSystemCapabilities.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" #if KSCRASH_HAS_SIGNAL @@ -46,7 +47,6 @@ #include #include - // ============================================================================ #pragma mark - Globals - // ============================================================================ @@ -58,11 +58,11 @@ static KSStackCursor g_stackCursor; #if KSCRASH_HAS_SIGNAL_STACK /** Our custom signal stack. The signal handler will use this as its stack. */ -static stack_t g_signalStack = {0}; +static stack_t g_signalStack = { 0 }; #endif /** Signal handlers that were installed before we installed ours. */ -static struct sigaction* g_previousSignalHandlers = NULL; +static struct sigaction *g_previousSignalHandlers = NULL; static char g_eventID[37]; @@ -82,11 +82,10 @@ static char g_eventID[37]; * * @param userContext Other contextual information. */ -static void handleSignal(int sigNum, siginfo_t* signalInfo, void* userContext) +static void handleSignal(int sigNum, siginfo_t *signalInfo, void *userContext) { KSLOG_DEBUG("Trapped signal %d", sigNum); - if(g_isEnabled) - { + if (g_isEnabled) { thread_act_array_t threads = NULL; mach_msg_type_number_t numThreads = 0; ksmc_suspendEnvironment(&threads, &numThreads); @@ -97,7 +96,7 @@ static void handleSignal(int sigNum, siginfo_t* signalInfo, void* userContext) ksmc_getContextForSignal(userContext, machineContext); kssc_initWithMachineContext(&g_stackCursor, KSSC_MAX_STACK_DEPTH, machineContext); - KSCrash_MonitorContext* crashContext = &g_monitorContext; + KSCrash_MonitorContext *crashContext = &g_monitorContext; memset(crashContext, 0, sizeof(*crashContext)); ksmc_fillMonitorContext(crashContext, kscm_signal_getAPI()); crashContext->eventID = g_eventID; @@ -117,7 +116,6 @@ static void handleSignal(int sigNum, siginfo_t* signalInfo, void* userContext) raise(sigNum); } - // ============================================================================ #pragma mark - API - // ============================================================================ @@ -128,32 +126,28 @@ static bool installSignalHandler(void) #if KSCRASH_HAS_SIGNAL_STACK - if(g_signalStack.ss_size == 0) - { + if (g_signalStack.ss_size == 0) { KSLOG_DEBUG("Allocating signal stack area."); g_signalStack.ss_size = SIGSTKSZ; g_signalStack.ss_sp = malloc(g_signalStack.ss_size); } KSLOG_DEBUG("Setting signal stack area."); - if(sigaltstack(&g_signalStack, NULL) != 0) - { + if (sigaltstack(&g_signalStack, NULL) != 0) { KSLOG_ERROR("signalstack: %s", strerror(errno)); goto failed; } #endif - const int* fatalSignals = kssignal_fatalSignals(); + const int *fatalSignals = kssignal_fatalSignals(); int fatalSignalsCount = kssignal_numFatalSignals(); - if(g_previousSignalHandlers == NULL) - { + if (g_previousSignalHandlers == NULL) { KSLOG_DEBUG("Allocating memory to store previous signal handlers."); - g_previousSignalHandlers = malloc(sizeof(*g_previousSignalHandlers) - * (unsigned)fatalSignalsCount); + g_previousSignalHandlers = malloc(sizeof(*g_previousSignalHandlers) * (unsigned)fatalSignalsCount); } - struct sigaction action = {{0}}; + struct sigaction action = { { 0 } }; action.sa_flags = SA_SIGINFO | SA_ONSTACK; #if KSCRASH_HOST_APPLE && defined(__LP64__) action.sa_flags |= SA_64REGSET; @@ -161,22 +155,18 @@ static bool installSignalHandler(void) sigemptyset(&action.sa_mask); action.sa_sigaction = &handleSignal; - for(int i = 0; i < fatalSignalsCount; i++) - { + for (int i = 0; i < fatalSignalsCount; i++) { KSLOG_DEBUG("Assigning handler for signal %d", fatalSignals[i]); - if(sigaction(fatalSignals[i], &action, &g_previousSignalHandlers[i]) != 0) - { + if (sigaction(fatalSignals[i], &action, &g_previousSignalHandlers[i]) != 0) { char sigNameBuff[30]; - const char* sigName = kssignal_signalName(fatalSignals[i]); - if(sigName == NULL) - { + const char *sigName = kssignal_signalName(fatalSignals[i]); + if (sigName == NULL) { snprintf(sigNameBuff, sizeof(sigNameBuff), "%d", fatalSignals[i]); sigName = sigNameBuff; } KSLOG_ERROR("sigaction (%s): %s", sigName, strerror(errno)); // Try to reverse the damage - for(i--;i >= 0; i--) - { + for (i--; i >= 0; i--) { sigaction(fatalSignals[i], &g_previousSignalHandlers[i], NULL); } goto failed; @@ -194,80 +184,61 @@ static void uninstallSignalHandler(void) { KSLOG_DEBUG("Uninstalling signal handlers."); - const int* fatalSignals = kssignal_fatalSignals(); + const int *fatalSignals = kssignal_fatalSignals(); int fatalSignalsCount = kssignal_numFatalSignals(); - for(int i = 0; i < fatalSignalsCount; i++) - { + for (int i = 0; i < fatalSignalsCount; i++) { KSLOG_DEBUG("Restoring original handler for signal %d", fatalSignals[i]); sigaction(fatalSignals[i], &g_previousSignalHandlers[i], NULL); } - + #if KSCRASH_HAS_SIGNAL_STACK - g_signalStack = (stack_t){0}; + g_signalStack = (stack_t) { 0 }; #endif KSLOG_DEBUG("Signal handlers uninstalled."); } -static const char* monitorId(void) -{ - return "Signal"; -} +static const char *monitorId(void) { return "Signal"; } -static KSCrashMonitorFlag monitorFlags(void) -{ - return KSCrashMonitorFlagFatal | KSCrashMonitorFlagAsyncSafe; -} +static KSCrashMonitorFlag monitorFlags(void) { return KSCrashMonitorFlagFatal | KSCrashMonitorFlagAsyncSafe; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { ksid_generate(g_eventID); - if(!installSignalHandler()) - { + if (!installSignalHandler()) { return; } - } - else - { + } else { uninstallSignalHandler(); } } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -static void addContextualInfoToEvent(struct KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(struct KSCrash_MonitorContext *eventContext) { const char *machName = kscm_getMonitorId(kscm_machexception_getAPI()); - if(!(strcmp(eventContext->monitorId, monitorId()) == 0 || - (machName && strcmp(eventContext->monitorId, machName) == 0))) - { + if (!(strcmp(eventContext->monitorId, monitorId()) == 0 || + (machName && strcmp(eventContext->monitorId, machName) == 0))) { eventContext->signal.signum = SIGABRT; } } #endif /* KSCRASH_HAS_SIGNAL */ -KSCrashMonitorAPI* kscm_signal_getAPI(void) +KSCrashMonitorAPI *kscm_signal_getAPI(void) { #if KSCRASH_HAS_SIGNAL - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .monitorFlags = monitorFlags, - .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent - }; + static KSCrashMonitorAPI api = { .monitorId = monitorId, + .monitorFlags = monitorFlags, + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; return &api; #else return NULL; diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.h index bf3e76da4..c9cc296f8 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Signal.h @@ -24,11 +24,9 @@ // THE SOFTWARE. // - /* Catches fatal unix signals. */ - #ifndef HDR_KSCrashMonitor_Signal_h #define HDR_KSCrashMonitor_Signal_h @@ -38,14 +36,12 @@ extern "C" { #endif - /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_signal_getAPI(void); - +KSCrashMonitorAPI *kscm_signal_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_Signal_h +#endif // HDR_KSCrashMonitor_Signal_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.h index 6dd47ee67..8b9e8e79f 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.h @@ -33,11 +33,9 @@ extern "C" { #endif - /** Access the Monitor API. */ - KSCrashMonitorAPI* kscm_system_getAPI(void); - +KSCrashMonitorAPI *kscm_system_getAPI(void); #ifdef __cplusplus } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.m b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.m index 81db0453f..6eb2d3998 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.m +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_System.m @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashMonitor_System.h" #import "KSCPU.h" @@ -34,46 +33,44 @@ #import "KSSysCtl.h" #import "KSSystemCapabilities.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" -#import #import +#import #if KSCRASH_HAS_UIKIT #import #endif -#include #include +#include - -typedef struct -{ - const char* systemName; - const char* systemVersion; - const char* machine; - const char* model; - const char* kernelVersion; - const char* osVersion; +typedef struct { + const char *systemName; + const char *systemVersion; + const char *machine; + const char *model; + const char *kernelVersion; + const char *osVersion; bool isJailbroken; - const char* appStartTime; - const char* executablePath; - const char* executableName; - const char* bundleID; - const char* bundleName; - const char* bundleVersion; - const char* bundleShortVersion; - const char* appID; - const char* cpuArchitecture; + const char *appStartTime; + const char *executablePath; + const char *executableName; + const char *bundleID; + const char *bundleName; + const char *bundleVersion; + const char *bundleShortVersion; + const char *appID; + const char *cpuArchitecture; int cpuType; int cpuSubType; int binaryCPUType; int binaryCPUSubType; - const char* timezone; - const char* processName; + const char *timezone; + const char *processName; int processID; int parentProcessID; - const char* deviceAppHash; - const char* buildType; + const char *deviceAppHash; + const char *buildType; uint64_t memorySize; } SystemData; @@ -85,28 +82,23 @@ #pragma mark - Utility - // ============================================================================ -static const char* cString(NSString* str) -{ - return str == NULL ? NULL : strdup(str.UTF8String); -} +static const char *cString(NSString *str) { return str == NULL ? NULL : strdup(str.UTF8String); } -static NSString* nsstringSysctl(NSString* name) +static NSString *nsstringSysctl(NSString *name) { - NSString* str = nil; + NSString *str = nil; int size = (int)kssysctl_stringForName(name.UTF8String, NULL, 0); - - if(size <= 0) - { + + if (size <= 0) { return @""; } - - NSMutableData* value = [NSMutableData dataWithLength:(unsigned)size]; - - if(kssysctl_stringForName(name.UTF8String, value.mutableBytes, size) != 0) - { + + NSMutableData *value = [NSMutableData dataWithLength:(unsigned)size]; + + if (kssysctl_stringForName(name.UTF8String, value.mutableBytes, size) != 0) { str = [NSString stringWithCString:value.mutableBytes encoding:NSUTF8StringEncoding]; } - + return str; } @@ -116,27 +108,25 @@ * * @return The result of the sysctl call. */ -static const char* stringSysctl(const char* name) +static const char *stringSysctl(const char *name) { int size = (int)kssysctl_stringForName(name, NULL, 0); - if(size <= 0) - { + if (size <= 0) { return NULL; } - char* value = malloc((size_t)size); - if(kssysctl_stringForName(name, value, size) <= 0) - { + char *value = malloc((size_t)size); + if (kssysctl_stringForName(name, value, size) <= 0) { free(value); return NULL; } - + return value; } -static const char* dateString(time_t date) +static const char *dateString(time_t date) { - char* buffer = malloc(21); + char *buffer = malloc(21); ksdate_utcStringFromTimestamp(date, buffer); return buffer; } @@ -149,28 +139,23 @@ * * @return true if the operation was successful. */ -static bool VMStats(vm_statistics_data_t* const vmStats, vm_size_t* const pageSize) +static bool VMStats(vm_statistics_data_t *const vmStats, vm_size_t *const pageSize) { kern_return_t kr; const mach_port_t hostPort = mach_host_self(); - - if((kr = host_page_size(hostPort, pageSize)) != KERN_SUCCESS) - { + + if ((kr = host_page_size(hostPort, pageSize)) != KERN_SUCCESS) { KSLOG_ERROR(@"host_page_size: %s", mach_error_string(kr)); return false; } - + mach_msg_type_number_t hostSize = sizeof(*vmStats) / sizeof(natural_t); - kr = host_statistics(hostPort, - HOST_VM_INFO, - (host_info_t)vmStats, - &hostSize); - if(kr != KERN_SUCCESS) - { + kr = host_statistics(hostPort, HOST_VM_INFO, (host_info_t)vmStats, &hostSize); + if (kr != KERN_SUCCESS) { KSLOG_ERROR(@"host_statistics: %s", mach_error_string(kr)); return false; } - + return true; } @@ -178,8 +163,7 @@ static uint64_t freeMemory(void) { vm_statistics_data_t vmStats; vm_size_t pageSize; - if(VMStats(&vmStats, &pageSize)) - { + if (VMStats(&vmStats, &pageSize)) { return ((uint64_t)pageSize) * vmStats.free_count; } return 0; @@ -189,12 +173,9 @@ static uint64_t usableMemory(void) { vm_statistics_data_t vmStats; vm_size_t pageSize; - if(VMStats(&vmStats, &pageSize)) - { - return ((uint64_t)pageSize) * (vmStats.active_count + - vmStats.inactive_count + - vmStats.wire_count + - vmStats.free_count); + if (VMStats(&vmStats, &pageSize)) { + return ((uint64_t)pageSize) * + (vmStats.active_count + vmStats.inactive_count + vmStats.wire_count + vmStats.free_count); } return 0; } @@ -205,12 +186,12 @@ static uint64_t usableMemory(void) * * @return The human readable form of the UUID. */ -static const char* uuidBytesToString(const uint8_t* uuidBytes) +static const char *uuidBytesToString(const uint8_t *uuidBytes) { - CFUUIDRef uuidRef = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes*)uuidBytes)); - NSString* str = (__bridge_transfer NSString*)CFUUIDCreateString(NULL, uuidRef); + CFUUIDRef uuidRef = CFUUIDCreateFromUUIDBytes(NULL, *((CFUUIDBytes *)uuidBytes)); + NSString *str = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuidRef); CFRelease(uuidRef); - + return cString(str); } @@ -218,12 +199,12 @@ static uint64_t usableMemory(void) * * @return Executable path. */ -static NSString* getExecutablePath(void) +static NSString *getExecutablePath(void) { - NSBundle* mainBundle = [NSBundle mainBundle]; - NSDictionary* infoDict = [mainBundle infoDictionary]; - NSString* bundlePath = [mainBundle bundlePath]; - NSString* executableName = infoDict[@"CFBundleExecutable"]; + NSBundle *mainBundle = [NSBundle mainBundle]; + NSDictionary *infoDict = [mainBundle infoDictionary]; + NSString *bundlePath = [mainBundle bundlePath]; + NSString *executableName = infoDict[@"CFBundleExecutable"]; return [bundlePath stringByAppendingPathComponent:executableName]; } @@ -231,26 +212,23 @@ static uint64_t usableMemory(void) * * @return The UUID. */ -static const char* getAppUUID(void) +static const char *getAppUUID(void) { - const char* result = nil; - - NSString* exePath = getExecutablePath(); - - if(exePath != nil) - { - const uint8_t* uuidBytes = ksdl_imageUUID(exePath.UTF8String, true); - if(uuidBytes == NULL) - { + const char *result = nil; + + NSString *exePath = getExecutablePath(); + + if (exePath != nil) { + const uint8_t *uuidBytes = ksdl_imageUUID(exePath.UTF8String, true); + if (uuidBytes == NULL) { // OSX app image path is a lie. uuidBytes = ksdl_imageUUID(exePath.lastPathComponent.UTF8String, false); } - if(uuidBytes != NULL) - { + if (uuidBytes != NULL) { result = uuidBytesToString(uuidBytes); } } - + return result; } @@ -258,14 +236,11 @@ static uint64_t usableMemory(void) * * @return The current CPU archutecture. */ -static const char* getCPUArchForCPUType(cpu_type_t cpuType, cpu_subtype_t subType) +static const char *getCPUArchForCPUType(cpu_type_t cpuType, cpu_subtype_t subType) { - switch(cpuType) - { - case CPU_TYPE_ARM: - { - switch (subType) - { + switch (cpuType) { + case CPU_TYPE_ARM: { + switch (subType) { case CPU_SUBTYPE_ARM_V6: return "armv6"; case CPU_SUBTYPE_ARM_V7: @@ -281,10 +256,8 @@ static uint64_t usableMemory(void) } break; } - case CPU_TYPE_ARM64: - { - switch (subType) - { + case CPU_TYPE_ARM64: { + switch (subType) { case CPU_SUBTYPE_ARM64E: return "arm64e"; } @@ -295,17 +268,16 @@ static uint64_t usableMemory(void) case CPU_TYPE_X86_64: return "x86_64"; } - + return NULL; } -static const char* getCurrentCPUArch(void) +static const char *getCurrentCPUArch(void) { - const char* result = getCPUArchForCPUType(kssysctl_int32ForName("hw.cputype"), - kssysctl_int32ForName("hw.cpusubtype")); + const char *result = + getCPUArchForCPUType(kssysctl_int32ForName("hw.cputype"), kssysctl_int32ForName("hw.cpusubtype")); - if(result == NULL) - { + if (result == NULL) { result = kscpu_currentArch(); } return result; @@ -315,10 +287,7 @@ static uint64_t usableMemory(void) * * @return YES if the device is jailbroken. */ -static bool isJailbroken(void) -{ - return ksdl_imageNamed("MobileSubstrate", false) != UINT32_MAX; -} +static bool isJailbroken(void) { return ksdl_imageNamed("MobileSubstrate", false) != UINT32_MAX; } /** Check if the current build is a debug build. * @@ -350,9 +319,9 @@ static bool isSimulatorBuild(void) * * @return App Store receipt for iOS 7+, nil otherwise. */ -static NSString* getReceiptUrlPath(void) +static NSString *getReceiptUrlPath(void) { - NSString* path = nil; + NSString *path = nil; #if KSCRASH_HOST_IOS path = [NSBundle mainBundle].appStoreReceiptURL.path; #endif @@ -365,46 +334,42 @@ static bool isSimulatorBuild(void) * * @return The stringified hex representation of the hash for this device + app. */ -static const char* getDeviceAndAppHash(void) +static const char *getDeviceAndAppHash(void) { - NSMutableData* data = nil; - + NSMutableData *data = nil; + #if KSCRASH_HAS_UIDEVICE - if([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) - { + if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) { data = [NSMutableData dataWithLength:16]; [[UIDevice currentDevice].identifierForVendor getUUIDBytes:data.mutableBytes]; - } - else + } else #endif { data = [NSMutableData dataWithLength:6]; kssysctl_getMacAddress("en0", [data mutableBytes]); } - + // Append some device-specific data. - [data appendData:(NSData* _Nonnull )[nsstringSysctl(@"hw.machine") dataUsingEncoding:NSUTF8StringEncoding]]; - [data appendData:(NSData* _Nonnull )[nsstringSysctl(@"hw.model") dataUsingEncoding:NSUTF8StringEncoding]]; - const char* cpuArch = getCurrentCPUArch(); + [data appendData:(NSData *_Nonnull)[nsstringSysctl(@"hw.machine") dataUsingEncoding:NSUTF8StringEncoding]]; + [data appendData:(NSData *_Nonnull)[nsstringSysctl(@"hw.model") dataUsingEncoding:NSUTF8StringEncoding]]; + const char *cpuArch = getCurrentCPUArch(); [data appendBytes:cpuArch length:strlen(cpuArch)]; - + // Append the bundle ID. - NSData* bundleID = [[[NSBundle mainBundle] bundleIdentifier] dataUsingEncoding:NSUTF8StringEncoding]; - if(bundleID != nil) - { + NSData *bundleID = [[[NSBundle mainBundle] bundleIdentifier] dataUsingEncoding:NSUTF8StringEncoding]; + if (bundleID != nil) { [data appendData:bundleID]; } - + // SHA the whole thing. uint8_t sha[CC_SHA1_DIGEST_LENGTH]; CC_SHA1([data bytes], (CC_LONG)[data length], sha); - - NSMutableString* hash = [NSMutableString string]; - for(unsigned i = 0; i < sizeof(sha); i++) - { + + NSMutableString *hash = [NSMutableString string]; + for (unsigned i = 0; i < sizeof(sha); i++) { [hash appendFormat:@"%02x", sha[i]]; } - + return cString(hash); } @@ -413,10 +378,7 @@ static bool isSimulatorBuild(void) * * @return YES if this is a testing build. */ -static bool isTestBuild(void) -{ - return [getReceiptUrlPath().lastPathComponent isEqualToString:@"sandboxReceipt"]; -} +static bool isTestBuild(void) { return [getReceiptUrlPath().lastPathComponent isEqualToString:@"sandboxReceipt"]; } /** Check if the app has an app store receipt. * Only apps released through the app store will have a receipt. @@ -425,33 +387,28 @@ static bool isTestBuild(void) */ static bool hasAppStoreReceipt(void) { - NSString* receiptPath = getReceiptUrlPath(); - if(receiptPath == nil) - { + NSString *receiptPath = getReceiptUrlPath(); + if (receiptPath == nil) { return NO; } bool isAppStoreReceipt = [receiptPath.lastPathComponent isEqualToString:@"receipt"]; bool receiptExists = [[NSFileManager defaultManager] fileExistsAtPath:receiptPath]; - + return isAppStoreReceipt && receiptExists; } -static const char* getBuildType(void) +static const char *getBuildType(void) { - if(isSimulatorBuild()) - { + if (isSimulatorBuild()) { return "simulator"; } - if(isDebugBuild()) - { + if (isDebugBuild()) { return "debug"; } - if(isTestBuild()) - { + if (isTestBuild()) { return "test"; } - if(hasAppStoreReceipt()) - { + if (hasAppStoreReceipt()) { return "app store"; } return "unknown"; @@ -464,13 +421,12 @@ static bool hasAppStoreReceipt(void) static void initialize(void) { static bool isInitialized = false; - if(!isInitialized) - { + if (!isInitialized) { isInitialized = true; - NSBundle* mainBundle = [NSBundle mainBundle]; - NSDictionary* infoDict = [mainBundle infoDictionary]; - const struct mach_header* header = _dyld_get_image_header(0); + NSBundle *mainBundle = [NSBundle mainBundle]; + NSDictionary *infoDict = [mainBundle infoDictionary]; + const struct mach_header *header = _dyld_get_image_header(0); #if KSCRASH_HAS_UIDEVICE g_systemData.systemName = cString([UIDevice currentDevice].systemName); @@ -482,25 +438,21 @@ static void initialize(void) #if KSCRASH_HOST_WATCH g_systemData.systemName = "watchOS"; #endif - NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion;; - NSString* systemVersion; - if(version.patchVersion == 0) - { + NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion; + ; + NSString *systemVersion; + if (version.patchVersion == 0) { systemVersion = [NSString stringWithFormat:@"%d.%d", (int)version.majorVersion, (int)version.minorVersion]; - } - else - { - systemVersion = [NSString stringWithFormat:@"%d.%d.%d", (int)version.majorVersion, (int)version.minorVersion, (int)version.patchVersion]; + } else { + systemVersion = [NSString stringWithFormat:@"%d.%d.%d", (int)version.majorVersion, + (int)version.minorVersion, (int)version.patchVersion]; } g_systemData.systemVersion = cString(systemVersion); #endif - if(isSimulatorBuild()) - { + if (isSimulatorBuild()) { g_systemData.machine = cString([NSProcessInfo processInfo].environment[@"SIMULATOR_MODEL_IDENTIFIER"]); g_systemData.model = "simulator"; - } - else - { + } else { #if KSCRASH_HOST_MAC // MacOS has the machine in the model field, and no model g_systemData.machine = stringSysctl("hw.model"); @@ -509,7 +461,7 @@ static void initialize(void) g_systemData.model = stringSysctl("hw.model"); #endif } - + g_systemData.kernelVersion = stringSysctl("kern.version"); g_systemData.osVersion = stringSysctl("kern.osversion"); g_systemData.isJailbroken = isJailbroken(); @@ -536,32 +488,23 @@ static void initialize(void) } } -static const char* monitorId(void) -{ - return "System"; -} +static const char *monitorId(void) { return "System"; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { initialize(); } } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(KSCrash_MonitorContext *eventContext) { - if(g_isEnabled) - { + if (g_isEnabled) { #define COPY_REFERENCE(NAME) eventContext->System.NAME = g_systemData.NAME COPY_REFERENCE(systemName); COPY_REFERENCE(systemVersion); @@ -595,14 +538,11 @@ static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) } } -KSCrashMonitorAPI* kscm_system_getAPI(void) +KSCrashMonitorAPI *kscm_system_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent - }; + static KSCrashMonitorAPI api = { .monitorId = monitorId, + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; return &api; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.c b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.c index f416fe76a..99ffb812f 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.c +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.c @@ -23,45 +23,35 @@ // #include "KSCrashMonitor_User.h" -#include "KSCrashMonitorContextHelper.h" + #include "KSCrashMonitorContext.h" +#include "KSCrashMonitorContextHelper.h" #include "KSID.h" -#include "KSThread.h" #include "KSStackCursor_SelfThread.h" +#include "KSThread.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - +// #define KSLogger_LocalLevel TRACE #include #include +#include "KSLogger.h" + /** Context to fill with crash information. */ static volatile bool g_isEnabled = false; - -void kscm_reportUserException(const char* name, - const char* reason, - const char* language, - const char* lineOfCode, - const char* stackTrace, - bool logAllThreads, - bool terminateProgram) +void kscm_reportUserException(const char *name, const char *reason, const char *language, const char *lineOfCode, + const char *stackTrace, bool logAllThreads, bool terminateProgram) { - if(!g_isEnabled) - { + if (!g_isEnabled) { KSLOG_WARN("User-reported exception monitor is not installed. Exception has not been recorded."); - } - else - { + } else { thread_act_array_t threads = NULL; mach_msg_type_number_t numThreads = 0; - if(logAllThreads) - { + if (logAllThreads) { ksmc_suspendEnvironment(&threads, &numThreads); } - if(terminateProgram) - { + if (terminateProgram) { kscm_notifyFatalExceptionCaptured(false); } @@ -72,7 +62,6 @@ void kscm_reportUserException(const char* name, KSStackCursor stackCursor; kssc_initSelfThread(&stackCursor, 0); - KSLOG_DEBUG("Filling out context."); KSCrash_MonitorContext context; memset(&context, 0, sizeof(context)); @@ -89,39 +78,23 @@ void kscm_reportUserException(const char* name, kscm_handleException(&context); - if(logAllThreads) - { + if (logAllThreads) { ksmc_resumeEnvironment(threads, numThreads); } - if(terminateProgram) - { + if (terminateProgram) { abort(); } } } -static const char* monitorId(void) -{ - return "UserReported"; -} +static const char *monitorId(void) { return "UserReported"; } -static void setEnabled(bool isEnabled) -{ - g_isEnabled = isEnabled; -} +static void setEnabled(bool isEnabled) { g_isEnabled = isEnabled; } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -KSCrashMonitorAPI* kscm_user_getAPI(void) +KSCrashMonitorAPI *kscm_user_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .setEnabled = setEnabled, - .isEnabled = isEnabled - }; + static KSCrashMonitorAPI api = { .monitorId = monitorId, .setEnabled = setEnabled, .isEnabled = isEnabled }; return &api; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.h index 35344465f..606f348b0 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_User.h @@ -25,15 +25,14 @@ #ifndef HDR_KSCrashMonitor_User_h #define HDR_KSCrashMonitor_User_h -#include "KSCrashMonitor.h" - #include +#include "KSCrashMonitor.h" + #ifdef __cplusplus extern "C" { #endif - /** Report a custom, user defined exception. * If terminateProgram is true, all sentries will be uninstalled and the application will * terminate with an abort(). @@ -54,21 +53,15 @@ extern "C" { * * @param terminateProgram If true, do not return from this function call. Terminate the program instead. */ -void kscm_reportUserException(const char* name, - const char* reason, - const char* language, - const char* lineOfCode, - const char* stackTrace, - bool logAllThreads, - bool terminateProgram); +void kscm_reportUserException(const char *name, const char *reason, const char *language, const char *lineOfCode, + const char *stackTrace, bool logAllThreads, bool terminateProgram); /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_user_getAPI(void); - +KSCrashMonitorAPI *kscm_user_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_User_h +#endif // HDR_KSCrashMonitor_User_h diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.c b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.c index dfb0c2f5e..ed5f475b1 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.c +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.c @@ -24,63 +24,57 @@ // THE SOFTWARE. // - #include "KSCrashMonitor_Zombie.h" -#include "KSCrashMonitorContext.h" -#include "KSObjC.h" -#include "KSLogger.h" #include #include +#include "KSCrashMonitorContext.h" +#include "KSLogger.h" +#include "KSObjC.h" #define CACHE_SIZE 0x8000 // Compiler hints for "if" statements -#define likely_if(x) if(__builtin_expect(x,1)) -#define unlikely_if(x) if(__builtin_expect(x,0)) +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) -typedef struct -{ - const void* object; - const char* className; +typedef struct { + const void *object; + const char *className; } Zombie; -static volatile Zombie* g_zombieCache; +static volatile Zombie *g_zombieCache; static unsigned g_zombieHashMask; static volatile bool g_isEnabled = false; -static struct -{ +static struct { Class class; - const void* address; + const void *address; char name[100]; char reason[900]; } g_lastDeallocedException; -static inline unsigned hashIndex(const void* object) +static inline unsigned hashIndex(const void *object) { uintptr_t objPtr = (uintptr_t)object; - objPtr >>= (sizeof(object)-1); + objPtr >>= (sizeof(object) - 1); return objPtr & g_zombieHashMask; } -static bool copyStringIvar(const void* self, const char* ivarName, char* buffer, int bufferLength) +static bool copyStringIvar(const void *self, const char *ivarName, char *buffer, int bufferLength) { Class class = object_getClass((id)self); - KSObjCIvar ivar = {0}; + KSObjCIvar ivar = { 0 }; likely_if(ksobjc_ivarNamed(class, ivarName, &ivar)) { - void* pointer; + void *pointer; likely_if(ksobjc_ivarValue(self, ivar.index, &pointer)) { likely_if(ksobjc_isValidObject(pointer)) { - likely_if(ksobjc_copyStringContents(pointer, buffer, bufferLength) > 0) - { - return true; - } + likely_if(ksobjc_copyStringContents(pointer, buffer, bufferLength) > 0) { return true; } else { KSLOG_DEBUG("ksobjc_copyStringContents %s failed", ivarName); @@ -103,51 +97,48 @@ static bool copyStringIvar(const void* self, const char* ivarName, char* buffer, return false; } -static void storeException(const void* exception) +static void storeException(const void *exception) { g_lastDeallocedException.address = exception; copyStringIvar(exception, "name", g_lastDeallocedException.name, sizeof(g_lastDeallocedException.name)); copyStringIvar(exception, "reason", g_lastDeallocedException.reason, sizeof(g_lastDeallocedException.reason)); } -static inline void handleDealloc(const void* self) +static inline void handleDealloc(const void *self) { - volatile Zombie* cache = g_zombieCache; + volatile Zombie *cache = g_zombieCache; likely_if(cache != NULL) { - Zombie* zombie = (Zombie*)cache + hashIndex(self); + Zombie *zombie = (Zombie *)cache + hashIndex(self); zombie->object = self; Class class = object_getClass((id)self); zombie->className = class_getName(class); - for(; class != nil; class = class_getSuperclass(class)) - { - unlikely_if(class == g_lastDeallocedException.class) - { - storeException(self); - } + for (; class != nil; class = class_getSuperclass(class)) { + unlikely_if(class == g_lastDeallocedException.class) { storeException(self); } } } } -#define CREATE_ZOMBIE_HANDLER_INSTALLER(CLASS) \ -static IMP g_originalDealloc_ ## CLASS; \ -static void handleDealloc_ ## CLASS(id self, SEL _cmd) \ -{ \ - handleDealloc(self); \ - typedef void (*fn)(id,SEL); \ - fn f = (fn)g_originalDealloc_ ## CLASS; \ - f(self, _cmd); \ -} \ -static void installDealloc_ ## CLASS(void) \ -{ \ - Method method = class_getInstanceMethod(objc_getClass(#CLASS), sel_registerName("dealloc")); \ - g_originalDealloc_ ## CLASS = method_getImplementation(method); \ - method_setImplementation(method, (IMP)handleDealloc_ ## CLASS); \ -} +#define CREATE_ZOMBIE_HANDLER_INSTALLER(CLASS) \ + static IMP g_originalDealloc_##CLASS; \ + static void handleDealloc_##CLASS(id self, SEL _cmd) \ + { \ + handleDealloc(self); \ + typedef void (*fn)(id, SEL); \ + fn f = (fn)g_originalDealloc_##CLASS; \ + f(self, _cmd); \ + } \ + static void installDealloc_##CLASS(void) \ + { \ + Method method = class_getInstanceMethod(objc_getClass(#CLASS), sel_registerName("dealloc")); \ + g_originalDealloc_##CLASS = method_getImplementation(method); \ + method_setImplementation(method, (IMP)handleDealloc_##CLASS); \ + } // TODO: Uninstall doesn't work. -//static void uninstallDealloc_ ## CLASS() \ +// static void uninstallDealloc_ ## CLASS() \ //{ \ -// method_setImplementation(class_getInstanceMethod(objc_getClass(#CLASS), sel_registerName("dealloc")), g_originalDealloc_ ## CLASS); \ +// method_setImplementation(class_getInstanceMethod(objc_getClass(#CLASS), sel_registerName("dealloc")), +// g_originalDealloc_ ## CLASS); \ //} CREATE_ZOMBIE_HANDLER_INSTALLER(NSObject) @@ -158,10 +149,9 @@ static void install(void) unsigned cacheSize = CACHE_SIZE; g_zombieHashMask = cacheSize - 1; g_zombieCache = calloc(cacheSize, sizeof(*g_zombieCache)); - if(g_zombieCache == NULL) - { + if (g_zombieCache == NULL) { KSLOG_ERROR("Error: Could not allocate %u bytes of memory. KSZombie NOT installed!", - cacheSize * sizeof(*g_zombieCache)); + cacheSize * sizeof(*g_zombieCache)); return; } @@ -175,7 +165,7 @@ static void install(void) } // TODO: Uninstall doesn't work. -//static void uninstall(void) +// static void uninstall(void) //{ // uninstallDealloc_NSObject(); // uninstallDealloc_NSProxy(); @@ -189,68 +179,52 @@ static void install(void) // }); //} -const char* kszombie_className(const void* object) +const char *kszombie_className(const void *object) { - volatile Zombie* cache = g_zombieCache; - if(cache == NULL || object == NULL) - { + volatile Zombie *cache = g_zombieCache; + if (cache == NULL || object == NULL) { return NULL; } - Zombie* zombie = (Zombie*)cache + hashIndex(object); - if(zombie->object == object) - { + Zombie *zombie = (Zombie *)cache + hashIndex(object); + if (zombie->object == object) { return zombie->className; } return NULL; } -static const char* monitorId(void) -{ - return "Zombie"; -} +static const char *monitorId(void) { return "Zombie"; } static void setEnabled(bool isEnabled) { - if(isEnabled != g_isEnabled) - { + if (isEnabled != g_isEnabled) { g_isEnabled = isEnabled; - if(isEnabled) - { + if (isEnabled) { install(); - } - else - { + } else { // TODO: Uninstall doesn't work. g_isEnabled = true; -// uninstall(); + // uninstall(); } } } -static bool isEnabled(void) -{ - return g_isEnabled; -} +static bool isEnabled(void) { return g_isEnabled; } -static void addContextualInfoToEvent(KSCrash_MonitorContext* eventContext) +static void addContextualInfoToEvent(KSCrash_MonitorContext *eventContext) { - if(g_isEnabled) - { + if (g_isEnabled) { eventContext->ZombieException.address = (uintptr_t)g_lastDeallocedException.address; eventContext->ZombieException.name = g_lastDeallocedException.name; eventContext->ZombieException.reason = g_lastDeallocedException.reason; } } -KSCrashMonitorAPI* kscm_zombie_getAPI(void) +KSCrashMonitorAPI *kscm_zombie_getAPI(void) { - static KSCrashMonitorAPI api = - { - .monitorId = monitorId, - .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent - }; + static KSCrashMonitorAPI api = { .monitorId = monitorId, + .setEnabled = setEnabled, + .isEnabled = isEnabled, + .addContextualInfoToEvent = addContextualInfoToEvent }; return &api; } diff --git a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.h b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.h index da43a6a56..0b3dfba09 100644 --- a/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.h +++ b/Sources/KSCrashRecording/Monitors/KSCrashMonitor_Zombie.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - /* Poor man's zombie tracking. * * Benefits: @@ -41,9 +40,10 @@ #ifndef HDR_KSZombie_h #define HDR_KSZombie_h -#include "KSCrashMonitor.h" #include +#include "KSCrashMonitor.h" + #ifdef __cplusplus extern "C" { #endif @@ -54,15 +54,14 @@ extern "C" { * * @return The object's class name, or NULL if it wasn't found. */ -const char* kszombie_className(const void* object); +const char *kszombie_className(const void *object); /** Access the Monitor API. */ -KSCrashMonitorAPI* kscm_zombie_getAPI(void); - +KSCrashMonitorAPI *kscm_zombie_getAPI(void); #ifdef __cplusplus } #endif -#endif // HDR_KSZombie_h +#endif // HDR_KSZombie_h diff --git a/Sources/KSCrashRecording/include/KSCrash.h b/Sources/KSCrashRecording/include/KSCrash.h index 764754bf9..2f3ae2436 100644 --- a/Sources/KSCrashRecording/include/KSCrash.h +++ b/Sources/KSCrashRecording/include/KSCrash.h @@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN * * Default: nil */ -@property (atomic, readwrite, strong, nullable) NSDictionary* userInfo; +@property(atomic, readwrite, strong, nullable) NSDictionary *userInfo; /** The report sink where reports get sent. * This MUST be set or else the reporter will not send reports (although it will @@ -58,42 +58,42 @@ NS_ASSUME_NONNULL_BEGIN * Note: If you use an installation, it will automatically set this property. * Do not modify it in such a case. */ -@property (nonatomic, readwrite, strong, nullable) id sink; +@property(nonatomic, readwrite, strong, nullable) id sink; #pragma mark - Information - /** Exposes the uncaughtExceptionHandler if set from KSCrash. Is nil if debugger is running. */ -@property(nonatomic,readonly,assign) NSUncaughtExceptionHandler* uncaughtExceptionHandler; +@property(nonatomic, readonly, assign) NSUncaughtExceptionHandler *uncaughtExceptionHandler; /** Exposes the currentSnapshotUserReportedExceptionHandler if set from KSCrash. Is nil if debugger is running. */ -@property(nonatomic,readonly,assign) NSUncaughtExceptionHandler* currentSnapshotUserReportedExceptionHandler; +@property(nonatomic, readonly, assign) NSUncaughtExceptionHandler *currentSnapshotUserReportedExceptionHandler; /** Total active time elapsed since the last crash. */ -@property(nonatomic,readonly,assign) NSTimeInterval activeDurationSinceLastCrash; +@property(nonatomic, readonly, assign) NSTimeInterval activeDurationSinceLastCrash; /** Total time backgrounded elapsed since the last crash. */ -@property(nonatomic,readonly,assign) NSTimeInterval backgroundDurationSinceLastCrash; +@property(nonatomic, readonly, assign) NSTimeInterval backgroundDurationSinceLastCrash; /** Number of app launches since the last crash. */ -@property(nonatomic,readonly,assign) NSInteger launchesSinceLastCrash; +@property(nonatomic, readonly, assign) NSInteger launchesSinceLastCrash; /** Number of sessions (launch, resume from suspend) since last crash. */ -@property(nonatomic,readonly,assign) NSInteger sessionsSinceLastCrash; +@property(nonatomic, readonly, assign) NSInteger sessionsSinceLastCrash; /** Total active time elapsed since launch. */ -@property(nonatomic,readonly,assign) NSTimeInterval activeDurationSinceLaunch; +@property(nonatomic, readonly, assign) NSTimeInterval activeDurationSinceLaunch; /** Total time backgrounded elapsed since launch. */ -@property(nonatomic,readonly,assign) NSTimeInterval backgroundDurationSinceLaunch; +@property(nonatomic, readonly, assign) NSTimeInterval backgroundDurationSinceLaunch; /** Number of sessions (launch, resume from suspend) since app launch. */ -@property(nonatomic,readonly,assign) NSInteger sessionsSinceLaunch; +@property(nonatomic, readonly, assign) NSInteger sessionsSinceLaunch; /** If true, the application crashed on the previous launch. */ -@property(nonatomic,readonly,assign) BOOL crashedLastLaunch; +@property(nonatomic, readonly, assign) BOOL crashedLastLaunch; /** The total number of unsent reports. Note: This is an expensive operation. */ -@property(nonatomic,readonly,assign) NSInteger reportCount; +@property(nonatomic, readonly, assign) NSInteger reportCount; /** Information about the operating system and environment. * @@ -101,12 +101,12 @@ NS_ASSUME_NONNULL_BEGIN * To access these values, refer to the optional * `KSCrashBootTimeMonitor` and `KSCrashDiscSpaceMonitor` modules. */ -@property(nonatomic,readonly,strong) NSDictionary* systemInfo; +@property(nonatomic, readonly, strong) NSDictionary *systemInfo; #pragma mark - API - -- (instancetype) init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; /** * Specifies a custom base path for KSCrash installation. @@ -118,13 +118,13 @@ NS_ASSUME_NONNULL_BEGIN * @note This method SHOULD be called before any use of `sharedInstance` method. * Any call of this method after that is ignored. */ -+ (void) setBasePath:(nullable NSString*) basePath; ++ (void)setBasePath:(nullable NSString *)basePath; /** Get the singleton instance of the crash reporter. * * @note To specify a custom base direcory for KSCrash use `setBasePath:` method. */ -+ (instancetype) sharedInstance NS_SWIFT_NAME(shared()); ++ (instancetype)sharedInstance NS_SWIFT_NAME(shared()); /** Install the crash reporter. * The reporter will record crashes, but will not send any crash reports unless @@ -132,7 +132,7 @@ NS_ASSUME_NONNULL_BEGIN * * @return YES if the reporter successfully installed. */ -- (BOOL) installWithConfiguration:(KSCrashConfiguration*) configuration; +- (BOOL)installWithConfiguration:(KSCrashConfiguration *)configuration; /** Send all outstanding crash reports to the current sink. * It will only attempt to send the most recent 5 reports. All others will be @@ -144,10 +144,10 @@ NS_ASSUME_NONNULL_BEGIN * * @param onCompletion Called when sending is complete (nil = ignore). */ -- (void) sendAllReportsWithCompletion:(nullable KSCrashReportFilterCompletion) onCompletion; +- (void)sendAllReportsWithCompletion:(nullable KSCrashReportFilterCompletion)onCompletion; /** Get all unsent report IDs. */ -@property(nonatomic,readonly,strong) NSArray* reportIDs; +@property(nonatomic, readonly, strong) NSArray *reportIDs; /** Get report. * @@ -155,17 +155,17 @@ NS_ASSUME_NONNULL_BEGIN * * @return A crash report with a dictionary value. The dectionary fields are described in KSCrashReportFields.h. */ -- (nullable KSCrashReport*) reportForID:(int64_t) reportID NS_SWIFT_NAME(report(for:)); +- (nullable KSCrashReport *)reportForID:(int64_t)reportID NS_SWIFT_NAME(report(for:)); /** Delete all unsent reports. */ -- (void) deleteAllReports; +- (void)deleteAllReports; /** Delete report. * * @param reportID An ID of report to delete. */ -- (void) deleteReportWithID:(int64_t) reportID NS_SWIFT_NAME(deleteReport(with:)); +- (void)deleteReportWithID:(int64_t)reportID NS_SWIFT_NAME(deleteReport(with:)); /** Report a custom, user defined exception. * This can be useful when dealing with scripting languages. @@ -181,18 +181,19 @@ NS_ASSUME_NONNULL_BEGIN * * @param lineOfCode A copy of the offending line of code (nil = ignore). * - * @param stackTrace An array of frames (dictionaries or strings) representing the call stack leading to the exception (nil = ignore). + * @param stackTrace An array of frames (dictionaries or strings) representing the call stack leading to the exception + * (nil = ignore). * * @param logAllThreads If true, suspend all threads and log their state. Note that this incurs a * performance penalty, so it's best to use only on fatal errors. * * @param terminateProgram If true, do not return from this function call. Terminate the program instead. */ -- (void)reportUserException:(NSString*)name - reason:(nullable NSString*)reason - language:(nullable NSString*)language - lineOfCode:(nullable NSString*)lineOfCode - stackTrace:(nullable NSArray*)stackTrace +- (void)reportUserException:(NSString *)name + reason:(nullable NSString *)reason + language:(nullable NSString *)language + lineOfCode:(nullable NSString *)lineOfCode + stackTrace:(nullable NSArray *)stackTrace logAllThreads:(BOOL)logAllThreads terminateProgram:(BOOL)terminateProgram; diff --git a/Sources/KSCrashRecording/include/KSCrashAppMemory.h b/Sources/KSCrashRecording/include/KSCrashAppMemory.h index deb3b7f99..b3503cd92 100644 --- a/Sources/KSCrashRecording/include/KSCrashAppMemory.h +++ b/Sources/KSCrashRecording/include/KSCrashAppMemory.h @@ -59,17 +59,15 @@ NS_ASSUME_NONNULL_BEGIN /** Notification sent when the memory level changes. */ -FOUNDATION_EXPORT NSNotificationName const KSCrashAppMemoryLevelChangedNotification -NS_SWIFT_NAME(AppMemoryLevelChangedNotification); +FOUNDATION_EXPORT NSNotificationName const KSCrashAppMemoryLevelChangedNotification NS_SWIFT_NAME(AppMemoryLevelChangedNotification); /** Notification sent when the memory pressure changes. */ -FOUNDATION_EXPORT NSNotificationName const KSCrashAppMemoryPressureChangedNotification -NS_SWIFT_NAME(AppMemoryPressureChangedNotification); +FOUNDATION_EXPORT NSNotificationName const KSCrashAppMemoryPressureChangedNotification NS_SWIFT_NAME(AppMemoryPressureChangedNotification); /** Notification keys that hold new and old values in the _userInfo_ dictionary. */ typedef NSString *KSCrashAppMemoryKeys NS_TYPED_ENUM NS_SWIFT_NAME(AppMemoryKeys); FOUNDATION_EXPORT KSCrashAppMemoryKeys const KSCrashAppMemoryNewValueKey NS_SWIFT_NAME(newValue); -FOUNDATION_EXPORT KSCrashAppMemoryKeys const KSCrashAppMemoryOldValueKey NS_SWIFT_NAME(oldValue); +FOUNDATION_EXPORT KSCrashAppMemoryKeys const KSCrashAppMemoryOldValueKey NS_SWIFT_NAME(oldValue); /** The memory state for level and pressure. */ typedef NS_ENUM(NSUInteger, KSCrashAppMemoryState) { @@ -135,10 +133,9 @@ NS_SWIFT_NAME(AppMemory) * `KSCrashAppMemoryStateToString` returns a `const char*` * because it needs to be async safe. */ -FOUNDATION_EXPORT const char *KSCrashAppMemoryStateToString(KSCrashAppMemoryState state) -NS_SWIFT_NAME(string(from:)); +FOUNDATION_EXPORT const char *KSCrashAppMemoryStateToString(KSCrashAppMemoryState state) NS_SWIFT_NAME(string(from:)); FOUNDATION_EXPORT KSCrashAppMemoryState KSCrashAppMemoryStateFromString(NSString *const string) -NS_SWIFT_NAME(memoryState(from:)); + NS_SWIFT_NAME(memoryState(from:)); NS_ASSUME_NONNULL_END diff --git a/Sources/KSCrashRecording/include/KSCrashAppMemoryTracker.h b/Sources/KSCrashRecording/include/KSCrashAppMemoryTracker.h index fd5590d37..675e1c07a 100644 --- a/Sources/KSCrashRecording/include/KSCrashAppMemoryTracker.h +++ b/Sources/KSCrashRecording/include/KSCrashAppMemoryTracker.h @@ -30,10 +30,10 @@ NS_ASSUME_NONNULL_BEGIN typedef NS_OPTIONS(NSUInteger, KSCrashAppMemoryTrackerChangeType) { - KSCrashAppMemoryTrackerChangeTypeNone = 0, - KSCrashAppMemoryTrackerChangeTypeLevel = 1 << 0, - KSCrashAppMemoryTrackerChangeTypePressure = 1 << 1, - KSCrashAppMemoryTrackerChangeTypeFootprint = 1 << 2, + KSCrashAppMemoryTrackerChangeTypeNone = 0, + KSCrashAppMemoryTrackerChangeTypeLevel = 1 << 0, + KSCrashAppMemoryTrackerChangeTypePressure = 1 << 1, + KSCrashAppMemoryTrackerChangeTypeFootprint = 1 << 2, } NS_SWIFT_NAME(AppMemoryTrackerChangeType); @protocol KSCrashAppMemoryTrackerDelegate; diff --git a/Sources/KSCrashRecording/include/KSCrashAppStateTracker.h b/Sources/KSCrashRecording/include/KSCrashAppStateTracker.h index 9a1cdbbfc..4420c6162 100644 --- a/Sources/KSCrashRecording/include/KSCrashAppStateTracker.h +++ b/Sources/KSCrashRecording/include/KSCrashAppStateTracker.h @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN */ typedef void (^KSCrashAppStateTrackerObserverBlock)(KSCrashAppTransitionState transitionState) -NS_SWIFT_UNAVAILABLE("Use Swift closures instead!"); + NS_SWIFT_UNAVAILABLE("Use Swift closures instead!"); @protocol KSCrashAppStateTrackerObserving; @@ -61,9 +61,9 @@ NS_SWIFT_NAME(AppStateTracker) - (instancetype)initWithNotificationCenter:(NSNotificationCenter *)notificationCenter NS_DESIGNATED_INITIALIZER; -@property (atomic, readonly) KSCrashAppTransitionState transitionState; +@property(atomic, readonly) KSCrashAppTransitionState transitionState; -/** +/** * Adds an observer that implements the _KSCrashAppStateTrackerObserving_ protocol. * You do not need to remove the observer as it is held weakly. */ @@ -79,7 +79,7 @@ NS_SWIFT_NAME(AppStateTracker) /** Removes an observer */ - (void)removeObserver:(id)observer; -/** +/** * Start/Stop * * WARNING: Don't call these on the shared tracker. diff --git a/Sources/KSCrashRecording/include/KSCrashAppTransitionState.h b/Sources/KSCrashRecording/include/KSCrashAppTransitionState.h index ed1ab8ae7..90048837a 100644 --- a/Sources/KSCrashRecording/include/KSCrashAppTransitionState.h +++ b/Sources/KSCrashRecording/include/KSCrashAppTransitionState.h @@ -26,8 +26,8 @@ #ifndef KSCrashAppTransitionState_h #define KSCrashAppTransitionState_h -#include #include +#include #ifdef __OBJC__ #include #endif @@ -40,6 +40,7 @@ extern "C" { #define NS_SWIFT_NAME(_name) #endif +// clang-format off /** States of transition for the application */ #ifdef __OBJC__ typedef NS_ENUM(uint8_t, KSCrashAppTransitionState) @@ -60,18 +61,18 @@ enum #ifndef __OBJC__ typedef uint8_t KSCrashAppTransitionState; #endif +// clang-format on /** * Returns true if the transition state is user perceptible. */ bool ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionState state) -NS_SWIFT_NAME(isUserPerceptible(transitionState:)); + NS_SWIFT_NAME(isUserPerceptible(transitionState:)); /** * Returns a string for the app state passed in. */ -const char *ksapp_transitionStateToString(KSCrashAppTransitionState state) -NS_SWIFT_NAME(string(for:)); +const char *ksapp_transitionStateToString(KSCrashAppTransitionState state) NS_SWIFT_NAME(string(for:)); #ifdef __cplusplus } diff --git a/Sources/KSCrashRecording/include/KSCrashC.h b/Sources/KSCrashRecording/include/KSCrashC.h index 415d07a87..a9a580141 100644 --- a/Sources/KSCrashRecording/include/KSCrashC.h +++ b/Sources/KSCrashRecording/include/KSCrashC.h @@ -24,19 +24,17 @@ // THE SOFTWARE. // - /* Primary C entry point into the crash reporting system. */ - #ifndef HDR_KSCrashC_h #define HDR_KSCrashC_h +#include + +#include "KSCrashCConfiguration.h" #include "KSCrashMonitorType.h" #include "KSCrashReportWriter.h" -#include "KSCrashCConfiguration.h" - -#include #ifdef __cplusplus extern "C" { @@ -77,14 +75,14 @@ extern "C" { * @note Once installed, the crash reporter cannot be re-installed or modified * without restarting the application. */ -void kscrash_install(const char* appName, const char* const installPath, KSCrashCConfiguration configuration); +void kscrash_install(const char *appName, const char *const installPath, KSCrashCConfiguration configuration); /** Set the user-supplied data in JSON format. * * @param userInfoJSON Pre-baked JSON containing user-supplied information. * NULL = delete. */ -void kscrash_setUserInfoJSON(const char* const userInfoJSON); +void kscrash_setUserInfoJSON(const char *const userInfoJSON); /** Get a copy of the user-supplied data in JSON format. * @@ -92,7 +90,7 @@ void kscrash_setUserInfoJSON(const char* const userInfoJSON); * or NULL if no information is set. * The caller is responsible for freeing the returned string. */ -const char* kscrash_getUserInfoJSON(void); +const char *kscrash_getUserInfoJSON(void); /** Report a custom, user defined exception. * This can be useful when dealing with scripting languages. @@ -116,15 +114,10 @@ const char* kscrash_getUserInfoJSON(void); * * @param terminateProgram If true, do not return from this function call. Terminate the program instead. */ -void kscrash_reportUserException(const char* name, - const char* reason, - const char* language, - const char* lineOfCode, - const char* stackTrace, - bool logAllThreads, - bool terminateProgram); +void kscrash_reportUserException(const char *name, const char *reason, const char *language, const char *lineOfCode, + const char *stackTrace, bool logAllThreads, bool terminateProgram); -#pragma mark -- Notifications -- +#pragma mark-- Notifications -- /** Notify the crash reporter of KSCrash being added to Objective-C runtime system. */ @@ -151,8 +144,7 @@ void kscrash_notifyAppTerminate(void); */ void kscrash_notifyAppCrash(void); - -#pragma mark -- Reporting -- +#pragma mark-- Reporting -- /** Get the number of reports on disk. */ @@ -165,7 +157,7 @@ int kscrash_getReportCount(void); * * @return The number of report IDs that were placed in the array. */ -int kscrash_getReportIDs(int64_t* reportIDs, int count); +int kscrash_getReportIDs(int64_t *reportIDs, int count); /** Read a report. * @@ -174,7 +166,7 @@ int kscrash_getReportIDs(int64_t* reportIDs, int count); * @return The NULL terminated report, or NULL if not found. * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on the returned value. */ -char* kscrash_readReport(int64_t reportID); +char *kscrash_readReport(int64_t reportID); /** Read a report at a specified path. * @@ -183,7 +175,7 @@ char* kscrash_readReport(int64_t reportID); * @return The NULL terminated report, or NULL if not found. * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on the returned value. */ -char* kscrash_readReportAtPath(const char* path); +char *kscrash_readReportAtPath(const char *path); /** Add a custom report to the store. * @@ -192,7 +184,7 @@ char* kscrash_readReportAtPath(const char* path); * * @return the new report's ID. */ -int64_t kscrash_addUserReport(const char* report, int reportLength); +int64_t kscrash_addUserReport(const char *report, int reportLength); /** Delete all reports on disk. */ @@ -204,9 +196,8 @@ void kscrash_deleteAllReports(void); */ void kscrash_deleteReportWithID(int64_t reportID); - #ifdef __cplusplus } #endif -#endif // HDR_KSCrashC_h +#endif // HDR_KSCrashC_h diff --git a/Sources/KSCrashRecording/include/KSCrashCConfiguration.h b/Sources/KSCrashRecording/include/KSCrashCConfiguration.h index a782556ce..548faa20b 100644 --- a/Sources/KSCrashRecording/include/KSCrashCConfiguration.h +++ b/Sources/KSCrashRecording/include/KSCrashCConfiguration.h @@ -28,6 +28,7 @@ #define KSCrashCConfiguration_h #include + #include "KSCrashMonitorType.h" #include "KSCrashReportWriter.h" @@ -54,7 +55,7 @@ typedef struct { * This JSON string contains user-specific data that will be included in * the crash report. If NULL is passed, any existing user data will be deleted. */ - const char* userInfoJSON; + const char *userInfoJSON; /** The maximum time to allow the main thread to run without returning. * @@ -98,8 +99,8 @@ typedef struct { * **Default**: NULL */ struct { - const char** strings; /**< Array of strings. */ - int length; /**< Length of the array. */ + const char **strings; /**< Array of strings. */ + int length; /**< Length of the array. */ } doNotIntrospectClasses; /** Callback to invoke upon a crash. @@ -162,20 +163,18 @@ typedef struct { static inline KSCrashCConfiguration KSCrashCConfiguration_Default(void) { - return (KSCrashCConfiguration) { - .monitors = KSCrashMonitorTypeProductionSafeMinimal, - .userInfoJSON = NULL, - .deadlockWatchdogInterval = 0.0, - .enableQueueNameSearch = false, - .enableMemoryIntrospection = false, - .doNotIntrospectClasses = { .strings = NULL, .length = 0 }, - .crashNotifyCallback = NULL, - .reportWrittenCallback = NULL, - .addConsoleLogToReport = false, - .printPreviousLogOnStartup = false, - .maxReportCount = 5, - .enableSwapCxaThrow = false - }; + return (KSCrashCConfiguration) { .monitors = KSCrashMonitorTypeProductionSafeMinimal, + .userInfoJSON = NULL, + .deadlockWatchdogInterval = 0.0, + .enableQueueNameSearch = false, + .enableMemoryIntrospection = false, + .doNotIntrospectClasses = { .strings = NULL, .length = 0 }, + .crashNotifyCallback = NULL, + .reportWrittenCallback = NULL, + .addConsoleLogToReport = false, + .printPreviousLogOnStartup = false, + .maxReportCount = 5, + .enableSwapCxaThrow = false }; } #ifdef __cplusplus @@ -183,4 +182,3 @@ static inline KSCrashCConfiguration KSCrashCConfiguration_Default(void) #endif #endif /* KSCrashCConfiguration_h */ - diff --git a/Sources/KSCrashRecording/include/KSCrashConfiguration.h b/Sources/KSCrashRecording/include/KSCrashConfiguration.h index 46341c143..a61785dcc 100644 --- a/Sources/KSCrashRecording/include/KSCrashConfiguration.h +++ b/Sources/KSCrashRecording/include/KSCrashConfiguration.h @@ -1,6 +1,6 @@ // // KSCrashConfiguration.h -// +// // Created by Gleb Linnik on 11.06.2024. // // Copyright (c) 2012 Karl Stenerud. All rights reserved. @@ -40,17 +40,17 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { /** The crash types that will be handled. * Some crash types may not be enabled depending on circumstances (e.g., running in a debugger). - * + * * **Default**: `KSCrashMonitorTypeProductionSafeMinimal` */ -@property (nonatomic, assign) KSCrashMonitorType monitors; +@property(nonatomic, assign) KSCrashMonitorType monitors; /** User-supplied data in JSON format. NULL to delete. * * This JSON string contains user-specific data that will be included in * the crash report. If NULL is passed, any existing user data will be deleted. */ -@property (nonatomic, copy, nullable) NSDictionary * userInfoJSON; +@property(nonatomic, copy, nullable) NSDictionary *userInfoJSON; /** The maximum time to allow the main thread to run without returning. * @@ -63,7 +63,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * application on a different thread or set this to a higher value until initialization * is complete. */ -@property (nonatomic, assign) double deadlockWatchdogInterval; +@property(nonatomic, assign) double deadlockWatchdogInterval; /** If true, attempt to fetch dispatch queue names for each running thread. * @@ -73,7 +73,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: false */ -@property (nonatomic, assign) BOOL enableQueueNameSearch; +@property(nonatomic, assign) BOOL enableQueueNameSearch; /** If true, introspect memory contents during a crash. * @@ -83,7 +83,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: false */ -@property (nonatomic, assign) BOOL enableMemoryIntrospection; +@property(nonatomic, assign) BOOL enableMemoryIntrospection; /** List of Objective-C classes that should never be introspected. * @@ -93,7 +93,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: NULL */ -@property (nonatomic, strong, nullable) NSArray *doNotIntrospectClasses; +@property(nonatomic, strong, nullable) NSArray *doNotIntrospectClasses; /** Callback to invoke upon a crash. * @@ -103,7 +103,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: NULL */ -@property (nonatomic, copy, nullable) void (^crashNotifyCallback)(const struct KSCrashReportWriter* writer); +@property(nonatomic, copy, nullable) void (^crashNotifyCallback)(const struct KSCrashReportWriter *writer); /** Callback to invoke upon finishing writing a crash report. * @@ -113,7 +113,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: NULL */ -@property (nonatomic, copy, nullable) void (^reportWrittenCallback)(int64_t reportID); +@property(nonatomic, copy, nullable) void (^reportWrittenCallback)(int64_t reportID); /** If true, append KSLOG console messages to the crash report. * @@ -121,7 +121,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: false */ -@property (nonatomic, assign) BOOL addConsoleLogToReport; +@property(nonatomic, assign) BOOL addConsoleLogToReport; /** If true, print the previous log to the console on startup. * @@ -130,7 +130,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: false */ -@property (nonatomic, assign) BOOL printPreviousLogOnStartup; +@property(nonatomic, assign) BOOL printPreviousLogOnStartup; /** The maximum number of crash reports allowed on disk before old ones get deleted. * @@ -139,7 +139,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: 5 */ -@property (nonatomic, assign) int maxReportCount; +@property(nonatomic, assign) int maxReportCount; /** If true, enable C++ exceptions catching with `__cxa_throw` swap. * @@ -150,7 +150,7 @@ typedef NS_ENUM(NSUInteger, KSCDeleteBehavior) { * * **Default**: false */ -@property (nonatomic, assign) BOOL enableSwapCxaThrow; +@property(nonatomic, assign) BOOL enableSwapCxaThrow; /** What to do after sending reports via sendAllReportsWithCompletion: * diff --git a/Sources/KSCrashRecording/include/KSCrashMonitorType.h b/Sources/KSCrashRecording/include/KSCrashMonitorType.h index 01774f205..ef210fa5f 100644 --- a/Sources/KSCrashRecording/include/KSCrashMonitorType.h +++ b/Sources/KSCrashRecording/include/KSCrashMonitorType.h @@ -37,6 +37,8 @@ extern "C" { #define NS_SWIFT_NAME(_name) #endif +// clang-format off + /** Various aspects of the system that can be monitored: * - Mach kernel exception * - Fatal signal @@ -147,8 +149,10 @@ KSCrashMonitorType #endif ; +// clang-format on + #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitorType_h +#endif // HDR_KSCrashMonitorType_h diff --git a/Sources/KSCrashRecording/include/KSCrashReport.h b/Sources/KSCrashRecording/include/KSCrashReport.h index 94d8a20f9..777c538c5 100644 --- a/Sources/KSCrashRecording/include/KSCrashReport.h +++ b/Sources/KSCrashRecording/include/KSCrashReport.h @@ -44,36 +44,36 @@ NS_SWIFT_NAME(CrashReport) /** * The type of the value of this crash report (dictionary, string, data) */ -@property (nonatomic, readonly, assign) KSCrashReportValueType valueType; +@property(nonatomic, readonly, assign) KSCrashReportValueType valueType; /** * A structured dictionary version of crash report. * This is usually a raw report that can be serialized to JSON. */ -@property (nonatomic, readonly, nullable, copy) NSDictionary* dictionaryValue; +@property(nonatomic, readonly, nullable, copy) NSDictionary *dictionaryValue; /** * A serialized or formatted string version of crash report. */ -@property (nonatomic, readonly, nullable, copy) NSString* stringValue; +@property(nonatomic, readonly, nullable, copy) NSString *stringValue; /** * A serialized data version of crash report. * This usually contain a serialized JSON. */ -@property (nonatomic, readonly, nullable, copy) NSData* dataValue; +@property(nonatomic, readonly, nullable, copy) NSData *dataValue; -- (instancetype) init NS_UNAVAILABLE; -+ (instancetype) new NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; -- (instancetype) initWithValueType:(KSCrashReportValueType) valueType - dictionaryValue:(nullable NSDictionary*) dictionaryValue - stringValue:(nullable NSString*) stringValue - dataValue:(nullable NSData*) dataValue NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithValueType:(KSCrashReportValueType)valueType + dictionaryValue:(nullable NSDictionary *)dictionaryValue + stringValue:(nullable NSString *)stringValue + dataValue:(nullable NSData *)dataValue NS_DESIGNATED_INITIALIZER; -+ (instancetype) reportWithDictionary:(NSDictionary*) dictionaryValue; -+ (instancetype) reportWithString:(NSString*) stringValue; -+ (instancetype) reportWithData:(NSData*) dataValue; ++ (instancetype)reportWithDictionary:(NSDictionary *)dictionaryValue; ++ (instancetype)reportWithString:(NSString *)stringValue; ++ (instancetype)reportWithData:(NSData *)dataValue; @end diff --git a/Sources/KSCrashRecording/include/KSCrashReportFields.h b/Sources/KSCrashRecording/include/KSCrashReportFields.h index 4db5e08af..ef5544f5c 100644 --- a/Sources/KSCrashRecording/include/KSCrashReportFields.h +++ b/Sources/KSCrashRecording/include/KSCrashReportFields.h @@ -29,10 +29,10 @@ #ifdef __OBJC__ #include -typedef NSString* KSCrashReportField; +typedef NSString *KSCrashReportField; #define KSCRF_CONVERT_STRING(str) @str #else /* __OBJC__ */ -typedef const char* KSCrashReportField; +typedef const char *KSCrashReportField; #define KSCRF_CONVERT_STRING(str) str #endif /* __OBJC__ */ @@ -248,4 +248,4 @@ KSCRF_DEFINE_CONSTANT(KSCrashField, AppTransitionState, appTransitionState, "app } #endif -#endif // HDR_KSCrashReportFields_h +#endif // HDR_KSCrashReportFields_h diff --git a/Sources/KSCrashRecording/include/KSCrashReportFilter.h b/Sources/KSCrashRecording/include/KSCrashReportFilter.h index 37e25b200..6f2499263 100644 --- a/Sources/KSCrashRecording/include/KSCrashReportFilter.h +++ b/Sources/KSCrashRecording/include/KSCrashReportFilter.h @@ -39,11 +39,9 @@ NS_ASSUME_NONNULL_BEGIN * user cancelling the operation). * @param error Non-nil if an error occurred. */ -typedef void(^KSCrashReportFilterCompletion)(NSArray* _Nullable filteredReports, - BOOL completed, - NSError* _Nullable error) -NS_SWIFT_UNAVAILABLE("Use Swift closures instead!"); - +typedef void (^KSCrashReportFilterCompletion)(NSArray *_Nullable filteredReports, BOOL completed, + NSError *_Nullable error) + NS_SWIFT_UNAVAILABLE("Use Swift closures instead!"); /** * A filter receives a set of reports, possibly transforms them, and then @@ -57,12 +55,11 @@ NS_SWIFT_NAME(CrashReportFilter) * @param reports The reports to process. * @param onCompletion Block to call when processing is complete. */ -- (void) filterReports:(NSArray*) reports - onCompletion:(nullable KSCrashReportFilterCompletion) onCompletion; +- (void)filterReports:(NSArray *)reports + onCompletion:(nullable KSCrashReportFilterCompletion)onCompletion; @end - /** Conditionally call a completion method if it's not nil. * * @param onCompletion The completion block. If nil, this function does nothing. @@ -71,12 +68,10 @@ NS_SWIFT_NAME(CrashReportFilter) * @param error The parameter to send as "error". */ static inline void kscrash_callCompletion(KSCrashReportFilterCompletion _Nullable onCompletion, - NSArray* _Nullable filteredReports, - BOOL completed, - NSError* _Nullable error) + NSArray *_Nullable filteredReports, BOOL completed, + NSError *_Nullable error) { - if(onCompletion) - { + if (onCompletion) { onCompletion(filteredReports, completed, error); } } diff --git a/Sources/KSCrashRecording/include/KSCrashReportWriter.h b/Sources/KSCrashRecording/include/KSCrashReportWriter.h index ffecb4d95..6827310b5 100644 --- a/Sources/KSCrashRecording/include/KSCrashReportWriter.h +++ b/Sources/KSCrashRecording/include/KSCrashReportWriter.h @@ -24,12 +24,10 @@ // THE SOFTWARE. // - /* Pointers to functions for writing to a crash report. All JSON types are * supported. */ - #ifndef HDR_KSCrashReportWriter_h #define HDR_KSCrashReportWriter_h @@ -55,8 +53,7 @@ extern "C" { /** * Encapsulates report writing functionality. */ -typedef struct KSCrashReportWriter -{ +typedef struct KSCrashReportWriter { /** Add a boolean element to the report. * * @param writer This writer. @@ -65,9 +62,7 @@ typedef struct KSCrashReportWriter * * @param value The value to add. */ - void (*addBooleanElement)(const struct KSCrashReportWriter* writer, - const char* name, - bool value); + void (*addBooleanElement)(const struct KSCrashReportWriter *writer, const char *name, bool value); /** Add a floating point element to the report. * @@ -77,9 +72,7 @@ typedef struct KSCrashReportWriter * * @param value The value to add. */ - void (*addFloatingPointElement)(const struct KSCrashReportWriter* writer, - const char* name, - double value); + void (*addFloatingPointElement)(const struct KSCrashReportWriter *writer, const char *name, double value); /** Add an integer element to the report. * @@ -89,9 +82,7 @@ typedef struct KSCrashReportWriter * * @param value The value to add. */ - void (*addIntegerElement)(const struct KSCrashReportWriter* writer, - const char* name, - int64_t value); + void (*addIntegerElement)(const struct KSCrashReportWriter *writer, const char *name, int64_t value); /** Add an unsigned integer element to the report. * @@ -101,9 +92,7 @@ typedef struct KSCrashReportWriter * * @param value The value to add. */ - void (*addUIntegerElement)(const struct KSCrashReportWriter* writer, - const char* name, - uint64_t value); + void (*addUIntegerElement)(const struct KSCrashReportWriter *writer, const char *name, uint64_t value); /** Add a string element to the report. * @@ -113,9 +102,7 @@ typedef struct KSCrashReportWriter * * @param value The value to add. */ - void (*addStringElement)(const struct KSCrashReportWriter* writer, - const char* name, - const char* value); + void (*addStringElement)(const struct KSCrashReportWriter *writer, const char *name, const char *value); /** Add a string element from a text file to the report. * @@ -125,9 +112,7 @@ typedef struct KSCrashReportWriter * * @param filePath The path to the file containing the value to add. */ - void (*addTextFileElement)(const struct KSCrashReportWriter* writer, - const char* name, - const char* filePath); + void (*addTextFileElement)(const struct KSCrashReportWriter *writer, const char *name, const char *filePath); /** Add an array of string elements representing lines from a text file to the report. * @@ -137,9 +122,7 @@ typedef struct KSCrashReportWriter * * @param filePath The path to the file containing the value to add. */ - void (*addTextFileLinesElement)(const struct KSCrashReportWriter* writer, - const char* name, - const char* filePath); + void (*addTextFileLinesElement)(const struct KSCrashReportWriter *writer, const char *name, const char *filePath); /** Add a JSON element from a text file to the report. * @@ -151,11 +134,9 @@ typedef struct KSCrashReportWriter * * @param closeLastContainer If false, do not close the last container. */ - void (*addJSONFileElement)(const struct KSCrashReportWriter* writer, - const char* name, - const char* filePath, + void (*addJSONFileElement)(const struct KSCrashReportWriter *writer, const char *name, const char *filePath, const bool closeLastContainer); - + /** Add a hex encoded data element to the report. * * @param writer This writer. @@ -166,9 +147,7 @@ typedef struct KSCrashReportWriter * * @paramn length The length of the data. */ - void (*addDataElement)(const struct KSCrashReportWriter* writer, - const char* name, - const char* value, + void (*addDataElement)(const struct KSCrashReportWriter *writer, const char *name, const char *value, const int length); /** Begin writing a hex encoded data element to the report. @@ -177,8 +156,7 @@ typedef struct KSCrashReportWriter * * @param name The name to give this element. */ - void (*beginDataElement)(const struct KSCrashReportWriter* writer, - const char* name); + void (*beginDataElement)(const struct KSCrashReportWriter *writer, const char *name); /** Append hex encoded data to the current data element in the report. * @@ -188,15 +166,13 @@ typedef struct KSCrashReportWriter * * @paramn length The length of the data. */ - void (*appendDataElement)(const struct KSCrashReportWriter* writer, - const char* value, - const int length); + void (*appendDataElement)(const struct KSCrashReportWriter *writer, const char *value, const int length); /** Complete writing a hex encoded data element to the report. * * @param writer This writer. */ - void (*endDataElement)(const struct KSCrashReportWriter* writer); + void (*endDataElement)(const struct KSCrashReportWriter *writer); /** Add a UUID element to the report. * @@ -206,9 +182,7 @@ typedef struct KSCrashReportWriter * * @param value A pointer to the binary UUID data. */ - void (*addUUIDElement)(const struct KSCrashReportWriter* writer, - const char* name, - const unsigned char* value); + void (*addUUIDElement)(const struct KSCrashReportWriter *writer, const char *name, const unsigned char *value); /** Add a preformatted JSON element to the report. * @@ -220,9 +194,7 @@ typedef struct KSCrashReportWriter * * @param closeLastContainer If false, do not close the last container. */ - void (*addJSONElement)(const struct KSCrashReportWriter* writer, - const char* name, - const char* jsonElement, + void (*addJSONElement)(const struct KSCrashReportWriter *writer, const char *name, const char *jsonElement, bool closeLastContainer); /** Begin a new object container. @@ -231,8 +203,7 @@ typedef struct KSCrashReportWriter * * @param name The name to give this element. */ - void (*beginObject)(const struct KSCrashReportWriter* writer, - const char* name); + void (*beginObject)(const struct KSCrashReportWriter *writer, const char *name); /** Begin a new array container. * @@ -240,28 +211,25 @@ typedef struct KSCrashReportWriter * * @param name The name to give this element. */ - void (*beginArray)(const struct KSCrashReportWriter* writer, - const char* name); + void (*beginArray)(const struct KSCrashReportWriter *writer, const char *name); /** Leave the current container, returning to the next higher level * container. * * @param writer This writer. */ - void (*endContainer)(const struct KSCrashReportWriter* writer); + void (*endContainer)(const struct KSCrashReportWriter *writer); /** Internal contextual data for the writer */ - void* context; + void *context; } NS_SWIFT_NAME(ReportWriter) KSCrashReportWriter; -typedef void (*KSReportWriteCallback)(const KSCrashReportWriter* writer) -NS_SWIFT_UNAVAILABLE("Use Swift closures instead!"); - +typedef void (*KSReportWriteCallback)(const KSCrashReportWriter *writer) + NS_SWIFT_UNAVAILABLE("Use Swift closures instead!"); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashReportWriter_h - +#endif // HDR_KSCrashReportWriter_h diff --git a/Sources/KSCrashRecordingCore/KSCPU.c b/Sources/KSCrashRecordingCore/KSCPU.c index 113e4e41d..2f47cd6cd 100644 --- a/Sources/KSCrashRecordingCore/KSCPU.c +++ b/Sources/KSCrashRecordingCore/KSCPU.c @@ -24,101 +24,93 @@ // THE SOFTWARE. // - #include "KSCPU.h" -#include "KSSystemCapabilities.h" - -#include #include +#include -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 160000 // Xcode 14 +#include "KSSystemCapabilities.h" + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 160000 // Xcode 14 #include #define _HAS_MACH_O_UTILS 1 #else #define _HAS_MACH_O_UTILS 0 #endif -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" #if !_HAS_MACH_O_UTILS || !KSCRASH_HOST_VISION -static inline const char* currentArch_nx(void) +static inline const char *currentArch_nx(void) { - const NXArchInfo* archInfo = NXGetLocalArchInfo(); + const NXArchInfo *archInfo = NXGetLocalArchInfo(); return archInfo == NULL ? NULL : archInfo->name; } -static inline const char* archForCPU_nx(cpu_type_t majorCode, cpu_subtype_t minorCode) +static inline const char *archForCPU_nx(cpu_type_t majorCode, cpu_subtype_t minorCode) { - const NXArchInfo* info = NXGetArchInfoFromCpuType(majorCode, minorCode); + const NXArchInfo *info = NXGetArchInfoFromCpuType(majorCode, minorCode); return info == NULL ? NULL : info->name; } #endif -const char* kscpu_currentArch(void) +const char *kscpu_currentArch(void) { #if _HAS_MACH_O_UTILS #if !KSCRASH_HOST_VISION - if(__builtin_available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 8.0, *)) + if (__builtin_available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 8.0, *)) #endif { return macho_arch_name_for_mach_header(NULL); } #if !KSCRASH_HOST_VISION - else - { + else { return currentArch_nx(); } #endif -#else // _HAS_MACH_O_UTILS +#else // _HAS_MACH_O_UTILS return currentArch_nx(); -#endif // _HAS_MACH_O_UTILS +#endif // _HAS_MACH_O_UTILS } -const char* kscpu_archForCPU(cpu_type_t majorCode, cpu_subtype_t minorCode) +const char *kscpu_archForCPU(cpu_type_t majorCode, cpu_subtype_t minorCode) { #if _HAS_MACH_O_UTILS #if !KSCRASH_HOST_VISION - if(__builtin_available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 8.0, *)) + if (__builtin_available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 8.0, *)) #endif { return macho_arch_name_for_cpu_type(majorCode, minorCode); } #if !KSCRASH_HOST_VISION - else - { + else { return archForCPU_nx(majorCode, minorCode); } #endif -#else // _HAS_MACH_O_UTILS +#else // _HAS_MACH_O_UTILS return archForCPU_nx(majorCode, minorCode); -#endif // _HAS_MACH_O_UTILS +#endif // _HAS_MACH_O_UTILS } #if KSCRASH_HAS_THREADS_API -bool kscpu_i_fillState(const thread_t thread, - const thread_state_t state, - const thread_state_flavor_t flavor, +bool kscpu_i_fillState(const thread_t thread, const thread_state_t state, const thread_state_flavor_t flavor, const mach_msg_type_number_t stateCount) { KSLOG_TRACE("Filling thread state with flavor %x.", flavor); mach_msg_type_number_t stateCountBuff = stateCount; kern_return_t kr; - + kr = thread_get_state(thread, flavor, state, &stateCountBuff); - if(kr != KERN_SUCCESS) - { + if (kr != KERN_SUCCESS) { KSLOG_ERROR("thread_get_state: %s", mach_error_string(kr)); return false; } return true; } #else -bool kscpu_i_fillState(__unused const thread_t thread, - __unused const thread_state_t state, - __unused const thread_state_flavor_t flavor, - __unused const mach_msg_type_number_t stateCount) +bool kscpu_i_fillState(__unused const thread_t thread, __unused const thread_state_t state, + __unused const thread_state_flavor_t flavor, __unused const mach_msg_type_number_t stateCount) { return false; } diff --git a/Sources/KSCrashRecordingCore/KSCPU_arm.c b/Sources/KSCrashRecordingCore/KSCPU_arm.c index 12411bde9..b9250239f 100644 --- a/Sources/KSCrashRecordingCore/KSCPU_arm.c +++ b/Sources/KSCrashRecordingCore/KSCPU_arm.c @@ -24,118 +24,87 @@ // THE SOFTWARE. // -#if defined (__arm__) +#if defined(__arm__) +#include #include "KSCPU.h" #include "KSCPU_Apple.h" #include "KSMachineContext.h" #include "KSMachineContext_Apple.h" -#include -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" +static const char *g_registerNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", + "r9", "r10", "r11", "ip", "sp", "lr", "pc", "cpsr" }; +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); -static const char* g_registerNames[] = -{ - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "ip", - "sp", "lr", "pc", "cpsr" -}; -static const int g_registerNamesCount = -sizeof(g_registerNames) / sizeof(*g_registerNames); +static const char *g_exceptionRegisterNames[] = { "exception", "fsr", "far" }; +static const int g_exceptionRegisterNamesCount = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); +uintptr_t kscpu_framePointer(const KSMachineContext *const context) { return context->machineContext.__ss.__r[7]; } -static const char* g_exceptionRegisterNames[] = -{ - "exception", "fsr", "far" -}; -static const int g_exceptionRegisterNamesCount = -sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); +uintptr_t kscpu_stackPointer(const KSMachineContext *const context) { return context->machineContext.__ss.__sp; } +uintptr_t kscpu_instructionAddress(const KSMachineContext *const context) { return context->machineContext.__ss.__pc; } -uintptr_t kscpu_framePointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__r[7]; -} - -uintptr_t kscpu_stackPointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__sp; -} - -uintptr_t kscpu_instructionAddress(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__pc; -} - -uintptr_t kscpu_linkRegister(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__lr; -} +uintptr_t kscpu_linkRegister(const KSMachineContext *const context) { return context->machineContext.__ss.__lr; } -void kscpu_getState(KSMachineContext* context) +void kscpu_getState(KSMachineContext *context) { thread_t thread = context->thisThread; - STRUCT_MCONTEXT_L* const machineContext = &context->machineContext; - + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; + kscpu_i_fillState(thread, (thread_state_t)&machineContext->__ss, ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT); kscpu_i_fillState(thread, (thread_state_t)&machineContext->__es, ARM_EXCEPTION_STATE, ARM_EXCEPTION_STATE_COUNT); } -int kscpu_numRegisters(void) -{ - return g_registerNamesCount; -} +int kscpu_numRegisters(void) { return g_registerNamesCount; } -const char* kscpu_registerName(const int regNumber) +const char *kscpu_registerName(const int regNumber) { - if(regNumber < kscpu_numRegisters()) - { + if (regNumber < kscpu_numRegisters()) { return g_registerNames[regNumber]; } return NULL; } -uint64_t kscpu_registerValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_registerValue(const KSMachineContext *const context, const int regNumber) { - if(regNumber <= 12) - { + if (regNumber <= 12) { return context->machineContext.__ss.__r[regNumber]; } - switch(regNumber) - { - case 13: return context->machineContext.__ss.__sp; - case 14: return context->machineContext.__ss.__lr; - case 15: return context->machineContext.__ss.__pc; - case 16: return context->machineContext.__ss.__cpsr; + switch (regNumber) { + case 13: + return context->machineContext.__ss.__sp; + case 14: + return context->machineContext.__ss.__lr; + case 15: + return context->machineContext.__ss.__pc; + case 16: + return context->machineContext.__ss.__cpsr; } KSLOG_ERROR("Invalid register number: %d", regNumber); return 0; } -int kscpu_numExceptionRegisters(void) -{ - return g_exceptionRegisterNamesCount; -} +int kscpu_numExceptionRegisters(void) { return g_exceptionRegisterNamesCount; } -const char* kscpu_exceptionRegisterName(const int regNumber) +const char *kscpu_exceptionRegisterName(const int regNumber) { - if(regNumber < kscpu_numExceptionRegisters()) - { + if (regNumber < kscpu_numExceptionRegisters()) { return g_exceptionRegisterNames[regNumber]; } KSLOG_ERROR("Invalid register number: %d", regNumber); return NULL; } -uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_exceptionRegisterValue(const KSMachineContext *const context, const int regNumber) { - switch(regNumber) - { + switch (regNumber) { case 0: return context->machineContext.__es.__exception; case 1: @@ -148,19 +117,10 @@ uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, con return 0; } -uintptr_t kscpu_faultAddress(const KSMachineContext* const context) -{ - return context->machineContext.__es.__far; -} +uintptr_t kscpu_faultAddress(const KSMachineContext *const context) { return context->machineContext.__es.__far; } -int kscpu_stackGrowDirection(void) -{ - return -1; -} +int kscpu_stackGrowDirection(void) { return -1; } -uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) -{ - return ip; -} +uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) { return ip; } #endif diff --git a/Sources/KSCrashRecordingCore/KSCPU_arm64.c b/Sources/KSCrashRecordingCore/KSCPU_arm64.c index e96a9585e..789ab6b88 100644 --- a/Sources/KSCrashRecordingCore/KSCPU_arm64.c +++ b/Sources/KSCrashRecordingCore/KSCPU_arm64.c @@ -24,122 +24,94 @@ // THE SOFTWARE. // -#if defined (__arm64__) +#if defined(__arm64__) +#include #include "KSCPU.h" #include "KSCPU_Apple.h" #include "KSMachineContext.h" #include "KSMachineContext_Apple.h" -#include -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" #define KSPACStrippingMask_ARM64e 0x0000000fffffffff -static const char* g_registerNames[] = -{ - "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", - "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", - "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", - "x24", "x25", "x26", "x27", "x28", "x29", - "fp", "lr", "sp", "pc", "cpsr" -}; -static const int g_registerNamesCount = -sizeof(g_registerNames) / sizeof(*g_registerNames); +static const char *g_registerNames[] = { "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", + "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", + "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", + "x27", "x28", "x29", "fp", "lr", "sp", "pc", "cpsr" }; +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); +static const char *g_exceptionRegisterNames[] = { "exception", "esr", "far" }; +static const int g_exceptionRegisterNamesCount = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); -static const char* g_exceptionRegisterNames[] = -{ - "exception", "esr", "far" -}; -static const int g_exceptionRegisterNamesCount = -sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); +uintptr_t kscpu_framePointer(const KSMachineContext *const context) { return context->machineContext.__ss.__fp; } +uintptr_t kscpu_stackPointer(const KSMachineContext *const context) { return context->machineContext.__ss.__sp; } -uintptr_t kscpu_framePointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__fp; -} +uintptr_t kscpu_instructionAddress(const KSMachineContext *const context) { return context->machineContext.__ss.__pc; } -uintptr_t kscpu_stackPointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__sp; -} - -uintptr_t kscpu_instructionAddress(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__pc; -} +uintptr_t kscpu_linkRegister(const KSMachineContext *const context) { return context->machineContext.__ss.__lr; } -uintptr_t kscpu_linkRegister(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__lr; -} - -void kscpu_getState(KSMachineContext* context) +void kscpu_getState(KSMachineContext *context) { thread_t thread = context->thisThread; - STRUCT_MCONTEXT_L* const machineContext = &context->machineContext; - + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; + kscpu_i_fillState(thread, (thread_state_t)&machineContext->__ss, ARM_THREAD_STATE64, ARM_THREAD_STATE64_COUNT); - kscpu_i_fillState(thread, (thread_state_t)&machineContext->__es, ARM_EXCEPTION_STATE64, ARM_EXCEPTION_STATE64_COUNT); + kscpu_i_fillState(thread, (thread_state_t)&machineContext->__es, ARM_EXCEPTION_STATE64, + ARM_EXCEPTION_STATE64_COUNT); } -int kscpu_numRegisters(void) -{ - return g_registerNamesCount; -} +int kscpu_numRegisters(void) { return g_registerNamesCount; } -const char* kscpu_registerName(const int regNumber) +const char *kscpu_registerName(const int regNumber) { - if(regNumber < kscpu_numRegisters()) - { + if (regNumber < kscpu_numRegisters()) { return g_registerNames[regNumber]; } return NULL; } -uint64_t kscpu_registerValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_registerValue(const KSMachineContext *const context, const int regNumber) { - if(regNumber <= 29) - { + if (regNumber <= 29) { return context->machineContext.__ss.__x[regNumber]; } - switch(regNumber) - { - case 30: return context->machineContext.__ss.__fp; - case 31: return context->machineContext.__ss.__lr; - case 32: return context->machineContext.__ss.__sp; - case 33: return context->machineContext.__ss.__pc; - case 34: return context->machineContext.__ss.__cpsr; + switch (regNumber) { + case 30: + return context->machineContext.__ss.__fp; + case 31: + return context->machineContext.__ss.__lr; + case 32: + return context->machineContext.__ss.__sp; + case 33: + return context->machineContext.__ss.__pc; + case 34: + return context->machineContext.__ss.__cpsr; } KSLOG_ERROR("Invalid register number: %d", regNumber); return 0; } -int kscpu_numExceptionRegisters(void) -{ - return g_exceptionRegisterNamesCount; -} +int kscpu_numExceptionRegisters(void) { return g_exceptionRegisterNamesCount; } -const char* kscpu_exceptionRegisterName(const int regNumber) +const char *kscpu_exceptionRegisterName(const int regNumber) { - if(regNumber < kscpu_numExceptionRegisters()) - { + if (regNumber < kscpu_numExceptionRegisters()) { return g_exceptionRegisterNames[regNumber]; } KSLOG_ERROR("Invalid register number: %d", regNumber); return NULL; } -uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_exceptionRegisterValue(const KSMachineContext *const context, const int regNumber) { - switch(regNumber) - { + switch (regNumber) { case 0: return context->machineContext.__es.__exception; case 1: @@ -152,19 +124,10 @@ uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, con return 0; } -uintptr_t kscpu_faultAddress(const KSMachineContext* const context) -{ - return context->machineContext.__es.__far; -} +uintptr_t kscpu_faultAddress(const KSMachineContext *const context) { return context->machineContext.__es.__far; } -int kscpu_stackGrowDirection(void) -{ - return -1; -} +int kscpu_stackGrowDirection(void) { return -1; } -uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) -{ - return ip & KSPACStrippingMask_ARM64e; -} +uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) { return ip & KSPACStrippingMask_ARM64e; } #endif diff --git a/Sources/KSCrashRecordingCore/KSCPU_x86_32.c b/Sources/KSCrashRecordingCore/KSCPU_x86_32.c index b5f29252f..4023c9d30 100644 --- a/Sources/KSCrashRecordingCore/KSCPU_x86_32.c +++ b/Sources/KSCrashRecordingCore/KSCPU_x86_32.c @@ -24,87 +24,57 @@ // THE SOFTWARE. // +#if defined(__i386__) -#if defined (__i386__) - +#include #include "KSCPU.h" #include "KSCPU_Apple.h" #include "KSMachineContext.h" #include "KSMachineContext_Apple.h" -#include -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" - -static const char* g_registerNames[] = -{ - "eax", "ebx", "ecx", "edx", - "edi", "esi", - "ebp", "esp", "ss", - "eflags", "eip", - "cs", "ds", "es", "fs", "gs", +static const char *g_registerNames[] = { + "eax", "ebx", "ecx", "edx", "edi", "esi", "ebp", "esp", "ss", "eflags", "eip", "cs", "ds", "es", "fs", "gs", }; -static const int g_registerNamesCount = -sizeof(g_registerNames) / sizeof(*g_registerNames); +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); +static const char *g_exceptionRegisterNames[] = { "trapno", "err", "faultvaddr" }; +static const int g_exceptionRegisterNamesCount = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); -static const char* g_exceptionRegisterNames[] = -{ - "trapno", "err", "faultvaddr" -}; -static const int g_exceptionRegisterNamesCount = -sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); +uintptr_t kscpu_framePointer(const KSMachineContext *const context) { return context->machineContext.__ss.__ebp; } +uintptr_t kscpu_stackPointer(const KSMachineContext *const context) { return context->machineContext.__ss.__esp; } -uintptr_t kscpu_framePointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__ebp; -} - -uintptr_t kscpu_stackPointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__esp; -} - -uintptr_t kscpu_instructionAddress(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__eip; -} +uintptr_t kscpu_instructionAddress(const KSMachineContext *const context) { return context->machineContext.__ss.__eip; } -uintptr_t kscpu_linkRegister(__unused const KSMachineContext* const context) -{ - return 0; -} +uintptr_t kscpu_linkRegister(__unused const KSMachineContext *const context) { return 0; } -void kscpu_getState(KSMachineContext* context) +void kscpu_getState(KSMachineContext *context) { thread_t thread = context->thisThread; - STRUCT_MCONTEXT_L* const machineContext = &context->machineContext; + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; kscpu_i_fillState(thread, (thread_state_t)&machineContext->__ss, x86_THREAD_STATE32, x86_THREAD_STATE32_COUNT); - kscpu_i_fillState(thread, (thread_state_t)&machineContext->__es, x86_EXCEPTION_STATE32, x86_EXCEPTION_STATE32_COUNT); + kscpu_i_fillState(thread, (thread_state_t)&machineContext->__es, x86_EXCEPTION_STATE32, + x86_EXCEPTION_STATE32_COUNT); } -int kscpu_numRegisters(void) -{ - return g_registerNamesCount; -} +int kscpu_numRegisters(void) { return g_registerNamesCount; } -const char* kscpu_registerName(const int regNumber) +const char *kscpu_registerName(const int regNumber) { - if(regNumber < kscpu_numRegisters()) - { + if (regNumber < kscpu_numRegisters()) { return g_registerNames[regNumber]; } return NULL; } -uint64_t kscpu_registerValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_registerValue(const KSMachineContext *const context, const int regNumber) { - switch(regNumber) - { + switch (regNumber) { case 0: return context->machineContext.__ss.__eax; case 1: @@ -143,25 +113,20 @@ uint64_t kscpu_registerValue(const KSMachineContext* const context, const int re return 0; } -int kscpu_numExceptionRegisters(void) -{ - return g_exceptionRegisterNamesCount; -} +int kscpu_numExceptionRegisters(void) { return g_exceptionRegisterNamesCount; } -const char* kscpu_exceptionRegisterName(const int regNumber) +const char *kscpu_exceptionRegisterName(const int regNumber) { - if(regNumber < kscpu_numExceptionRegisters()) - { + if (regNumber < kscpu_numExceptionRegisters()) { return g_exceptionRegisterNames[regNumber]; } KSLOG_ERROR("Invalid register number: %d", regNumber); return NULL; } -uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_exceptionRegisterValue(const KSMachineContext *const context, const int regNumber) { - switch(regNumber) - { + switch (regNumber) { case 0: return context->machineContext.__es.__trapno; case 1: @@ -174,19 +139,13 @@ uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, con return 0; } -uintptr_t kscpu_faultAddress(const KSMachineContext* const context) +uintptr_t kscpu_faultAddress(const KSMachineContext *const context) { return context->machineContext.__es.__faultvaddr; } -int kscpu_stackGrowDirection(void) -{ - return -1; -} +int kscpu_stackGrowDirection(void) { return -1; } -uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) -{ - return ip; -} +uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) { return ip; } #endif diff --git a/Sources/KSCrashRecordingCore/KSCPU_x86_64.c b/Sources/KSCrashRecordingCore/KSCPU_x86_64.c index f731a53d4..8f2e2f6a7 100644 --- a/Sources/KSCrashRecordingCore/KSCPU_x86_64.c +++ b/Sources/KSCrashRecordingCore/KSCPU_x86_64.c @@ -24,89 +24,56 @@ // THE SOFTWARE. // +#if defined(__x86_64__) -#if defined (__x86_64__) - +#include #include "KSCPU.h" #include "KSCPU_Apple.h" #include "KSMachineContext.h" #include "KSMachineContext_Apple.h" -#include - -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" +static const char *g_registerNames[] = { "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp", "r8", "r9", "r10", + "r11", "r12", "r13", "r14", "r15", "rip", "rflags", "cs", "fs", "gs" }; +static const int g_registerNamesCount = sizeof(g_registerNames) / sizeof(*g_registerNames); -static const char* g_registerNames[] = -{ - "rax", "rbx", "rcx", "rdx", - "rdi", "rsi", - "rbp", "rsp", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "rip", "rflags", - "cs", "fs", "gs" -}; -static const int g_registerNamesCount = -sizeof(g_registerNames) / sizeof(*g_registerNames); - - -static const char* g_exceptionRegisterNames[] = -{ - "trapno", "err", "faultvaddr" -}; -static const int g_exceptionRegisterNamesCount = -sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); +static const char *g_exceptionRegisterNames[] = { "trapno", "err", "faultvaddr" }; +static const int g_exceptionRegisterNamesCount = sizeof(g_exceptionRegisterNames) / sizeof(*g_exceptionRegisterNames); +uintptr_t kscpu_framePointer(const KSMachineContext *const context) { return context->machineContext.__ss.__rbp; } -uintptr_t kscpu_framePointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__rbp; -} +uintptr_t kscpu_stackPointer(const KSMachineContext *const context) { return context->machineContext.__ss.__rsp; } -uintptr_t kscpu_stackPointer(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__rsp; -} +uintptr_t kscpu_instructionAddress(const KSMachineContext *const context) { return context->machineContext.__ss.__rip; } -uintptr_t kscpu_instructionAddress(const KSMachineContext* const context) -{ - return context->machineContext.__ss.__rip; -} +uintptr_t kscpu_linkRegister(__unused const KSMachineContext *const context) { return 0; } -uintptr_t kscpu_linkRegister(__unused const KSMachineContext* const context) -{ - return 0; -} - -void kscpu_getState(KSMachineContext* context) +void kscpu_getState(KSMachineContext *context) { thread_t thread = context->thisThread; - STRUCT_MCONTEXT_L* const machineContext = &context->machineContext; - + STRUCT_MCONTEXT_L *const machineContext = &context->machineContext; + kscpu_i_fillState(thread, (thread_state_t)&machineContext->__ss, x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT); - kscpu_i_fillState(thread, (thread_state_t)&machineContext->__es, x86_EXCEPTION_STATE64, x86_EXCEPTION_STATE64_COUNT); + kscpu_i_fillState(thread, (thread_state_t)&machineContext->__es, x86_EXCEPTION_STATE64, + x86_EXCEPTION_STATE64_COUNT); } -int kscpu_numRegisters(void) -{ - return g_registerNamesCount; -} +int kscpu_numRegisters(void) { return g_registerNamesCount; } -const char* kscpu_registerName(const int regNumber) +const char *kscpu_registerName(const int regNumber) { - if(regNumber < kscpu_numRegisters()) - { + if (regNumber < kscpu_numRegisters()) { return g_registerNames[regNumber]; } return NULL; } -uint64_t kscpu_registerValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_registerValue(const KSMachineContext *const context, const int regNumber) { - switch(regNumber) - { + switch (regNumber) { case 0: return context->machineContext.__ss.__rax; case 1: @@ -155,25 +122,20 @@ uint64_t kscpu_registerValue(const KSMachineContext* const context, const int re return 0; } -int kscpu_numExceptionRegisters(void) -{ - return g_exceptionRegisterNamesCount; -} +int kscpu_numExceptionRegisters(void) { return g_exceptionRegisterNamesCount; } -const char* kscpu_exceptionRegisterName(const int regNumber) +const char *kscpu_exceptionRegisterName(const int regNumber) { - if(regNumber < kscpu_numExceptionRegisters()) - { + if (regNumber < kscpu_numExceptionRegisters()) { return g_exceptionRegisterNames[regNumber]; } KSLOG_ERROR("Invalid register number: %d", regNumber); return NULL; } -uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, const int regNumber) +uint64_t kscpu_exceptionRegisterValue(const KSMachineContext *const context, const int regNumber) { - switch(regNumber) - { + switch (regNumber) { case 0: return context->machineContext.__es.__trapno; case 1: @@ -186,19 +148,13 @@ uint64_t kscpu_exceptionRegisterValue(const KSMachineContext* const context, con return 0; } -uintptr_t kscpu_faultAddress(const KSMachineContext* const context) +uintptr_t kscpu_faultAddress(const KSMachineContext *const context) { return context->machineContext.__es.__faultvaddr; } -int kscpu_stackGrowDirection(void) -{ - return -1; -} +int kscpu_stackGrowDirection(void) { return -1; } -uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) -{ - return ip; -} +uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip) { return ip; } #endif diff --git a/Sources/KSCrashRecordingCore/KSCrashMonitor.c b/Sources/KSCrashRecordingCore/KSCrashMonitor.c index 0005fcafb..d9510dfd2 100644 --- a/Sources/KSCrashRecordingCore/KSCrashMonitor.c +++ b/Sources/KSCrashRecordingCore/KSCrashMonitor.c @@ -24,25 +24,23 @@ // THE SOFTWARE. // - #include "KSCrashMonitor.h" -#include "KSCrashMonitorHelper.h" -#include "KSCrashMonitorContext.h" +#include +#include + +#include "KSCrashMonitorContext.h" +#include "KSCrashMonitorHelper.h" #include "KSDebug.h" #include "KSString.h" -#include "KSThread.h" #include "KSSystemCapabilities.h" +#include "KSThread.h" -#include -#include - -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" -typedef struct -{ - KSCrashMonitorAPI** apis; // Array of MonitorAPIs +typedef struct { + KSCrashMonitorAPI **apis; // Array of MonitorAPIs size_t count; size_t capacity; } MonitorList; @@ -60,39 +58,35 @@ static bool g_handlingFatalException = false; static bool g_crashedDuringExceptionHandling = false; static bool g_requiresAsyncSafety = false; -static void (*g_onExceptionEvent)(struct KSCrash_MonitorContext* monitorContext); +static void (*g_onExceptionEvent)(struct KSCrash_MonitorContext *monitorContext); -static void initializeMonitorList(MonitorList* list) +static void initializeMonitorList(MonitorList *list) { list->count = 0; list->capacity = INITIAL_MONITOR_CAPACITY; - list->apis = (KSCrashMonitorAPI**)malloc(list->capacity * sizeof(KSCrashMonitorAPI*)); + list->apis = (KSCrashMonitorAPI **)malloc(list->capacity * sizeof(KSCrashMonitorAPI *)); } -static void addMonitor(MonitorList* list, KSCrashMonitorAPI* api) +static void addMonitor(MonitorList *list, KSCrashMonitorAPI *api) { - if (list->count >= list->capacity) - { + if (list->count >= list->capacity) { list->capacity *= 2; - list->apis = (KSCrashMonitorAPI**)realloc(list->apis, list->capacity * sizeof(KSCrashMonitorAPI*)); + list->apis = (KSCrashMonitorAPI **)realloc(list->apis, list->capacity * sizeof(KSCrashMonitorAPI *)); } list->apis[list->count++] = api; } -static void removeMonitor(MonitorList* list, const KSCrashMonitorAPI* api) +static void removeMonitor(MonitorList *list, const KSCrashMonitorAPI *api) { - if (list == NULL || api == NULL) - { + if (list == NULL || api == NULL) { KSLOG_DEBUG("Either list or func is NULL. Removal operation aborted."); return; } bool found = false; - for (size_t i = 0; i < list->count; i++) - { - if (list->apis[i] == api) - { + for (size_t i = 0; i < list->count; i++) { + if (list->apis[i] == api) { found = true; kscm_setMonitorEnabled(list->apis[i], false); @@ -107,13 +101,12 @@ static void removeMonitor(MonitorList* list, const KSCrashMonitorAPI* api) } } - if (!found) - { + if (!found) { KSLOG_DEBUG("Monitor %s not found in the list. No removal performed.", getMonitorNameForLogging(func)); } } -static void freeMonitorFuncList(MonitorList* list) +static void freeMonitorFuncList(MonitorList *list) { free(list->apis); list->apis = NULL; @@ -135,8 +128,9 @@ void kscm_resetState(void) #pragma mark - Helpers -__attribute__((unused)) // Suppress unused function warnings, especially in release builds. -static inline const char* getMonitorNameForLogging(const KSCrashMonitorAPI* api) +__attribute__((unused)) // Suppress unused function warnings, especially in release builds. +static inline const char * +getMonitorNameForLogging(const KSCrashMonitorAPI *api) { return kscm_getMonitorId(api) ?: "Unknown"; } @@ -145,7 +139,7 @@ static inline const char* getMonitorNameForLogging(const KSCrashMonitorAPI* api) #pragma mark - API - // ============================================================================ -void kscm_setEventCallback(void (*onEvent)(struct KSCrash_MonitorContext* monitorContext)) +void kscm_setEventCallback(void (*onEvent)(struct KSCrash_MonitorContext *monitorContext)) { g_onExceptionEvent = onEvent; } @@ -156,11 +150,9 @@ void kscm_activateMonitors(void) bool isDebuggerUnsafe = ksdebug_isBeingTraced(); bool isAsyncSafeRequired = g_requiresAsyncSafety; - if (isDebuggerUnsafe) - { + if (isDebuggerUnsafe) { static bool hasWarned = false; - if (!hasWarned) - { + if (!hasWarned) { hasWarned = true; KSLOGBASIC_WARN(" ************************ Crash Handler Notice ************************"); KSLOGBASIC_WARN(" * App is running in a debugger. Masking out unsafe monitors. *"); @@ -169,25 +161,21 @@ void kscm_activateMonitors(void) } } - if (isAsyncSafeRequired) - { + if (isAsyncSafeRequired) { KSLOG_DEBUG("Async-safe environment detected. Masking out unsafe monitors."); } // Enable or disable monitors - for (size_t i = 0; i < g_monitors.count; i++) - { - KSCrashMonitorAPI* api = g_monitors.apis[i]; + for (size_t i = 0; i < g_monitors.count; i++) { + KSCrashMonitorAPI *api = g_monitors.apis[i]; KSCrashMonitorFlag flags = kscm_getMonitorFlags(api); bool shouldEnable = true; - if (isDebuggerUnsafe && (flags & KSCrashMonitorFlagDebuggerUnsafe)) - { + if (isDebuggerUnsafe && (flags & KSCrashMonitorFlagDebuggerUnsafe)) { shouldEnable = false; } - if (isAsyncSafeRequired && !(flags & KSCrashMonitorFlagAsyncSafe)) - { + if (isAsyncSafeRequired && !(flags & KSCrashMonitorFlagAsyncSafe)) { shouldEnable = false; } @@ -196,66 +184,55 @@ void kscm_activateMonitors(void) // Log active monitors KSLOG_DEBUG("Active monitors are now:"); - for (size_t i = 0; i < g_monitors.count; i++) - { - KSCrashMonitorAPI* api = g_monitors.apis[i]; - if (kscm_isMonitorEnabled(api)) - { + for (size_t i = 0; i < g_monitors.count; i++) { + KSCrashMonitorAPI *api = g_monitors.apis[i]; + if (kscm_isMonitorEnabled(api)) { KSLOG_DEBUG("Monitor %s is enabled.", getMonitorNameForLogging(api)); - } - else - { + } else { KSLOG_DEBUG("Monitor %s is disabled.", getMonitorNameForLogging(api)); } } // Notify monitors about system enable - for (size_t i = 0; i < g_monitors.count; i++) - { - KSCrashMonitorAPI* api = g_monitors.apis[i]; + for (size_t i = 0; i < g_monitors.count; i++) { + KSCrashMonitorAPI *api = g_monitors.apis[i]; kscm_notifyPostSystemEnable(api); } } void kscm_disableAllMonitors(void) { - for (size_t i = 0; i < g_monitors.count; i++) - { - KSCrashMonitorAPI* api = g_monitors.apis[i]; + for (size_t i = 0; i < g_monitors.count; i++) { + KSCrashMonitorAPI *api = g_monitors.apis[i]; kscm_setMonitorEnabled(api, false); } KSLOG_DEBUG("All monitors have been disabled."); } -bool kscm_addMonitor(KSCrashMonitorAPI* api) +bool kscm_addMonitor(KSCrashMonitorAPI *api) { - if (api == NULL) - { + if (api == NULL) { KSLOG_DEBUG("Attempted to add a NULL monitor. Operation aborted."); return false; } - const char* newMonitorId = kscm_getMonitorId(api); - if (newMonitorId == NULL) - { + const char *newMonitorId = kscm_getMonitorId(api); + if (newMonitorId == NULL) { KSLOG_DEBUG("Monitor has a NULL ID. Operation aborted."); return false; } - if (!g_areMonitorsInitialized) - { + if (!g_areMonitorsInitialized) { initializeMonitorList(&g_monitors); g_areMonitorsInitialized = true; } // Check for duplicate monitors - for (size_t i = 0; i < g_monitors.count; i++) - { - KSCrashMonitorAPI* existingApi = g_monitors.apis[i]; - const char* existingMonitorId = kscm_getMonitorId(existingApi); + for (size_t i = 0; i < g_monitors.count; i++) { + KSCrashMonitorAPI *existingApi = g_monitors.apis[i]; + const char *existingMonitorId = kscm_getMonitorId(existingApi); - if (ksstring_safeStrcmp(existingMonitorId, newMonitorId) == 0) - { + if (ksstring_safeStrcmp(existingMonitorId, newMonitorId) == 0) { KSLOG_DEBUG("Monitor %s already exists. Skipping addition.", getMonitorNameForLogging(api)); return false; } @@ -266,10 +243,9 @@ bool kscm_addMonitor(KSCrashMonitorAPI* api) return true; } -void kscm_removeMonitor(const KSCrashMonitorAPI* api) +void kscm_removeMonitor(const KSCrashMonitorAPI *api) { - if (api == NULL) - { + if (api == NULL) { KSLOG_DEBUG("Attempted to remove a NULL monitor. Operation aborted."); return; } @@ -277,11 +253,10 @@ void kscm_removeMonitor(const KSCrashMonitorAPI* api) removeMonitor(&g_monitors, api); } -//KSCrashMonitorType kscm_getActiveMonitors(void) +// KSCrashMonitorType kscm_getActiveMonitors(void) //{ -// return g_monitors; -//} - +// return g_monitors; +// } // ============================================================================ #pragma mark - Private API - @@ -289,57 +264,47 @@ void kscm_removeMonitor(const KSCrashMonitorAPI* api) bool kscm_notifyFatalExceptionCaptured(bool isAsyncSafeEnvironment) { - g_requiresAsyncSafety |= isAsyncSafeEnvironment; // Don't let it be unset. - if(g_handlingFatalException) - { + g_requiresAsyncSafety |= isAsyncSafeEnvironment; // Don't let it be unset. + if (g_handlingFatalException) { g_crashedDuringExceptionHandling = true; } g_handlingFatalException = true; - if(g_crashedDuringExceptionHandling) - { + if (g_crashedDuringExceptionHandling) { KSLOG_INFO("Detected crash in the crash reporter. Uninstalling KSCrash."); kscm_disableAllMonitors(); } return g_crashedDuringExceptionHandling; } -void kscm_handleException(struct KSCrash_MonitorContext* context) +void kscm_handleException(struct KSCrash_MonitorContext *context) { // We're handling a crash if the crash type is fatal bool hasFatalFlag = (context->monitorFlags & KSCrashMonitorFlagFatal) != KSCrashMonitorFlagNone; context->handlingCrash = context->handlingCrash || hasFatalFlag; context->requiresAsyncSafety = g_requiresAsyncSafety; - if (g_crashedDuringExceptionHandling) - { + if (g_crashedDuringExceptionHandling) { context->crashedDuringCrashHandling = true; } // Add contextual info to the event for all enabled monitors - for (size_t i = 0; i < g_monitors.count; i++) - { - KSCrashMonitorAPI* api = g_monitors.apis[i]; - if (kscm_isMonitorEnabled(api)) - { + for (size_t i = 0; i < g_monitors.count; i++) { + KSCrashMonitorAPI *api = g_monitors.apis[i]; + if (kscm_isMonitorEnabled(api)) { kscm_addContextualInfoToEvent(api, context); } } // Call the exception event handler if it exists - if (g_onExceptionEvent) - { + if (g_onExceptionEvent) { g_onExceptionEvent(context); } // Restore original handlers if the exception is fatal and not already handled - if (context->currentSnapshotUserReported) - { + if (context->currentSnapshotUserReported) { g_handlingFatalException = false; - } - else - { - if (g_handlingFatalException && !g_crashedDuringExceptionHandling) - { + } else { + if (g_handlingFatalException && !g_crashedDuringExceptionHandling) { KSLOG_DEBUG("Exception is fatal. Restoring original handlers."); kscm_disableAllMonitors(); } diff --git a/Sources/KSCrashRecordingCore/KSCxaThrowSwapper.c b/Sources/KSCrashRecordingCore/KSCxaThrowSwapper.c index 9d39e420a..5f09fd9c9 100644 --- a/Sources/KSCrashRecordingCore/KSCxaThrowSwapper.c +++ b/Sources/KSCrashRecordingCore/KSCxaThrowSwapper.c @@ -50,25 +50,23 @@ #include "KSCxaThrowSwapper.h" -#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include +#include "KSLogger.h" #include "KSMach-O.h" #include "KSPlatformSpecificDefines.h" -#include "KSLogger.h" -typedef struct -{ +typedef struct { uintptr_t image; uintptr_t function; } KSAddressPair; @@ -84,12 +82,10 @@ static void addPair(KSAddressPair pair) { KSLOG_DEBUG("Adding address pair: image=%p, function=%p", (void *)pair.image, (void *)pair.function); - if (g_cxa_originals_count == g_cxa_originals_capacity) - { + if (g_cxa_originals_count == g_cxa_originals_capacity) { g_cxa_originals_capacity *= 2; - g_cxa_originals = (KSAddressPair *) realloc(g_cxa_originals, sizeof(KSAddressPair) * g_cxa_originals_capacity); - if (g_cxa_originals == NULL) - { + g_cxa_originals = (KSAddressPair *)realloc(g_cxa_originals, sizeof(KSAddressPair) * g_cxa_originals_capacity); + if (g_cxa_originals == NULL) { KSLOG_ERROR("Failed to realloc memory for g_cxa_originals: %s", strerror(errno)); return; } @@ -101,15 +97,13 @@ static uintptr_t findAddress(void *address) { KSLOG_TRACE("Finding address for %p", address); - for (size_t i = 0; i < g_cxa_originals_count; i++) - { - if (g_cxa_originals[i].image == (uintptr_t) address) - { + for (size_t i = 0; i < g_cxa_originals_count; i++) { + if (g_cxa_originals[i].image == (uintptr_t)address) { return g_cxa_originals[i].function; } } KSLOG_WARN("Address %p not found", address); - return (uintptr_t) NULL; + return (uintptr_t)NULL; } static void __cxa_throw_decorator(void *thrown_exception, void *tinfo, void (*dest)(void *)) @@ -124,25 +118,19 @@ static void __cxa_throw_decorator(void *thrown_exception, void *tinfo, void (*de int count = backtrace(backtraceArr, k_requiredFrames); Dl_info info; - if (count >= k_requiredFrames) - { - if (dladdr(backtraceArr[k_requiredFrames - 1], &info) != 0) - { + if (count >= k_requiredFrames) { + if (dladdr(backtraceArr[k_requiredFrames - 1], &info) != 0) { uintptr_t function = findAddress(info.dli_fbase); - if (function != (uintptr_t) NULL) - { + if (function != (uintptr_t)NULL) { KSLOG_TRACE("Calling original __cxa_throw function at %p", (void *)function); - cxa_throw_type original = (cxa_throw_type) function; + cxa_throw_type original = (cxa_throw_type)function; original(thrown_exception, tinfo, dest); } } } } -static void perform_rebinding_with_section(const section_t *dataSection, - intptr_t slide, - nlist_t *symtab, - char *strtab, +static void perform_rebinding_with_section(const section_t *dataSection, intptr_t slide, nlist_t *symtab, char *strtab, uint32_t *indirect_symtab) { KSLOG_TRACE("Performing rebinding with section %s,%s", dataSection->segname, dataSection->sectname); @@ -151,93 +139,69 @@ static void perform_rebinding_with_section(const section_t *dataSection, uint32_t *indirect_symbol_indices = indirect_symtab + dataSection->reserved1; void **indirect_symbol_bindings = (void **)((uintptr_t)slide + dataSection->addr); vm_prot_t oldProtection = VM_PROT_READ; - if (isDataConst) - { + if (isDataConst) { oldProtection = ksmacho_getSectionProtection(indirect_symbol_bindings); - if (mprotect(indirect_symbol_bindings, dataSection->size, PROT_READ | PROT_WRITE) != 0) - { - KSLOG_DEBUG("mprotect failed to set PROT_READ | PROT_WRITE for section %s,%s: %s", - dataSection->segname, - dataSection->sectname, - strerror(errno)); + if (mprotect(indirect_symbol_bindings, dataSection->size, PROT_READ | PROT_WRITE) != 0) { + KSLOG_DEBUG("mprotect failed to set PROT_READ | PROT_WRITE for section %s,%s: %s", dataSection->segname, + dataSection->sectname, strerror(errno)); return; } } - for (uint i = 0; i < dataSection->size / sizeof(void *); i++) - { + for (uint i = 0; i < dataSection->size / sizeof(void *); i++) { uint32_t symtab_index = indirect_symbol_indices[i]; - if (symtab_index == INDIRECT_SYMBOL_ABS || - symtab_index == INDIRECT_SYMBOL_LOCAL || - symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) - { + if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || + symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { continue; } uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; char *symbol_name = strtab + strtab_offset; bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1]; - if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], g_cxa_throw_name) == 0) - { + if (symbol_name_longer_than_1 && strcmp(&symbol_name[1], g_cxa_throw_name) == 0) { Dl_info info; - if (dladdr(dataSection, &info) != 0) - { - KSAddressPair pair = {(uintptr_t)info.dli_fbase, (uintptr_t)indirect_symbol_bindings[i]}; + if (dladdr(dataSection, &info) != 0) { + KSAddressPair pair = { (uintptr_t)info.dli_fbase, (uintptr_t)indirect_symbol_bindings[i] }; addPair(pair); } indirect_symbol_bindings[i] = (void *)__cxa_throw_decorator; continue; } } - if (isDataConst) - { + if (isDataConst) { int protection = 0; - if (oldProtection & VM_PROT_READ) - { + if (oldProtection & VM_PROT_READ) { protection |= PROT_READ; } - if (oldProtection & VM_PROT_WRITE) - { + if (oldProtection & VM_PROT_WRITE) { protection |= PROT_WRITE; } - if (oldProtection & VM_PROT_EXECUTE) - { + if (oldProtection & VM_PROT_EXECUTE) { protection |= PROT_EXEC; } - if (mprotect(indirect_symbol_bindings, dataSection->size, protection) != 0) - { - KSLOG_ERROR("mprotect failed to restore protection for section %s,%s: %s", - dataSection->segname, - dataSection->sectname, - strerror(errno)); + if (mprotect(indirect_symbol_bindings, dataSection->size, protection) != 0) { + KSLOG_ERROR("mprotect failed to restore protection for section %s,%s: %s", dataSection->segname, + dataSection->sectname, strerror(errno)); } } } -static void process_segment(const struct mach_header *header, - intptr_t slide, - const char *segname, - nlist_t *symtab, - char *strtab, - uint32_t *indirect_symtab) +static void process_segment(const struct mach_header *header, intptr_t slide, const char *segname, nlist_t *symtab, + char *strtab, uint32_t *indirect_symtab) { KSLOG_DEBUG("Processing segment %s", segname); const segment_command_t *segment = ksmacho_getSegmentByNameFromHeader((mach_header_t *)header, segname); - if (segment != NULL) - { + if (segment != NULL) { const section_t *lazy_sym_sect = ksmacho_getSectionByTypeFlagFromSegment(segment, S_LAZY_SYMBOL_POINTERS); - const section_t *non_lazy_sym_sect = ksmacho_getSectionByTypeFlagFromSegment(segment, S_NON_LAZY_SYMBOL_POINTERS); + const section_t *non_lazy_sym_sect = + ksmacho_getSectionByTypeFlagFromSegment(segment, S_NON_LAZY_SYMBOL_POINTERS); - if (lazy_sym_sect != NULL) - { + if (lazy_sym_sect != NULL) { perform_rebinding_with_section(lazy_sym_sect, slide, symtab, strtab, indirect_symtab); } - if (non_lazy_sym_sect != NULL) - { + if (non_lazy_sym_sect != NULL) { perform_rebinding_with_section(non_lazy_sym_sect, slide, symtab, strtab, indirect_symtab); } - } - else - { + } else { KSLOG_WARN("Segment %s not found", segname); } } @@ -252,21 +216,19 @@ static void rebind_symbols_for_image(const struct mach_header *header, intptr_t return; } KSLOG_DEBUG("Image name: %s", info.dli_fname); - if (slide == 0) - { + if (slide == 0) { KSLOG_DEBUG("Zero slide, can't do anything with it"); return; } - const struct symtab_command *symtab_cmd = + const struct symtab_command *symtab_cmd = (struct symtab_command *)ksmacho_getCommandByTypeFromHeader((const mach_header_t *)header, LC_SYMTAB); - const struct dysymtab_command *dysymtab_cmd = + const struct dysymtab_command *dysymtab_cmd = (struct dysymtab_command *)ksmacho_getCommandByTypeFromHeader((const mach_header_t *)header, LC_DYSYMTAB); - const segment_command_t *linkedit_segment = + const segment_command_t *linkedit_segment = ksmacho_getSegmentByNameFromHeader((mach_header_t *)header, SEG_LINKEDIT); - if (symtab_cmd == NULL || dysymtab_cmd == NULL || linkedit_segment == NULL) - { + if (symtab_cmd == NULL || dysymtab_cmd == NULL || linkedit_segment == NULL) { KSLOG_WARN("Required commands or segments not found"); return; } @@ -287,29 +249,23 @@ int ksct_swap(const cxa_throw_type handler) { KSLOG_DEBUG("Swapping __cxa_throw handler"); - if (g_cxa_originals == NULL) - { + if (g_cxa_originals == NULL) { g_cxa_originals_capacity = 25; g_cxa_originals = (KSAddressPair *)malloc(sizeof(KSAddressPair) * g_cxa_originals_capacity); - if (g_cxa_originals == NULL) - { + if (g_cxa_originals == NULL) { KSLOG_ERROR("Failed to allocate memory for g_cxa_originals: %s", strerror(errno)); return -1; } } g_cxa_originals_count = 0; - if (g_cxa_throw_handler == NULL) - { + if (g_cxa_throw_handler == NULL) { g_cxa_throw_handler = handler; _dyld_register_func_for_add_image(rebind_symbols_for_image); - } - else - { + } else { g_cxa_throw_handler = handler; uint32_t c = _dyld_image_count(); - for (uint32_t i = 0; i < c; i++) - { + for (uint32_t i = 0; i < c; i++) { rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); } } diff --git a/Sources/KSCrashRecordingCore/KSDate.c b/Sources/KSCrashRecordingCore/KSDate.c index f88d281e8..60248f02f 100644 --- a/Sources/KSCrashRecordingCore/KSDate.c +++ b/Sources/KSCrashRecordingCore/KSDate.c @@ -23,38 +23,28 @@ // #include "KSDate.h" + #include -#include #include +#include -void ksdate_utcStringFromTimestamp(time_t timestamp, char* buffer21Chars) +void ksdate_utcStringFromTimestamp(time_t timestamp, char *buffer21Chars) { - struct tm result = {0}; + struct tm result = { 0 }; gmtime_r(×tamp, &result); - snprintf(buffer21Chars, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ", - result.tm_year + 1900, - result.tm_mon + 1, - result.tm_mday, - result.tm_hour, - result.tm_min, - result.tm_sec); + snprintf(buffer21Chars, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ", result.tm_year + 1900, result.tm_mon + 1, + result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec); } -void ksdate_utcStringFromMicroseconds(int64_t microseconds, char* buffer28Chars) +void ksdate_utcStringFromMicroseconds(int64_t microseconds, char *buffer28Chars) { - struct tm result = {0}; + struct tm result = { 0 }; time_t curtime = (time_t)(microseconds / 1000000); long micros = (long)(microseconds % 1000000); gmtime_r(&curtime, &result); - snprintf(buffer28Chars, 28, "%04d-%02d-%02dT%02d:%02d:%02d.%06ldZ", - result.tm_year + 1900, - result.tm_mon + 1, - result.tm_mday, - result.tm_hour, - result.tm_min, - result.tm_sec, - micros); + snprintf(buffer28Chars, 28, "%04d-%02d-%02dT%02d:%02d:%02d.%06ldZ", result.tm_year + 1900, result.tm_mon + 1, + result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec, micros); } int64_t ksdate_microseconds(void) diff --git a/Sources/KSCrashRecordingCore/KSDebug.c b/Sources/KSCrashRecordingCore/KSDebug.c index 390a4b5cd..4882297a2 100644 --- a/Sources/KSCrashRecordingCore/KSDebug.c +++ b/Sources/KSCrashRecordingCore/KSDebug.c @@ -24,17 +24,15 @@ // THE SOFTWARE. // - #include "KSDebug.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - +// #define KSLogger_LocalLevel TRACE #include #include #include #include +#include "KSLogger.h" /** Check if the current process is being traced or not. * @@ -44,13 +42,12 @@ bool ksdebug_isBeingTraced(void) { struct kinfo_proc procInfo; size_t structSize = sizeof(procInfo); - int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; - - if(sysctl(mib, sizeof(mib)/sizeof(*mib), &procInfo, &structSize, NULL, 0) != 0) - { + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; + + if (sysctl(mib, sizeof(mib) / sizeof(*mib), &procInfo, &structSize, NULL, 0) != 0) { KSLOG_ERROR("sysctl: %s", strerror(errno)); return false; } - + return (procInfo.kp_proc.p_flag & P_TRACED) != 0; } diff --git a/Sources/KSCrashRecordingCore/KSDemangle_CPP.cpp b/Sources/KSCrashRecordingCore/KSDemangle_CPP.cpp index 24cae5470..eeb4e92e6 100644 --- a/Sources/KSCrashRecordingCore/KSDemangle_CPP.cpp +++ b/Sources/KSCrashRecordingCore/KSDemangle_CPP.cpp @@ -24,13 +24,13 @@ // THE SOFTWARE. // +#include "KSDemangle_CPP.h" #include -#include "KSDemangle_CPP.h" -extern "C" char* ksdm_demangleCPP(const char* mangledSymbol) +extern "C" char *ksdm_demangleCPP(const char *mangledSymbol) { int status = 0; - char* demangled = __cxxabiv1::__cxa_demangle(mangledSymbol, NULL, NULL, &status); + char *demangled = __cxxabiv1::__cxa_demangle(mangledSymbol, NULL, NULL, &status); return status == 0 ? demangled : NULL; } diff --git a/Sources/KSCrashRecordingCore/KSDemangle_Swift.cpp b/Sources/KSCrashRecordingCore/KSDemangle_Swift.cpp index 12f3f5b29..bf738aac5 100644 --- a/Sources/KSCrashRecordingCore/KSDemangle_Swift.cpp +++ b/Sources/KSCrashRecordingCore/KSDemangle_Swift.cpp @@ -24,16 +24,15 @@ // THE SOFTWARE. // +#include "KSDemangle_Swift.h" #include "Demangle.h" -#include "KSDemangle_Swift.h" -extern "C" char* ksdm_demangleSwift(const char* mangledSymbol) +extern "C" char *ksdm_demangleSwift(const char *mangledSymbol) { swift::Demangle::DemangleOptions options = swift::Demangle::DemangleOptions::SimplifiedUIDemangleOptions(); std::string demangled = swift::Demangle::demangleSymbolAsString(mangledSymbol, options); - if(demangled.length() == 0) - { + if (demangled.length() == 0) { return NULL; } return strdup(demangled.c_str()); diff --git a/Sources/KSCrashRecordingCore/KSDynamicLinker.c b/Sources/KSCrashRecordingCore/KSDynamicLinker.c index d9f4b0fd3..a67a0b101 100644 --- a/Sources/KSCrashRecordingCore/KSDynamicLinker.c +++ b/Sources/KSCrashRecordingCore/KSDynamicLinker.c @@ -28,9 +28,9 @@ #include #include +#include #include #include -#include #include #include "KSLogger.h" @@ -38,24 +38,23 @@ #include "KSPlatformSpecificDefines.h" #ifndef KSDL_MaxCrashInfoStringLength - #define KSDL_MaxCrashInfoStringLength 4096 +#define KSDL_MaxCrashInfoStringLength 4096 #endif #pragma pack(8) typedef struct { unsigned version; - const char* message; - const char* signature; - const char* backtrace; - const char* message2; - void* reserved; - void* reserved2; - void* reserved3; // First introduced in version 5 + const char *message; + const char *signature; + const char *backtrace; + const char *message2; + void *reserved; + void *reserved2; + void *reserved3; // First introduced in version 5 } crash_info_t; #pragma pack() #define KSDL_SECT_CRASH_INFO "__crash_info" - /** Get the address of the first command following a header (which will be of * type struct load_command). * @@ -64,16 +63,15 @@ typedef struct { * @return The address of the first command, or NULL if none was found (which * should not happen unless the header or image is corrupt). */ -static uintptr_t firstCmdAfterHeader(const struct mach_header* const header) +static uintptr_t firstCmdAfterHeader(const struct mach_header *const header) { - switch(header->magic) - { + switch (header->magic) { case MH_MAGIC: case MH_CIGAM: return (uintptr_t)(header + 1); case MH_MAGIC_64: case MH_CIGAM_64: - return (uintptr_t)(((struct mach_header_64*)header) + 1); + return (uintptr_t)(((struct mach_header_64 *)header) + 1); default: // Header is corrupt return 0; @@ -88,38 +86,27 @@ static uintptr_t firstCmdAfterHeader(const struct mach_header* const header) static uint32_t imageIndexContainingAddress(const uintptr_t address) { const uint32_t imageCount = _dyld_image_count(); - const struct mach_header* header = 0; - - for(uint32_t iImg = 0; iImg < imageCount; iImg++) - { + const struct mach_header *header = 0; + + for (uint32_t iImg = 0; iImg < imageCount; iImg++) { header = _dyld_get_image_header(iImg); - if(header != NULL) - { + if (header != NULL) { // Look for a segment command with this address within its range. uintptr_t addressWSlide = address - (uintptr_t)_dyld_get_image_vmaddr_slide(iImg); uintptr_t cmdPtr = firstCmdAfterHeader(header); - if(cmdPtr == 0) - { + if (cmdPtr == 0) { continue; } - for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) - { - const struct load_command* loadCmd = (struct load_command*)cmdPtr; - if(loadCmd->cmd == LC_SEGMENT) - { - const struct segment_command* segCmd = (struct segment_command*)cmdPtr; - if(addressWSlide >= segCmd->vmaddr && - addressWSlide < segCmd->vmaddr + segCmd->vmsize) - { + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SEGMENT) { + const struct segment_command *segCmd = (struct segment_command *)cmdPtr; + if (addressWSlide >= segCmd->vmaddr && addressWSlide < segCmd->vmaddr + segCmd->vmsize) { return iImg; } - } - else if(loadCmd->cmd == LC_SEGMENT_64) - { - const struct segment_command_64* segCmd = (struct segment_command_64*)cmdPtr; - if(addressWSlide >= segCmd->vmaddr && - addressWSlide < segCmd->vmaddr + segCmd->vmsize) - { + } else if (loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segCmd = (struct segment_command_64 *)cmdPtr; + if (addressWSlide >= segCmd->vmaddr && addressWSlide < segCmd->vmaddr + segCmd->vmsize) { return iImg; } } @@ -139,59 +126,45 @@ static uint32_t imageIndexContainingAddress(const uintptr_t address) */ static uintptr_t segmentBaseOfImageIndex(const uint32_t idx) { - const struct mach_header* header = _dyld_get_image_header(idx); - + const struct mach_header *header = _dyld_get_image_header(idx); + // Look for a segment command and return the file image address. uintptr_t cmdPtr = firstCmdAfterHeader(header); - if(cmdPtr == 0) - { + if (cmdPtr == 0) { return 0; } - for(uint32_t i = 0;i < header->ncmds; i++) - { - const struct load_command* loadCmd = (struct load_command*)cmdPtr; - if(loadCmd->cmd == LC_SEGMENT) - { - const struct segment_command* segmentCmd = (struct segment_command*)cmdPtr; - if(strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) - { + for (uint32_t i = 0; i < header->ncmds; i++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SEGMENT) { + const struct segment_command *segmentCmd = (struct segment_command *)cmdPtr; + if (strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { return segmentCmd->vmaddr - segmentCmd->fileoff; } - } - else if(loadCmd->cmd == LC_SEGMENT_64) - { - const struct segment_command_64* segmentCmd = (struct segment_command_64*)cmdPtr; - if(strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) - { + } else if (loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segmentCmd = (struct segment_command_64 *)cmdPtr; + if (strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { return (uintptr_t)(segmentCmd->vmaddr - segmentCmd->fileoff); } } cmdPtr += loadCmd->cmdsize; } - + return 0; } -uint32_t ksdl_imageNamed(const char* const imageName, bool exactMatch) +uint32_t ksdl_imageNamed(const char *const imageName, bool exactMatch) { - if(imageName != NULL) - { + if (imageName != NULL) { const uint32_t imageCount = _dyld_image_count(); - for(uint32_t iImg = 0; iImg < imageCount; iImg++) - { - const char* name = _dyld_get_image_name(iImg); - if(exactMatch) - { - if(strcmp(name, imageName) == 0) - { + for (uint32_t iImg = 0; iImg < imageCount; iImg++) { + const char *name = _dyld_get_image_name(iImg); + if (exactMatch) { + if (strcmp(name, imageName) == 0) { return iImg; } - } - else - { - if(strstr(name, imageName) != NULL) - { + } else { + if (strstr(name, imageName) != NULL) { return iImg; } } @@ -200,25 +173,19 @@ uint32_t ksdl_imageNamed(const char* const imageName, bool exactMatch) return UINT32_MAX; } -const uint8_t* ksdl_imageUUID(const char* const imageName, bool exactMatch) +const uint8_t *ksdl_imageUUID(const char *const imageName, bool exactMatch) { - if(imageName != NULL) - { + if (imageName != NULL) { const uint32_t iImg = ksdl_imageNamed(imageName, exactMatch); - if(iImg != UINT32_MAX) - { - const struct mach_header* header = _dyld_get_image_header(iImg); - if(header != NULL) - { + if (iImg != UINT32_MAX) { + const struct mach_header *header = _dyld_get_image_header(iImg); + if (header != NULL) { uintptr_t cmdPtr = firstCmdAfterHeader(header); - if(cmdPtr != 0) - { - for(uint32_t iCmd = 0;iCmd < header->ncmds; iCmd++) - { - const struct load_command* loadCmd = (struct load_command*)cmdPtr; - if(loadCmd->cmd == LC_UUID) - { - struct uuid_command* uuidCmd = (struct uuid_command*)cmdPtr; + if (cmdPtr != 0) { + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_UUID) { + struct uuid_command *uuidCmd = (struct uuid_command *)cmdPtr; return uuidCmd->uuid; } cmdPtr += loadCmd->cmdsize; @@ -230,7 +197,7 @@ const uint8_t* ksdl_imageUUID(const char* const imageName, bool exactMatch) return NULL; } -bool ksdl_dladdr(const uintptr_t address, Dl_info* const info) +bool ksdl_dladdr(const uintptr_t address, Dl_info *const info) { info->dli_fname = NULL; info->dli_fbase = NULL; @@ -238,74 +205,59 @@ bool ksdl_dladdr(const uintptr_t address, Dl_info* const info) info->dli_saddr = NULL; const uint32_t idx = imageIndexContainingAddress(address); - if(idx == UINT_MAX) - { + if (idx == UINT_MAX) { return false; } - const struct mach_header* header = _dyld_get_image_header(idx); + const struct mach_header *header = _dyld_get_image_header(idx); const uintptr_t imageVMAddrSlide = (uintptr_t)_dyld_get_image_vmaddr_slide(idx); const uintptr_t addressWithSlide = address - imageVMAddrSlide; const uintptr_t segmentBase = segmentBaseOfImageIndex(idx) + imageVMAddrSlide; - if(segmentBase == 0) - { + if (segmentBase == 0) { return false; } info->dli_fname = _dyld_get_image_name(idx); - info->dli_fbase = (void*)header; + info->dli_fbase = (void *)header; // Find symbol tables and get whichever symbol is closest to the address. - const nlist_t* bestMatch = NULL; + const nlist_t *bestMatch = NULL; uintptr_t bestDistance = ULONG_MAX; uintptr_t cmdPtr = firstCmdAfterHeader(header); - if(cmdPtr == 0) - { + if (cmdPtr == 0) { return false; } - for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) - { - const struct load_command* loadCmd = (struct load_command*)cmdPtr; - if(loadCmd->cmd == LC_SYMTAB) - { - const struct symtab_command* symtabCmd = (struct symtab_command*)cmdPtr; - const nlist_t* symbolTable = (nlist_t*)(segmentBase + symtabCmd->symoff); + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SYMTAB) { + const struct symtab_command *symtabCmd = (struct symtab_command *)cmdPtr; + const nlist_t *symbolTable = (nlist_t *)(segmentBase + symtabCmd->symoff); const uintptr_t stringTable = segmentBase + symtabCmd->stroff; - for(uint32_t iSym = 0; iSym < symtabCmd->nsyms; iSym++) - { + for (uint32_t iSym = 0; iSym < symtabCmd->nsyms; iSym++) { // Skip all debug N_STAB symbols - if ((symbolTable[iSym].n_type & N_STAB) != 0) - { + if ((symbolTable[iSym].n_type & N_STAB) != 0) { continue; } // If n_value is 0, the symbol refers to an external object. - if(symbolTable[iSym].n_value != 0) - { + if (symbolTable[iSym].n_value != 0) { uintptr_t symbolBase = symbolTable[iSym].n_value; uintptr_t currentDistance = addressWithSlide - symbolBase; - if((addressWithSlide >= symbolBase) && - (currentDistance <= bestDistance)) - { + if ((addressWithSlide >= symbolBase) && (currentDistance <= bestDistance)) { bestMatch = symbolTable + iSym; bestDistance = currentDistance; } } } - if(bestMatch != NULL) - { - info->dli_saddr = (void*)(bestMatch->n_value + imageVMAddrSlide); - if(bestMatch->n_desc == 16) - { + if (bestMatch != NULL) { + info->dli_saddr = (void *)(bestMatch->n_value + imageVMAddrSlide); + if (bestMatch->n_desc == 16) { // This image has been stripped. The name is meaningless, and // almost certainly resolves to "_mh_execute_header" info->dli_sname = NULL; - } - else - { - info->dli_sname = (char*)((intptr_t)stringTable + (intptr_t)bestMatch->n_un.n_strx); - if(*info->dli_sname == '_') - { + } else { + info->dli_sname = (char *)((intptr_t)stringTable + (intptr_t)bestMatch->n_un.n_strx); + if (*info->dli_sname == '_') { info->dli_sname++; } } @@ -314,152 +266,126 @@ bool ksdl_dladdr(const uintptr_t address, Dl_info* const info) } cmdPtr += loadCmd->cmdsize; } - + return true; } -static bool isValidCrashInfoMessage(const char* str) +static bool isValidCrashInfoMessage(const char *str) { - if(str == NULL) - { + if (str == NULL) { return false; } int maxReadableBytes = ksmem_maxReadableBytes(str, KSDL_MaxCrashInfoStringLength + 1); - if(maxReadableBytes == 0) - { + if (maxReadableBytes == 0) { return false; } - for(int i = 0; i < maxReadableBytes; ++i) { - if(str[i] == 0) - { + for (int i = 0; i < maxReadableBytes; ++i) { + if (str[i] == 0) { return true; } } return false; } -static void getCrashInfo(const struct mach_header* header, KSBinaryImage* buffer) +static void getCrashInfo(const struct mach_header *header, KSBinaryImage *buffer) { unsigned long size = 0; - crash_info_t* crashInfo = - (crash_info_t*)getsectiondata((mach_header_t*)header, SEG_DATA, KSDL_SECT_CRASH_INFO, &size); - if(crashInfo == NULL) - { + crash_info_t *crashInfo = + (crash_info_t *)getsectiondata((mach_header_t *)header, SEG_DATA, KSDL_SECT_CRASH_INFO, &size); + if (crashInfo == NULL) { return; } KSLOG_TRACE("Found crash info section in binary: %s", buffer->name); - const unsigned int minimalSize = offsetof(crash_info_t, reserved); // Include message and message2 - if(size < minimalSize) - { + const unsigned int minimalSize = offsetof(crash_info_t, reserved); // Include message and message2 + if (size < minimalSize) { KSLOG_TRACE("Skipped reading crash info: section is too small"); return; } - if(!ksmem_isMemoryReadable(crashInfo, minimalSize)) - { + if (!ksmem_isMemoryReadable(crashInfo, minimalSize)) { KSLOG_TRACE("Skipped reading crash info: section memory is not readable"); return; } - if(crashInfo->version != 4 && crashInfo->version != 5) - { + if (crashInfo->version != 4 && crashInfo->version != 5) { KSLOG_TRACE("Skipped reading crash info: invalid version '%d'", crashInfo->version); return; } - if(crashInfo->message == NULL && crashInfo->message2 == NULL) - { + if (crashInfo->message == NULL && crashInfo->message2 == NULL) { KSLOG_TRACE("Skipped reading crash info: both messages are null"); return; } - if(isValidCrashInfoMessage(crashInfo->message)) - { + if (isValidCrashInfoMessage(crashInfo->message)) { KSLOG_DEBUG("Found first message: %s", crashInfo->message); buffer->crashInfoMessage = crashInfo->message; } - if(isValidCrashInfoMessage(crashInfo->message2)) - { + if (isValidCrashInfoMessage(crashInfo->message2)) { KSLOG_DEBUG("Found second message: %s", crashInfo->message2); buffer->crashInfoMessage2 = crashInfo->message2; } - if(isValidCrashInfoMessage(crashInfo->backtrace)) - { + if (isValidCrashInfoMessage(crashInfo->backtrace)) { KSLOG_DEBUG("Found backtrace: %s", crashInfo->backtrace); buffer->crashInfoBacktrace = crashInfo->backtrace; } - if(isValidCrashInfoMessage(crashInfo->signature)) - { + if (isValidCrashInfoMessage(crashInfo->signature)) { KSLOG_DEBUG("Found signature: %s", crashInfo->signature); buffer->crashInfoSignature = crashInfo->signature; } } -int ksdl_imageCount(void) -{ - return (int)_dyld_image_count(); -} +int ksdl_imageCount(void) { return (int)_dyld_image_count(); } -bool ksdl_getBinaryImage(int index, KSBinaryImage* buffer) +bool ksdl_getBinaryImage(int index, KSBinaryImage *buffer) { - const struct mach_header* header = _dyld_get_image_header((unsigned)index); - if(header == NULL) - { + const struct mach_header *header = _dyld_get_image_header((unsigned)index); + if (header == NULL) { return false; } - - return ksdl_getBinaryImageForHeader((const void*)header, _dyld_get_image_name((unsigned)index), buffer); + + return ksdl_getBinaryImageForHeader((const void *)header, _dyld_get_image_name((unsigned)index), buffer); } -bool ksdl_getBinaryImageForHeader(const void* const header_ptr, const char* const image_name, KSBinaryImage* buffer) +bool ksdl_getBinaryImageForHeader(const void *const header_ptr, const char *const image_name, KSBinaryImage *buffer) { - const struct mach_header* header = (const struct mach_header*)header_ptr; + const struct mach_header *header = (const struct mach_header *)header_ptr; uintptr_t cmdPtr = firstCmdAfterHeader(header); - if(cmdPtr == 0) - { + if (cmdPtr == 0) { return false; } - + // Look for the TEXT segment to get the image size. // Also look for a UUID command. uint64_t imageSize = 0; uint64_t imageVmAddr = 0; uint64_t version = 0; - uint8_t* uuid = NULL; - - for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) - { - struct load_command* loadCmd = (struct load_command*)cmdPtr; - switch(loadCmd->cmd) - { - case LC_SEGMENT: - { - struct segment_command* segCmd = (struct segment_command*)cmdPtr; - if(strcmp(segCmd->segname, SEG_TEXT) == 0) - { + uint8_t *uuid = NULL; + + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + struct load_command *loadCmd = (struct load_command *)cmdPtr; + switch (loadCmd->cmd) { + case LC_SEGMENT: { + struct segment_command *segCmd = (struct segment_command *)cmdPtr; + if (strcmp(segCmd->segname, SEG_TEXT) == 0) { imageSize = segCmd->vmsize; imageVmAddr = segCmd->vmaddr; } break; } - case LC_SEGMENT_64: - { - struct segment_command_64* segCmd = (struct segment_command_64*)cmdPtr; - if(strcmp(segCmd->segname, SEG_TEXT) == 0) - { + case LC_SEGMENT_64: { + struct segment_command_64 *segCmd = (struct segment_command_64 *)cmdPtr; + if (strcmp(segCmd->segname, SEG_TEXT) == 0) { imageSize = segCmd->vmsize; imageVmAddr = segCmd->vmaddr; } break; } - case LC_UUID: - { - struct uuid_command* uuidCmd = (struct uuid_command*)cmdPtr; + case LC_UUID: { + struct uuid_command *uuidCmd = (struct uuid_command *)cmdPtr; uuid = uuidCmd->uuid; break; } - case LC_ID_DYLIB: - { - - struct dylib_command* dc = (struct dylib_command*)cmdPtr; + case LC_ID_DYLIB: { + struct dylib_command *dc = (struct dylib_command *)cmdPtr; version = dc->dylib.current_version; break; } @@ -478,6 +404,6 @@ bool ksdl_getBinaryImageForHeader(const void* const header_ptr, const char* cons buffer->minorVersion = (version >> 8) & 0xff; buffer->revisionVersion = version & 0xff; getCrashInfo(header, buffer); - + return true; } diff --git a/Sources/KSCrashRecordingCore/KSFileUtils.c b/Sources/KSCrashRecordingCore/KSFileUtils.c index bb03d9f60..9f40051f6 100644 --- a/Sources/KSCrashRecordingCore/KSFileUtils.c +++ b/Sources/KSCrashRecordingCore/KSFileUtils.c @@ -24,69 +24,60 @@ // THE SOFTWARE. // - #include "KSFileUtils.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - +// #define KSLogger_LocalLevel TRACE #include #include #include #include #include #include -#include #include +#include #include +#include "KSLogger.h" + /** Buffer size to use in the "writeFmt" functions. * If the formatted output length would exceed this value, it is truncated. */ #ifndef KSFU_WriteFmtBufferSize - #define KSFU_WriteFmtBufferSize 1024 +#define KSFU_WriteFmtBufferSize 1024 #endif - // ============================================================================ #pragma mark - Utility - // ============================================================================ -static bool canDeletePath(const char* path) +static bool canDeletePath(const char *path) { - const char* lastComponent = strrchr(path, '/'); - if(lastComponent == NULL) - { + const char *lastComponent = strrchr(path, '/'); + if (lastComponent == NULL) { lastComponent = path; - } - else - { + } else { lastComponent++; } - if(strcmp(lastComponent, ".") == 0) - { + if (strcmp(lastComponent, ".") == 0) { return false; } - if(strcmp(lastComponent, "..") == 0) - { + if (strcmp(lastComponent, "..") == 0) { return false; } return true; } -static int dirContentsCount(const char* path) +static int dirContentsCount(const char *path) { int count = 0; - DIR* dir = opendir(path); - if(dir == NULL) - { + DIR *dir = opendir(path); + if (dir == NULL) { KSLOG_ERROR("Error reading directory %s: %s", path, strerror(errno)); return 0; } - struct dirent* ent; - while((ent = readdir(dir))) - { + struct dirent *ent; + while ((ent = readdir(dir))) { count++; } @@ -94,29 +85,25 @@ static int dirContentsCount(const char* path) return count; } -static void dirContents(const char* path, char*** entries, int* count) +static void dirContents(const char *path, char ***entries, int *count) { - DIR* dir = NULL; - char** entryList = NULL; + DIR *dir = NULL; + char **entryList = NULL; int entryCount = dirContentsCount(path); - if(entryCount <= 0) - { + if (entryCount <= 0) { goto done; } dir = opendir(path); - if(dir == NULL) - { + if (dir == NULL) { KSLOG_ERROR("Error reading directory %s: %s", path, strerror(errno)); goto done; } - entryList = calloc((unsigned)entryCount, sizeof(char*)); - struct dirent* ent; + entryList = calloc((unsigned)entryCount, sizeof(char *)); + struct dirent *ent; int index = 0; - while((ent = readdir(dir))) - { - if(index >= entryCount) - { + while ((ent = readdir(dir))) { + if (index >= entryCount) { KSLOG_ERROR("Contents of %s have been mutated", path); goto done; } @@ -125,27 +112,22 @@ static void dirContents(const char* path, char*** entries, int* count) } done: - if(dir != NULL) - { + if (dir != NULL) { closedir(dir); } - if(entryList == NULL) - { + if (entryList == NULL) { entryCount = 0; } *entries = entryList; *count = entryCount; } -static void freeDirListing(char** entries, int count) +static void freeDirListing(char **entries, int count) { - if(entries != NULL) - { - for(int i = 0; i < count; i++) - { - char* ptr = entries[i]; - if(ptr != NULL) - { + if (entries != NULL) { + for (int i = 0; i < count; i++) { + char *ptr = entries[i]; + if (ptr != NULL) { free(ptr); } } @@ -153,31 +135,27 @@ static void freeDirListing(char** entries, int count) } } -static bool deletePathContents(const char* path, bool deleteTopLevelPathAlso) +static bool deletePathContents(const char *path, bool deleteTopLevelPathAlso) { - struct stat statStruct = {0}; - if(stat(path, &statStruct) != 0) - { + struct stat statStruct = { 0 }; + if (stat(path, &statStruct) != 0) { KSLOG_ERROR("Could not stat %s: %s", path, strerror(errno)); return false; } - if(S_ISDIR(statStruct.st_mode)) - { - char** entries = NULL; + if (S_ISDIR(statStruct.st_mode)) { + char **entries = NULL; int entryCount = 0; dirContents(path, &entries, &entryCount); int bufferLength = KSFU_MAX_PATH_LENGTH; - char* pathBuffer = malloc((unsigned)bufferLength); + char *pathBuffer = malloc((unsigned)bufferLength); snprintf(pathBuffer, bufferLength, "%s/", path); - char* pathPtr = pathBuffer + strlen(pathBuffer); + char *pathPtr = pathBuffer + strlen(pathBuffer); int pathRemainingLength = bufferLength - (int)(pathPtr - pathBuffer); - for(int i = 0; i < entryCount; i++) - { - char* entry = entries[i]; - if(entry != NULL && canDeletePath(entry)) - { + for (int i = 0; i < entryCount; i++) { + char *entry = entries[i]; + if (entry != NULL && canDeletePath(entry)) { strncpy(pathPtr, entry, pathRemainingLength); deletePathContents(pathBuffer, true); } @@ -185,17 +163,12 @@ static bool deletePathContents(const char* path, bool deleteTopLevelPathAlso) free(pathBuffer); freeDirListing(entries, entryCount); - if(deleteTopLevelPathAlso) - { + if (deleteTopLevelPathAlso) { ksfu_removeFile(path, false); } - } - else if(S_ISREG(statStruct.st_mode)) - { + } else if (S_ISREG(statStruct.st_mode)) { ksfu_removeFile(path, false); - } - else - { + } else { KSLOG_ERROR("Could not delete %s: Not a regular file.", path); return false; } @@ -206,25 +179,22 @@ static bool deletePathContents(const char* path, bool deleteTopLevelPathAlso) #pragma mark - API - // ============================================================================ -const char* ksfu_lastPathEntry(const char* const path) +const char *ksfu_lastPathEntry(const char *const path) { - if(path == NULL) - { + if (path == NULL) { return NULL; } - char* lastFile = strrchr(path, '/'); + char *lastFile = strrchr(path, '/'); return lastFile == NULL ? path : lastFile + 1; } -bool ksfu_writeBytesToFD(const int fd, const char* const bytes, int length) +bool ksfu_writeBytesToFD(const int fd, const char *const bytes, int length) { - const char* pos = bytes; - while(length > 0) - { + const char *pos = bytes; + while (length > 0) { int bytesWritten = (int)write(fd, pos, (unsigned)length); - if(bytesWritten == -1) - { + if (bytesWritten == -1) { KSLOG_ERROR("Could not write to fd %d: %s", fd, strerror(errno)); return false; } @@ -234,72 +204,61 @@ bool ksfu_writeBytesToFD(const int fd, const char* const bytes, int length) return true; } -bool ksfu_readBytesFromFD(const int fd, char* const bytes, int length) +bool ksfu_readBytesFromFD(const int fd, char *const bytes, int length) { - char* pos = bytes; - while(length > 0) - { + char *pos = bytes; + while (length > 0) { int bytesRead = (int)read(fd, pos, (unsigned)length); - if(bytesRead == -1) - { + if (bytesRead == -1) { KSLOG_ERROR("Could not read fd %d: %s", fd, strerror(errno)); return false; - } - else if (bytesRead == 0) { + } else if (bytesRead == 0) { KSLOG_ERROR("Read returns 0 bytes, likely EOF for fd %d: %s", fd, strerror(errno)); return false; } - + length -= bytesRead; pos += bytesRead; } return true; } -bool ksfu_readEntireFile(const char* const path, char** data, int* length, int maxLength) +bool ksfu_readEntireFile(const char *const path, char **data, int *length, int maxLength) { bool isSuccessful = false; int bytesRead = 0; - char* mem = NULL; + char *mem = NULL; int fd = -1; int bytesToRead = maxLength; struct stat st; - if(stat(path, &st) < 0) - { + if (stat(path, &st) < 0) { KSLOG_ERROR("Could not stat %s: %s", path, strerror(errno)); goto done; } fd = open(path, O_RDONLY); - if(fd < 0) - { + if (fd < 0) { KSLOG_ERROR("Could not open %s: %s", path, strerror(errno)); goto done; } - if(bytesToRead == 0 || bytesToRead >= (int)st.st_size) - { + if (bytesToRead == 0 || bytesToRead >= (int)st.st_size) { bytesToRead = (int)st.st_size; - } - else if(bytesToRead > 0) - { - if(lseek(fd, -bytesToRead, SEEK_END) < 0) - { + } else if (bytesToRead > 0) { + if (lseek(fd, -bytesToRead, SEEK_END) < 0) { KSLOG_ERROR("Could not seek to %d from end of %s: %s", -bytesToRead, path, strerror(errno)); goto done; } } mem = malloc((unsigned)bytesToRead + 1); - if(mem == NULL) - { + if (mem == NULL) { KSLOG_ERROR("Out of memory"); goto done; } - if(!ksfu_readBytesFromFD(fd, mem, bytesToRead)) - { + if (!ksfu_readBytesFromFD(fd, mem, bytesToRead)) { goto done; } @@ -308,38 +267,31 @@ bool ksfu_readEntireFile(const char* const path, char** data, int* length, int m isSuccessful = true; done: - if(fd >= 0) - { + if (fd >= 0) { close(fd); } - if(!isSuccessful && mem != NULL) - { + if (!isSuccessful && mem != NULL) { free(mem); mem = NULL; } *data = mem; - if(length != NULL) - { + if (length != NULL) { *length = bytesRead; } return isSuccessful; } -bool ksfu_writeStringToFD(const int fd, const char* const string) +bool ksfu_writeStringToFD(const int fd, const char *const string) { - if(*string != 0) - { + if (*string != 0) { int bytesToWrite = (int)strlen(string); - const char* pos = string; - while(bytesToWrite > 0) - { + const char *pos = string; + while (bytesToWrite > 0) { int bytesWritten = (int)write(fd, pos, (unsigned)bytesToWrite); - if(bytesWritten == -1) - { - KSLOG_ERROR("Could not write to fd %d: %s", - fd, strerror(errno)); + if (bytesWritten == -1) { + KSLOG_ERROR("Could not write to fd %d: %s", fd, strerror(errno)); return false; } bytesToWrite -= bytesWritten; @@ -350,12 +302,11 @@ bool ksfu_writeStringToFD(const int fd, const char* const string) return false; } -bool ksfu_writeFmtToFD(const int fd, const char* const fmt, ...) +bool ksfu_writeFmtToFD(const int fd, const char *const fmt, ...) { - if(*fmt != 0) - { + if (*fmt != 0) { va_list args; - va_start(args,fmt); + va_start(args, fmt); bool result = ksfu_writeFmtArgsToFD(fd, fmt, args); va_end(args); return result; @@ -363,12 +314,9 @@ bool ksfu_writeFmtToFD(const int fd, const char* const fmt, ...) return false; } -bool ksfu_writeFmtArgsToFD(const int fd, - const char* const fmt, - va_list args) +bool ksfu_writeFmtArgsToFD(const int fd, const char *const fmt, va_list args) { - if(*fmt != 0) - { + if (*fmt != 0) { char buffer[KSFU_WriteFmtBufferSize]; vsnprintf(buffer, sizeof(buffer), fmt, args); return ksfu_writeStringToFD(fd, buffer); @@ -376,21 +324,17 @@ bool ksfu_writeFmtArgsToFD(const int fd, return false; } -int ksfu_readLineFromFD(const int fd, char* const buffer, const int maxLength) +int ksfu_readLineFromFD(const int fd, char *const buffer, const int maxLength) { - char* end = buffer + maxLength - 1; + char *end = buffer + maxLength - 1; *end = 0; - char* ch; - for(ch = buffer; ch < end; ch++) - { + char *ch; + for (ch = buffer; ch < end; ch++) { int bytesRead = (int)read(fd, ch, 1); - if(bytesRead < 0) - { + if (bytesRead < 0) { KSLOG_ERROR("Could not read from fd %d: %s", fd, strerror(errno)); return -1; - } - else if(bytesRead == 0 || *ch == '\n') - { + } else if (bytesRead == 0 || *ch == '\n') { break; } } @@ -398,25 +342,21 @@ int ksfu_readLineFromFD(const int fd, char* const buffer, const int maxLength) return (int)(ch - buffer); } -bool ksfu_makePath(const char* absolutePath) +bool ksfu_makePath(const char *absolutePath) { bool isSuccessful = false; - char* pathCopy = strdup(absolutePath); - for(char* ptr = pathCopy+1; *ptr != '\0';ptr++) - { - if(*ptr == '/') - { + char *pathCopy = strdup(absolutePath); + for (char *ptr = pathCopy + 1; *ptr != '\0'; ptr++) { + if (*ptr == '/') { *ptr = '\0'; - if(mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST) - { + if (mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST) { KSLOG_ERROR("Could not create directory %s: %s", pathCopy, strerror(errno)); goto done; } *ptr = '/'; } } - if(mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST) - { + if (mkdir(pathCopy, S_IRWXU) < 0 && errno != EEXIST) { KSLOG_ERROR("Could not create directory %s: %s", pathCopy, strerror(errno)); goto done; } @@ -427,12 +367,10 @@ bool ksfu_makePath(const char* absolutePath) return isSuccessful; } -bool ksfu_removeFile(const char* path, bool mustExist) +bool ksfu_removeFile(const char *path, bool mustExist) { - if(remove(path) < 0) - { - if(mustExist || errno != ENOENT) - { + if (remove(path) < 0) { + if (mustExist || errno != ENOENT) { KSLOG_ERROR("Could not delete %s: %s", path, strerror(errno)); } return false; @@ -440,55 +378,48 @@ bool ksfu_removeFile(const char* path, bool mustExist) return true; } -bool ksfu_deleteContentsOfPath(const char* path) +bool ksfu_deleteContentsOfPath(const char *path) { - if(path == NULL) - { + if (path == NULL) { return false; } - if(!canDeletePath(path)) - { + if (!canDeletePath(path)) { return false; } return deletePathContents(path, false); } -bool ksfu_openBufferedWriter(KSBufferedWriter* writer, const char* const path, char* writeBuffer, int writeBufferLength) +bool ksfu_openBufferedWriter(KSBufferedWriter *writer, const char *const path, char *writeBuffer, int writeBufferLength) { writer->buffer = writeBuffer; writer->bufferLength = writeBufferLength; writer->position = 0; writer->fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0644); - if(writer->fd < 0) - { + if (writer->fd < 0) { KSLOG_ERROR("Could not open crash report file %s: %s", path, strerror(errno)); return false; } return true; } -void ksfu_closeBufferedWriter(KSBufferedWriter* writer) +void ksfu_closeBufferedWriter(KSBufferedWriter *writer) { - if(writer->fd > 0) - { + if (writer->fd > 0) { ksfu_flushBufferedWriter(writer); close(writer->fd); writer->fd = -1; } } -bool ksfu_writeBufferedWriter(KSBufferedWriter* writer, const char* restrict const data, const int length) +bool ksfu_writeBufferedWriter(KSBufferedWriter *writer, const char *restrict const data, const int length) { - if(length > writer->bufferLength - writer->position) - { - if (!ksfu_flushBufferedWriter(writer)) - { + if (length > writer->bufferLength - writer->position) { + if (!ksfu_flushBufferedWriter(writer)) { return false; } } - if(length > writer->bufferLength) - { + if (length > writer->bufferLength) { return ksfu_writeBytesToFD(writer->fd, data, length); } memcpy(writer->buffer + writer->position, data, length); @@ -496,12 +427,10 @@ bool ksfu_writeBufferedWriter(KSBufferedWriter* writer, const char* restrict con return true; } -bool ksfu_flushBufferedWriter(KSBufferedWriter* writer) +bool ksfu_flushBufferedWriter(KSBufferedWriter *writer) { - if(writer->fd > 0 && writer->position > 0) - { - if(!ksfu_writeBytesToFD(writer->fd, writer->buffer, writer->position)) - { + if (writer->fd > 0 && writer->position > 0) { + if (!ksfu_writeBytesToFD(writer->fd, writer->buffer, writer->position)) { return false; } writer->position = 0; @@ -509,61 +438,49 @@ bool ksfu_flushBufferedWriter(KSBufferedWriter* writer) return true; } -static inline bool isReadBufferEmpty(KSBufferedReader* reader) -{ - return reader->dataEndPos == reader->dataStartPos; -} +static inline bool isReadBufferEmpty(KSBufferedReader *reader) { return reader->dataEndPos == reader->dataStartPos; } -static bool fillReadBuffer(KSBufferedReader* reader) +static bool fillReadBuffer(KSBufferedReader *reader) { - if(reader->dataStartPos > 0) - { + if (reader->dataStartPos > 0) { memmove(reader->buffer, reader->buffer + reader->dataStartPos, reader->dataStartPos); reader->dataEndPos -= reader->dataStartPos; reader->dataStartPos = 0; reader->buffer[reader->dataEndPos] = '\0'; } int bytesToRead = reader->bufferLength - reader->dataEndPos; - if(bytesToRead <= 0) - { + if (bytesToRead <= 0) { return true; } int bytesRead = (int)read(reader->fd, reader->buffer + reader->dataEndPos, (size_t)bytesToRead); - if(bytesRead < 0) - { + if (bytesRead < 0) { KSLOG_ERROR("Could not read: %s", strerror(errno)); return false; - } - else - { + } else { reader->dataEndPos += bytesRead; reader->buffer[reader->dataEndPos] = '\0'; } return true; } -int ksfu_readBufferedReader(KSBufferedReader* reader, char* dstBuffer, int byteCount) +int ksfu_readBufferedReader(KSBufferedReader *reader, char *dstBuffer, int byteCount) { int bytesRemaining = byteCount; int bytesConsumed = 0; - char* pDst = dstBuffer; - while(bytesRemaining > 0) - { + char *pDst = dstBuffer; + while (bytesRemaining > 0) { int bytesInReader = reader->dataEndPos - reader->dataStartPos; - if(bytesInReader <= 0) - { - if(!fillReadBuffer(reader)) - { + if (bytesInReader <= 0) { + if (!fillReadBuffer(reader)) { break; } bytesInReader = reader->dataEndPos - reader->dataStartPos; - if(bytesInReader <= 0) - { + if (bytesInReader <= 0) { break; } } int bytesToCopy = bytesInReader <= bytesRemaining ? bytesInReader : bytesRemaining; - char* pSrc = reader->buffer + reader->dataStartPos; + char *pSrc = reader->buffer + reader->dataStartPos; memcpy(pDst, pSrc, bytesToCopy); pDst += bytesToCopy; reader->dataStartPos += bytesToCopy; @@ -574,23 +491,20 @@ int ksfu_readBufferedReader(KSBufferedReader* reader, char* dstBuffer, int byteC return bytesConsumed; } -bool ksfu_readBufferedReaderUntilChar(KSBufferedReader* reader, int ch, char* dstBuffer, int* length) +bool ksfu_readBufferedReaderUntilChar(KSBufferedReader *reader, int ch, char *dstBuffer, int *length) { int bytesRemaining = *length; int bytesConsumed = 0; - char* pDst = dstBuffer; - while(bytesRemaining > 0) - { + char *pDst = dstBuffer; + while (bytesRemaining > 0) { int bytesInReader = reader->dataEndPos - reader->dataStartPos; int bytesToCopy = bytesInReader <= bytesRemaining ? bytesInReader : bytesRemaining; - char* pSrc = reader->buffer + reader->dataStartPos; - char* pChar = strchr(pSrc, ch); + char *pSrc = reader->buffer + reader->dataStartPos; + char *pChar = strchr(pSrc, ch); bool isFound = pChar != NULL; - if(isFound) - { + if (isFound) { int bytesToChar = (int)(pChar - pSrc) + 1; - if(bytesToChar < bytesToCopy) - { + if (bytesToChar < bytesToCopy) { bytesToCopy = bytesToChar; } } @@ -599,16 +513,13 @@ bool ksfu_readBufferedReaderUntilChar(KSBufferedReader* reader, int ch, char* ds reader->dataStartPos += bytesToCopy; bytesConsumed += bytesToCopy; bytesRemaining -= bytesToCopy; - if(isFound) - { + if (isFound) { *length = bytesConsumed; return true; } - if(bytesRemaining > 0) - { + if (bytesRemaining > 0) { fillReadBuffer(reader); - if(isReadBufferEmpty(reader)) - { + if (isReadBufferEmpty(reader)) { break; } } @@ -618,7 +529,7 @@ bool ksfu_readBufferedReaderUntilChar(KSBufferedReader* reader, int ch, char* ds return false; } -bool ksfu_openBufferedReader(KSBufferedReader* reader, const char* const path, char* readBuffer, int readBufferLength) +bool ksfu_openBufferedReader(KSBufferedReader *reader, const char *const path, char *readBuffer, int readBufferLength) { readBuffer[0] = '\0'; readBuffer[readBufferLength - 1] = '\0'; @@ -627,8 +538,7 @@ bool ksfu_openBufferedReader(KSBufferedReader* reader, const char* const path, c reader->dataStartPos = 0; reader->dataEndPos = 0; reader->fd = open(path, O_RDONLY); - if(reader->fd < 0) - { + if (reader->fd < 0) { KSLOG_ERROR("Could not open file %s: %s", path, strerror(errno)); return false; } @@ -636,46 +546,45 @@ bool ksfu_openBufferedReader(KSBufferedReader* reader, const char* const path, c return true; } -void ksfu_closeBufferedReader(KSBufferedReader* reader) +void ksfu_closeBufferedReader(KSBufferedReader *reader) { - if(reader->fd > 0) - { + if (reader->fd > 0) { close(reader->fd); reader->fd = -1; } } -void *ksfu_mmap(const char* path, int size) +void *ksfu_mmap(const char *path, int size) { int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd == -1) { KSLOG_ERROR("Could not open file %s: %s", path, strerror(errno)); return NULL; } - + if (lseek(fd, size, SEEK_SET) == -1) { KSLOG_ERROR("Could not seek file %s: %s", path, strerror(errno)); close(fd); unlink(path); return NULL; } - + if (write(fd, "", 1) == -1) { KSLOG_ERROR("Could not write file %s: %s", path, strerror(errno)); close(fd); unlink(path); return NULL; } - + void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - + if (ptr == MAP_FAILED) { KSLOG_ERROR("Could not mmap file %s: %s", path, strerror(errno)); // This comes before close which is ok since it'll happen // when all fd's are closed. unlink(path); } - + close(fd); return ptr; } diff --git a/Sources/KSCrashRecordingCore/KSID.c b/Sources/KSCrashRecordingCore/KSID.c index 7d389feed..aa72da180 100644 --- a/Sources/KSCrashRecordingCore/KSID.c +++ b/Sources/KSCrashRecordingCore/KSID.c @@ -22,32 +22,16 @@ // THE SOFTWARE. // - #include #include - -void ksid_generate(char* destinationBuffer37Bytes) +void ksid_generate(char *destinationBuffer37Bytes) { uuid_t uuid; uuid_generate(uuid); - sprintf(destinationBuffer37Bytes, - "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - (unsigned)uuid[0], - (unsigned)uuid[1], - (unsigned)uuid[2], - (unsigned)uuid[3], - (unsigned)uuid[4], - (unsigned)uuid[5], - (unsigned)uuid[6], - (unsigned)uuid[7], - (unsigned)uuid[8], - (unsigned)uuid[9], - (unsigned)uuid[10], - (unsigned)uuid[11], - (unsigned)uuid[12], - (unsigned)uuid[13], - (unsigned)uuid[14], - (unsigned)uuid[15] - ); + sprintf(destinationBuffer37Bytes, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + (unsigned)uuid[0], (unsigned)uuid[1], (unsigned)uuid[2], (unsigned)uuid[3], (unsigned)uuid[4], + (unsigned)uuid[5], (unsigned)uuid[6], (unsigned)uuid[7], (unsigned)uuid[8], (unsigned)uuid[9], + (unsigned)uuid[10], (unsigned)uuid[11], (unsigned)uuid[12], (unsigned)uuid[13], (unsigned)uuid[14], + (unsigned)uuid[15]); } diff --git a/Sources/KSCrashRecordingCore/KSJSONCodec.c b/Sources/KSCrashRecordingCore/KSJSONCodec.c index 039f3afa6..ddb6377ef 100644 --- a/Sources/KSCrashRecordingCore/KSJSONCodec.c +++ b/Sources/KSCrashRecordingCore/KSJSONCodec.c @@ -24,18 +24,16 @@ // THE SOFTWARE. // - #include "KSJSONCodec.h" #include #include #include #include +#include #include #include #include -#include - // ============================================================================ #pragma mark - Configuration - @@ -43,42 +41,36 @@ /** Set to 1 if you're also compiling KSLogger and want to use it here */ #ifndef KSJSONCODEC_UseKSLogger - #define KSJSONCODEC_UseKSLogger 1 +#define KSJSONCODEC_UseKSLogger 1 #endif #if KSJSONCODEC_UseKSLogger - #include "KSLogger.h" +#include "KSLogger.h" #else - #define KSLOG_DEBUG(FMT, ...) +#define KSLOG_DEBUG(FMT, ...) #endif /** The work buffer size to use when escaping string values. * There's little reason to change this since nothing ever gets truncated. */ #ifndef KSJSONCODEC_WorkBufferSize - #define KSJSONCODEC_WorkBufferSize 512 +#define KSJSONCODEC_WorkBufferSize 512 #endif - // ============================================================================ #pragma mark - Helpers - // ============================================================================ // Compiler hints for "if" statements -#define likely_if(x) if(__builtin_expect(x,1)) -#define unlikely_if(x) if(__builtin_expect(x,0)) +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) /** Used for writing hex string values. */ -static char g_hexNybbles[] = -{ - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; +static char g_hexNybbles[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; -const char* ksjson_stringForError(const int error) +const char *ksjson_stringForError(const int error) { - switch (error) - { + switch (error) { case KSJSON_ERROR_INVALID_CHARACTER: return "Invalid character"; case KSJSON_ERROR_DATA_TOO_LONG: @@ -94,7 +86,6 @@ const char* ksjson_stringForError(const int error) } } - // ============================================================================ #pragma mark - Encode - // ============================================================================ @@ -110,8 +101,7 @@ const char* ksjson_stringForError(const int error) * * @return KSJSON_OK if the data was handled successfully. */ -#define addJSONData(CONTEXT,DATA,LENGTH) \ - (CONTEXT)->addJSONData(DATA, LENGTH, (CONTEXT)->userData) +#define addJSONData(CONTEXT, DATA, LENGTH) (CONTEXT)->addJSONData(DATA, LENGTH, (CONTEXT)->userData) /** Escape a string portion for use with JSON and send to data handler. * @@ -123,30 +113,22 @@ const char* ksjson_stringForError(const int error) * * @return KSJSON_OK if the data was handled successfully. */ -static int appendEscapedString(KSJSONEncodeContext* const context, - const char* restrict const string, - int length) +static int appendEscapedString(KSJSONEncodeContext *const context, const char *restrict const string, int length) { char workBuffer[KSJSONCODEC_WorkBufferSize]; - const char* const srcEnd = string + length; + const char *const srcEnd = string + length; - const char* restrict src = string; - char* restrict dst = workBuffer; + const char *restrict src = string; + char *restrict dst = workBuffer; // Simple case (no escape or special characters) - for(; src < srcEnd && - *src != '\\' && - *src != '\"' && - (unsigned char)*src >= ' '; src++) - { + for (; src < srcEnd && *src != '\\' && *src != '\"' && (unsigned char)*src >= ' '; src++) { *dst++ = *src; } // Deal with complicated case (if any) - for(; src < srcEnd; src++) - { - switch(*src) - { + for (; src < srcEnd; src++) { + switch (*src) { case '\\': case '\"': *dst++ = '\\'; @@ -174,11 +156,10 @@ static int appendEscapedString(KSJSONEncodeContext* const context, break; default: unlikely_if((unsigned char)*src < ' ') - { - KSLOG_DEBUG("Invalid character 0x%02x in string: %s", - *src, string); - return KSJSON_ERROR_INVALID_CHARACTER; - } + { + KSLOG_DEBUG("Invalid character 0x%02x in string: %s", *src, string); + return KSJSON_ERROR_INVALID_CHARACTER; + } *dst++ = *src; } } @@ -197,26 +178,17 @@ static int appendEscapedString(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the data was handled successfully. */ -static int addEscapedString(KSJSONEncodeContext* const context, - const char* restrict const string, - int length) +static int addEscapedString(KSJSONEncodeContext *const context, const char *restrict const string, int length) { int result = KSJSON_OK; // Keep adding portions until the whole string has been processed. int offset = 0; - while(offset < length) - { + while (offset < length) { int toAdd = length - offset; - unlikely_if(toAdd > KSJSONCODEC_WorkBufferSize / 2) - { - toAdd = KSJSONCODEC_WorkBufferSize / 2; - } + unlikely_if(toAdd > KSJSONCODEC_WorkBufferSize / 2) { toAdd = KSJSONCODEC_WorkBufferSize / 2; } result = appendEscapedString(context, string + offset, toAdd); - unlikely_if(result != KSJSON_OK) - { - break; - } + unlikely_if(result != KSJSON_OK) { break; } offset += toAdd; } return result; @@ -232,15 +204,10 @@ static int addEscapedString(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the data was handled successfully. */ -static int addQuotedEscapedString(KSJSONEncodeContext* const context, - const char* restrict const string, - int length) +static int addQuotedEscapedString(KSJSONEncodeContext *const context, const char *restrict const string, int length) { int result; - unlikely_if((result = addJSONData(context, "\"", 1)) != KSJSON_OK) - { - return result; - } + unlikely_if((result = addJSONData(context, "\"", 1)) != KSJSON_OK) { return result; } result = addEscapedString(context, string, length); // Always close string, even if we failed to write its content @@ -249,231 +216,151 @@ static int addQuotedEscapedString(KSJSONEncodeContext* const context, return result || closeResult; } -int ksjson_beginElement(KSJSONEncodeContext* const context, const char* const name) +int ksjson_beginElement(KSJSONEncodeContext *const context, const char *const name) { int result = KSJSON_OK; // Decide if a comma is warranted. - unlikely_if(context->containerFirstEntry) - { - context->containerFirstEntry = false; - } + unlikely_if(context->containerFirstEntry) { context->containerFirstEntry = false; } else { - unlikely_if((result = addJSONData(context, ",", 1)) != KSJSON_OK) - { - return result; - } + unlikely_if((result = addJSONData(context, ",", 1)) != KSJSON_OK) { return result; } } // Pretty printing unlikely_if(context->prettyPrint && context->containerLevel > 0) { - unlikely_if((result = addJSONData(context, "\n", 1)) != KSJSON_OK) - { - return result; - } - for(int i = 0; i < context->containerLevel; i++) - { - unlikely_if((result = addJSONData(context, " ", 4)) != KSJSON_OK) - { - return result; - } + unlikely_if((result = addJSONData(context, "\n", 1)) != KSJSON_OK) { return result; } + for (int i = 0; i < context->containerLevel; i++) { + unlikely_if((result = addJSONData(context, " ", 4)) != KSJSON_OK) { return result; } } } // Add a name field if we're in an object. - if(context->isObject[context->containerLevel]) - { + if (context->isObject[context->containerLevel]) { unlikely_if(name == NULL) { KSLOG_DEBUG("Name was null inside an object"); return KSJSON_ERROR_INVALID_DATA; } - unlikely_if((result = addQuotedEscapedString(context, name, (int)strlen(name))) != KSJSON_OK) - { - return result; - } + unlikely_if((result = addQuotedEscapedString(context, name, (int)strlen(name))) != KSJSON_OK) { return result; } unlikely_if(context->prettyPrint) { - unlikely_if((result = addJSONData(context, ": ", 2)) != KSJSON_OK) - { - return result; - } + unlikely_if((result = addJSONData(context, ": ", 2)) != KSJSON_OK) { return result; } } else { - unlikely_if((result = addJSONData(context, ":", 1)) != KSJSON_OK) - { - return result; - } + unlikely_if((result = addJSONData(context, ":", 1)) != KSJSON_OK) { return result; } } } return result; } -int ksjson_addRawJSONData(KSJSONEncodeContext* const context, - const char* const data, - const int length) +int ksjson_addRawJSONData(KSJSONEncodeContext *const context, const char *const data, const int length) { return addJSONData(context, data, length); } -int ksjson_addBooleanElement(KSJSONEncodeContext* const context, - const char* const name, - const bool value) +int ksjson_addBooleanElement(KSJSONEncodeContext *const context, const char *const name, const bool value) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } - if(value) - { + unlikely_if(result != KSJSON_OK) { return result; } + if (value) { return addJSONData(context, "true", 4); - } - else - { + } else { return addJSONData(context, "false", 5); } } -int ksjson_addFloatingPointElement(KSJSONEncodeContext* const context, - const char* const name, - double value) +int ksjson_addFloatingPointElement(KSJSONEncodeContext *const context, const char *const name, double value) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } char buff[30]; sprintf(buff, "%lg", value); return addJSONData(context, buff, (int)strlen(buff)); } -int ksjson_addIntegerElement(KSJSONEncodeContext* const context, - const char* const name, - int64_t value) +int ksjson_addIntegerElement(KSJSONEncodeContext *const context, const char *const name, int64_t value) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } char buff[30]; sprintf(buff, "%" PRId64, value); return addJSONData(context, buff, (int)strlen(buff)); } -int ksjson_addUIntegerElement(KSJSONEncodeContext* const context, - const char* const name, - uint64_t value) +int ksjson_addUIntegerElement(KSJSONEncodeContext *const context, const char *const name, uint64_t value) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } char buff[30]; sprintf(buff, "%" PRIu64, value); return addJSONData(context, buff, (int)strlen(buff)); } -int ksjson_addNullElement(KSJSONEncodeContext* const context, - const char* const name) +int ksjson_addNullElement(KSJSONEncodeContext *const context, const char *const name) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } return addJSONData(context, "null", 4); } -int ksjson_addStringElement(KSJSONEncodeContext* const context, - const char* const name, - const char* const value, +int ksjson_addStringElement(KSJSONEncodeContext *const context, const char *const name, const char *const value, int length) { - unlikely_if(value == NULL) - { - return ksjson_addNullElement(context, name); - } + unlikely_if(value == NULL) { return ksjson_addNullElement(context, name); } int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } - if(length == KSJSON_SIZE_AUTOMATIC) - { + unlikely_if(result != KSJSON_OK) { return result; } + if (length == KSJSON_SIZE_AUTOMATIC) { length = (int)strlen(value); } return addQuotedEscapedString(context, value, length); } -int ksjson_beginStringElement(KSJSONEncodeContext* const context, - const char* const name) +int ksjson_beginStringElement(KSJSONEncodeContext *const context, const char *const name) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } return addJSONData(context, "\"", 1); } -int ksjson_appendStringElement(KSJSONEncodeContext* const context, - const char* const value, - int length) +int ksjson_appendStringElement(KSJSONEncodeContext *const context, const char *const value, int length) { return addEscapedString(context, value, length); } -int ksjson_endStringElement(KSJSONEncodeContext* const context) -{ - return addJSONData(context, "\"", 1); -} +int ksjson_endStringElement(KSJSONEncodeContext *const context) { return addJSONData(context, "\"", 1); } -int ksjson_addDataElement(KSJSONEncodeContext* const context, - const char* name, - const char* value, - int length) +int ksjson_addDataElement(KSJSONEncodeContext *const context, const char *name, const char *value, int length) { int result = KSJSON_OK; result = ksjson_beginDataElement(context, name); - if(result == KSJSON_OK) - { + if (result == KSJSON_OK) { result = ksjson_appendDataElement(context, value, length); } - if(result == KSJSON_OK) - { + if (result == KSJSON_OK) { result = ksjson_endDataElement(context); } return result; } -int ksjson_beginDataElement(KSJSONEncodeContext* const context, - const char* const name) +int ksjson_beginDataElement(KSJSONEncodeContext *const context, const char *const name) { return ksjson_beginStringElement(context, name); } -int ksjson_appendDataElement(KSJSONEncodeContext* const context, - const char* const value, - int length) +int ksjson_appendDataElement(KSJSONEncodeContext *const context, const char *const value, int length) { - unsigned char* currentByte = (unsigned char*)value; - unsigned char* end = currentByte + length; + unsigned char *currentByte = (unsigned char *)value; + unsigned char *end = currentByte + length; char chars[2]; int result = KSJSON_OK; - while(currentByte < end) - { - chars[0] = g_hexNybbles[(*currentByte>>4)&15]; - chars[1] = g_hexNybbles[*currentByte&15]; + while (currentByte < end) { + chars[0] = g_hexNybbles[(*currentByte >> 4) & 15]; + chars[1] = g_hexNybbles[*currentByte & 15]; result = addJSONData(context, chars, sizeof(chars)); - if(result != KSJSON_OK) - { + if (result != KSJSON_OK) { break; } currentByte++; @@ -481,21 +368,14 @@ int ksjson_appendDataElement(KSJSONEncodeContext* const context, return result; } -int ksjson_endDataElement(KSJSONEncodeContext* const context) -{ - return ksjson_endStringElement(context); -} +int ksjson_endDataElement(KSJSONEncodeContext *const context) { return ksjson_endStringElement(context); } -int ksjson_beginArray(KSJSONEncodeContext* const context, - const char* const name) +int ksjson_beginArray(KSJSONEncodeContext *const context, const char *const name) { likely_if(context->containerLevel >= 0) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } } context->containerLevel++; @@ -505,16 +385,12 @@ int ksjson_beginArray(KSJSONEncodeContext* const context, return addJSONData(context, "[", 1); } -int ksjson_beginObject(KSJSONEncodeContext* const context, - const char* const name) +int ksjson_beginObject(KSJSONEncodeContext *const context, const char *const name) { likely_if(context->containerLevel >= 0) { int result = ksjson_beginElement(context, name); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } } context->containerLevel++; @@ -524,12 +400,9 @@ int ksjson_beginObject(KSJSONEncodeContext* const context, return addJSONData(context, "{", 1); } -int ksjson_endContainer(KSJSONEncodeContext* const context) +int ksjson_endContainer(KSJSONEncodeContext *const context) { - unlikely_if(context->containerLevel <= 0) - { - return KSJSON_OK; - } + unlikely_if(context->containerLevel <= 0) { return KSJSON_OK; } bool isObject = context->isObject[context->containerLevel]; context->containerLevel--; @@ -538,26 +411,17 @@ int ksjson_endContainer(KSJSONEncodeContext* const context) unlikely_if(context->prettyPrint && !context->containerFirstEntry) { int result; - unlikely_if((result = addJSONData(context, "\n", 1)) != KSJSON_OK) - { - return result; - } - for(int i = 0; i < context->containerLevel; i++) - { - unlikely_if((result = addJSONData(context, " ", 4)) != KSJSON_OK) - { - return result; - } + unlikely_if((result = addJSONData(context, "\n", 1)) != KSJSON_OK) { return result; } + for (int i = 0; i < context->containerLevel; i++) { + unlikely_if((result = addJSONData(context, " ", 4)) != KSJSON_OK) { return result; } } } context->containerFirstEntry = false; return addJSONData(context, isObject ? "}" : "]", 1); } -void ksjson_beginEncode(KSJSONEncodeContext* const context, - bool prettyPrint, - KSJSONAddDataFunc addJSONDataFunc, - void* const userData) +void ksjson_beginEncode(KSJSONEncodeContext *const context, bool prettyPrint, KSJSONAddDataFunc addJSONDataFunc, + void *const userData) { memset(context, 0, sizeof(*context)); context->addJSONData = addJSONDataFunc; @@ -566,71 +430,59 @@ void ksjson_beginEncode(KSJSONEncodeContext* const context, context->containerFirstEntry = true; } -int ksjson_endEncode(KSJSONEncodeContext* const context) +int ksjson_endEncode(KSJSONEncodeContext *const context) { int result = KSJSON_OK; - while(context->containerLevel > 0) - { - unlikely_if((result = ksjson_endContainer(context)) != KSJSON_OK) - { - return result; - } + while (context->containerLevel > 0) { + unlikely_if((result = ksjson_endContainer(context)) != KSJSON_OK) { return result; } } return result; } - // ============================================================================ #pragma mark - Decode - // ============================================================================ #define INV 0x11111 -typedef struct -{ +typedef struct { /** Pointer to current work area in the buffer. */ - const char* bufferPtr; + const char *bufferPtr; /** Pointer to the end of the buffer. */ - const char* bufferEnd; + const char *bufferEnd; /** Pointer to a buffer for storing a decoded name. */ - char* nameBuffer; + char *nameBuffer; /** Length of the name buffer. */ int nameBufferLength; /** Pointer to a buffer for storing a decoded string. */ - char* stringBuffer; + char *stringBuffer; /** Length of the string buffer. */ int stringBufferLength; /** The callbacks to call while decoding. */ - KSJSONDecodeCallbacks* const callbacks; + KSJSONDecodeCallbacks *const callbacks; /** Data that was specified when calling ksjson_decode(). */ - void* userData; + void *userData; } KSJSONDecodeContext; /** Lookup table for converting hex values to integers. * INV (0x11111) is used to mark invalid characters so that any attempted * invalid nybble conversion is always > 0xffff. */ -static const unsigned int g_hexConversion[] = -{ - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, INV, INV, INV, INV, INV, INV, - INV, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, +static const unsigned int g_hexConversion[] = { + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, INV, INV, INV, INV, INV, INV, INV, 0xa, + 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, }; - /** Encode a UTF-16 character to UTF-8. The dest pointer gets incremented * by however many bytes were needed for the conversion (1-4). * @@ -640,7 +492,7 @@ static const unsigned int g_hexConversion[] = * * @return KSJSON_OK if the encoding was successful. */ -static int writeUTF8(unsigned int character, char** dst); +static int writeUTF8(unsigned int character, char **dst); /** Decode a string value. * @@ -652,7 +504,7 @@ static int writeUTF8(unsigned int character, char** dst); * * @return KSJSON_OK if successful. */ -static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBufferLength); +static int decodeString(KSJSONDecodeContext *context, char *dstBuffer, int dstBufferLength); /** Decode a JSON element. * @@ -662,20 +514,16 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu * * @return KSJSON_OK if successful. */ -static int decodeElement(const char* const name, - KSJSONDecodeContext* context); - +static int decodeElement(const char *const name, KSJSONDecodeContext *context); /** Skip past any whitespace. * * @param CONTEXT The decoding context. */ -#define SKIP_WHITESPACE(CONTEXT) \ -while(CONTEXT->bufferPtr < CONTEXT->bufferEnd && isspace(*CONTEXT->bufferPtr)) \ -{ \ - CONTEXT->bufferPtr++; \ -} - +#define SKIP_WHITESPACE(CONTEXT) \ + while (CONTEXT->bufferPtr < CONTEXT->bufferEnd && isspace(*CONTEXT->bufferPtr)) { \ + CONTEXT->bufferPtr++; \ + } /** Check if a character is valid for representing part of a floating point * number. @@ -686,34 +534,43 @@ while(CONTEXT->bufferPtr < CONTEXT->bufferEnd && isspace(*CONTEXT->bufferPtr)) \ */ static inline bool isFPChar(char ch) { - switch(ch) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '.': case 'e': case 'E': case '+': case '-': + switch (ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + case 'e': + case 'E': + case '+': + case '-': return true; default: return false; } } -static int writeUTF8(unsigned int character, char** dst) +static int writeUTF8(unsigned int character, char **dst) { likely_if(character <= 0x7f) { - **dst = (char) character; + **dst = (char)character; (*dst)++; return KSJSON_OK; } - if(character <= 0x7ff) - { + if (character <= 0x7ff) { (*dst)[0] = (char)(0xc0 | (character >> 6)); (*dst)[1] = (char)(0x80 | (character & 0x3f)); *dst += 2; return KSJSON_OK; } - if(character <= 0xffff) - { + if (character <= 0xffff) { (*dst)[0] = (char)(0xe0 | (character >> 12)); (*dst)[1] = (char)(0x80 | ((character >> 6) & 0x3f)); (*dst)[2] = (char)(0x80 | (character & 0x3f)); @@ -721,8 +578,7 @@ static int writeUTF8(unsigned int character, char** dst) return KSJSON_OK; } // RFC3629 restricts UTF-8 to end at 0x10ffff. - if(character <= 0x10ffff) - { + if (character <= 0x10ffff) { (*dst)[0] = (char)(0xf0 | (character >> 18)); (*dst)[1] = (char)(0x80 | ((character >> 12) & 0x3f)); (*dst)[2] = (char)(0x80 | ((character >> 6) & 0x3f)); @@ -736,7 +592,7 @@ static int writeUTF8(unsigned int character, char** dst) return KSJSON_ERROR_INVALID_CHARACTER; } -static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBufferLength) +static int decodeString(KSJSONDecodeContext *context, char *dstBuffer, int dstBufferLength) { *dstBuffer = '\0'; unlikely_if(*context->bufferPtr != '\"') @@ -745,11 +601,10 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu return KSJSON_ERROR_INVALID_CHARACTER; } - const char* src = context->bufferPtr + 1; + const char *src = context->bufferPtr + 1; bool fastCopy = true; - for(; src < context->bufferEnd && *src != '\"'; src++) - { + for (; src < context->bufferEnd && *src != '\"'; src++) { unlikely_if(*src == '\\') { fastCopy = false; @@ -761,11 +616,10 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - const char* srcEnd = src; + const char *srcEnd = src; src = context->bufferPtr + 1; int length = (int)(srcEnd - src); - if(length >= dstBufferLength) - { + if (length >= dstBufferLength) { KSLOG_DEBUG("String is too long"); return KSJSON_ERROR_DATA_TOO_LONG; } @@ -780,19 +634,14 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu return KSJSON_OK; } - char* dst = dstBuffer; + char *dst = dstBuffer; - for(; src < srcEnd; src++) - { - likely_if(*src != '\\') - { - *dst++ = *src; - } + for (; src < srcEnd; src++) { + likely_if(*src != '\\') { *dst++ = *src; } else { src++; - switch(*src) - { + switch (*src) { case '"': *dst++ = '\"'; continue; @@ -817,30 +666,24 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu case 'f': *dst++ = '\f'; continue; - case 'u': - { + case 'u': { unlikely_if(src + 5 > srcEnd) { KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - unsigned int accum = - g_hexConversion[src[1]] << 12 | - g_hexConversion[src[2]] << 8 | - g_hexConversion[src[3]] << 4 | - g_hexConversion[src[4]]; + unsigned int accum = g_hexConversion[src[1]] << 12 | g_hexConversion[src[2]] << 8 | + g_hexConversion[src[3]] << 4 | g_hexConversion[src[4]]; unlikely_if(accum > 0xffff) { - KSLOG_DEBUG("Invalid unicode sequence: %c%c%c%c", - src[1], src[2], src[3], src[4]); + KSLOG_DEBUG("Invalid unicode sequence: %c%c%c%c", src[1], src[2], src[3], src[4]); return KSJSON_ERROR_INVALID_CHARACTER; } // UTF-16 Trail surrogate on its own. unlikely_if(accum >= 0xdc00 && accum <= 0xdfff) { - KSLOG_DEBUG("Unexpected trail surrogate: 0x%04x", - accum); + KSLOG_DEBUG("Unexpected trail surrogate: 0x%04x", accum); return KSJSON_ERROR_INVALID_CHARACTER; } @@ -853,23 +696,17 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - unlikely_if(src[5] != '\\' || - src[6] != 'u') + unlikely_if(src[5] != '\\' || src[6] != 'u') { - KSLOG_DEBUG("Expected \"\\u\" but got: \"%c%c\"", - src[5], src[6]); + KSLOG_DEBUG("Expected \"\\u\" but got: \"%c%c\"", src[5], src[6]); return KSJSON_ERROR_INVALID_CHARACTER; } src += 6; - unsigned int accum2 = - g_hexConversion[src[1]] << 12 | - g_hexConversion[src[2]] << 8 | - g_hexConversion[src[3]] << 4 | - g_hexConversion[src[4]]; + unsigned int accum2 = g_hexConversion[src[1]] << 12 | g_hexConversion[src[2]] << 8 | + g_hexConversion[src[3]] << 4 | g_hexConversion[src[4]]; unlikely_if(accum2 < 0xdc00 || accum2 > 0xdfff) { - KSLOG_DEBUG("Invalid trail surrogate: 0x%04x", - accum2); + KSLOG_DEBUG("Invalid trail surrogate: 0x%04x", accum2); return KSJSON_ERROR_INVALID_CHARACTER; } // And combine 20 bit result. @@ -877,10 +714,7 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu } int result = writeUTF8(accum, &dst); - unlikely_if(result != KSJSON_OK) - { - return result; - } + unlikely_if(result != KSJSON_OK) { return result; } src += 4; continue; } @@ -895,7 +729,7 @@ static int decodeString(KSJSONDecodeContext* context, char* dstBuffer, int dstBu return KSJSON_OK; } -static int decodeElement(const char* const name, KSJSONDecodeContext* context) +static int decodeElement(const char *const name, KSJSONDecodeContext *context) { SKIP_WHITESPACE(context); unlikely_if(context->bufferPtr >= context->bufferEnd) @@ -907,20 +741,14 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) int sign = 1; int result; - switch(*context->bufferPtr) - { - case '[': - { + switch (*context->bufferPtr) { + case '[': { context->bufferPtr++; result = context->callbacks->onBeginArray(name, context->userData); unlikely_if(result != KSJSON_OK) return result; - while(context->bufferPtr < context->bufferEnd) - { + while (context->bufferPtr < context->bufferEnd) { SKIP_WHITESPACE(context); - unlikely_if(context->bufferPtr >= context->bufferEnd) - { - break; - } + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } unlikely_if(*context->bufferPtr == ']') { context->bufferPtr++; @@ -929,30 +757,19 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) result = decodeElement(NULL, context); unlikely_if(result != KSJSON_OK) return result; SKIP_WHITESPACE(context); - unlikely_if(context->bufferPtr >= context->bufferEnd) - { - break; - } - likely_if(*context->bufferPtr == ',') - { - context->bufferPtr++; - } + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } + likely_if(*context->bufferPtr == ',') { context->bufferPtr++; } } KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - case '{': - { + case '{': { context->bufferPtr++; result = context->callbacks->onBeginObject(name, context->userData); unlikely_if(result != KSJSON_OK) return result; - while(context->bufferPtr < context->bufferEnd) - { + while (context->bufferPtr < context->bufferEnd) { SKIP_WHITESPACE(context); - unlikely_if(context->bufferPtr >= context->bufferEnd) - { - break; - } + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } unlikely_if(*context->bufferPtr == '}') { context->bufferPtr++; @@ -961,10 +778,7 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) result = decodeString(context, context->nameBuffer, context->nameBufferLength); unlikely_if(result != KSJSON_OK) return result; SKIP_WHITESPACE(context); - unlikely_if(context->bufferPtr >= context->bufferEnd) - { - break; - } + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } unlikely_if(*context->bufferPtr != ':') { KSLOG_DEBUG("Expected ':' but got '%c'", *context->bufferPtr); @@ -975,77 +789,59 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) result = decodeElement(context->nameBuffer, context); unlikely_if(result != KSJSON_OK) return result; SKIP_WHITESPACE(context); - unlikely_if(context->bufferPtr >= context->bufferEnd) - { - break; - } - likely_if(*context->bufferPtr == ',') - { - context->bufferPtr++; - } + unlikely_if(context->bufferPtr >= context->bufferEnd) { break; } + likely_if(*context->bufferPtr == ',') { context->bufferPtr++; } } KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - case '\"': - { + case '\"': { result = decodeString(context, context->stringBuffer, context->stringBufferLength); unlikely_if(result != KSJSON_OK) return result; - result = context->callbacks->onStringElement(name, - context->stringBuffer, - context->userData); + result = context->callbacks->onStringElement(name, context->stringBuffer, context->userData); return result; } - case 'f': - { + case 'f': { unlikely_if(context->bufferEnd - context->bufferPtr < 5) { KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - unlikely_if(!(context->bufferPtr[1] == 'a' && - context->bufferPtr[2] == 'l' && - context->bufferPtr[3] == 's' && - context->bufferPtr[4] == 'e')) + unlikely_if(!(context->bufferPtr[1] == 'a' && context->bufferPtr[2] == 'l' && + context->bufferPtr[3] == 's' && context->bufferPtr[4] == 'e')) { - KSLOG_DEBUG("Expected \"false\" but got \"f%c%c%c%c\"", - context->bufferPtr[1], context->bufferPtr[2], context->bufferPtr[3], context->bufferPtr[4]); + KSLOG_DEBUG("Expected \"false\" but got \"f%c%c%c%c\"", context->bufferPtr[1], context->bufferPtr[2], + context->bufferPtr[3], context->bufferPtr[4]); return KSJSON_ERROR_INVALID_CHARACTER; } context->bufferPtr += 5; return context->callbacks->onBooleanElement(name, false, context->userData); } - case 't': - { + case 't': { unlikely_if(context->bufferEnd - context->bufferPtr < 4) { KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - unlikely_if(!(context->bufferPtr[1] == 'r' && - context->bufferPtr[2] == 'u' && - context->bufferPtr[3] == 'e')) + unlikely_if(!(context->bufferPtr[1] == 'r' && context->bufferPtr[2] == 'u' && context->bufferPtr[3] == 'e')) { - KSLOG_DEBUG("Expected \"true\" but got \"t%c%c%c\"", - context->bufferPtr[1], context->bufferPtr[2], context->bufferPtr[3]); + KSLOG_DEBUG("Expected \"true\" but got \"t%c%c%c\"", context->bufferPtr[1], context->bufferPtr[2], + context->bufferPtr[3]); return KSJSON_ERROR_INVALID_CHARACTER; } context->bufferPtr += 4; return context->callbacks->onBooleanElement(name, true, context->userData); } - case 'n': - { + case 'n': { unlikely_if(context->bufferEnd - context->bufferPtr < 4) { KSLOG_DEBUG("Premature end of data"); return KSJSON_ERROR_INCOMPLETE; } - unlikely_if(!(context->bufferPtr[1] == 'u' && - context->bufferPtr[2] == 'l' && - context->bufferPtr[3] == 'l')) + unlikely_if(!(context->bufferPtr[1] == 'u' && context->bufferPtr[2] == 'l' && context->bufferPtr[3] == 'l')) { - KSLOG_DEBUG("Expected \"null\" but got \"n%c%c%c\"", - context->bufferPtr[1], context->bufferPtr[2], context->bufferPtr[3]); + KSLOG_DEBUG("Expected \"null\" but got \"n%c%c%c\"", context->bufferPtr[1], context->bufferPtr[2], + context->bufferPtr[3]); return KSJSON_ERROR_INVALID_CHARACTER; } context->bufferPtr += 4; @@ -1055,31 +851,31 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) sign = -1; context->bufferPtr++; unlikely_if(!isdigit(*context->bufferPtr)) - { - KSLOG_DEBUG("Not a digit: '%c'", *context->bufferPtr); - return KSJSON_ERROR_INVALID_CHARACTER; - } + { + KSLOG_DEBUG("Not a digit: '%c'", *context->bufferPtr); + return KSJSON_ERROR_INVALID_CHARACTER; + } // Fall through - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { // Try integer conversion. uint64_t accum = 0; bool isOverflow = false; - const char* const start = context->bufferPtr; + const char *const start = context->bufferPtr; - for(; context->bufferPtr < context->bufferEnd && isdigit(*context->bufferPtr); context->bufferPtr++) - { - unlikely_if((isOverflow = accum > (ULLONG_MAX / 10))) - { - break; - } + for (; context->bufferPtr < context->bufferEnd && isdigit(*context->bufferPtr); context->bufferPtr++) { + unlikely_if((isOverflow = accum > (ULLONG_MAX / 10))) { break; } accum *= 10; uint64_t nextDigit = (uint64_t)(*context->bufferPtr - '0'); - unlikely_if((isOverflow = accum > (ULLONG_MAX - nextDigit))) - { - break; - } + unlikely_if((isOverflow = accum > (ULLONG_MAX - nextDigit))) { break; } accum += nextDigit; } @@ -1089,18 +885,15 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) return KSJSON_ERROR_INCOMPLETE; } - if(!isFPChar(*context->bufferPtr) && !isOverflow) - { - if(sign > 0 || accum <= ((uint64_t)LLONG_MAX + 1)) - { + if (!isFPChar(*context->bufferPtr) && !isOverflow) { + if (sign > 0 || accum <= ((uint64_t)LLONG_MAX + 1)) { int64_t signedAccum = (int64_t)accum; signedAccum *= sign; return context->callbacks->onIntegerElement(name, signedAccum, context->userData); } } - while(context->bufferPtr < context->bufferEnd && isFPChar(*context->bufferPtr)) - { + while (context->bufferPtr < context->bufferEnd && isFPChar(*context->bufferPtr)) { context->bufferPtr++; } @@ -1115,8 +908,7 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) // instead we create a temporary string. double value; int len = (int)(context->bufferPtr - start); - if(len >= context->stringBufferLength) - { + if (len >= context->stringBufferLength) { KSLOG_DEBUG("Number is too long."); return KSJSON_ERROR_DATA_TOO_LONG; } @@ -1133,72 +925,54 @@ static int decodeElement(const char* const name, KSJSONDecodeContext* context) return KSJSON_ERROR_INVALID_CHARACTER; } -int ksjson_decode(const char* const data, - int length, - char* stringBuffer, - int stringBufferLength, - KSJSONDecodeCallbacks* const callbacks, - void* const userData, - int* const errorOffset) +int ksjson_decode(const char *const data, int length, char *stringBuffer, int stringBufferLength, + KSJSONDecodeCallbacks *const callbacks, void *const userData, int *const errorOffset) { - char* nameBuffer = stringBuffer; + char *nameBuffer = stringBuffer; int nameBufferLength = stringBufferLength / 4; stringBuffer = nameBuffer + nameBufferLength; stringBufferLength -= nameBufferLength; - KSJSONDecodeContext context = - { - .bufferPtr = (char*)data, - .bufferEnd = (char*)data + length, - .nameBuffer = nameBuffer, - .nameBufferLength = nameBufferLength, - .stringBuffer = stringBuffer, - .stringBufferLength = (int)stringBufferLength, - .callbacks = callbacks, - .userData = userData - }; + KSJSONDecodeContext context = { .bufferPtr = (char *)data, + .bufferEnd = (char *)data + length, + .nameBuffer = nameBuffer, + .nameBufferLength = nameBufferLength, + .stringBuffer = stringBuffer, + .stringBufferLength = (int)stringBufferLength, + .callbacks = callbacks, + .userData = userData }; - const char* ptr = data; + const char *ptr = data; int result = decodeElement(NULL, &context); - likely_if(result == KSJSON_OK) - { - result = callbacks->onEndData(userData); - } + likely_if(result == KSJSON_OK) { result = callbacks->onEndData(userData); } - unlikely_if(result != KSJSON_OK && errorOffset != NULL) - { - *errorOffset = (int)(ptr - data); - } + unlikely_if(result != KSJSON_OK && errorOffset != NULL) { *errorOffset = (int)(ptr - data); } return result; } struct JSONFromFileContext; -typedef void (*UpdateDecoderCallback)(struct JSONFromFileContext* context); +typedef void (*UpdateDecoderCallback)(struct JSONFromFileContext *context); -typedef struct JSONFromFileContext -{ - KSJSONEncodeContext* encodeContext; - KSJSONDecodeContext* decodeContext; - char* bufferStart; - const char* sourceFilename; +typedef struct JSONFromFileContext { + KSJSONEncodeContext *encodeContext; + KSJSONDecodeContext *decodeContext; + char *bufferStart; + const char *sourceFilename; int fd; bool isEOF; bool closeLastContainer; UpdateDecoderCallback updateDecoderCallback; } JSONFromFileContext; -static void updateDecoder_doNothing(__unused struct JSONFromFileContext* context) -{ - -} +static void updateDecoder_doNothing(__unused struct JSONFromFileContext *context) {} -static void updateDecoder_readFile(struct JSONFromFileContext* context) +static void updateDecoder_readFile(struct JSONFromFileContext *context) { likely_if(!context->isEOF) { - const char* end = context->decodeContext->bufferEnd; - char* start = context->bufferStart; - const char* ptr = context->decodeContext->bufferPtr; + const char *end = context->decodeContext->bufferEnd; + char *start = context->bufferStart; + const char *ptr = context->decodeContext->bufferPtr; int bufferLength = (int)(end - start); int remainingLength = (int)(end - ptr); unlikely_if(remainingLength < bufferLength / 2) @@ -1206,11 +980,10 @@ static void updateDecoder_readFile(struct JSONFromFileContext* context) int fillLength = bufferLength - remainingLength; memcpy(start, ptr, remainingLength); context->decodeContext->bufferPtr = start; - int bytesRead = (int)read(context->fd, start+remainingLength, (unsigned)fillLength); + int bytesRead = (int)read(context->fd, start + remainingLength, (unsigned)fillLength); unlikely_if(bytesRead < fillLength) { - if(bytesRead < 0) - { + if (bytesRead < 0) { KSLOG_ERROR("Error reading file %s: %s", context->sourceFilename, strerror(errno)); } context->isEOF = true; @@ -1219,97 +992,79 @@ static void updateDecoder_readFile(struct JSONFromFileContext* context) } } -static int addJSONFromFile_onBooleanElement(const char* const name, - const bool value, - void* const userData) +static int addJSONFromFile_onBooleanElement(const char *const name, const bool value, void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = ksjson_addBooleanElement(context->encodeContext, name, value); context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onFloatingPointElement(const char* const name, - const double value, - void* const userData) +static int addJSONFromFile_onFloatingPointElement(const char *const name, const double value, void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = ksjson_addFloatingPointElement(context->encodeContext, name, value); context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onIntegerElement(const char* const name, - const int64_t value, - void* const userData) +static int addJSONFromFile_onIntegerElement(const char *const name, const int64_t value, void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = ksjson_addIntegerElement(context->encodeContext, name, value); context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onNullElement(const char* const name, - void* const userData) +static int addJSONFromFile_onNullElement(const char *const name, void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = ksjson_addNullElement(context->encodeContext, name); context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onStringElement(const char* const name, - const char* const value, - void* const userData) +static int addJSONFromFile_onStringElement(const char *const name, const char *const value, void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = ksjson_addStringElement(context->encodeContext, name, value, (int)strlen(value)); context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onBeginObject(const char* const name, - void* const userData) +static int addJSONFromFile_onBeginObject(const char *const name, void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = ksjson_beginObject(context->encodeContext, name); context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onBeginArray(const char* const name, - void* const userData) +static int addJSONFromFile_onBeginArray(const char *const name, void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = ksjson_beginArray(context->encodeContext, name); context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onEndContainer(void* const userData) +static int addJSONFromFile_onEndContainer(void *const userData) { - JSONFromFileContext* context = (JSONFromFileContext*)userData; + JSONFromFileContext *context = (JSONFromFileContext *)userData; int result = KSJSON_OK; - if(context->closeLastContainer || context->encodeContext->containerLevel > 2) - { + if (context->closeLastContainer || context->encodeContext->containerLevel > 2) { result = ksjson_endContainer(context->encodeContext); } context->updateDecoderCallback(context); return result; } -static int addJSONFromFile_onEndData(__unused void* const userData) -{ - return KSJSON_OK; -} +static int addJSONFromFile_onEndData(__unused void *const userData) { return KSJSON_OK; } -int ksjson_addJSONFromFile(KSJSONEncodeContext* const encodeContext, - const char* restrict const name, - const char* restrict const filename, - const bool closeLastContainer) +int ksjson_addJSONFromFile(KSJSONEncodeContext *const encodeContext, const char *restrict const name, + const char *restrict const filename, const bool closeLastContainer) { - KSJSONDecodeCallbacks callbacks = - { + KSJSONDecodeCallbacks callbacks = { .onBeginArray = addJSONFromFile_onBeginArray, .onBeginObject = addJSONFromFile_onBeginObject, .onBooleanElement = addJSONFromFile_onBooleanElement, @@ -1320,11 +1075,10 @@ int ksjson_addJSONFromFile(KSJSONEncodeContext* const encodeContext, .onNullElement = addJSONFromFile_onNullElement, .onStringElement = addJSONFromFile_onStringElement, }; - char nameBuffer[100] = {0}; - char stringBuffer[500] = {0}; - char fileBuffer[1000] = {0}; - KSJSONDecodeContext decodeContext = - { + char nameBuffer[100] = { 0 }; + char stringBuffer[500] = { 0 }; + char fileBuffer[1000] = { 0 }; + KSJSONDecodeContext decodeContext = { .bufferPtr = fileBuffer, .bufferEnd = fileBuffer + sizeof(fileBuffer), .nameBuffer = nameBuffer, @@ -1336,8 +1090,7 @@ int ksjson_addJSONFromFile(KSJSONEncodeContext* const encodeContext, }; int fd = open(filename, O_RDONLY); - JSONFromFileContext jsonContext = - { + JSONFromFileContext jsonContext = { .encodeContext = encodeContext, .decodeContext = &decodeContext, .bufferStart = fileBuffer, @@ -1356,22 +1109,17 @@ int ksjson_addJSONFromFile(KSJSONEncodeContext* const encodeContext, int result = decodeElement(name, &decodeContext); close(fd); - while(closeLastContainer && encodeContext->containerLevel > containerLevel) - { + while (closeLastContainer && encodeContext->containerLevel > containerLevel) { ksjson_endContainer(encodeContext); } return result; } -int ksjson_addJSONElement(KSJSONEncodeContext* const encodeContext, - const char* restrict const name, - const char* restrict const jsonData, - const int jsonDataLength, - const bool closeLastContainer) +int ksjson_addJSONElement(KSJSONEncodeContext *const encodeContext, const char *restrict const name, + const char *restrict const jsonData, const int jsonDataLength, const bool closeLastContainer) { - KSJSONDecodeCallbacks callbacks = - { + KSJSONDecodeCallbacks callbacks = { .onBeginArray = addJSONFromFile_onBeginArray, .onBeginObject = addJSONFromFile_onBeginObject, .onBooleanElement = addJSONFromFile_onBooleanElement, @@ -1382,10 +1130,9 @@ int ksjson_addJSONElement(KSJSONEncodeContext* const encodeContext, .onNullElement = addJSONFromFile_onNullElement, .onStringElement = addJSONFromFile_onStringElement, }; - char nameBuffer[100] = {0}; - char stringBuffer[5000] = {0}; - KSJSONDecodeContext decodeContext = - { + char nameBuffer[100] = { 0 }; + char stringBuffer[5000] = { 0 }; + KSJSONDecodeContext decodeContext = { .bufferPtr = jsonData, .bufferEnd = jsonData + jsonDataLength, .nameBuffer = nameBuffer, @@ -1395,12 +1142,11 @@ int ksjson_addJSONElement(KSJSONEncodeContext* const encodeContext, .callbacks = &callbacks, .userData = NULL, }; - - JSONFromFileContext jsonContext = - { + + JSONFromFileContext jsonContext = { .encodeContext = encodeContext, .decodeContext = &decodeContext, - .bufferStart = (char*)jsonData, + .bufferStart = (char *)jsonData, .sourceFilename = NULL, .fd = 0, .closeLastContainer = closeLastContainer, @@ -1409,12 +1155,11 @@ int ksjson_addJSONElement(KSJSONEncodeContext* const encodeContext, }; decodeContext.userData = &jsonContext; int containerLevel = encodeContext->containerLevel; - + int result = decodeElement(name, &decodeContext); - while(closeLastContainer && encodeContext->containerLevel > containerLevel) - { + while (closeLastContainer && encodeContext->containerLevel > containerLevel) { ksjson_endContainer(encodeContext); } - + return result; } diff --git a/Sources/KSCrashRecordingCore/KSJSONCodecObjC.m b/Sources/KSCrashRecordingCore/KSJSONCodecObjC.m index 316061bbd..b3837d09a 100644 --- a/Sources/KSCrashRecordingCore/KSJSONCodecObjC.m +++ b/Sources/KSCrashRecordingCore/KSJSONCodecObjC.m @@ -24,48 +24,45 @@ // THE SOFTWARE. // - #import "KSJSONCodecObjC.h" +#import "KSDate.h" #import "KSJSONCodec.h" #import "NSError+SimpleConstructor.h" -#import "KSDate.h" - @interface KSJSONCodec () #pragma mark Properties /** Callbacks from the C library */ -@property(nonatomic,readwrite,assign) KSJSONDecodeCallbacks* callbacks; +@property(nonatomic, readwrite, assign) KSJSONDecodeCallbacks *callbacks; /** Stack of arrays/objects as the decoded content is built */ -@property(nonatomic,readwrite,retain) NSMutableArray* containerStack; +@property(nonatomic, readwrite, retain) NSMutableArray *containerStack; /** Current array or object being decoded (weak ref) */ -@property(nonatomic,readwrite,assign) id currentContainer; +@property(nonatomic, readwrite, assign) id currentContainer; /** Top level array or object in the decoded tree */ -@property(nonatomic,readwrite,retain) id topLevelContainer; +@property(nonatomic, readwrite, retain) id topLevelContainer; /** Data that has been serialized into JSON form */ -@property(nonatomic,readwrite,retain) NSMutableData* serializedData; +@property(nonatomic, readwrite, retain) NSMutableData *serializedData; /** Any error that has occurred */ -@property(nonatomic,readwrite,retain) NSError* error; +@property(nonatomic, readwrite, retain) NSError *error; /** If true, pretty print while encoding */ -@property(nonatomic,readwrite,assign) bool prettyPrint; +@property(nonatomic, readwrite, assign) bool prettyPrint; /** If true, sort object keys while encoding */ -@property(nonatomic,readwrite,assign) bool sorted; +@property(nonatomic, readwrite, assign) bool sorted; /** If true, don't store nulls in arrays */ -@property(nonatomic,readwrite,assign) bool ignoreNullsInArrays; +@property(nonatomic, readwrite, assign) bool ignoreNullsInArrays; /** If true, don't store nulls in objects */ -@property(nonatomic,readwrite,assign) bool ignoreNullsInObjects; - +@property(nonatomic, readwrite, assign) bool ignoreNullsInObjects; #pragma mark Constructors @@ -77,8 +74,8 @@ @interface KSJSONCodec () * * @return A new codec. */ -+ (KSJSONCodec*) codecWithEncodeOptions:(KSJSONEncodeOption) encodeOptions - decodeOptions:(KSJSONDecodeOption) decodeOptions; ++ (KSJSONCodec *)codecWithEncodeOptions:(KSJSONEncodeOption)encodeOptions + decodeOptions:(KSJSONDecodeOption)decodeOptions; /** Initializer. * @@ -88,16 +85,13 @@ + (KSJSONCodec*) codecWithEncodeOptions:(KSJSONEncodeOption) encodeOptions * * @return The initialized codec. */ -- (id) initWithEncodeOptions:(KSJSONEncodeOption) encodeOptions - decodeOptions:(KSJSONDecodeOption) decodeOptions; +- (id)initWithEncodeOptions:(KSJSONEncodeOption)encodeOptions decodeOptions:(KSJSONDecodeOption)decodeOptions; @end - #pragma mark - #pragma mark - - @implementation KSJSONCodec #pragma mark Properties @@ -115,17 +109,15 @@ @implementation KSJSONCodec #pragma mark Constructors/Destructor -+ (KSJSONCodec*) codecWithEncodeOptions:(KSJSONEncodeOption) encodeOptions - decodeOptions:(KSJSONDecodeOption) decodeOptions ++ (KSJSONCodec *)codecWithEncodeOptions:(KSJSONEncodeOption)encodeOptions + decodeOptions:(KSJSONDecodeOption)decodeOptions { return [[self alloc] initWithEncodeOptions:encodeOptions decodeOptions:decodeOptions]; } -- (id) initWithEncodeOptions:(KSJSONEncodeOption) encodeOptions - decodeOptions:(KSJSONDecodeOption) decodeOptions +- (id)initWithEncodeOptions:(KSJSONEncodeOption)encodeOptions decodeOptions:(KSJSONDecodeOption)decodeOptions { - if((self = [super init])) - { + if ((self = [super init])) { self.containerStack = [NSMutableArray array]; self.callbacks = malloc(sizeof(*self.callbacks)); self.callbacks->onBeginArray = onBeginArray; @@ -145,17 +137,16 @@ - (id) initWithEncodeOptions:(KSJSONEncodeOption) encodeOptions return self; } -- (void) dealloc +- (void)dealloc { free(self.callbacks); } #pragma mark Utility -static inline NSString* stringFromCString(const char* const string) +static inline NSString *stringFromCString(const char *const string) { - if(string == NULL) - { + if (string == NULL) { return nil; } return [NSString stringWithCString:string encoding:NSUTF8StringEncoding]; @@ -163,40 +154,30 @@ - (void) dealloc #pragma mark Callbacks -static int onElement(KSJSONCodec* codec, NSString* name, id element) +static int onElement(KSJSONCodec *codec, NSString *name, id element) { - if(codec->_currentContainer == nil) - { + if (codec->_currentContainer == nil) { codec.error = [NSError errorWithDomain:@"KSJSONCodecObjC" code:0 - description:@"Type %@ not allowed as top level container", - [element class]]; + description:@"Type %@ not allowed as top level container", [element class]]; return KSJSON_ERROR_INVALID_DATA; } - if([codec->_currentContainer isKindOfClass:[NSMutableDictionary class]]) - { - [(NSMutableDictionary*)codec->_currentContainer setValue:element - forKey:name]; - } - else - { - [(NSMutableArray*)codec->_currentContainer addObject:element]; + if ([codec->_currentContainer isKindOfClass:[NSMutableDictionary class]]) { + [(NSMutableDictionary *)codec->_currentContainer setValue:element forKey:name]; + } else { + [(NSMutableArray *)codec->_currentContainer addObject:element]; } return KSJSON_OK; } -static int onBeginContainer(KSJSONCodec* codec, NSString* name, id container) +static int onBeginContainer(KSJSONCodec *codec, NSString *name, id container) { - if(codec->_topLevelContainer == nil) - { + if (codec->_topLevelContainer == nil) { codec->_topLevelContainer = container; - } - else - { + } else { int result = onElement(codec, name, container); - if(result != KSJSON_OK) - { + if (result != KSJSON_OK) { return result; } } @@ -205,79 +186,72 @@ static int onBeginContainer(KSJSONCodec* codec, NSString* name, id container) return KSJSON_OK; } -static int onBooleanElement(const char* const cName, const bool value, void* const userData) +static int onBooleanElement(const char *const cName, const bool value, void *const userData) { - NSString* name = stringFromCString(cName); + NSString *name = stringFromCString(cName); id element = [NSNumber numberWithBool:value]; - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; return onElement(codec, name, element); } -static int onFloatingPointElement(const char* const cName, const double value, void* const userData) +static int onFloatingPointElement(const char *const cName, const double value, void *const userData) { - NSString* name = stringFromCString(cName); + NSString *name = stringFromCString(cName); id element = [NSNumber numberWithDouble:value]; - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; return onElement(codec, name, element); } -static int onIntegerElement(const char* const cName, - const int64_t value, - void* const userData) +static int onIntegerElement(const char *const cName, const int64_t value, void *const userData) { - NSString* name = stringFromCString(cName); + NSString *name = stringFromCString(cName); id element = [NSNumber numberWithLongLong:value]; - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; return onElement(codec, name, element); } -static int onNullElement(const char* const cName, void* const userData) +static int onNullElement(const char *const cName, void *const userData) { - NSString* name = stringFromCString(cName); - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; - - if((codec->_ignoreNullsInArrays && - [codec->_currentContainer isKindOfClass:[NSArray class]]) || - (codec->_ignoreNullsInObjects && - [codec->_currentContainer isKindOfClass:[NSDictionary class]])) - { + NSString *name = stringFromCString(cName); + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; + + if ((codec->_ignoreNullsInArrays && [codec->_currentContainer isKindOfClass:[NSArray class]]) || + (codec->_ignoreNullsInObjects && [codec->_currentContainer isKindOfClass:[NSDictionary class]])) { return KSJSON_OK; } return onElement(codec, name, [NSNull null]); } -static int onStringElement(const char* const cName, const char* const value, void* const userData) +static int onStringElement(const char *const cName, const char *const value, void *const userData) { - NSString* name = stringFromCString(cName); - id element = [NSString stringWithCString:value - encoding:NSUTF8StringEncoding]; - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; + NSString *name = stringFromCString(cName); + id element = [NSString stringWithCString:value encoding:NSUTF8StringEncoding]; + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; return onElement(codec, name, element); } -static int onBeginObject(const char* const cName, void* const userData) +static int onBeginObject(const char *const cName, void *const userData) { - NSString* name = stringFromCString(cName); + NSString *name = stringFromCString(cName); id container = [NSMutableDictionary dictionary]; - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; return onBeginContainer(codec, name, container); } -static int onBeginArray(const char* const cName, void* const userData) +static int onBeginArray(const char *const cName, void *const userData) { - NSString* name = stringFromCString(cName); + NSString *name = stringFromCString(cName); id container = [NSMutableArray array]; - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; return onBeginContainer(codec, name, container); } -static int onEndContainer(void* const userData) +static int onEndContainer(void *const userData) { - KSJSONCodec* codec = (__bridge KSJSONCodec*)userData; + KSJSONCodec *codec = (__bridge KSJSONCodec *)userData; - if([codec->_containerStack count] == 0) - { + if ([codec->_containerStack count] == 0) { codec.error = [NSError errorWithDomain:@"KSJSONCodecObjC" code:0 description:@"Already at the top level; no container left to end"]; @@ -285,39 +259,31 @@ static int onEndContainer(void* const userData) } [codec->_containerStack removeLastObject]; NSUInteger count = [codec->_containerStack count]; - if(count > 0) - { + if (count > 0) { codec->_currentContainer = [codec->_containerStack objectAtIndex:count - 1]; - } - else - { + } else { codec->_currentContainer = nil; } return KSJSON_OK; } -static int onEndData(__unused void* const userData) -{ - return KSJSON_OK; -} +static int onEndData(__unused void *const userData) { return KSJSON_OK; } -static int addJSONData(const char* const bytes, const int length, void* const userData) +static int addJSONData(const char *const bytes, const int length, void *const userData) { - NSMutableData* data = (__bridge NSMutableData*)userData; + NSMutableData *data = (__bridge NSMutableData *)userData; [data appendBytes:bytes length:(unsigned)length]; return KSJSON_OK; } -static int encodeObject(KSJSONCodec* codec, id object, NSString* name, KSJSONEncodeContext* context) +static int encodeObject(KSJSONCodec *codec, id object, NSString *name, KSJSONEncodeContext *context) { int result; - const char* cName = [name UTF8String]; - if([object isKindOfClass:[NSString class]]) - { - NSData* data = [object dataUsingEncoding:NSUTF8StringEncoding]; + const char *cName = [name UTF8String]; + if ([object isKindOfClass:[NSString class]]) { + NSData *data = [object dataUsingEncoding:NSUTF8StringEncoding]; result = ksjson_addStringElement(context, cName, data.bytes, (int)data.length); - if(result == KSJSON_ERROR_INVALID_CHARACTER) - { + if (result == KSJSON_ERROR_INVALID_CHARACTER) { codec.error = [NSError errorWithDomain:@"KSJSONCodecObjC" code:0 description:@"Invalid character in %@", object]; @@ -325,10 +291,8 @@ static int encodeObject(KSJSONCodec* codec, id object, NSString* name, KSJSONEnc return result; } - if([object isKindOfClass:[NSNumber class]]) - { - switch (CFNumberGetType((__bridge CFNumberRef)object)) - { + if ([object isKindOfClass:[NSNumber class]]) { + switch (CFNumberGetType((__bridge CFNumberRef)object)) { case kCFNumberFloat32Type: case kCFNumberFloat64Type: case kCFNumberFloatType: @@ -342,67 +306,52 @@ static int encodeObject(KSJSONCodec* codec, id object, NSString* name, KSJSONEnc } } - if([object isKindOfClass:[NSArray class]]) - { - if((result = ksjson_beginArray(context, cName)) != KSJSON_OK) - { + if ([object isKindOfClass:[NSArray class]]) { + if ((result = ksjson_beginArray(context, cName)) != KSJSON_OK) { return result; } - for(id subObject in object) - { - if((result = encodeObject(codec, subObject, NULL, context)) != KSJSON_OK) - { + for (id subObject in object) { + if ((result = encodeObject(codec, subObject, NULL, context)) != KSJSON_OK) { return result; } } return ksjson_endContainer(context); } - if([object isKindOfClass:[NSDictionary class]]) - { - if((result = ksjson_beginObject(context, cName)) != KSJSON_OK) - { + if ([object isKindOfClass:[NSDictionary class]]) { + if ((result = ksjson_beginObject(context, cName)) != KSJSON_OK) { return result; } - NSArray* keys = [(NSDictionary*)object allKeys]; - if(codec->_sorted) - { + NSArray *keys = [(NSDictionary *)object allKeys]; + if (codec->_sorted) { keys = [keys sortedArrayUsingSelector:@selector(compare:)]; } - for(id key in keys) - { - if([key isKindOfClass:[NSString class]] == NO) - { - codec.error = [NSError errorWithDomain:@"KSJSONCodecObjC" - code:0 - description:@"Invalid key: %@", key]; + for (id key in keys) { + if ([key isKindOfClass:[NSString class]] == NO) { + codec.error = [NSError errorWithDomain:@"KSJSONCodecObjC" code:0 description:@"Invalid key: %@", key]; return KSJSON_ERROR_INVALID_DATA; } - if((result = encodeObject(codec, [object valueForKey:key], key, context)) != KSJSON_OK) - { + if ((result = encodeObject(codec, [object valueForKey:key], key, context)) != KSJSON_OK) { return result; } } return ksjson_endContainer(context); } - if([object isKindOfClass:[NSNull class]]) - { + if ([object isKindOfClass:[NSNull class]]) { return ksjson_addNullElement(context, cName); } - if([object isKindOfClass:[NSDate class]]) - { + if ([object isKindOfClass:[NSDate class]]) { char string[21]; - time_t timestamp = (time_t)((NSDate*)object).timeIntervalSince1970; + time_t timestamp = (time_t)((NSDate *)object).timeIntervalSince1970; ksdate_utcStringFromTimestamp(timestamp, string); - NSData* data = [NSData dataWithBytes:string length:strnlen(string, 20)]; + NSData *data = [NSData dataWithBytes:string length:strnlen(string, 20)]; return ksjson_addStringElement(context, cName, data.bytes, (int)data.length); } - if([object isKindOfClass:[NSData class]]) - { - NSData* data = (NSData*)object; + if ([object isKindOfClass:[NSData class]]) { + NSData *data = (NSData *)object; return ksjson_addDataElement(context, cName, data.bytes, (int)data.length); } @@ -412,59 +361,39 @@ static int encodeObject(KSJSONCodec* codec, id object, NSString* name, KSJSONEnc return KSJSON_ERROR_INVALID_DATA; } - #pragma mark Public API -+ (NSData*) encode:(id) object - options:(KSJSONEncodeOption) encodeOptions - error:(NSError* __autoreleasing *) error ++ (NSData *)encode:(id)object options:(KSJSONEncodeOption)encodeOptions error:(NSError *__autoreleasing *)error { - NSMutableData* data = [NSMutableData data]; + NSMutableData *data = [NSMutableData data]; KSJSONEncodeContext JSONContext; - ksjson_beginEncode(&JSONContext, - encodeOptions & KSJSONEncodeOptionPretty, - addJSONData, - (__bridge void*)data); - KSJSONCodec* codec = [self codecWithEncodeOptions:encodeOptions - decodeOptions:KSJSONDecodeOptionNone]; + ksjson_beginEncode(&JSONContext, encodeOptions & KSJSONEncodeOptionPretty, addJSONData, (__bridge void *)data); + KSJSONCodec *codec = [self codecWithEncodeOptions:encodeOptions decodeOptions:KSJSONDecodeOptionNone]; int result = encodeObject(codec, object, NULL, &JSONContext); - if(error != nil) - { + if (error != nil) { *error = codec.error; } return result == KSJSON_OK ? data : nil; } -+ (id) decode:(NSData*) JSONData - options:(KSJSONDecodeOption) decodeOptions - error:(NSError* __autoreleasing *) error ++ (id)decode:(NSData *)JSONData options:(KSJSONDecodeOption)decodeOptions error:(NSError *__autoreleasing *)error { - KSJSONCodec* codec = [self codecWithEncodeOptions:0 - decodeOptions:decodeOptions]; - NSMutableData* stringData = [NSMutableData dataWithLength:10001]; + KSJSONCodec *codec = [self codecWithEncodeOptions:0 decodeOptions:decodeOptions]; + NSMutableData *stringData = [NSMutableData dataWithLength:10001]; int errorOffset; - int result = ksjson_decode(JSONData.bytes, - (int)JSONData.length, - stringData.mutableBytes, - (int)stringData.length, - codec.callbacks, - (__bridge void*)codec, &errorOffset); - if(result != KSJSON_OK && codec.error == nil) - { + int result = ksjson_decode(JSONData.bytes, (int)JSONData.length, stringData.mutableBytes, (int)stringData.length, + codec.callbacks, (__bridge void *)codec, &errorOffset); + if (result != KSJSON_OK && codec.error == nil) { codec.error = [NSError errorWithDomain:@"KSJSONCodecObjC" code:0 - description:@"%s (offset %d)", - ksjson_stringForError(result), - errorOffset]; + description:@"%s (offset %d)", ksjson_stringForError(result), errorOffset]; } - if(error != nil) - { + if (error != nil) { *error = codec.error; } - if(result != KSJSON_OK && !(decodeOptions & KSJSONDecodeOptionKeepPartialObject)) - { + if (result != KSJSON_OK && !(decodeOptions & KSJSONDecodeOptionKeepPartialObject)) { return nil; } return codec.topLevelContainer; diff --git a/Sources/KSCrashRecordingCore/KSLogger.c b/Sources/KSCrashRecordingCore/KSLogger.c index ee901ae6b..c91f8bd33 100644 --- a/Sources/KSCrashRecordingCore/KSLogger.c +++ b/Sources/KSCrashRecordingCore/KSLogger.c @@ -24,8 +24,8 @@ // THE SOFTWARE. // - #include "KSLogger.h" + #include "KSSystemCapabilities.h" // =========================================================================== @@ -39,11 +39,9 @@ #include #include - // Compiler hints for "if" statements -#define likely_if(x) if(__builtin_expect(x,1)) -#define unlikely_if(x) if(__builtin_expect(x,0)) - +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) /** The buffer size to use when writing log entries. * @@ -65,7 +63,7 @@ static char g_logFilename[1024]; * * @param fmt The format string, followed by its arguments. */ -static void writeFmtToLog(const char* fmt, ...); +static void writeFmtToLog(const char *fmt, ...); /** Write a formatted string to the log using a vararg list. * @@ -73,23 +71,22 @@ static void writeFmtToLog(const char* fmt, ...); * * @param args The variable arguments. */ -static void writeFmtArgsToLog(const char* fmt, va_list args); +static void writeFmtArgsToLog(const char *fmt, va_list args); /** Flush the log stream. */ static void flushLog(void); - -static inline const char* lastPathEntry(const char* const path) +static inline const char *lastPathEntry(const char *const path) { - const char* lastFile = strrchr(path, '/'); + const char *lastFile = strrchr(path, '/'); return lastFile == 0 ? path : lastFile + 1; } -static inline void writeFmtToLog(const char* fmt, ...) +static inline void writeFmtToLog(const char *fmt, ...) { va_list args; - va_start(args,fmt); + va_start(args, fmt); writeFmtArgsToLog(fmt, args); va_end(args); } @@ -99,20 +96,14 @@ static inline void writeFmtToLog(const char* fmt, ...) /** The file descriptor where log entries get written. */ static int g_fd = -1; - -static void writeToLog(const char* const str) +static void writeToLog(const char *const str) { - if(g_fd >= 0) - { + if (g_fd >= 0) { int bytesToWrite = (int)strlen(str); - const char* pos = str; - while(bytesToWrite > 0) - { + const char *pos = str; + while (bytesToWrite > 0) { int bytesWritten = (int)write(g_fd, pos, (unsigned)bytesToWrite); - unlikely_if(bytesWritten == -1) - { - break; - } + unlikely_if(bytesWritten == -1) { break; } bytesToWrite -= bytesWritten; pos += bytesWritten; } @@ -120,12 +111,9 @@ static void writeToLog(const char* const str) write(STDOUT_FILENO, str, strlen(str)); } -static inline void writeFmtArgsToLog(const char* fmt, va_list args) +static inline void writeFmtArgsToLog(const char *fmt, va_list args) { - unlikely_if(fmt == NULL) - { - writeToLog("(null)"); - } + unlikely_if(fmt == NULL) { writeToLog("(null)"); } else { char buffer[KSLOGGER_CBufferSize]; @@ -141,21 +129,18 @@ static inline void flushLog(void) static inline void setLogFD(int fd) { - if(g_fd >= 0 && g_fd != STDOUT_FILENO && g_fd != STDERR_FILENO && g_fd != STDIN_FILENO) - { + if (g_fd >= 0 && g_fd != STDOUT_FILENO && g_fd != STDERR_FILENO && g_fd != STDIN_FILENO) { close(g_fd); } g_fd = fd; } -bool kslog_setLogFilename(const char* filename, bool overwrite) +bool kslog_setLogFilename(const char *filename, bool overwrite) { static int fd = -1; - if(filename != NULL) - { + if (filename != NULL) { int openMask = O_WRONLY | O_CREAT; - if(overwrite) - { + if (overwrite) { openMask |= O_TRUNC; } fd = open(filename, openMask, 0644); @@ -164,66 +149,53 @@ bool kslog_setLogFilename(const char* filename, bool overwrite) writeFmtToLog("KSLogger: Could not open %s: %s", filename, strerror(errno)); return false; } - if(filename != g_logFilename) - { + if (filename != g_logFilename) { strncpy(g_logFilename, filename, sizeof(g_logFilename)); } } - + setLogFD(fd); return true; } -#else // if KSLogger_CBufferSize <= 0 +#else // if KSLogger_CBufferSize <= 0 -static FILE* g_file = NULL; +static FILE *g_file = NULL; -static inline void setLogFD(FILE* file) +static inline void setLogFD(FILE *file) { - if(g_file != NULL && g_file != stdout && g_file != stderr && g_file != stdin) - { + if (g_file != NULL && g_file != stdout && g_file != stderr && g_file != stdin) { fclose(g_file); } g_file = file; } -void writeToLog(const char* const str) +void writeToLog(const char *const str) { - if(g_file != NULL) - { + if (g_file != NULL) { fprintf(g_file, "%s", str); } fprintf(stdout, "%s", str); } -static inline void writeFmtArgsToLog(const char* fmt, va_list args) +static inline void writeFmtArgsToLog(const char *fmt, va_list args) { - unlikely_if(g_file == NULL) - { - g_file = stdout; - } - - if(fmt == NULL) - { + unlikely_if(g_file == NULL) { g_file = stdout; } + + if (fmt == NULL) { writeToLog("(null)"); - } - else - { + } else { vfprintf(g_file, fmt, args); } } -static inline void flushLog(void) -{ - fflush(g_file); -} +static inline void flushLog(void) { fflush(g_file); } -bool kslog_setLogFilename(const char* filename, bool overwrite) +bool kslog_setLogFilename(const char *filename, bool overwrite) { - static FILE* file = NULL; - FILE* oldFile = file; - if(filename != NULL) - { + static FILE *file = NULL; + FILE *oldFile = file; + if (filename != NULL) { file = fopen(filename, overwrite ? "wb" : "ab"); unlikely_if(file == NULL) { @@ -231,13 +203,11 @@ bool kslog_setLogFilename(const char* filename, bool overwrite) return false; } } - if(filename != g_logFilename) - { + if (filename != g_logFilename) { strncpy(g_logFilename, filename, sizeof(g_logFilename)); } - if(oldFile != NULL) - { + if (oldFile != NULL) { fclose(oldFile); } @@ -247,42 +217,34 @@ bool kslog_setLogFilename(const char* filename, bool overwrite) #endif -bool kslog_clearLogFile(void) -{ - return kslog_setLogFilename(g_logFilename, true); -} - +bool kslog_clearLogFile(void) { return kslog_setLogFilename(g_logFilename, true); } // =========================================================================== #pragma mark - C - // =========================================================================== -void i_kslog_logCBasic(const char* const fmt, ...) +void i_kslog_logCBasic(const char *const fmt, ...) { va_list args; - va_start(args,fmt); + va_start(args, fmt); writeFmtArgsToLog(fmt, args); va_end(args); writeToLog("\n"); flushLog(); } -void i_kslog_logC(const char* const level, - const char* const file, - const int line, - const char* const function, - const char* const fmt, ...) +void i_kslog_logC(const char *const level, const char *const file, const int line, const char *const function, + const char *const fmt, ...) { writeFmtToLog("%s: %s (%u): %s: ", level, lastPathEntry(file), line, function); va_list args; - va_start(args,fmt); + va_start(args, fmt); writeFmtArgsToLog(fmt, args); va_end(args); writeToLog("\n"); flushLog(); } - // =========================================================================== #pragma mark - Objective-C - // =========================================================================== @@ -292,57 +254,47 @@ void i_kslog_logC(const char* const level, void i_kslog_logObjCBasic(CFStringRef fmt, ...) { - if(fmt == NULL) - { + if (fmt == NULL) { writeToLog("(null)"); return; } - + va_list args; - va_start(args,fmt); + va_start(args, fmt); CFStringRef entry = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, args); va_end(args); - + int bufferLength = (int)CFStringGetLength(entry) * 4 + 1; - char* stringBuffer = malloc((unsigned)bufferLength); - if(CFStringGetCString(entry, stringBuffer, (CFIndex)bufferLength, kCFStringEncodingUTF8)) - { + char *stringBuffer = malloc((unsigned)bufferLength); + if (CFStringGetCString(entry, stringBuffer, (CFIndex)bufferLength, kCFStringEncodingUTF8)) { writeToLog(stringBuffer); - } - else - { + } else { writeToLog("Could not convert log string to UTF-8. No logging performed."); } writeToLog("\n"); - + free(stringBuffer); CFRelease(entry); } -void i_kslog_logObjC(const char* const level, - const char* const file, - const int line, - const char* const function, +void i_kslog_logObjC(const char *const level, const char *const file, const int line, const char *const function, CFStringRef fmt, ...) { CFStringRef logFmt = NULL; - if(fmt == NULL) - { + if (fmt == NULL) { logFmt = CFStringCreateWithCString(NULL, "%s: %s (%u): %s: (null)", kCFStringEncodingUTF8); i_kslog_logObjCBasic(logFmt, level, lastPathEntry(file), line, function); - } - else - { + } else { va_list args; - va_start(args,fmt); + va_start(args, fmt); CFStringRef entry = CFStringCreateWithFormatAndArguments(NULL, NULL, fmt, args); va_end(args); - + logFmt = CFStringCreateWithCString(NULL, "%s: %s (%u): %s: %@", kCFStringEncodingUTF8); i_kslog_logObjCBasic(logFmt, level, lastPathEntry(file), line, function, entry); - + CFRelease(entry); } CFRelease(logFmt); } -#endif // KSCRASH_HAS_OBJC +#endif // KSCRASH_HAS_OBJC diff --git a/Sources/KSCrashRecordingCore/KSMach-O.c b/Sources/KSCrashRecordingCore/KSMach-O.c index 06c336efc..c2d544e68 100644 --- a/Sources/KSCrashRecordingCore/KSMach-O.c +++ b/Sources/KSCrashRecordingCore/KSMach-O.c @@ -47,30 +47,28 @@ #include "KSMach-O.h" -#include "KSLogger.h" #include #include #include #include -const struct load_command* ksmacho_getCommandByTypeFromHeader(const mach_header_t* header, uint32_t commandType) +#include "KSLogger.h" + +const struct load_command *ksmacho_getCommandByTypeFromHeader(const mach_header_t *header, uint32_t commandType) { KSLOG_TRACE("Getting command by type %u in Mach header at %p", commandType, header); - if (header == NULL) - { + if (header == NULL) { KSLOG_ERROR("Header is NULL"); return NULL; } uintptr_t current = (uintptr_t)header + sizeof(mach_header_t); - struct load_command* loadCommand = NULL; + struct load_command *loadCommand = NULL; - for (uint commandIndex = 0; commandIndex < header->ncmds; commandIndex++) - { - loadCommand = (struct load_command*)current; - if (loadCommand->cmd == commandType) - { + for (uint commandIndex = 0; commandIndex < header->ncmds; commandIndex++) { + loadCommand = (struct load_command *)current; + if (loadCommand->cmd == commandType) { return loadCommand; } current += loadCommand->cmdsize; @@ -79,53 +77,47 @@ const struct load_command* ksmacho_getCommandByTypeFromHeader(const mach_header_ return NULL; } -const segment_command_t* ksmacho_getSegmentByNameFromHeader(const mach_header_t* header, const char* segmentName) +const segment_command_t *ksmacho_getSegmentByNameFromHeader(const mach_header_t *header, const char *segmentName) { KSLOG_TRACE("Searching for segment %s in Mach header at %p", segmentName, header); - - if (header == NULL) - { + + if (header == NULL) { KSLOG_ERROR("Header is NULL"); return NULL; } - const segment_command_t* segmentCommand; + const segment_command_t *segmentCommand; unsigned long commandIndex; - segmentCommand = (segment_command_t*)((uintptr_t)header + sizeof(mach_header_t)); - for (commandIndex = 0; commandIndex < header->ncmds; commandIndex++) - { + segmentCommand = (segment_command_t *)((uintptr_t)header + sizeof(mach_header_t)); + for (commandIndex = 0; commandIndex < header->ncmds; commandIndex++) { if (segmentCommand->cmd == LC_SEGMENT_ARCH_DEPENDENT && - strncmp(segmentCommand->segname, segmentName, sizeof(segmentCommand->segname)) == 0) - { + strncmp(segmentCommand->segname, segmentName, sizeof(segmentCommand->segname)) == 0) { KSLOG_DEBUG("Segment %s found at %p", segmentName, segmentCommand); return segmentCommand; } - segmentCommand = (segment_command_t*)((uintptr_t)segmentCommand + segmentCommand->cmdsize); + segmentCommand = (segment_command_t *)((uintptr_t)segmentCommand + segmentCommand->cmdsize); } KSLOG_WARN("Segment %s not found in Mach header at %p", segmentName, header); return NULL; } -const section_t* ksmacho_getSectionByTypeFlagFromSegment(const segment_command_t* segmentCommand, uint32_t flag) +const section_t *ksmacho_getSectionByTypeFlagFromSegment(const segment_command_t *segmentCommand, uint32_t flag) { KSLOG_TRACE("Getting section by flag %u in segment %s", flag, segmentCommand->segname); - - if (segmentCommand == NULL) - { + + if (segmentCommand == NULL) { KSLOG_ERROR("Segment is NULL"); return NULL; } uintptr_t current = (uintptr_t)segmentCommand + sizeof(segment_command_t); - const section_t* section = NULL; + const section_t *section = NULL; - for (uint sectionIndex = 0; sectionIndex < segmentCommand->nsects; sectionIndex++) - { - section = (const section_t*)(current + sectionIndex * sizeof(section_t)); - if ((section->flags & SECTION_TYPE) == flag) - { + for (uint sectionIndex = 0; sectionIndex < segmentCommand->nsects; sectionIndex++) { + section = (const section_t *)(current + sectionIndex * sizeof(section_t)); + if ((section->flags & SECTION_TYPE) == flag) { return section; } } @@ -134,7 +126,7 @@ const section_t* ksmacho_getSectionByTypeFlagFromSegment(const segment_command_t return NULL; } -vm_prot_t ksmacho_getSectionProtection(void* sectionStart) +vm_prot_t ksmacho_getSectionProtection(void *sectionStart) { KSLOG_TRACE("Getting protection for section starting at %p", sectionStart); @@ -146,20 +138,17 @@ vm_prot_t ksmacho_getSectionProtection(void* sectionStart) mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; vm_region_basic_info_data_64_t info; kern_return_t info_ret = - vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_64_t)&info, &count, &object); + vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_64_t)&info, &count, &object); #else mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT; vm_region_basic_info_data_t info; kern_return_t info_ret = - vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object); + vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object); #endif - if (info_ret == KERN_SUCCESS) - { + if (info_ret == KERN_SUCCESS) { KSLOG_DEBUG("Protection obtained: %d", info.protection); return info.protection; - } - else - { + } else { KSLOG_ERROR("Failed to get protection for section: %s", mach_error_string(info_ret)); return VM_PROT_READ; } diff --git a/Sources/KSCrashRecordingCore/KSMach.c b/Sources/KSCrashRecordingCore/KSMach.c index 6ac607222..30f115a2f 100644 --- a/Sources/KSCrashRecordingCore/KSMach.c +++ b/Sources/KSCrashRecordingCore/KSMach.c @@ -27,93 +27,92 @@ #include #include -#define RETURN_NAME_FOR_ENUM(A) case A: return #A +#define RETURN_NAME_FOR_ENUM(A) \ + case A: \ + return #A -const char* ksmach_exceptionName(const int64_t exceptionType) +const char *ksmach_exceptionName(const int64_t exceptionType) { - switch (exceptionType) - { - RETURN_NAME_FOR_ENUM(EXC_BAD_ACCESS); - RETURN_NAME_FOR_ENUM(EXC_BAD_INSTRUCTION); - RETURN_NAME_FOR_ENUM(EXC_ARITHMETIC); - RETURN_NAME_FOR_ENUM(EXC_EMULATION); - RETURN_NAME_FOR_ENUM(EXC_SOFTWARE); - RETURN_NAME_FOR_ENUM(EXC_BREAKPOINT); - RETURN_NAME_FOR_ENUM(EXC_SYSCALL); - RETURN_NAME_FOR_ENUM(EXC_MACH_SYSCALL); - RETURN_NAME_FOR_ENUM(EXC_RPC_ALERT); - RETURN_NAME_FOR_ENUM(EXC_CRASH); + switch (exceptionType) { + RETURN_NAME_FOR_ENUM(EXC_BAD_ACCESS); + RETURN_NAME_FOR_ENUM(EXC_BAD_INSTRUCTION); + RETURN_NAME_FOR_ENUM(EXC_ARITHMETIC); + RETURN_NAME_FOR_ENUM(EXC_EMULATION); + RETURN_NAME_FOR_ENUM(EXC_SOFTWARE); + RETURN_NAME_FOR_ENUM(EXC_BREAKPOINT); + RETURN_NAME_FOR_ENUM(EXC_SYSCALL); + RETURN_NAME_FOR_ENUM(EXC_MACH_SYSCALL); + RETURN_NAME_FOR_ENUM(EXC_RPC_ALERT); + RETURN_NAME_FOR_ENUM(EXC_CRASH); } return NULL; } -const char* ksmach_kernelReturnCodeName(const int64_t returnCode) +const char *ksmach_kernelReturnCodeName(const int64_t returnCode) { - switch (returnCode) - { - RETURN_NAME_FOR_ENUM(KERN_SUCCESS); - RETURN_NAME_FOR_ENUM(KERN_INVALID_ADDRESS); - RETURN_NAME_FOR_ENUM(KERN_PROTECTION_FAILURE); - RETURN_NAME_FOR_ENUM(KERN_NO_SPACE); - RETURN_NAME_FOR_ENUM(KERN_INVALID_ARGUMENT); - RETURN_NAME_FOR_ENUM(KERN_FAILURE); - RETURN_NAME_FOR_ENUM(KERN_RESOURCE_SHORTAGE); - RETURN_NAME_FOR_ENUM(KERN_NOT_RECEIVER); - RETURN_NAME_FOR_ENUM(KERN_NO_ACCESS); - RETURN_NAME_FOR_ENUM(KERN_MEMORY_FAILURE); - RETURN_NAME_FOR_ENUM(KERN_MEMORY_ERROR); - RETURN_NAME_FOR_ENUM(KERN_ALREADY_IN_SET); - RETURN_NAME_FOR_ENUM(KERN_NOT_IN_SET); - RETURN_NAME_FOR_ENUM(KERN_NAME_EXISTS); - RETURN_NAME_FOR_ENUM(KERN_ABORTED); - RETURN_NAME_FOR_ENUM(KERN_INVALID_NAME); - RETURN_NAME_FOR_ENUM(KERN_INVALID_TASK); - RETURN_NAME_FOR_ENUM(KERN_INVALID_RIGHT); - RETURN_NAME_FOR_ENUM(KERN_INVALID_VALUE); - RETURN_NAME_FOR_ENUM(KERN_UREFS_OVERFLOW); - RETURN_NAME_FOR_ENUM(KERN_INVALID_CAPABILITY); - RETURN_NAME_FOR_ENUM(KERN_RIGHT_EXISTS); - RETURN_NAME_FOR_ENUM(KERN_INVALID_HOST); - RETURN_NAME_FOR_ENUM(KERN_MEMORY_PRESENT); - RETURN_NAME_FOR_ENUM(KERN_MEMORY_DATA_MOVED); - RETURN_NAME_FOR_ENUM(KERN_MEMORY_RESTART_COPY); - RETURN_NAME_FOR_ENUM(KERN_INVALID_PROCESSOR_SET); - RETURN_NAME_FOR_ENUM(KERN_POLICY_LIMIT); - RETURN_NAME_FOR_ENUM(KERN_INVALID_POLICY); - RETURN_NAME_FOR_ENUM(KERN_INVALID_OBJECT); - RETURN_NAME_FOR_ENUM(KERN_ALREADY_WAITING); - RETURN_NAME_FOR_ENUM(KERN_DEFAULT_SET); - RETURN_NAME_FOR_ENUM(KERN_EXCEPTION_PROTECTED); - RETURN_NAME_FOR_ENUM(KERN_INVALID_LEDGER); - RETURN_NAME_FOR_ENUM(KERN_INVALID_MEMORY_CONTROL); - RETURN_NAME_FOR_ENUM(KERN_INVALID_SECURITY); - RETURN_NAME_FOR_ENUM(KERN_NOT_DEPRESSED); - RETURN_NAME_FOR_ENUM(KERN_TERMINATED); - RETURN_NAME_FOR_ENUM(KERN_LOCK_SET_DESTROYED); - RETURN_NAME_FOR_ENUM(KERN_LOCK_UNSTABLE); - RETURN_NAME_FOR_ENUM(KERN_LOCK_OWNED); - RETURN_NAME_FOR_ENUM(KERN_LOCK_OWNED_SELF); - RETURN_NAME_FOR_ENUM(KERN_SEMAPHORE_DESTROYED); - RETURN_NAME_FOR_ENUM(KERN_RPC_SERVER_TERMINATED); - RETURN_NAME_FOR_ENUM(KERN_RPC_TERMINATE_ORPHAN); - RETURN_NAME_FOR_ENUM(KERN_RPC_CONTINUE_ORPHAN); - RETURN_NAME_FOR_ENUM(KERN_NOT_SUPPORTED); - RETURN_NAME_FOR_ENUM(KERN_NODE_DOWN); - RETURN_NAME_FOR_ENUM(KERN_NOT_WAITING); - RETURN_NAME_FOR_ENUM(KERN_OPERATION_TIMED_OUT); - RETURN_NAME_FOR_ENUM(KERN_CODESIGN_ERROR); + switch (returnCode) { + RETURN_NAME_FOR_ENUM(KERN_SUCCESS); + RETURN_NAME_FOR_ENUM(KERN_INVALID_ADDRESS); + RETURN_NAME_FOR_ENUM(KERN_PROTECTION_FAILURE); + RETURN_NAME_FOR_ENUM(KERN_NO_SPACE); + RETURN_NAME_FOR_ENUM(KERN_INVALID_ARGUMENT); + RETURN_NAME_FOR_ENUM(KERN_FAILURE); + RETURN_NAME_FOR_ENUM(KERN_RESOURCE_SHORTAGE); + RETURN_NAME_FOR_ENUM(KERN_NOT_RECEIVER); + RETURN_NAME_FOR_ENUM(KERN_NO_ACCESS); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_FAILURE); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_ERROR); + RETURN_NAME_FOR_ENUM(KERN_ALREADY_IN_SET); + RETURN_NAME_FOR_ENUM(KERN_NOT_IN_SET); + RETURN_NAME_FOR_ENUM(KERN_NAME_EXISTS); + RETURN_NAME_FOR_ENUM(KERN_ABORTED); + RETURN_NAME_FOR_ENUM(KERN_INVALID_NAME); + RETURN_NAME_FOR_ENUM(KERN_INVALID_TASK); + RETURN_NAME_FOR_ENUM(KERN_INVALID_RIGHT); + RETURN_NAME_FOR_ENUM(KERN_INVALID_VALUE); + RETURN_NAME_FOR_ENUM(KERN_UREFS_OVERFLOW); + RETURN_NAME_FOR_ENUM(KERN_INVALID_CAPABILITY); + RETURN_NAME_FOR_ENUM(KERN_RIGHT_EXISTS); + RETURN_NAME_FOR_ENUM(KERN_INVALID_HOST); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_PRESENT); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_DATA_MOVED); + RETURN_NAME_FOR_ENUM(KERN_MEMORY_RESTART_COPY); + RETURN_NAME_FOR_ENUM(KERN_INVALID_PROCESSOR_SET); + RETURN_NAME_FOR_ENUM(KERN_POLICY_LIMIT); + RETURN_NAME_FOR_ENUM(KERN_INVALID_POLICY); + RETURN_NAME_FOR_ENUM(KERN_INVALID_OBJECT); + RETURN_NAME_FOR_ENUM(KERN_ALREADY_WAITING); + RETURN_NAME_FOR_ENUM(KERN_DEFAULT_SET); + RETURN_NAME_FOR_ENUM(KERN_EXCEPTION_PROTECTED); + RETURN_NAME_FOR_ENUM(KERN_INVALID_LEDGER); + RETURN_NAME_FOR_ENUM(KERN_INVALID_MEMORY_CONTROL); + RETURN_NAME_FOR_ENUM(KERN_INVALID_SECURITY); + RETURN_NAME_FOR_ENUM(KERN_NOT_DEPRESSED); + RETURN_NAME_FOR_ENUM(KERN_TERMINATED); + RETURN_NAME_FOR_ENUM(KERN_LOCK_SET_DESTROYED); + RETURN_NAME_FOR_ENUM(KERN_LOCK_UNSTABLE); + RETURN_NAME_FOR_ENUM(KERN_LOCK_OWNED); + RETURN_NAME_FOR_ENUM(KERN_LOCK_OWNED_SELF); + RETURN_NAME_FOR_ENUM(KERN_SEMAPHORE_DESTROYED); + RETURN_NAME_FOR_ENUM(KERN_RPC_SERVER_TERMINATED); + RETURN_NAME_FOR_ENUM(KERN_RPC_TERMINATE_ORPHAN); + RETURN_NAME_FOR_ENUM(KERN_RPC_CONTINUE_ORPHAN); + RETURN_NAME_FOR_ENUM(KERN_NOT_SUPPORTED); + RETURN_NAME_FOR_ENUM(KERN_NODE_DOWN); + RETURN_NAME_FOR_ENUM(KERN_NOT_WAITING); + RETURN_NAME_FOR_ENUM(KERN_OPERATION_TIMED_OUT); + RETURN_NAME_FOR_ENUM(KERN_CODESIGN_ERROR); } return NULL; } #define EXC_UNIX_BAD_SYSCALL 0x10000 /* SIGSYS */ -#define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ -#define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ +#define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ +#define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ int ksmach_machExceptionForSignal(const int sigNum) { - switch(sigNum) - { + switch (sigNum) { case SIGFPE: return EXC_ARITHMETIC; case SIGSEGV: @@ -139,11 +138,9 @@ int ksmach_machExceptionForSignal(const int sigNum) return 0; } -int ksmach_signalForMachException(const int exception, - const mach_exception_code_t code) +int ksmach_signalForMachException(const int exception, const mach_exception_code_t code) { - switch(exception) - { + switch (exception) { case EXC_ARITHMETIC: return SIGFPE; case EXC_BAD_ACCESS: @@ -154,10 +151,8 @@ int ksmach_signalForMachException(const int exception, return SIGTRAP; case EXC_EMULATION: return SIGEMT; - case EXC_SOFTWARE: - { - switch (code) - { + case EXC_SOFTWARE: { + switch (code) { case EXC_UNIX_BAD_SYSCALL: return SIGSYS; case EXC_UNIX_BAD_PIPE: diff --git a/Sources/KSCrashRecordingCore/KSMachineContext.c b/Sources/KSCrashRecordingCore/KSMachineContext.c index caf16f15e..4ffab2d19 100644 --- a/Sources/KSCrashRecordingCore/KSMachineContext.c +++ b/Sources/KSCrashRecordingCore/KSMachineContext.c @@ -24,16 +24,17 @@ // THE SOFTWARE. // -#include "KSMachineContext_Apple.h" #include "KSMachineContext.h" -#include "KSSystemCapabilities.h" + +#include + #include "KSCPU.h" #include "KSCPU_Apple.h" +#include "KSMachineContext_Apple.h" #include "KSStackCursor_MachineContext.h" +#include "KSSystemCapabilities.h" -#include - -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" #ifdef __arm64__ @@ -55,18 +56,16 @@ static KSThread g_reservedThreads[10]; static int g_reservedThreadsMaxIndex = sizeof(g_reservedThreads) / sizeof(g_reservedThreads[0]) - 1; static int g_reservedThreadsCount = 0; - -static inline bool isStackOverflow(const KSMachineContext* const context) +static inline bool isStackOverflow(const KSMachineContext *const context) { KSStackCursor stackCursor; kssc_initWithMachineContext(&stackCursor, KSSC_STACK_OVERFLOW_THRESHOLD, context); - while(stackCursor.advanceCursor(&stackCursor)) - { + while (stackCursor.advanceCursor(&stackCursor)) { } return stackCursor.state.hasGivenUp; } -static inline bool getThreadList(KSMachineContext* context) +static inline bool getThreadList(KSMachineContext *context) { const task_t thisTask = mach_task_self(); KSLOG_DEBUG("Getting thread list"); @@ -74,27 +73,23 @@ static inline bool getThreadList(KSMachineContext* context) thread_act_array_t threads; mach_msg_type_number_t actualThreadCount; - if((kr = task_threads(thisTask, &threads, &actualThreadCount)) != KERN_SUCCESS) - { + if ((kr = task_threads(thisTask, &threads, &actualThreadCount)) != KERN_SUCCESS) { KSLOG_ERROR("task_threads: %s", mach_error_string(kr)); return false; } KSLOG_TRACE("Got %d threads", context->threadCount); int threadCount = (int)actualThreadCount; int maxThreadCount = sizeof(context->allThreads) / sizeof(context->allThreads[0]); - if(threadCount > maxThreadCount) - { + if (threadCount > maxThreadCount) { KSLOG_ERROR("Thread count %d is higher than maximum of %d", threadCount, maxThreadCount); threadCount = maxThreadCount; } - for(int i = 0; i < threadCount; i++) - { + for (int i = 0; i < threadCount; i++) { context->allThreads[i] = threads[i]; } context->threadCount = threadCount; - for(mach_msg_type_number_t i = 0; i < actualThreadCount; i++) - { + for (mach_msg_type_number_t i = 0; i < actualThreadCount; i++) { mach_port_deallocate(thisTask, threads[i]); } vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * actualThreadCount); @@ -102,17 +97,11 @@ static inline bool getThreadList(KSMachineContext* context) return true; } -int ksmc_contextSize(void) -{ - return sizeof(KSMachineContext); -} +int ksmc_contextSize(void) { return sizeof(KSMachineContext); } -KSThread ksmc_getThreadFromContext(const KSMachineContext* const context) -{ - return context->thisThread; -} +KSThread ksmc_getThreadFromContext(const KSMachineContext *const context) { return context->thisThread; } -bool ksmc_getContextForThread(KSThread thread, KSMachineContext* destinationContext, bool isCrashedContext) +bool ksmc_getContextForThread(KSThread thread, KSMachineContext *destinationContext, bool isCrashedContext) { KSLOG_DEBUG("Fill thread 0x%x context into %p. is crashed = %d", thread, destinationContext, isCrashedContext); memset(destinationContext, 0, sizeof(*destinationContext)); @@ -120,12 +109,10 @@ bool ksmc_getContextForThread(KSThread thread, KSMachineContext* destinationCont destinationContext->isCurrentThread = thread == ksthread_self(); destinationContext->isCrashedContext = isCrashedContext; destinationContext->isSignalContext = false; - if(ksmc_canHaveCPUState(destinationContext)) - { + if (ksmc_canHaveCPUState(destinationContext)) { kscpu_getState(destinationContext); } - if(ksmc_isCrashedContext(destinationContext)) - { + if (ksmc_isCrashedContext(destinationContext)) { destinationContext->isStackOverflow = isStackOverflow(destinationContext); getThreadList(destinationContext); } @@ -133,10 +120,10 @@ bool ksmc_getContextForThread(KSThread thread, KSMachineContext* destinationCont return true; } -bool ksmc_getContextForSignal(void* signalUserContext, KSMachineContext* destinationContext) +bool ksmc_getContextForSignal(void *signalUserContext, KSMachineContext *destinationContext) { KSLOG_DEBUG("Get context from signal user context and put into %p.", destinationContext); - _STRUCT_MCONTEXT* sourceContext = ((SignalUserContext*)signalUserContext)->UC_MCONTEXT; + _STRUCT_MCONTEXT *sourceContext = ((SignalUserContext *)signalUserContext)->UC_MCONTEXT; memcpy(&destinationContext->machineContext, sourceContext, sizeof(destinationContext->machineContext)); destinationContext->thisThread = (thread_t)ksthread_self(); destinationContext->isCrashedContext = true; @@ -150,8 +137,7 @@ bool ksmc_getContextForSignal(void* signalUserContext, KSMachineContext* destina void ksmc_addReservedThread(KSThread thread) { int nextIndex = g_reservedThreadsCount; - if(nextIndex > g_reservedThreadsMaxIndex) - { + if (nextIndex > g_reservedThreadsMaxIndex) { KSLOG_ERROR("Too many reserved threads (%d). Max is %d", nextIndex, g_reservedThreadsMaxIndex); return; } @@ -159,12 +145,10 @@ void ksmc_addReservedThread(KSThread thread) } #if KSCRASH_HAS_THREADS_API -static inline bool isThreadInList(thread_t thread, KSThread* list, int listCount) +static inline bool isThreadInList(thread_t thread, KSThread *list, int listCount) { - for(int i = 0; i < listCount; i++) - { - if(list[i] == (KSThread)thread) - { + for (int i = 0; i < listCount; i++) { + if (list[i] == (KSThread)thread) { return true; } } @@ -172,33 +156,30 @@ static inline bool isThreadInList(thread_t thread, KSThread* list, int listCount } #endif -void ksmc_suspendEnvironment(__unused thread_act_array_t *suspendedThreads, __unused mach_msg_type_number_t *numSuspendedThreads) +void ksmc_suspendEnvironment(__unused thread_act_array_t *suspendedThreads, + __unused mach_msg_type_number_t *numSuspendedThreads) { #if KSCRASH_HAS_THREADS_API KSLOG_DEBUG("Suspending environment."); kern_return_t kr; const task_t thisTask = mach_task_self(); const thread_t thisThread = (thread_t)ksthread_self(); - - if((kr = task_threads(thisTask, suspendedThreads, numSuspendedThreads)) != KERN_SUCCESS) - { + + if ((kr = task_threads(thisTask, suspendedThreads, numSuspendedThreads)) != KERN_SUCCESS) { KSLOG_ERROR("task_threads: %s", mach_error_string(kr)); return; } - - for(mach_msg_type_number_t i = 0; i < *numSuspendedThreads; i++) - { + + for (mach_msg_type_number_t i = 0; i < *numSuspendedThreads; i++) { thread_t thread = (*suspendedThreads)[i]; - if(thread != thisThread && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount)) - { - if((kr = thread_suspend(thread)) != KERN_SUCCESS) - { + if (thread != thisThread && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount)) { + if ((kr = thread_suspend(thread)) != KERN_SUCCESS) { // Record the error and keep going. KSLOG_ERROR("thread_suspend (%08x): %s", thread, mach_error_string(kr)); } } } - + KSLOG_DEBUG("Suspend complete."); #endif } @@ -210,82 +191,59 @@ void ksmc_resumeEnvironment(__unused thread_act_array_t threads, __unused mach_m kern_return_t kr; const task_t thisTask = mach_task_self(); const thread_t thisThread = (thread_t)ksthread_self(); - - if(threads == NULL || numThreads == 0) - { + + if (threads == NULL || numThreads == 0) { KSLOG_ERROR("we should call ksmc_suspendEnvironment() first"); return; } - - for(mach_msg_type_number_t i = 0; i < numThreads; i++) - { + + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { thread_t thread = threads[i]; - if(thread != thisThread && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount)) - { - if((kr = thread_resume(thread)) != KERN_SUCCESS) - { + if (thread != thisThread && !isThreadInList(thread, g_reservedThreads, g_reservedThreadsCount)) { + if ((kr = thread_resume(thread)) != KERN_SUCCESS) { // Record the error and keep going. KSLOG_ERROR("thread_resume (%08x): %s", thread, mach_error_string(kr)); } } } - - for(mach_msg_type_number_t i = 0; i < numThreads; i++) - { + + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { mach_port_deallocate(thisTask, threads[i]); } vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads); - + KSLOG_DEBUG("Resume complete."); #endif } -int ksmc_getThreadCount(const KSMachineContext* const context) -{ - return context->threadCount; -} +int ksmc_getThreadCount(const KSMachineContext *const context) { return context->threadCount; } -KSThread ksmc_getThreadAtIndex(const KSMachineContext* const context, int index) -{ - return context->allThreads[index]; - -} +KSThread ksmc_getThreadAtIndex(const KSMachineContext *const context, int index) { return context->allThreads[index]; } -int ksmc_indexOfThread(const KSMachineContext* const context, KSThread thread) +int ksmc_indexOfThread(const KSMachineContext *const context, KSThread thread) { KSLOG_TRACE("check thread vs %d threads", context->threadCount); - for(int i = 0; i < (int)context->threadCount; i++) - { + for (int i = 0; i < (int)context->threadCount; i++) { KSLOG_TRACE("%d: %x vs %x", i, thread, context->allThreads[i]); - if(context->allThreads[i] == thread) - { + if (context->allThreads[i] == thread) { return i; } } return -1; } -bool ksmc_isCrashedContext(const KSMachineContext* const context) -{ - return context->isCrashedContext; -} +bool ksmc_isCrashedContext(const KSMachineContext *const context) { return context->isCrashedContext; } -static inline bool isContextForCurrentThread(const KSMachineContext* const context) -{ - return context->isCurrentThread; -} +static inline bool isContextForCurrentThread(const KSMachineContext *const context) { return context->isCurrentThread; } -static inline bool isSignalContext(const KSMachineContext* const context) -{ - return context->isSignalContext; -} +static inline bool isSignalContext(const KSMachineContext *const context) { return context->isSignalContext; } -bool ksmc_canHaveCPUState(const KSMachineContext* const context) +bool ksmc_canHaveCPUState(const KSMachineContext *const context) { return !isContextForCurrentThread(context) || isSignalContext(context); } -bool ksmc_hasValidExceptionRegisters(const KSMachineContext* const context) +bool ksmc_hasValidExceptionRegisters(const KSMachineContext *const context) { return ksmc_canHaveCPUState(context) && ksmc_isCrashedContext(context); } diff --git a/Sources/KSCrashRecordingCore/KSMemory.c b/Sources/KSCrashRecordingCore/KSMemory.c index ba0f806b5..de0e4cd77 100644 --- a/Sources/KSCrashRecordingCore/KSMemory.c +++ b/Sources/KSCrashRecordingCore/KSMemory.c @@ -24,68 +24,53 @@ // THE SOFTWARE. // - #include "KSMemory.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - +// #define KSLogger_LocalLevel TRACE #include +#include "KSLogger.h" -static inline int copySafely(const void* restrict const src, void* restrict const dst, const int byteCount) +static inline int copySafely(const void *restrict const src, void *restrict const dst, const int byteCount) { vm_size_t bytesCopied = 0; - kern_return_t result = vm_read_overwrite(mach_task_self(), - (vm_address_t)src, - (vm_size_t)byteCount, - (vm_address_t)dst, - &bytesCopied); - if(result != KERN_SUCCESS) - { + kern_return_t result = + vm_read_overwrite(mach_task_self(), (vm_address_t)src, (vm_size_t)byteCount, (vm_address_t)dst, &bytesCopied); + if (result != KERN_SUCCESS) { return 0; } return (int)bytesCopied; } -static inline int copyMaxPossible(const void* restrict const src, void* restrict const dst, const int byteCount) +static inline int copyMaxPossible(const void *restrict const src, void *restrict const dst, const int byteCount) { - const uint8_t* pSrc = src; - const uint8_t* pSrcMax = (uint8_t*)src + byteCount; - const uint8_t* pSrcEnd = (uint8_t*)src + byteCount; - uint8_t* pDst = dst; - + const uint8_t *pSrc = src; + const uint8_t *pSrcMax = (uint8_t *)src + byteCount; + const uint8_t *pSrcEnd = (uint8_t *)src + byteCount; + uint8_t *pDst = dst; + int bytesCopied = 0; - + // Short-circuit if no memory is readable - if(copySafely(src, dst, 1) != 1) - { + if (copySafely(src, dst, 1) != 1) { return 0; - } - else if(byteCount <= 1) - { + } else if (byteCount <= 1) { return byteCount; } - - for(;;) - { + + for (;;) { int copyLength = (int)(pSrcEnd - pSrc); - if(copyLength <= 0) - { + if (copyLength <= 0) { break; } - - if(copySafely(pSrc, pDst, copyLength) == copyLength) - { + + if (copySafely(pSrc, pDst, copyLength) == copyLength) { bytesCopied += copyLength; pSrc += copyLength; pDst += copyLength; pSrcEnd = pSrc + (pSrcMax - pSrc) / 2; - } - else - { - if(copyLength <= 1) - { + } else { + if (copyLength <= 1) { break; } pSrcMax = pSrcEnd; @@ -96,16 +81,14 @@ static inline int copyMaxPossible(const void* restrict const src, void* restrict } static char g_memoryTestBuffer[10240]; -static inline bool isMemoryReadable(const void* const memory, const int byteCount) +static inline bool isMemoryReadable(const void *const memory, const int byteCount) { const int testBufferSize = sizeof(g_memoryTestBuffer); int bytesRemaining = byteCount; - - while(bytesRemaining > 0) - { + + while (bytesRemaining > 0) { int bytesToCopy = bytesRemaining > testBufferSize ? testBufferSize : bytesRemaining; - if(copySafely(memory, g_memoryTestBuffer, bytesToCopy) != bytesToCopy) - { + if (copySafely(memory, g_memoryTestBuffer, bytesToCopy) != bytesToCopy) { break; } bytesRemaining -= bytesToCopy; @@ -113,16 +96,14 @@ static inline bool isMemoryReadable(const void* const memory, const int byteCoun return bytesRemaining == 0; } -int ksmem_maxReadableBytes(const void* const memory, const int tryByteCount) +int ksmem_maxReadableBytes(const void *const memory, const int tryByteCount) { const int testBufferSize = sizeof(g_memoryTestBuffer); - const uint8_t* currentPosition = memory; + const uint8_t *currentPosition = memory; int bytesRemaining = tryByteCount; - while(bytesRemaining > testBufferSize) - { - if(!isMemoryReadable(currentPosition, testBufferSize)) - { + while (bytesRemaining > testBufferSize) { + if (!isMemoryReadable(currentPosition, testBufferSize)) { break; } currentPosition += testBufferSize; @@ -132,17 +113,17 @@ int ksmem_maxReadableBytes(const void* const memory, const int tryByteCount) return tryByteCount - bytesRemaining; } -bool ksmem_isMemoryReadable(const void* const memory, const int byteCount) +bool ksmem_isMemoryReadable(const void *const memory, const int byteCount) { return isMemoryReadable(memory, byteCount); } -int ksmem_copyMaxPossible(const void* restrict const src, void* restrict const dst, const int byteCount) +int ksmem_copyMaxPossible(const void *restrict const src, void *restrict const dst, const int byteCount) { return copyMaxPossible(src, dst, byteCount); } -bool ksmem_copySafely(const void* restrict const src, void* restrict const dst, const int byteCount) +bool ksmem_copySafely(const void *restrict const src, void *restrict const dst, const int byteCount) { return copySafely(src, dst, byteCount); } diff --git a/Sources/KSCrashRecordingCore/KSObjC.c b/Sources/KSCrashRecordingCore/KSObjC.c index a96dcef4f..51496df25 100644 --- a/Sources/KSCrashRecordingCore/KSObjC.c +++ b/Sources/KSCrashRecordingCore/KSObjC.c @@ -24,15 +24,13 @@ // THE SOFTWARE. // - #include "KSObjC.h" -#include "KSObjCApple.h" +#include "KSLogger.h" #include "KSMemory.h" +#include "KSObjCApple.h" #include "KSString.h" -#include "KSLogger.h" - #if __IPHONE_OS_VERSION_MAX_ALLOWED > 70000 #include #else @@ -51,7 +49,6 @@ typedef unsigned int NSUInteger; #include "TargetConditionals.h" - #define kMaxNameLength 128 //====================================================================== @@ -59,16 +56,14 @@ typedef unsigned int NSUInteger; //====================================================================== // Compiler hints for "if" statements -#define likely_if(x) if(__builtin_expect(x,1)) -#define unlikely_if(x) if(__builtin_expect(x,0)) - +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) //====================================================================== #pragma mark - Types - //====================================================================== -typedef enum -{ +typedef enum { ClassSubtypeNone = 0, ClassSubtypeCFArray, ClassSubtypeNSArrayMutable, @@ -76,97 +71,95 @@ typedef enum ClassSubtypeCFString, } ClassSubtype; -typedef struct -{ - const char* name; +typedef struct { + const char *name; KSObjCClassType type; ClassSubtype subtype; bool isMutable; - bool (*isValidObject)(const void* object); - int (*description)(const void* object, char* buffer, int bufferLength); - const void* class; + bool (*isValidObject)(const void *object); + int (*description)(const void *object, char *buffer, int bufferLength); + const void *class; } ClassData; - //====================================================================== #pragma mark - Globals - //====================================================================== // Forward references -static bool objectIsValid(const void* object); -static bool taggedObjectIsValid(const void* object); -static bool stringIsValid(const void* object); -static bool urlIsValid(const void* object); -static bool arrayIsValid(const void* object); -static bool dateIsValid(const void* object); -static bool numberIsValid(const void* object); -static bool taggedDateIsValid(const void* object); -static bool taggedNumberIsValid(const void* object); -static bool taggedStringIsValid(const void* object); - -static int objectDescription(const void* object, char* buffer, int bufferLength); -static int taggedObjectDescription(const void* object, char* buffer, int bufferLength); -static int stringDescription(const void* object, char* buffer, int bufferLength); -static int urlDescription(const void* object, char* buffer, int bufferLength); -static int arrayDescription(const void* object, char* buffer, int bufferLength); -static int dateDescription(const void* object, char* buffer, int bufferLength); -static int numberDescription(const void* object, char* buffer, int bufferLength); -static int taggedDateDescription(const void* object, char* buffer, int bufferLength); -static int taggedNumberDescription(const void* object, char* buffer, int bufferLength); -static int taggedStringDescription(const void* object, char* buffer, int bufferLength); - - +static bool objectIsValid(const void *object); +static bool taggedObjectIsValid(const void *object); +static bool stringIsValid(const void *object); +static bool urlIsValid(const void *object); +static bool arrayIsValid(const void *object); +static bool dateIsValid(const void *object); +static bool numberIsValid(const void *object); +static bool taggedDateIsValid(const void *object); +static bool taggedNumberIsValid(const void *object); +static bool taggedStringIsValid(const void *object); + +static int objectDescription(const void *object, char *buffer, int bufferLength); +static int taggedObjectDescription(const void *object, char *buffer, int bufferLength); +static int stringDescription(const void *object, char *buffer, int bufferLength); +static int urlDescription(const void *object, char *buffer, int bufferLength); +static int arrayDescription(const void *object, char *buffer, int bufferLength); +static int dateDescription(const void *object, char *buffer, int bufferLength); +static int numberDescription(const void *object, char *buffer, int bufferLength); +static int taggedDateDescription(const void *object, char *buffer, int bufferLength); +static int taggedNumberDescription(const void *object, char *buffer, int bufferLength); +static int taggedStringDescription(const void *object, char *buffer, int bufferLength); + +// clang-format off static ClassData g_classData[] = { - {"__NSCFString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, - {"NSCFString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, - {"__NSCFConstantString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, - {"NSCFConstantString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, - {"__NSArray0", KSObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, arrayIsValid, arrayDescription}, - {"__NSArrayI", KSObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, arrayIsValid, arrayDescription}, - {"__NSArrayM", KSObjCClassTypeArray, ClassSubtypeNSArrayMutable, true, arrayIsValid, arrayDescription}, - {"__NSCFArray", KSObjCClassTypeArray, ClassSubtypeCFArray, false, arrayIsValid, arrayDescription}, - {"__NSSingleObjectArrayI", KSObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, arrayIsValid, arrayDescription}, - {"NSCFArray", KSObjCClassTypeArray, ClassSubtypeCFArray, false, arrayIsValid, arrayDescription}, - {"__NSDate", KSObjCClassTypeDate, ClassSubtypeNone, false, dateIsValid, dateDescription}, - {"NSDate", KSObjCClassTypeDate, ClassSubtypeNone, false, dateIsValid, dateDescription}, - {"__NSCFNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, numberDescription}, - {"NSCFNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, numberDescription}, - {"NSNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, numberDescription}, - {"NSURL", KSObjCClassTypeURL, ClassSubtypeNone, false, urlIsValid, urlDescription}, - {NULL, KSObjCClassTypeUnknown, ClassSubtypeNone, false, objectIsValid, objectDescription}, + {"__NSCFString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, + {"NSCFString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, + {"__NSCFConstantString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, + {"NSCFConstantString", KSObjCClassTypeString, ClassSubtypeNone, true, stringIsValid, stringDescription}, + {"__NSArray0", KSObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, arrayIsValid, arrayDescription}, + {"__NSArrayI", KSObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, arrayIsValid, arrayDescription}, + {"__NSArrayM", KSObjCClassTypeArray, ClassSubtypeNSArrayMutable, true, arrayIsValid, arrayDescription}, + {"__NSCFArray", KSObjCClassTypeArray, ClassSubtypeCFArray, false, arrayIsValid, arrayDescription}, + {"__NSSingleObjectArrayI", KSObjCClassTypeArray, ClassSubtypeNSArrayImmutable, false, arrayIsValid, arrayDescription}, + {"NSCFArray", KSObjCClassTypeArray, ClassSubtypeCFArray, false, arrayIsValid, arrayDescription}, + {"__NSDate", KSObjCClassTypeDate, ClassSubtypeNone, false, dateIsValid, dateDescription}, + {"NSDate", KSObjCClassTypeDate, ClassSubtypeNone, false, dateIsValid, dateDescription}, + {"__NSCFNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, numberDescription}, + {"NSCFNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, numberDescription}, + {"NSNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, numberIsValid, numberDescription}, + {"NSURL", KSObjCClassTypeURL, ClassSubtypeNone, false, urlIsValid, urlDescription}, + {NULL, KSObjCClassTypeUnknown, ClassSubtypeNone, false, objectIsValid, objectDescription}, }; static ClassData g_taggedClassData[] = { - {"NSAtom", KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, - {NULL, KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, - {"NSString", KSObjCClassTypeString, ClassSubtypeNone, false, taggedStringIsValid, taggedStringDescription}, - {"NSNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, taggedNumberIsValid, taggedNumberDescription}, - {"NSIndexPath", KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, - {"NSManagedObjectID", KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, - {"NSDate", KSObjCClassTypeDate, ClassSubtypeNone, false, taggedDateIsValid, taggedDateDescription}, - {NULL, KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, + {"NSAtom", KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, + {NULL, KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, + {"NSString", KSObjCClassTypeString, ClassSubtypeNone, false, taggedStringIsValid, taggedStringDescription}, + {"NSNumber", KSObjCClassTypeNumber, ClassSubtypeNone, false, taggedNumberIsValid, taggedNumberDescription}, + {"NSIndexPath", KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, + {"NSManagedObjectID", KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, + {"NSDate", KSObjCClassTypeDate, ClassSubtypeNone, false, taggedDateIsValid, taggedDateDescription}, + {NULL, KSObjCClassTypeUnknown, ClassSubtypeNone, false, taggedObjectIsValid, taggedObjectDescription}, }; +// clang-format on static int g_taggedClassDataCount = sizeof(g_taggedClassData) / sizeof(*g_taggedClassData); -static const char* g_blockBaseClassName = "NSBlock"; - +static const char *g_blockBaseClassName = "NSBlock"; //====================================================================== #pragma mark - Utility - //====================================================================== #if OBJC_HAVE_TAGGED_POINTERS -static bool isTaggedPointer(const void* pointer) { return _objc_isTaggedPointer(pointer); } -static int getTaggedSlot(const void* pointer) { return (int)_objc_getTaggedPointerTag(pointer); } -static uintptr_t getTaggedPayload(const void* pointer) { return _objc_getTaggedPointerValue(pointer); } -static intptr_t getTaggedSignedPayload(const void* pointer) { return _objc_getTaggedPointerSignedValue(pointer); } +static bool isTaggedPointer(const void *pointer) { return _objc_isTaggedPointer(pointer); } +static int getTaggedSlot(const void *pointer) { return (int)_objc_getTaggedPointerTag(pointer); } +static uintptr_t getTaggedPayload(const void *pointer) { return _objc_getTaggedPointerValue(pointer); } +static intptr_t getTaggedSignedPayload(const void *pointer) { return _objc_getTaggedPointerSignedValue(pointer); } #else -static bool isTaggedPointer(__unused const void* pointer) { return false; } -static int getTaggedSlot(__unused const void* pointer) { return 0; } -static uintptr_t getTaggedPayload(const void* pointer) { return (uintptr_t)pointer; } -static intptr_t getTaggedSignedPayload(const void* pointer) { return (intptr_t)pointer; } +static bool isTaggedPointer(__unused const void *pointer) { return false; } +static int getTaggedSlot(__unused const void *pointer) { return 0; } +static uintptr_t getTaggedPayload(const void *pointer) { return (uintptr_t)pointer; } +static intptr_t getTaggedSignedPayload(const void *pointer) { return (intptr_t)pointer; } #endif /** Get class data for a tagged pointer. @@ -174,72 +167,69 @@ static intptr_t getTaggedSignedPayload(const void* pointer) { return (intptr_t)p * @param object The tagged pointer. * @return The class data. */ -static const ClassData* getClassDataFromTaggedPointer(const void* const object) +static const ClassData *getClassDataFromTaggedPointer(const void *const object) { int slot = getTaggedSlot(object); return &g_taggedClassData[slot]; } -static bool isValidTaggedPointer(const void* object) +static bool isValidTaggedPointer(const void *object) { - if(isTaggedPointer(object)) - { - if(getTaggedSlot(object) <= g_taggedClassDataCount) - { - const ClassData* classData = getClassDataFromTaggedPointer(object); + if (isTaggedPointer(object)) { + if (getTaggedSlot(object) <= g_taggedClassDataCount) { + const ClassData *classData = getClassDataFromTaggedPointer(object); return classData->type != KSObjCClassTypeUnknown; } } return false; } -static const struct class_t* decodeIsaPointer(const void* const isaPointer) +static const struct class_t *decodeIsaPointer(const void *const isaPointer) { #if ISA_TAG_MASK uintptr_t isa = (uintptr_t)isaPointer; - if(isa & ISA_TAG_MASK) - { + if (isa & ISA_TAG_MASK) { #if defined(__arm64__) #if TARGET_OS_IOS if (floor(kCFCoreFoundationVersionNumber) <= kCFCoreFoundationVersionNumber_iOS_8_x_Max) { - return (const struct class_t*)(isa & ISA_MASK_OLD); + return (const struct class_t *)(isa & ISA_MASK_OLD); } #endif - - return (const struct class_t*)(isa & ISA_MASK); + + return (const struct class_t *)(isa & ISA_MASK); #else - return (const struct class_t*)(isa & ISA_MASK); + return (const struct class_t *)(isa & ISA_MASK); #endif } #endif - return (const struct class_t*)isaPointer; + return (const struct class_t *)isaPointer; } -static const void* getIsaPointer(const void* const objectOrClassPtr) +static const void *getIsaPointer(const void *const objectOrClassPtr) { // This is wrong. Should not get class data here. -// if(ksobjc_isTaggedPointer(objectOrClassPtr)) -// { -// return getClassDataFromTaggedPointer(objectOrClassPtr)->class; -// } - - const struct class_t* ptr = objectOrClassPtr; + // if(ksobjc_isTaggedPointer(objectOrClassPtr)) + // { + // return getClassDataFromTaggedPointer(objectOrClassPtr)->class; + // } + + const struct class_t *ptr = objectOrClassPtr; return decodeIsaPointer(ptr->isa); } -static inline struct class_rw_t* getClassRW(const struct class_t* const class) +static inline struct class_rw_t *getClassRW(const struct class_t *const class) { uintptr_t ptr = class->data_NEVER_USE & FAST_DATA_MASK; - return (struct class_rw_t*)ptr; + return (struct class_rw_t *)ptr; } -static inline const struct class_ro_t* getClassRO(const struct class_t* const class) +static inline const struct class_ro_t *getClassRO(const struct class_t *const class) { class_rw_t *rw = getClassRW(class); uintptr_t ext_ptr = rw->ro_or_rw_ext; /* When objc_class_abi_version >= 1, it's a tagged union based on the low bit: - * 0: class_ro_t 1: class_rw_ext_t - * @see https://opensource.apple.com/source/objc4/objc4-781/runtime/objc-runtime-new.h */ + * 0: class_ro_t 1: class_rw_ext_t + * @see https://opensource.apple.com/source/objc4/objc4-781/runtime/objc-runtime-new.h */ if (ext_ptr & 0x1UL) { ext_ptr &= ~0x1UL; struct class_rw_ext_t *rw_ext = (struct class_rw_ext_t *)ext_ptr; @@ -250,25 +240,19 @@ static inline const struct class_ro_t* getClassRO(const struct class_t* const cl } } -static inline const void* getSuperClass(const void* const classPtr) +static inline const void *getSuperClass(const void *const classPtr) { - const struct class_t* class = classPtr; + const struct class_t *class = classPtr; return class->superclass; } -static inline bool isMetaClass(const void* const classPtr) -{ - return (getClassRO(classPtr)->flags & RO_META) != 0; -} +static inline bool isMetaClass(const void *const classPtr) { return (getClassRO(classPtr)->flags & RO_META) != 0; } -static inline bool isRootClass(const void* const classPtr) -{ - return (getClassRO(classPtr)->flags & RO_ROOT) != 0; -} +static inline bool isRootClass(const void *const classPtr) { return (getClassRO(classPtr)->flags & RO_ROOT) != 0; } -static inline const char* getClassName(const void* classPtr) +static inline const char *getClassName(const void *classPtr) { - const struct class_ro_t* ro = getClassRO(classPtr); + const struct class_ro_t *ro = getClassRO(classPtr); return ro->name; } @@ -277,37 +261,28 @@ static inline const char* getClassName(const void* classPtr) * @param object The object to query. * @return true if the tagged pointer is an NSNumber. */ -static bool isTaggedPointerNSNumber(const void* const object) -{ - return getTaggedSlot(object) == OBJC_TAG_NSNumber; -} +static bool isTaggedPointerNSNumber(const void *const object) { return getTaggedSlot(object) == OBJC_TAG_NSNumber; } /** Check if a tagged pointer is a string. * * @param object The object to query. * @return true if the tagged pointer is an NSString. */ -static bool isTaggedPointerNSString(const void* const object) -{ - return getTaggedSlot(object) == OBJC_TAG_NSString; -} +static bool isTaggedPointerNSString(const void *const object) { return getTaggedSlot(object) == OBJC_TAG_NSString; } /** Check if a tagged pointer is a date. * * @param object The object to query. * @return true if the tagged pointer is an NSDate. */ -static bool isTaggedPointerNSDate(const void* const object) -{ - return getTaggedSlot(object) == OBJC_TAG_NSDate; -} +static bool isTaggedPointerNSDate(const void *const object) { return getTaggedSlot(object) == OBJC_TAG_NSDate; } /** Extract an integer from a tagged NSNumber. * * @param object The NSNumber object (must be a tagged pointer). * @return The integer value. */ -static int64_t extractTaggedNSNumber(const void* const object) +static int64_t extractTaggedNSNumber(const void *const object) { intptr_t value = getTaggedSignedPayload(object); @@ -315,46 +290,36 @@ static int64_t extractTaggedNSNumber(const void* const object) return (int64_t)(value >> 4); } -static int getTaggedNSStringLength(const void* const object) +static int getTaggedNSStringLength(const void *const object) { uintptr_t payload = getTaggedPayload(object); return (int)(payload & 0xf); } -static int extractTaggedNSString(const void* const object, char* buffer, int bufferLength) +static int extractTaggedNSString(const void *const object, char *buffer, int bufferLength) { int length = getTaggedNSStringLength(object); int copyLength = ((length + 1) > bufferLength) ? (bufferLength - 1) : length; uintptr_t payload = getTaggedPayload(object); uintptr_t value = payload >> 4; - static char* alphabet = "eilotrm.apdnsIc ufkMShjTRxgC4013bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX"; - if(length <=7) - { - for(int i = 0; i < copyLength; i++) - { + static char *alphabet = "eilotrm.apdnsIc ufkMShjTRxgC4013bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX"; + if (length <= 7) { + for (int i = 0; i < copyLength; i++) { // ASCII case, limit to bottom 7 bits just in case buffer[i] = (char)(value & 0x7f); value >>= 8; } - } - else if(length <= 9) - { - for(int i = 0; i < copyLength; i++) - { + } else if (length <= 9) { + for (int i = 0; i < copyLength; i++) { uintptr_t index = (value >> ((length - 1 - i) * 6)) & 0x3f; buffer[i] = alphabet[index]; } - } - else if(length <= 11) - { - for(int i = 0; i < copyLength; i++) - { + } else if (length <= 11) { + for (int i = 0; i < copyLength; i++) { uintptr_t index = (value >> ((length - 1 - i) * 5)) & 0x1f; buffer[i] = alphabet[index]; } - } - else - { + } else { buffer[0] = 0; } buffer[length] = 0; @@ -367,7 +332,8 @@ static int extractTaggedNSString(const void* const object, char* buffer, int buf * @param exp The 7-bit exponent value from the tagged NSDate pointer. * @return The decoded exponent value as a 64-bit unsigned integer. * - * @note This function is based on the LLVM code in the Cocoa.cpp file: https://github.com/apple/llvm-project/blob/5dc9d563e5a6cd2cdd44117697dead98955ccddf/lldb/source/Plugins/Language/ObjC/Cocoa.cpp#L934 + * @note This function is based on the LLVM code in the Cocoa.cpp file: + * https://github.com/apple/llvm-project/blob/5dc9d563e5a6cd2cdd44117697dead98955ccddf/lldb/source/Plugins/Language/ObjC/Cocoa.cpp#L934 */ static uint64_t decodeExponent(uint64_t exp) { @@ -395,13 +361,15 @@ static uint64_t decodeExponent(uint64_t exp) * @param object The NSDate object (must be a tagged pointer). * @return The date's absolute time. * - * @note This function is based on the LLVM code in the Cocoa.cpp file: https://github.com/apple/llvm-project/blob/5dc9d563e5a6cd2cdd44117697dead98955ccddf/lldb/source/Plugins/Language/ObjC/Cocoa.cpp#L913-L958 + * @note This function is based on the LLVM code in the Cocoa.cpp file: + * https://github.com/apple/llvm-project/blob/5dc9d563e5a6cd2cdd44117697dead98955ccddf/lldb/source/Plugins/Language/ObjC/Cocoa.cpp#L913-L958 */ -static CFAbsoluteTime extractTaggedNSDate(const void* const object) +static CFAbsoluteTime extractTaggedNSDate(const void *const object) { uintptr_t payload = getTaggedPayload(object); - if (kCFCoreFoundationVersionNumber > 1600) // https://github.com/apple/llvm-project/blob/5dc9d563e5a6cd2cdd44117697dead98955ccddf/lldb/source/Plugins/Language/ObjC/Cocoa.cpp#L1041 + if (kCFCoreFoundationVersionNumber > + 1600) // https://github.com/apple/llvm-project/blob/5dc9d563e5a6cd2cdd44117697dead98955ccddf/lldb/source/Plugins/Language/ObjC/Cocoa.cpp#L1041 { union { uintptr_t raw; @@ -413,10 +381,8 @@ static CFAbsoluteTime extractTaggedNSDate(const void* const object) } bits; } encodedBits = { .raw = payload }; - if (encodedBits.raw == 0) - return 0.0; - if (encodedBits.raw == UINT64_MAX) - return -0.0; + if (encodedBits.raw == 0) return 0.0; + if (encodedBits.raw == UINT64_MAX) return -0.0; union { CFAbsoluteTime value; @@ -425,18 +391,12 @@ static CFAbsoluteTime extractTaggedNSDate(const void* const object) uint64_t exponent : 11; uint64_t sign : 1; } bits; - } decodedBits = { - .bits = { - .fraction = encodedBits.bits.fraction, - .exponent = decodeExponent(encodedBits.bits.exponent), - .sign = encodedBits.bits.sign - } - }; + } decodedBits = { .bits = { .fraction = encodedBits.bits.fraction, + .exponent = decodeExponent(encodedBits.bits.exponent), + .sign = encodedBits.bits.sign } }; return decodedBits.value; - } - else - { + } else { // Payload is a 60-bit float. Fortunately we can just cast across from // an integer pointer after shifting out the upper 4 bits. union { @@ -463,19 +423,12 @@ static CFAbsoluteTime extractTaggedNSDate(const void* const object) * * @return The associated class data. */ -static ClassData* getClassData(const void* class) +static ClassData *getClassData(const void *class) { - const char* className = getClassName(class); - for(ClassData* data = g_classData;; data++) - { - unlikely_if(data->name == NULL) - { - return data; - } - unlikely_if(class == data->class) - { - return data; - } + const char *className = getClassName(class); + for (ClassData *data = g_classData;; data++) { + unlikely_if(data->name == NULL) { return data; } + unlikely_if(class == data->class) { return data; } unlikely_if(data->class == NULL && strcmp(className, data->name) == 0) { data->class = class; @@ -484,41 +437,33 @@ static ClassData* getClassData(const void* class) } } -static inline const ClassData* getClassDataFromObject(const void* object) +static inline const ClassData *getClassDataFromObject(const void *object) { - if(isTaggedPointer(object)) - { + if (isTaggedPointer(object)) { return getClassDataFromTaggedPointer(object); } - const struct class_t* obj = object; + const struct class_t *obj = object; return getClassData(getIsaPointer(obj)); } -static int stringPrintf(char* buffer, int bufferLength, const char* fmt, ...) +static int stringPrintf(char *buffer, int bufferLength, const char *fmt, ...) { - unlikely_if(bufferLength == 0) - { - return 0; - } - + unlikely_if(bufferLength == 0) { return 0; } + va_list args; - va_start(args,fmt); + va_start(args, fmt); int printLength = vsnprintf(buffer, bufferLength, fmt, args); va_end(args); - + unlikely_if(printLength < 0) { *buffer = 0; return 0; } - unlikely_if(printLength > bufferLength) - { - return bufferLength-1; - } + unlikely_if(printLength > bufferLength) { return bufferLength - 1; } return printLength; } - //====================================================================== #pragma mark - Validation - //====================================================================== @@ -527,55 +472,46 @@ static int stringPrintf(char* buffer, int bufferLength, const char* fmt, ...) // An ivar name must start with a letter, and can contain letters & numbers. // An ivar type can in theory be any combination of numbers, letters, and symbols // in the ASCII range (0x21-0x7e). -#define INV 0 // Invalid. -#define N_C 5 // Name character: Valid for anything except the first letter of a name. -#define N_S 7 // Name start character: Valid for anything. -#define T_C 4 // Type character: Valid for types only. - -static const unsigned int g_nameChars[] = -{ - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, - N_C, N_C, N_C, N_C, N_C, N_C, N_C, N_C, N_C, N_C, T_C, T_C, T_C, T_C, T_C, T_C, - T_C, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, - N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, T_C, T_C, T_C, T_C, N_S, - T_C, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, - N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, T_C, T_C, T_C, T_C, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, +#define INV 0 // Invalid. +#define N_C 5 // Name character: Valid for anything except the first letter of a name. +#define N_S 7 // Name start character: Valid for anything. +#define T_C 4 // Type character: Valid for types only. + +static const unsigned int g_nameChars[] = { + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, + T_C, T_C, T_C, T_C, N_C, N_C, N_C, N_C, N_C, N_C, N_C, N_C, N_C, N_C, T_C, T_C, T_C, T_C, T_C, T_C, T_C, N_S, + N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, + N_S, N_S, N_S, T_C, T_C, T_C, T_C, N_S, T_C, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, + N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, N_S, T_C, T_C, T_C, T_C, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, }; #define VALID_NAME_CHAR(A) ((g_nameChars[(uint8_t)(A)] & 1) != 0) #define VALID_NAME_START_CHAR(A) ((g_nameChars[(uint8_t)(A)] & 2) != 0) #define VALID_TYPE_CHAR(A) ((g_nameChars[(uint8_t)(A)] & 7) != 0) -static bool isValidName(const char* const name, const int maxLength) +static bool isValidName(const char *const name, const int maxLength) { - if((uintptr_t)name + (unsigned)maxLength < (uintptr_t)name) - { + if ((uintptr_t)name + (unsigned)maxLength < (uintptr_t)name) { // Wrapped around address space. return false; } char buffer[maxLength]; int length = ksmem_copyMaxPossible(name, buffer, maxLength); - if(length == 0 || !VALID_NAME_START_CHAR(name[0])) - { + if (length == 0 || !VALID_NAME_START_CHAR(name[0])) { return false; } - for(int i = 1; i < length; i++) - { + for (int i = 1; i < length; i++) { unlikely_if(!VALID_NAME_CHAR(name[i])) { - if(name[i] == 0) - { + if (name[i] == 0) { return true; } return false; @@ -584,28 +520,24 @@ static bool isValidName(const char* const name, const int maxLength) return false; } -static bool isValidIvarType(const char* const type) +static bool isValidIvarType(const char *const type) { char buffer[100]; const int maxLength = sizeof(buffer); - if((uintptr_t)type + maxLength < (uintptr_t)type) - { + if ((uintptr_t)type + maxLength < (uintptr_t)type) { // Wrapped around address space. return false; } int length = ksmem_copyMaxPossible(type, buffer, maxLength); - if(length == 0 || !VALID_TYPE_CHAR(type[0])) - { + if (length == 0 || !VALID_TYPE_CHAR(type[0])) { return false; } - for(int i = 0; i < length; i++) - { + for (int i = 0; i < length; i++) { unlikely_if(!VALID_TYPE_CHAR(type[i])) { - if(type[i] == 0) - { + if (type[i] == 0) { return true; } } @@ -626,66 +558,54 @@ static bool containsValidExtData(class_rw_t *rw) return true; } -static bool containsValidROData(const void* const classPtr) +static bool containsValidROData(const void *const classPtr) { - const struct class_t* const class = classPtr; - if(!ksmem_isMemoryReadable(class, sizeof(*class))) - { + const struct class_t *const class = classPtr; + if (!ksmem_isMemoryReadable(class, sizeof(*class))) { return false; } - class_rw_t* rw = getClassRW(class); - if(!ksmem_isMemoryReadable(rw, sizeof(*rw))) - { + class_rw_t *rw = getClassRW(class); + if (!ksmem_isMemoryReadable(rw, sizeof(*rw))) { return false; } if (!containsValidExtData(rw)) { return false; } - const class_ro_t* ro = getClassRO(class); - if(!ksmem_isMemoryReadable(ro, sizeof(*ro))) - { + const class_ro_t *ro = getClassRO(class); + if (!ksmem_isMemoryReadable(ro, sizeof(*ro))) { return false; } return true; } -static bool containsValidIvarData(const void* const classPtr) +static bool containsValidIvarData(const void *const classPtr) { - const struct class_ro_t* ro = getClassRO(classPtr); - const struct ivar_list_t* ivars = ro->ivars; - if(ivars == NULL) - { + const struct class_ro_t *ro = getClassRO(classPtr); + const struct ivar_list_t *ivars = ro->ivars; + if (ivars == NULL) { return true; } - if(!ksmem_isMemoryReadable(ivars, sizeof(*ivars))) - { + if (!ksmem_isMemoryReadable(ivars, sizeof(*ivars))) { return false; } - - if(ivars->count > 0) - { + + if (ivars->count > 0) { struct ivar_t ivar; - uint8_t* ivarPtr = (uint8_t*)(&ivars->first) + ivars->entsizeAndFlags; - for(uint32_t i = 1; i < ivars->count; i++) - { - if(!ksmem_copySafely(ivarPtr, &ivar, sizeof(ivar))) - { + uint8_t *ivarPtr = (uint8_t *)(&ivars->first) + ivars->entsizeAndFlags; + for (uint32_t i = 1; i < ivars->count; i++) { + if (!ksmem_copySafely(ivarPtr, &ivar, sizeof(ivar))) { return false; } - if(!ksmem_isMemoryReadable(ivarPtr, (int)ivars->entsizeAndFlags)) - { + if (!ksmem_isMemoryReadable(ivarPtr, (int)ivars->entsizeAndFlags)) { return false; } - if(!ksmem_isMemoryReadable(ivar.offset, sizeof(*ivar.offset))) - { + if (!ksmem_isMemoryReadable(ivar.offset, sizeof(*ivar.offset))) { return false; } - if(!isValidName(ivar.name, kMaxNameLength)) - { + if (!isValidName(ivar.name, kMaxNameLength)) { return false; } - if(!isValidIvarType(ivar.type)) - { + if (!isValidIvarType(ivar.type)) { return false; } ivarPtr += ivars->entsizeAndFlags; @@ -694,248 +614,202 @@ static bool containsValidIvarData(const void* const classPtr) return true; } -static bool containsValidClassName(const void* const classPtr) +static bool containsValidClassName(const void *const classPtr) { - const struct class_ro_t* ro = getClassRO(classPtr); + const struct class_ro_t *ro = getClassRO(classPtr); return isValidName(ro->name, kMaxNameLength); } -static bool hasValidIsaPointer(const void* object) { - const struct class_t* isaPtr = getIsaPointer(object); +static bool hasValidIsaPointer(const void *object) +{ + const struct class_t *isaPtr = getIsaPointer(object); return ksmem_isMemoryReadable(isaPtr, sizeof(*isaPtr)); } -static inline bool isValidClass(const void* classPtr) +static inline bool isValidClass(const void *classPtr) { - const class_t* class = classPtr; - if(!ksmem_isMemoryReadable(class, sizeof(*class))) - { + const class_t *class = classPtr; + if (!ksmem_isMemoryReadable(class, sizeof(*class))) { return false; } - if(!containsValidROData(class)) - { + if (!containsValidROData(class)) { return false; } - if(!containsValidClassName(class)) - { + if (!containsValidClassName(class)) { return false; } - if(!containsValidIvarData(class)) - { + if (!containsValidIvarData(class)) { return false; } return true; } -static inline bool isValidObject(const void* objectPtr) +static inline bool isValidObject(const void *objectPtr) { - if(isTaggedPointer(objectPtr)) - { + if (isTaggedPointer(objectPtr)) { return isValidTaggedPointer(objectPtr); } - const class_t* object = objectPtr; - if(!ksmem_isMemoryReadable(object, sizeof(*object))) - { + const class_t *object = objectPtr; + if (!ksmem_isMemoryReadable(object, sizeof(*object))) { return false; } - if(!hasValidIsaPointer(object)) - { + if (!hasValidIsaPointer(object)) { return false; } - if(!isValidClass(getIsaPointer(object))) - { + if (!isValidClass(getIsaPointer(object))) { return false; } return true; } - - //====================================================================== #pragma mark - Basic Objective-C Queries - //====================================================================== -const void* ksobjc_isaPointer(const void* const objectOrClassPtr) -{ - return getIsaPointer(objectOrClassPtr); -} +const void *ksobjc_isaPointer(const void *const objectOrClassPtr) { return getIsaPointer(objectOrClassPtr); } -const void* ksobjc_superClass(const void* const classPtr) -{ - return getSuperClass(classPtr); -} +const void *ksobjc_superClass(const void *const classPtr) { return getSuperClass(classPtr); } -bool ksobjc_isMetaClass(const void* const classPtr) -{ - return isMetaClass(classPtr); -} +bool ksobjc_isMetaClass(const void *const classPtr) { return isMetaClass(classPtr); } -bool ksobjc_isRootClass(const void* const classPtr) -{ - return isRootClass(classPtr); -} +bool ksobjc_isRootClass(const void *const classPtr) { return isRootClass(classPtr); } -const char* ksobjc_className(const void* classPtr) -{ - return getClassName(classPtr); -} +const char *ksobjc_className(const void *classPtr) { return getClassName(classPtr); } -const char* ksobjc_objectClassName(const void* objectPtr) +const char *ksobjc_objectClassName(const void *objectPtr) { - if(isTaggedPointer(objectPtr)) - { - if(isValidTaggedPointer(objectPtr)) - { - const ClassData* class = getClassDataFromTaggedPointer(objectPtr); + if (isTaggedPointer(objectPtr)) { + if (isValidTaggedPointer(objectPtr)) { + const ClassData *class = getClassDataFromTaggedPointer(objectPtr); return class->name; } return NULL; } - const void* isaPtr = getIsaPointer(objectPtr); + const void *isaPtr = getIsaPointer(objectPtr); return getClassName(isaPtr); } -bool ksobjc_isClassNamed(const void* const classPtr, const char* const className) +bool ksobjc_isClassNamed(const void *const classPtr, const char *const className) { - const char* name = getClassName(classPtr); - if(name == NULL || className == NULL) - { + const char *name = getClassName(classPtr); + if (name == NULL || className == NULL) { return false; } return strcmp(name, className) == 0; } -bool ksobjc_isKindOfClass(const void* const classPtr, const char* const className) +bool ksobjc_isKindOfClass(const void *const classPtr, const char *const className) { - if(className == NULL) - { + if (className == NULL) { return false; } - - const struct class_t* class = (const struct class_t*)classPtr; - - for(int i = 0; i < 20; i++) - { - const char* name = getClassName(class); - if(name == NULL) - { + + const struct class_t *class = (const struct class_t *)classPtr; + + for (int i = 0; i < 20; i++) { + const char *name = getClassName(class); + if (name == NULL) { return false; } - if(strcmp(className, name) == 0) - { + if (strcmp(className, name) == 0) { return true; } class = class->superclass; - if(!containsValidROData(class)) - { + if (!containsValidROData(class)) { return false; } } return false; } -const void* ksobjc_baseClass(const void* const classPtr) +const void *ksobjc_baseClass(const void *const classPtr) { - const struct class_t* superClass = classPtr; - const struct class_t* subClass = classPtr; - - for(int i = 0; i < 20; i++) - { - if(isRootClass(superClass)) - { + const struct class_t *superClass = classPtr; + const struct class_t *subClass = classPtr; + + for (int i = 0; i < 20; i++) { + if (isRootClass(superClass)) { return subClass; } subClass = superClass; superClass = superClass->superclass; - if(!containsValidROData(superClass)) - { + if (!containsValidROData(superClass)) { return NULL; } } return NULL; } -int ksobjc_ivarCount(const void* const classPtr) +int ksobjc_ivarCount(const void *const classPtr) { - const struct ivar_list_t* ivars = getClassRO(classPtr)->ivars; - if(ivars == NULL) - { + const struct ivar_list_t *ivars = getClassRO(classPtr)->ivars; + if (ivars == NULL) { return 0; } return (int)ivars->count; } -int ksobjc_ivarList(const void* const classPtr, KSObjCIvar* dstIvars, int ivarsCount) +int ksobjc_ivarList(const void *const classPtr, KSObjCIvar *dstIvars, int ivarsCount) { // TODO: Check this for a possible bad access. - if(dstIvars == NULL) - { + if (dstIvars == NULL) { return 0; } - + int count = ksobjc_ivarCount(classPtr); - if(count == 0) - { + if (count == 0) { return 0; } - if(ivarsCount < count) - { + if (ivarsCount < count) { count = ivarsCount; } - const struct ivar_list_t* srcIvars = getClassRO(classPtr)->ivars; + const struct ivar_list_t *srcIvars = getClassRO(classPtr)->ivars; uintptr_t srcPtr = (uintptr_t)&srcIvars->first; - const struct ivar_t* src = (void*)srcPtr; - for(int i = 0; i < count; i++) - { - KSObjCIvar* dst = &dstIvars[i]; + const struct ivar_t *src = (void *)srcPtr; + for (int i = 0; i < count; i++) { + KSObjCIvar *dst = &dstIvars[i]; dst->name = src->name; dst->type = src->type; dst->index = i; srcPtr += srcIvars->entsizeAndFlags; - src = (void*)srcPtr; + src = (void *)srcPtr; } return count; } -bool ksobjc_ivarNamed(const void* const classPtr, const char* name, KSObjCIvar* dst) +bool ksobjc_ivarNamed(const void *const classPtr, const char *name, KSObjCIvar *dst) { - if(name == NULL) - { + if (name == NULL) { return false; } - const struct ivar_list_t* ivars = getClassRO(classPtr)->ivars; + const struct ivar_list_t *ivars = getClassRO(classPtr)->ivars; uintptr_t ivarPtr = (uintptr_t)&ivars->first; - const struct ivar_t* ivar = (void*)ivarPtr; - for(int i = 0; i < (int)ivars->count; i++) - { - if(ivar->name != NULL && strcmp(name, ivar->name) == 0) - { + const struct ivar_t *ivar = (void *)ivarPtr; + for (int i = 0; i < (int)ivars->count; i++) { + if (ivar->name != NULL && strcmp(name, ivar->name) == 0) { dst->name = ivar->name; dst->type = ivar->type; dst->index = i; return true; } ivarPtr += ivars->entsizeAndFlags; - ivar = (void*)ivarPtr; + ivar = (void *)ivarPtr; } return false; } -bool ksobjc_ivarValue(const void* const objectPtr, int ivarIndex, void* dst) +bool ksobjc_ivarValue(const void *const objectPtr, int ivarIndex, void *dst) { #if OBJC_HAVE_TAGGED_POINTERS - if(isTaggedPointer(objectPtr)) - { + if (isTaggedPointer(objectPtr)) { // Naively assume they want "value". - if(isTaggedPointerNSDate(objectPtr)) - { + if (isTaggedPointerNSDate(objectPtr)) { CFTimeInterval value = extractTaggedNSDate(objectPtr); memcpy(dst, &value, sizeof(value)); return true; } - if(isTaggedPointerNSNumber(objectPtr)) - { + if (isTaggedPointerNSNumber(objectPtr)) { // TODO: Correct to assume 64-bit signed int? What does the actual ivar say? int64_t value = extractTaggedNSNumber(objectPtr); memcpy(dst, &value, sizeof(value)); @@ -944,223 +818,180 @@ bool ksobjc_ivarValue(const void* const objectPtr, int ivarIndex, void* dst) return false; } #endif - const void* const classPtr = getIsaPointer(objectPtr); - const struct ivar_list_t* ivars = getClassRO(classPtr)->ivars; - if(ivarIndex >= (int)ivars->count) - { + const void *const classPtr = getIsaPointer(objectPtr); + const struct ivar_list_t *ivars = getClassRO(classPtr)->ivars; + if (ivarIndex >= (int)ivars->count) { return false; } uintptr_t ivarPtr = (uintptr_t)&ivars->first; - const struct ivar_t* ivar = (void*)(ivarPtr + (uintptr_t)ivars->entsizeAndFlags * (uintptr_t)ivarIndex); - + const struct ivar_t *ivar = (void *)(ivarPtr + (uintptr_t)ivars->entsizeAndFlags * (uintptr_t)ivarIndex); + uintptr_t valuePtr = (uintptr_t)objectPtr + (uintptr_t)*ivar->offset; - if(!ksmem_copySafely((void*)valuePtr, dst, (int)ivar->size)) - { + if (!ksmem_copySafely((void *)valuePtr, dst, (int)ivar->size)) { return false; } return true; } -uintptr_t ksobjc_taggedPointerPayload(const void* taggedObjectPtr) -{ - return getTaggedPayload(taggedObjectPtr); -} +uintptr_t ksobjc_taggedPointerPayload(const void *taggedObjectPtr) { return getTaggedPayload(taggedObjectPtr); } -static inline bool isBlockClass(const void* class) +static inline bool isBlockClass(const void *class) { - const void* baseClass = ksobjc_baseClass(class); - if(baseClass == NULL) - { + const void *baseClass = ksobjc_baseClass(class); + if (baseClass == NULL) { return false; } - const char* name = getClassName(baseClass); - if(name == NULL) - { + const char *name = getClassName(baseClass); + if (name == NULL) { return false; } return strcmp(name, g_blockBaseClassName) == 0; } -KSObjCType ksobjc_objectType(const void* objectOrClassPtr) +KSObjCType ksobjc_objectType(const void *objectOrClassPtr) { - if(objectOrClassPtr == NULL) - { + if (objectOrClassPtr == NULL) { return KSObjCTypeUnknown; } - if(isTaggedPointer(objectOrClassPtr)) - { + if (isTaggedPointer(objectOrClassPtr)) { return KSObjCTypeObject; } - - if(!isValidObject(objectOrClassPtr) && !isValidClass(objectOrClassPtr)) - { + + if (!isValidObject(objectOrClassPtr) && !isValidClass(objectOrClassPtr)) { return KSObjCTypeUnknown; } - - const struct class_t* isa = getIsaPointer(objectOrClassPtr); - if(isBlockClass(isa)) - { + const struct class_t *isa = getIsaPointer(objectOrClassPtr); + + if (isBlockClass(isa)) { return KSObjCTypeBlock; } - if(!isMetaClass(isa)) - { + if (!isMetaClass(isa)) { return KSObjCTypeObject; } - + return KSObjCTypeClass; } - //====================================================================== #pragma mark - Unknown Object - //====================================================================== -static bool objectIsValid(__unused const void* object) +static bool objectIsValid(__unused const void *object) { // If it passed ksobjc_objectType, it's been validated as much as // possible. return true; } -static bool taggedObjectIsValid(const void* object) -{ - return isValidTaggedPointer(object); -} +static bool taggedObjectIsValid(const void *object) { return isValidTaggedPointer(object); } -static int objectDescription(const void* object, char* buffer, int bufferLength) +static int objectDescription(const void *object, char *buffer, int bufferLength) { - const void* class = getIsaPointer(object); - const char* name = getClassName(class); + const void *class = getIsaPointer(object); + const char *name = getClassName(class); uintptr_t objPointer = (uintptr_t)object; - const char* fmt = sizeof(uintptr_t) == sizeof(uint32_t) ? "<%s: 0x%08x>" : "<%s: 0x%016x>"; + const char *fmt = sizeof(uintptr_t) == sizeof(uint32_t) ? "<%s: 0x%08x>" : "<%s: 0x%016x>"; return stringPrintf(buffer, bufferLength, fmt, name, objPointer); } -static int taggedObjectDescription(const void* object, char* buffer, int bufferLength) +static int taggedObjectDescription(const void *object, char *buffer, int bufferLength) { - const ClassData* data = getClassDataFromTaggedPointer(object); - const char* name = data->name; + const ClassData *data = getClassDataFromTaggedPointer(object); + const char *name = data->name; uintptr_t objPointer = (uintptr_t)object; - const char* fmt = sizeof(uintptr_t) == sizeof(uint32_t) ? "<%s: 0x%08x>" : "<%s: 0x%016x>"; + const char *fmt = sizeof(uintptr_t) == sizeof(uint32_t) ? "<%s: 0x%08x>" : "<%s: 0x%016x>"; return stringPrintf(buffer, bufferLength, fmt, name, objPointer); } - //====================================================================== #pragma mark - NSString - //====================================================================== -static inline const char* stringStart(const struct __CFString* str) +static inline const char *stringStart(const struct __CFString *str) { - return (const char*)__CFStrContents(str) + (__CFStrHasLengthByte(str) ? 1 : 0); + return (const char *)__CFStrContents(str) + (__CFStrHasLengthByte(str) ? 1 : 0); } -static bool stringIsValid(const void* const stringPtr) +static bool stringIsValid(const void *const stringPtr) { - const struct __CFString* string = stringPtr; + const struct __CFString *string = stringPtr; struct __CFString temp; uint8_t oneByte; CFIndex length = -1; - if(!ksmem_copySafely(string, &temp, sizeof(string->base))) - { + if (!ksmem_copySafely(string, &temp, sizeof(string->base))) { return false; } - - if(__CFStrIsInline(string)) - { - if(!ksmem_copySafely(&string->variants.inline1, &temp, sizeof(string->variants.inline1))) - { + + if (__CFStrIsInline(string)) { + if (!ksmem_copySafely(&string->variants.inline1, &temp, sizeof(string->variants.inline1))) { return false; } length = string->variants.inline1.length; - } - else if(__CFStrIsMutable(string)) - { - if(!ksmem_copySafely(&string->variants.notInlineMutable, &temp, sizeof(string->variants.notInlineMutable))) - { + } else if (__CFStrIsMutable(string)) { + if (!ksmem_copySafely(&string->variants.notInlineMutable, &temp, sizeof(string->variants.notInlineMutable))) { return false; } length = string->variants.notInlineMutable.length; - } - else if(!__CFStrHasLengthByte(string)) - { - if(!ksmem_copySafely(&string->variants.notInlineImmutable1, &temp, sizeof(string->variants.notInlineImmutable1))) - { + } else if (!__CFStrHasLengthByte(string)) { + if (!ksmem_copySafely(&string->variants.notInlineImmutable1, &temp, + sizeof(string->variants.notInlineImmutable1))) { return false; } length = string->variants.notInlineImmutable1.length; - } - else - { - if(!ksmem_copySafely(&string->variants.notInlineImmutable2, &temp, sizeof(string->variants.notInlineImmutable2))) - { + } else { + if (!ksmem_copySafely(&string->variants.notInlineImmutable2, &temp, + sizeof(string->variants.notInlineImmutable2))) { return false; } - if(!ksmem_copySafely(__CFStrContents(string), &oneByte, sizeof(oneByte))) - { + if (!ksmem_copySafely(__CFStrContents(string), &oneByte, sizeof(oneByte))) { return false; } length = oneByte; } - - if(length < 0) - { + + if (length < 0) { return false; - } - else if(length > 0) - { - if(!ksmem_copySafely(stringStart(string), &oneByte, sizeof(oneByte))) - { + } else if (length > 0) { + if (!ksmem_copySafely(stringStart(string), &oneByte, sizeof(oneByte))) { return false; } } return true; } -int ksobjc_stringLength(const void* const stringPtr) +int ksobjc_stringLength(const void *const stringPtr) { - if(isTaggedPointer(stringPtr) && isTaggedPointerNSString(stringPtr)) - { + if (isTaggedPointer(stringPtr) && isTaggedPointerNSString(stringPtr)) { return getTaggedNSStringLength(stringPtr); } - const struct __CFString* string = stringPtr; + const struct __CFString *string = stringPtr; - if (__CFStrHasExplicitLength(string)) - { - if (__CFStrIsInline(string)) - { + if (__CFStrHasExplicitLength(string)) { + if (__CFStrIsInline(string)) { return (int)string->variants.inline1.length; - } - else - { + } else { return (int)string->variants.notInlineImmutable1.length; } - } - else - { + } else { return *((uint8_t *)__CFStrContents(string)); } } -#define kUTF16_LeadSurrogateStart 0xd800u -#define kUTF16_LeadSurrogateEnd 0xdbffu -#define kUTF16_TailSurrogateStart 0xdc00u -#define kUTF16_TailSurrogateEnd 0xdfffu -#define kUTF16_FirstSupplementaryPlane 0x10000u +#define kUTF16_LeadSurrogateStart 0xd800u +#define kUTF16_LeadSurrogateEnd 0xdbffu +#define kUTF16_TailSurrogateStart 0xdc00u +#define kUTF16_TailSurrogateEnd 0xdfffu +#define kUTF16_FirstSupplementaryPlane 0x10000u -static int copyAndConvertUTF16StringToUTF8(const void* const src, - void* const dst, - int charCount, - int maxByteCount) +static int copyAndConvertUTF16StringToUTF8(const void *const src, void *const dst, int charCount, int maxByteCount) { - const uint16_t* pSrc = src; - uint8_t* pDst = dst; - const uint8_t* const pDstEnd = pDst + maxByteCount - 1; // Leave room for null termination. - for(int charsRemaining = charCount; charsRemaining > 0 && pDst < pDstEnd; charsRemaining--) - { + const uint16_t *pSrc = src; + uint8_t *pDst = dst; + const uint8_t *const pDstEnd = pDst + maxByteCount - 1; // Leave room for null termination. + for (int charsRemaining = charCount; charsRemaining > 0 && pDst < pDstEnd; charsRemaining--) { // Decode UTF-16 uint32_t character = 0; uint16_t leadSurrogate = *pSrc++; @@ -1168,133 +999,113 @@ static int copyAndConvertUTF16StringToUTF8(const void* const src, { character = leadSurrogate; } - else if(leadSurrogate > kUTF16_LeadSurrogateEnd) + else if (leadSurrogate > kUTF16_LeadSurrogateEnd) { // Inverted surrogate - *((uint8_t*)dst) = 0; + *((uint8_t *)dst) = 0; return 0; } else { uint16_t tailSurrogate = *pSrc++; - if(tailSurrogate < kUTF16_TailSurrogateStart || tailSurrogate > kUTF16_TailSurrogateEnd) - { + if (tailSurrogate < kUTF16_TailSurrogateStart || tailSurrogate > kUTF16_TailSurrogateEnd) { // Invalid tail surrogate - *((uint8_t*)dst) = 0; + *((uint8_t *)dst) = 0; return 0; } - character = ((leadSurrogate - kUTF16_LeadSurrogateStart) << 10) + (tailSurrogate - kUTF16_TailSurrogateStart); + character = + ((leadSurrogate - kUTF16_LeadSurrogateStart) << 10) + (tailSurrogate - kUTF16_TailSurrogateStart); character += kUTF16_FirstSupplementaryPlane; charsRemaining--; } - + // Encode UTF-8 - likely_if(character <= 0x7f) + likely_if(character <= 0x7f) { *pDst++ = (uint8_t)character; } + else if (character <= 0x7ff) { - *pDst++ = (uint8_t)character; - } - else if(character <= 0x7ff) - { - if(pDstEnd - pDst >= 2) - { + if (pDstEnd - pDst >= 2) { *pDst++ = (uint8_t)(0xc0 | (character >> 6)); *pDst++ = (uint8_t)(0x80 | (character & 0x3f)); - } - else - { + } else { break; } } - else if(character <= 0xffff) + else if (character <= 0xffff) { - if(pDstEnd - pDst >= 3) - { + if (pDstEnd - pDst >= 3) { *pDst++ = (uint8_t)(0xe0 | (character >> 12)); *pDst++ = (uint8_t)(0x80 | ((character >> 6) & 0x3f)); *pDst++ = (uint8_t)(0x80 | (character & 0x3f)); - } - else - { + } else { break; } } // RFC3629 restricts UTF-8 to end at 0x10ffff. - else if(character <= 0x10ffff) + else if (character <= 0x10ffff) { - if(pDstEnd - pDst >= 4) - { + if (pDstEnd - pDst >= 4) { *pDst++ = (uint8_t)(0xf0 | (character >> 18)); *pDst++ = (uint8_t)(0x80 | ((character >> 12) & 0x3f)); *pDst++ = (uint8_t)(0x80 | ((character >> 6) & 0x3f)); *pDst++ = (uint8_t)(0x80 | (character & 0x3f)); - } - else - { + } else { break; } } else { // Invalid unicode. - *((uint8_t*)dst) = 0; + *((uint8_t *)dst) = 0; return 0; } } - + // Null terminate and return. *pDst = 0; - return (int)(pDst - (uint8_t*)dst); + return (int)(pDst - (uint8_t *)dst); } -static int copy8BitString(const void* const src, void* const dst, int charCount, int maxByteCount) +static int copy8BitString(const void *const src, void *const dst, int charCount, int maxByteCount) { - unlikely_if(maxByteCount == 0) - { - return 0; - } + unlikely_if(maxByteCount == 0) { return 0; } unlikely_if(charCount == 0) { - *((uint8_t*)dst) = 0; + *((uint8_t *)dst) = 0; return 0; } - unlikely_if(charCount >= maxByteCount) - { - charCount = maxByteCount - 1; - } + unlikely_if(charCount >= maxByteCount) { charCount = maxByteCount - 1; } unlikely_if(!ksmem_copySafely(src, dst, charCount)) { - *((uint8_t*)dst) = 0; + *((uint8_t *)dst) = 0; return 0; } - uint8_t* charDst = dst; + uint8_t *charDst = dst; charDst[charCount] = 0; return charCount; } -int ksobjc_copyStringContents(const void* stringPtr, char* dst, int maxByteCount) +int ksobjc_copyStringContents(const void *stringPtr, char *dst, int maxByteCount) { - if(isTaggedPointer(stringPtr) && isTaggedPointerNSString(stringPtr)) - { + if (isTaggedPointer(stringPtr) && isTaggedPointerNSString(stringPtr)) { return extractTaggedNSString(stringPtr, dst, maxByteCount); } - const struct __CFString* string = stringPtr; + const struct __CFString *string = stringPtr; int charCount = ksobjc_stringLength(string); - - const char* src = stringStart(string); - if(__CFStrIsUnicode(string)) - { + + const char *src = stringStart(string); + if (__CFStrIsUnicode(string)) { return copyAndConvertUTF16StringToUTF8(src, dst, charCount, maxByteCount); } - + return copy8BitString(src, dst, charCount, maxByteCount); } -static int stringDescription(const void* object, char* buffer, int bufferLength) +static int stringDescription(const void *object, char *buffer, int bufferLength) { - char* pBuffer = buffer; - char* pEnd = buffer + bufferLength; - + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": \""); pBuffer += ksobjc_copyStringContents(object, pBuffer, (int)(pEnd - pBuffer)); @@ -1303,95 +1114,91 @@ static int stringDescription(const void* object, char* buffer, int bufferLength) return (int)(pBuffer - buffer); } -static bool taggedStringIsValid(const void* const object) +static bool taggedStringIsValid(const void *const object) { return isValidTaggedPointer(object) && isTaggedPointerNSString(object); } -static int taggedStringDescription(const void* object, char* buffer, __unused int bufferLength) +static int taggedStringDescription(const void *object, char *buffer, __unused int bufferLength) { return extractTaggedNSString(object, buffer, bufferLength); } - //====================================================================== #pragma mark - NSURL - //====================================================================== -static bool urlIsValid(const void* const urlPtr) +static bool urlIsValid(const void *const urlPtr) { struct __CFURL url; - if(!ksmem_copySafely(urlPtr, &url, sizeof(url))) - { + if (!ksmem_copySafely(urlPtr, &url, sizeof(url))) { return false; } return stringIsValid(url._string); } -int ksobjc_copyURLContents(const void* const urlPtr, char* dst, int maxLength) +int ksobjc_copyURLContents(const void *const urlPtr, char *dst, int maxLength) { - const struct __CFURL* url = urlPtr; + const struct __CFURL *url = urlPtr; return ksobjc_copyStringContents(url->_string, dst, maxLength); } -static int urlDescription(const void* object, char* buffer, int bufferLength) +static int urlDescription(const void *object, char *buffer, int bufferLength) { - char* pBuffer = buffer; - char* pEnd = buffer + bufferLength; - + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": \""); pBuffer += ksobjc_copyURLContents(object, pBuffer, (int)(pEnd - pBuffer)); pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), "\""); - + return (int)(pBuffer - buffer); } - //====================================================================== #pragma mark - NSDate - //====================================================================== -static bool dateIsValid(const void* const datePtr) +static bool dateIsValid(const void *const datePtr) { struct __CFDate temp; return ksmem_copySafely(datePtr, &temp, sizeof(temp)); } -CFAbsoluteTime ksobjc_dateContents(const void* const datePtr) +CFAbsoluteTime ksobjc_dateContents(const void *const datePtr) { #if OBJC_HAVE_TAGGED_POINTERS - if(isValidTaggedPointer(datePtr)) - { + if (isValidTaggedPointer(datePtr)) { return extractTaggedNSDate(datePtr); } #endif - const struct __CFDate* date = datePtr; + const struct __CFDate *date = datePtr; return date->_time; } -static int dateDescription(const void* object, char* buffer, int bufferLength) +static int dateDescription(const void *object, char *buffer, int bufferLength) { - char* pBuffer = buffer; - char* pEnd = buffer + bufferLength; - + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + CFAbsoluteTime time = ksobjc_dateContents(object); pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %f", time); - + return (int)(pBuffer - buffer); } -static bool taggedDateIsValid(const void* const datePtr) +static bool taggedDateIsValid(const void *const datePtr) { return isValidTaggedPointer(datePtr) && isTaggedPointerNSDate(datePtr); } -static int taggedDateDescription(const void* object, char* buffer, int bufferLength) +static int taggedDateDescription(const void *object, char *buffer, int bufferLength) { #if OBJC_HAVE_TAGGED_POINTERS - char* pBuffer = buffer; - char* pEnd = buffer + bufferLength; + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; CFAbsoluteTime time = extractTaggedNSDate(object); pBuffer += taggedObjectDescription(object, pBuffer, (int)(pEnd - pBuffer)); @@ -1403,84 +1210,74 @@ static int taggedDateDescription(const void* object, char* buffer, int bufferLen #endif } - //====================================================================== #pragma mark - NSNumber - //====================================================================== #define NSNUMBER_CASE(CFTYPE, RETURN_TYPE, CAST_TYPE, DATA) \ - case CFTYPE: \ - { \ - RETURN_TYPE result; \ - memcpy(&result, DATA, sizeof(result)); \ - return (CAST_TYPE)result; \ - } - -#define EXTRACT_AND_RETURN_NSNUMBER(OBJECT, RETURN_TYPE) \ - if(isValidTaggedPointer(object)) \ - { \ - return extractTaggedNSNumber(object); \ - } \ - const struct __CFNumber* number = OBJECT; \ - CFNumberType cftype = CFNumberGetType((CFNumberRef)OBJECT); \ - const void *data = &(number->_pad); \ - switch(cftype) \ - { \ - NSNUMBER_CASE( kCFNumberSInt8Type, int8_t, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberSInt16Type, int16_t, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberSInt32Type, int32_t, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberSInt64Type, int64_t, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberFloat32Type, Float32, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberFloat64Type, Float64, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberCharType, char, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberShortType, short, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberIntType, int, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberLongType, long, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberLongLongType, long long, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberFloatType, float, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberDoubleType, double, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberCFIndexType, CFIndex, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberNSIntegerType, NSInteger, RETURN_TYPE, data ) \ - NSNUMBER_CASE( kCFNumberCGFloatType, CGFloat, RETURN_TYPE, data ) \ - } - -Float64 ksobjc_numberAsFloat(const void* object) + case CFTYPE: { \ + RETURN_TYPE result; \ + memcpy(&result, DATA, sizeof(result)); \ + return (CAST_TYPE)result; \ + } + +#define EXTRACT_AND_RETURN_NSNUMBER(OBJECT, RETURN_TYPE) \ + if (isValidTaggedPointer(object)) { \ + return extractTaggedNSNumber(object); \ + } \ + const struct __CFNumber *number = OBJECT; \ + CFNumberType cftype = CFNumberGetType((CFNumberRef)OBJECT); \ + const void *data = &(number->_pad); \ + switch (cftype) { \ + NSNUMBER_CASE(kCFNumberSInt8Type, int8_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberSInt16Type, int16_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberSInt32Type, int32_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberSInt64Type, int64_t, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberFloat32Type, Float32, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberFloat64Type, Float64, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberCharType, char, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberShortType, short, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberIntType, int, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberLongType, long, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberLongLongType, long long, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberFloatType, float, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberDoubleType, double, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberCFIndexType, CFIndex, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberNSIntegerType, NSInteger, RETURN_TYPE, data) \ + NSNUMBER_CASE(kCFNumberCGFloatType, CGFloat, RETURN_TYPE, data) \ + } + +Float64 ksobjc_numberAsFloat(const void *object) { EXTRACT_AND_RETURN_NSNUMBER(object, Float64); return NAN; } -int64_t ksobjc_numberAsInteger(const void* object) +int64_t ksobjc_numberAsInteger(const void *object) { EXTRACT_AND_RETURN_NSNUMBER(object, int64_t); return 0; } -bool ksobjc_numberIsFloat(const void* object) -{ - return CFNumberIsFloatType((CFNumberRef)object); -} +bool ksobjc_numberIsFloat(const void *object) { return CFNumberIsFloatType((CFNumberRef)object); } -static bool numberIsValid(const void* const datePtr) +static bool numberIsValid(const void *const datePtr) { struct __CFNumber temp; return ksmem_copySafely(datePtr, &temp, sizeof(temp)); } -static int numberDescription(const void* object, char* buffer, int bufferLength) +static int numberDescription(const void *object, char *buffer, int bufferLength) { - char* pBuffer = buffer; - char* pEnd = buffer + bufferLength; + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); - if(ksobjc_numberIsFloat(object)) - { + if (ksobjc_numberIsFloat(object)) { Float64 value = ksobjc_numberAsFloat(object); pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %lf", value); - } - else - { + } else { int64_t value = ksobjc_numberAsInteger(object); pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": %" PRId64, value); } @@ -1488,15 +1285,15 @@ static int numberDescription(const void* object, char* buffer, int bufferLength) return (int)(pBuffer - buffer); } -static bool taggedNumberIsValid(const void* const object) +static bool taggedNumberIsValid(const void *const object) { return isValidTaggedPointer(object) && isTaggedPointerNSNumber(object); } -static int taggedNumberDescription(const void* object, char* buffer, int bufferLength) +static int taggedNumberDescription(const void *object, char *buffer, int bufferLength) { - char* pBuffer = buffer; - char* pEnd = buffer + bufferLength; + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; int64_t value = extractTaggedNSNumber(object); pBuffer += taggedObjectDescription(object, pBuffer, (int)(pEnd - pBuffer)); @@ -1505,7 +1302,6 @@ static int taggedNumberDescription(const void* object, char* buffer, int bufferL return (int)(pBuffer - buffer); } - //====================================================================== #pragma mark - NSArray - //====================================================================== @@ -1513,17 +1309,14 @@ static int taggedNumberDescription(const void* object, char* buffer, int bufferL /** * For old types */ -struct NSArray -{ - struct - { - void* isa; +struct NSArray { + struct { + void *isa; CFIndex count; id firstEntry; } basic; }; - /** * @struct NSArrayDescriptor * @brief Descriptor for new types like `__NSSingleObjectArrayI`, `__NSArrayM`, `__NSFrozenArrayM`. @@ -1544,8 +1337,7 @@ struct NSArray * * @note The `packed` attribute ensures that there is no padding between the fields of the structure. */ -typedef struct __attribute__((packed)) -{ +typedef struct __attribute__((packed)) { uintptr_t _cow; uintptr_t _data; uint32_t _offset; @@ -1554,12 +1346,9 @@ typedef struct __attribute__((packed)) uint32_t _used; } NSArrayDescriptor; -static inline bool nsarrayIsMutable(const void* const arrayPtr) -{ - return getClassDataFromObject(arrayPtr)->isMutable; -} +static inline bool nsarrayIsMutable(const void *const arrayPtr) { return getClassDataFromObject(arrayPtr)->isMutable; } -static inline bool nsarrayIsValid(const void* const arrayPtr) +static inline bool nsarrayIsValid(const void *const arrayPtr) { struct NSArray temp; return ksmem_copySafely(arrayPtr, &temp, sizeof(temp.basic)); @@ -1571,94 +1360,75 @@ static inline bool nsarrayIsValid(const void* const arrayPtr) * @note This function is based on the LLVM code in the NSArray.cpp file: * https://github.com/apple/llvm-project/blob/29180d27e709b76965cc02c338188e37f2df9e7f/lldb/source/Plugins/Language/ObjC/NSArray.cpp#L396-L412 */ -static inline int nsarrayCount(const void* const arrayPtr) +static inline int nsarrayCount(const void *const arrayPtr) { - const char* const className = ksobjc_objectClassName(arrayPtr); + const char *const className = ksobjc_objectClassName(arrayPtr); bool isMutable = kCFCoreFoundationVersionNumber > 1437 && strcmp(className, "__NSArrayM") == 0; bool isFrozen = kCFCoreFoundationVersionNumber > 1436 && strcmp(className, "__NSFrozenArrayM") == 0; - if (isMutable || isFrozen) - { + if (isMutable || isFrozen) { NSArrayDescriptor descriptor = { 0 }; - if (ksmem_copySafely((const void*)((uintptr_t)arrayPtr + sizeof(uintptr_t)), &descriptor, - sizeof(NSArrayDescriptor))) - { + if (ksmem_copySafely((const void *)((uintptr_t)arrayPtr + sizeof(uintptr_t)), &descriptor, + sizeof(NSArrayDescriptor))) { return descriptor._used; } - } - else if (strcmp(className, "__NSSingleObjectArrayI") == 0) - { + } else if (strcmp(className, "__NSSingleObjectArrayI") == 0) { return 1; - } - else if (strcmp(className, "__NSArray0") == 0) - { + } else if (strcmp(className, "__NSArray0") == 0) { return 0; - } - else - { - const struct NSArray* array = arrayPtr; + } else { + const struct NSArray *array = arrayPtr; return (array->basic.count >= 0) ? (int)array->basic.count : 0; } return 0; } -static int nsarrayContents(const void* const arrayPtr, uintptr_t* contents, int count) +static int nsarrayContents(const void *const arrayPtr, uintptr_t *contents, int count) { int actualCount = nsarrayCount(arrayPtr); - const char* const className = ksobjc_objectClassName(arrayPtr); + const char *const className = ksobjc_objectClassName(arrayPtr); - if (actualCount < count) - { - if (actualCount <= 0) - { + if (actualCount < count) { + if (actualCount <= 0) { return 0; } count = actualCount; } - if (nsarrayIsMutable(arrayPtr)) - { + if (nsarrayIsMutable(arrayPtr)) { return 0; } - const uintptr_t* entry = NULL; + const uintptr_t *entry = NULL; - if (strcmp(className, "__NSSingleObjectArrayI") == 0) - { - const NSArrayDescriptor* arrayI = (const NSArrayDescriptor*)arrayPtr; + if (strcmp(className, "__NSSingleObjectArrayI") == 0) { + const NSArrayDescriptor *arrayI = (const NSArrayDescriptor *)arrayPtr; // Using a temp variable to handle aligment of NSArrayDescriptor uintptr_t temp_data = arrayI->_data; entry = &temp_data; - } - else - { - const struct NSArray* array = (const struct NSArray*)arrayPtr; - entry = (const uintptr_t*)&array->basic.firstEntry; + } else { + const struct NSArray *array = (const struct NSArray *)arrayPtr; + entry = (const uintptr_t *)&array->basic.firstEntry; } - if (!ksmem_copySafely(entry, contents, sizeof(*contents) * count)) - { + if (!ksmem_copySafely(entry, contents, sizeof(*contents) * count)) { return 0; } return count; } -static inline bool cfarrayIsValid(const void* const arrayPtr) +static inline bool cfarrayIsValid(const void *const arrayPtr) { struct __CFArray temp; - if(!ksmem_copySafely(arrayPtr, &temp, sizeof(temp))) - { + if (!ksmem_copySafely(arrayPtr, &temp, sizeof(temp))) { return false; } - const struct __CFArray* array = arrayPtr; - if(__CFArrayGetType(array) == __kCFArrayDeque) - { - if(array->_store != NULL) - { + const struct __CFArray *array = arrayPtr; + if (__CFArrayGetType(array) == __kCFArrayDeque) { + if (array->_store != NULL) { struct __CFArrayDeque deque; - if(!ksmem_copySafely(array->_store, &deque, sizeof(deque))) - { + if (!ksmem_copySafely(array->_store, &deque, sizeof(deque))) { return false; } } @@ -1666,202 +1436,174 @@ static inline bool cfarrayIsValid(const void* const arrayPtr) return true; } -static inline const void* cfarrayData(const void* const arrayPtr) -{ - return __CFArrayGetBucketsPtr(arrayPtr); -} +static inline const void *cfarrayData(const void *const arrayPtr) { return __CFArrayGetBucketsPtr(arrayPtr); } -static inline int cfarrayCount(const void* const arrayPtr) +static inline int cfarrayCount(const void *const arrayPtr) { - const struct __CFArray* array = arrayPtr; + const struct __CFArray *array = arrayPtr; return array->_count < 0 ? 0 : (int)array->_count; } -static int cfarrayContents(const void* const arrayPtr, uintptr_t* contents, int count) +static int cfarrayContents(const void *const arrayPtr, uintptr_t *contents, int count) { - const struct __CFArray* array = arrayPtr; - if(array->_count < (CFIndex)count) - { - if(array->_count <= 0) - { + const struct __CFArray *array = arrayPtr; + if (array->_count < (CFIndex)count) { + if (array->_count <= 0) { return 0; } count = (int)array->_count; } - - const void* firstEntry = cfarrayData(array); - if(!ksmem_copySafely(firstEntry, contents, (int)sizeof(*contents) * count)) - { + + const void *firstEntry = cfarrayData(array); + if (!ksmem_copySafely(firstEntry, contents, (int)sizeof(*contents) * count)) { return 0; } return count; } -static bool isCFArray(const void* const arrayPtr) +static bool isCFArray(const void *const arrayPtr) { - const ClassData* data = getClassDataFromObject(arrayPtr); + const ClassData *data = getClassDataFromObject(arrayPtr); return data->subtype == ClassSubtypeCFArray; } - - -int ksobjc_arrayCount(const void* const arrayPtr) +int ksobjc_arrayCount(const void *const arrayPtr) { - if(isCFArray(arrayPtr)) - { + if (isCFArray(arrayPtr)) { return cfarrayCount(arrayPtr); } return nsarrayCount(arrayPtr); } -int ksobjc_arrayContents(const void* const arrayPtr, uintptr_t* contents, int count) +int ksobjc_arrayContents(const void *const arrayPtr, uintptr_t *contents, int count) { - if(isCFArray(arrayPtr)) - { + if (isCFArray(arrayPtr)) { return cfarrayContents(arrayPtr, contents, count); } return nsarrayContents(arrayPtr, contents, count); } -bool arrayIsValid(const void* object) +bool arrayIsValid(const void *object) { - if(isCFArray(object)) - { + if (isCFArray(object)) { return cfarrayIsValid(object); } return nsarrayIsValid(object); } -static int arrayDescription(const void* object, char* buffer, int bufferLength) +static int arrayDescription(const void *object, char *buffer, int bufferLength) { - char* pBuffer = buffer; - char* pEnd = buffer + bufferLength; - + char *pBuffer = buffer; + char *pEnd = buffer + bufferLength; + pBuffer += objectDescription(object, pBuffer, (int)(pEnd - pBuffer)); pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), ": ["); - if(pBuffer < pEnd-1 && ksobjc_arrayCount(object) > 0) - { + if (pBuffer < pEnd - 1 && ksobjc_arrayCount(object) > 0) { uintptr_t contents = 0; - if(ksobjc_arrayContents(object, &contents, 1) == 1) - { - pBuffer += ksobjc_getDescription((void*)contents, pBuffer, (int)(pEnd - pBuffer)); + if (ksobjc_arrayContents(object, &contents, 1) == 1) { + pBuffer += ksobjc_getDescription((void *)contents, pBuffer, (int)(pEnd - pBuffer)); } } pBuffer += stringPrintf(pBuffer, (int)(pEnd - pBuffer), "]"); - + return (int)(pBuffer - buffer); } - //====================================================================== #pragma mark - NSDictionary (BROKEN) - //====================================================================== -bool ksobjc_dictionaryFirstEntry(const void* dict, uintptr_t* key, uintptr_t* value) +bool ksobjc_dictionaryFirstEntry(const void *dict, uintptr_t *key, uintptr_t *value) { // TODO: This is broken. // Ensure memory is valid. struct __CFBasicHash copy; - if(!ksmem_copySafely(dict, ©, sizeof(copy))) - { + if (!ksmem_copySafely(dict, ©, sizeof(copy))) { return false; } - - struct __CFBasicHash* ht = (struct __CFBasicHash*)dict; - uintptr_t* keys = (uintptr_t*)ht->pointers + ht->bits.keys_offset; - uintptr_t* values = (uintptr_t*)ht->pointers; - + + struct __CFBasicHash *ht = (struct __CFBasicHash *)dict; + uintptr_t *keys = (uintptr_t *)ht->pointers + ht->bits.keys_offset; + uintptr_t *values = (uintptr_t *)ht->pointers; + // Dereference key and value pointers. - if(!ksmem_copySafely(keys, &keys, sizeof(keys))) - { + if (!ksmem_copySafely(keys, &keys, sizeof(keys))) { return false; } - - if(!ksmem_copySafely(values, &values, sizeof(values))) - { + + if (!ksmem_copySafely(values, &values, sizeof(values))) { return false; } - + // Copy to destination. - if(!ksmem_copySafely(keys, key, sizeof(*key))) - { + if (!ksmem_copySafely(keys, key, sizeof(*key))) { return false; } - if(!ksmem_copySafely(values, value, sizeof(*value))) - { + if (!ksmem_copySafely(values, value, sizeof(*value))) { return false; } return true; } -//bool ksobjc_dictionaryContents(const void* dict, uintptr_t* keys, uintptr_t* values, CFIndex* count) +// bool ksobjc_dictionaryContents(const void* dict, uintptr_t* keys, uintptr_t* values, CFIndex* count) //{ -// struct CFBasicHash copy; -// void* pointers[100]; +// struct CFBasicHash copy; +// void* pointers[100]; // -// if(!ksmem_copySafely(dict, ©, sizeof(copy))) -// { -// return false; -// } +// if(!ksmem_copySafely(dict, ©, sizeof(copy))) +// { +// return false; +// } // -// struct CFBasicHash* ht = (struct CFBasicHash*)dict; -// int values_offset = 0; -// int keys_offset = copy.bits.keys_offset; -// if(!ksmem_copySafely(&ht->pointers, pointers, sizeof(*pointers) * keys_offset)) -// { -// return false; -// } +// struct CFBasicHash* ht = (struct CFBasicHash*)dict; +// int values_offset = 0; +// int keys_offset = copy.bits.keys_offset; +// if(!ksmem_copySafely(&ht->pointers, pointers, sizeof(*pointers) * keys_offset)) +// { +// return false; +// } // -// return true; -//} +// return true; +// } -int ksobjc_dictionaryCount(const void* dict) +int ksobjc_dictionaryCount(const void *dict) { // TODO: Implement me #pragma unused(dict) return 0; } - //====================================================================== #pragma mark - General Queries - //====================================================================== -int ksobjc_getDescription(void* object, char* buffer, int bufferLength) +int ksobjc_getDescription(void *object, char *buffer, int bufferLength) { - const ClassData* data = getClassDataFromObject(object); + const ClassData *data = getClassDataFromObject(object); return data->description(object, buffer, bufferLength); } -bool ksobjc_isTaggedPointer(const void* const pointer) -{ - return isTaggedPointer(pointer); -} +bool ksobjc_isTaggedPointer(const void *const pointer) { return isTaggedPointer(pointer); } -bool ksobjc_isValidTaggedPointer(const void* const pointer) -{ - return isValidTaggedPointer(pointer); -} +bool ksobjc_isValidTaggedPointer(const void *const pointer) { return isValidTaggedPointer(pointer); } -bool ksobjc_isValidObject(const void* object) +bool ksobjc_isValidObject(const void *object) { - if(!isValidObject(object)) - { + if (!isValidObject(object)) { return false; } - const ClassData* data = getClassDataFromObject(object); + const ClassData *data = getClassDataFromObject(object); return data->isValidObject(object); } -KSObjCClassType ksobjc_objectClassType(const void* object) +KSObjCClassType ksobjc_objectClassType(const void *object) { - const ClassData* data = getClassDataFromObject(object); + const ClassData *data = getClassDataFromObject(object); return data->type; } - //__NSArrayReversed //__NSCFBoolean //__NSCFDictionary @@ -1884,41 +1626,41 @@ KSObjCClassType ksobjc_objectClassType(const void* object) //__NSPlaceholderSet //__NSSetI //__NSSetM -//NSArray -//NSCFArray -//NSCFBoolean -//NSCFDictionary -//NSCFError -//NSCFNumber -//NSCFSet -//NSCheapMutableString -//NSClassicHashTable -//NSClassicMapTable -//SConcreteHashTable -//NSConcreteMapTable -//NSConcreteValue -//NSDate -//NSDecimalNumber -//NSDecimalNumberPlaceholder -//NSDictionary -//NSError -//NSException -//NSHashTable -//NSMutableArray -//NSMutableDictionary -//NSMutableIndexSet -//NSMutableOrderedSet -//NSMutableRLEArray -//NSMutableSet -//NSMutableString -//NSMutableStringProxy -//NSNumber -//NSOrderedSet -//NSPlaceholderMutableString -//NSPlaceholderNumber -//NSPlaceholderString -//NSRLEArray -//NSSet -//NSSimpleCString -//NSString -//NSURL +// NSArray +// NSCFArray +// NSCFBoolean +// NSCFDictionary +// NSCFError +// NSCFNumber +// NSCFSet +// NSCheapMutableString +// NSClassicHashTable +// NSClassicMapTable +// SConcreteHashTable +// NSConcreteMapTable +// NSConcreteValue +// NSDate +// NSDecimalNumber +// NSDecimalNumberPlaceholder +// NSDictionary +// NSError +// NSException +// NSHashTable +// NSMutableArray +// NSMutableDictionary +// NSMutableIndexSet +// NSMutableOrderedSet +// NSMutableRLEArray +// NSMutableSet +// NSMutableString +// NSMutableStringProxy +// NSNumber +// NSOrderedSet +// NSPlaceholderMutableString +// NSPlaceholderNumber +// NSPlaceholderString +// NSRLEArray +// NSSet +// NSSimpleCString +// NSString +// NSURL diff --git a/Sources/KSCrashRecordingCore/KSSignalInfo.c b/Sources/KSCrashRecordingCore/KSSignalInfo.c index 6968d235d..11ce0d5d9 100644 --- a/Sources/KSCrashRecordingCore/KSSignalInfo.c +++ b/Sources/KSCrashRecordingCore/KSSignalInfo.c @@ -24,68 +24,50 @@ // THE SOFTWARE. // - #include "KSSignalInfo.h" #include #include - -typedef struct -{ +typedef struct { const int code; - const char* const name; + const char *const name; } KSSignalCodeInfo; -typedef struct -{ +typedef struct { const int sigNum; - const char* const name; - const KSSignalCodeInfo* const codes; + const char *const name; + const KSSignalCodeInfo *const codes; const int numCodes; } KSSignalInfo; -#define ENUM_NAME_MAPPING(A) {A, #A} +#define ENUM_NAME_MAPPING(A) { A, #A } -static const KSSignalCodeInfo g_sigIllCodes[] = -{ +static const KSSignalCodeInfo g_sigIllCodes[] = { #ifdef ILL_NOOP ENUM_NAME_MAPPING(ILL_NOOP), #endif - ENUM_NAME_MAPPING(ILL_ILLOPC), - ENUM_NAME_MAPPING(ILL_ILLTRP), - ENUM_NAME_MAPPING(ILL_PRVOPC), - ENUM_NAME_MAPPING(ILL_ILLOPN), - ENUM_NAME_MAPPING(ILL_ILLADR), - ENUM_NAME_MAPPING(ILL_PRVREG), - ENUM_NAME_MAPPING(ILL_COPROC), - ENUM_NAME_MAPPING(ILL_BADSTK), + ENUM_NAME_MAPPING(ILL_ILLOPC), ENUM_NAME_MAPPING(ILL_ILLTRP), ENUM_NAME_MAPPING(ILL_PRVOPC), + ENUM_NAME_MAPPING(ILL_ILLOPN), ENUM_NAME_MAPPING(ILL_ILLADR), ENUM_NAME_MAPPING(ILL_PRVREG), + ENUM_NAME_MAPPING(ILL_COPROC), ENUM_NAME_MAPPING(ILL_BADSTK), }; -static const KSSignalCodeInfo g_sigTrapCodes[] = -{ +static const KSSignalCodeInfo g_sigTrapCodes[] = { ENUM_NAME_MAPPING(0), ENUM_NAME_MAPPING(TRAP_BRKPT), ENUM_NAME_MAPPING(TRAP_TRACE), }; -static const KSSignalCodeInfo g_sigFPECodes[] = -{ +static const KSSignalCodeInfo g_sigFPECodes[] = { #ifdef FPE_NOOP ENUM_NAME_MAPPING(FPE_NOOP), #endif - ENUM_NAME_MAPPING(FPE_FLTDIV), - ENUM_NAME_MAPPING(FPE_FLTOVF), - ENUM_NAME_MAPPING(FPE_FLTUND), - ENUM_NAME_MAPPING(FPE_FLTRES), - ENUM_NAME_MAPPING(FPE_FLTINV), - ENUM_NAME_MAPPING(FPE_FLTSUB), - ENUM_NAME_MAPPING(FPE_INTDIV), - ENUM_NAME_MAPPING(FPE_INTOVF), + ENUM_NAME_MAPPING(FPE_FLTDIV), ENUM_NAME_MAPPING(FPE_FLTOVF), ENUM_NAME_MAPPING(FPE_FLTUND), + ENUM_NAME_MAPPING(FPE_FLTRES), ENUM_NAME_MAPPING(FPE_FLTINV), ENUM_NAME_MAPPING(FPE_FLTSUB), + ENUM_NAME_MAPPING(FPE_INTDIV), ENUM_NAME_MAPPING(FPE_INTOVF), }; -static const KSSignalCodeInfo g_sigBusCodes[] = -{ +static const KSSignalCodeInfo g_sigBusCodes[] = { #ifdef BUS_NOOP ENUM_NAME_MAPPING(BUS_NOOP), #endif @@ -94,8 +76,7 @@ static const KSSignalCodeInfo g_sigBusCodes[] = ENUM_NAME_MAPPING(BUS_OBJERR), }; -static const KSSignalCodeInfo g_sigSegVCodes[] = -{ +static const KSSignalCodeInfo g_sigSegVCodes[] = { #ifdef SEGV_NOOP ENUM_NAME_MAPPING(SEGV_NOOP), #endif @@ -103,60 +84,38 @@ static const KSSignalCodeInfo g_sigSegVCodes[] = ENUM_NAME_MAPPING(SEGV_ACCERR), }; -#define SIGNAL_INFO(SIGNAL, CODES) {SIGNAL, #SIGNAL, CODES, sizeof(CODES) / sizeof(*CODES)} -#define SIGNAL_INFO_NOCODES(SIGNAL) {SIGNAL, #SIGNAL, 0, 0} +#define SIGNAL_INFO(SIGNAL, CODES) { SIGNAL, #SIGNAL, CODES, sizeof(CODES) / sizeof(*CODES) } +#define SIGNAL_INFO_NOCODES(SIGNAL) { SIGNAL, #SIGNAL, 0, 0 } -static const KSSignalInfo g_fatalSignalData[] = -{ - SIGNAL_INFO_NOCODES(SIGABRT), - SIGNAL_INFO(SIGBUS, g_sigBusCodes), - SIGNAL_INFO(SIGFPE, g_sigFPECodes), - SIGNAL_INFO(SIGILL, g_sigIllCodes), - SIGNAL_INFO_NOCODES(SIGPIPE), - SIGNAL_INFO(SIGSEGV, g_sigSegVCodes), - SIGNAL_INFO_NOCODES(SIGSYS), - SIGNAL_INFO(SIGTRAP, g_sigTrapCodes), - SIGNAL_INFO_NOCODES(SIGTERM), +static const KSSignalInfo g_fatalSignalData[] = { + SIGNAL_INFO_NOCODES(SIGABRT), SIGNAL_INFO(SIGBUS, g_sigBusCodes), SIGNAL_INFO(SIGFPE, g_sigFPECodes), + SIGNAL_INFO(SIGILL, g_sigIllCodes), SIGNAL_INFO_NOCODES(SIGPIPE), SIGNAL_INFO(SIGSEGV, g_sigSegVCodes), + SIGNAL_INFO_NOCODES(SIGSYS), SIGNAL_INFO(SIGTRAP, g_sigTrapCodes), SIGNAL_INFO_NOCODES(SIGTERM), }; static const int g_fatalSignalsCount = sizeof(g_fatalSignalData) / sizeof(*g_fatalSignalData); // Note: Dereferencing a NULL pointer causes SIGILL, ILL_ILLOPC on i386 // but causes SIGTRAP, 0 on arm. -static const int g_fatalSignals[] = -{ - SIGABRT, - SIGBUS, - SIGFPE, - SIGILL, - SIGPIPE, - SIGSEGV, - SIGSYS, - SIGTRAP, - SIGTERM, +static const int g_fatalSignals[] = { + SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGPIPE, SIGSEGV, SIGSYS, SIGTRAP, SIGTERM, }; -const char* kssignal_signalName(const int sigNum) +const char *kssignal_signalName(const int sigNum) { - for(int i = 0; i < g_fatalSignalsCount; i++) - { - if(g_fatalSignalData[i].sigNum == sigNum) - { + for (int i = 0; i < g_fatalSignalsCount; i++) { + if (g_fatalSignalData[i].sigNum == sigNum) { return g_fatalSignalData[i].name; } } return NULL; } -const char* kssignal_signalCodeName(const int sigNum, const int code) +const char *kssignal_signalCodeName(const int sigNum, const int code) { - for(int si = 0; si < g_fatalSignalsCount; si++) - { - if(g_fatalSignalData[si].sigNum == sigNum) - { - for(int ci = 0; ci < g_fatalSignalData[si].numCodes; ci++) - { - if(g_fatalSignalData[si].codes[ci].code == code) - { + for (int si = 0; si < g_fatalSignalsCount; si++) { + if (g_fatalSignalData[si].sigNum == sigNum) { + for (int ci = 0; ci < g_fatalSignalData[si].numCodes; ci++) { + if (g_fatalSignalData[si].codes[ci].code == code) { return g_fatalSignalData[si].codes[ci].name; } } @@ -165,13 +124,6 @@ const char* kssignal_signalCodeName(const int sigNum, const int code) return NULL; } -const int* kssignal_fatalSignals(void) -{ - return g_fatalSignals; -} - -int kssignal_numFatalSignals(void) -{ - return g_fatalSignalsCount; -} +const int *kssignal_fatalSignals(void) { return g_fatalSignals; } +int kssignal_numFatalSignals(void) { return g_fatalSignalsCount; } diff --git a/Sources/KSCrashRecordingCore/KSStackCursor.c b/Sources/KSCrashRecordingCore/KSStackCursor.c index b85c654f2..21d47182b 100644 --- a/Sources/KSCrashRecordingCore/KSStackCursor.c +++ b/Sources/KSCrashRecordingCore/KSStackCursor.c @@ -22,17 +22,20 @@ // THE SOFTWARE. // - #include "KSStackCursor.h" -#include "KSSymbolicator.h" + #include -//#define KSLogger_LocalLevel TRACE +#include "KSSymbolicator.h" + +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" static bool g_advanceCursor(__unused KSStackCursor *cursor) { - KSLOG_WARN("No stack cursor has been set. For C++, this means that hooking __cxa_throw() failed for some reason. Embedded frameworks can cause this: https://github.com/kstenerud/KSCrash/issues/205"); + KSLOG_WARN( + "No stack cursor has been set. For C++, this means that hooking __cxa_throw() failed for some reason. Embedded " + "frameworks can cause this: https://github.com/kstenerud/KSCrash/issues/205"); return false; } @@ -47,9 +50,8 @@ void kssc_resetCursor(KSStackCursor *cursor) cursor->stackEntry.symbolName = NULL; } -void kssc_initCursor(KSStackCursor *cursor, - void (*resetCursor)(KSStackCursor*), - bool (*advanceCursor)(KSStackCursor*)) +void kssc_initCursor(KSStackCursor *cursor, void (*resetCursor)(KSStackCursor *), + bool (*advanceCursor)(KSStackCursor *)) { cursor->symbolicate = kssymbolicator_symbolicate; cursor->advanceCursor = advanceCursor != NULL ? advanceCursor : g_advanceCursor; diff --git a/Sources/KSCrashRecordingCore/KSStackCursor_Backtrace.c b/Sources/KSCrashRecordingCore/KSStackCursor_Backtrace.c index 9005cf131..78d6e5b4d 100644 --- a/Sources/KSCrashRecordingCore/KSStackCursor_Backtrace.c +++ b/Sources/KSCrashRecordingCore/KSStackCursor_Backtrace.c @@ -22,24 +22,22 @@ // THE SOFTWARE. // - #include "KSStackCursor_Backtrace.h" + #include "KSCPU.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" static bool advanceCursor(KSStackCursor *cursor) { - KSStackCursor_Backtrace_Context* context = (KSStackCursor_Backtrace_Context*)cursor->context; + KSStackCursor_Backtrace_Context *context = (KSStackCursor_Backtrace_Context *)cursor->context; int endDepth = context->backtraceLength - context->skippedEntries; - if(cursor->state.currentDepth < endDepth) - { + if (cursor->state.currentDepth < endDepth) { int currentIndex = cursor->state.currentDepth + context->skippedEntries; uintptr_t nextAddress = context->backtrace[currentIndex]; // Bug: The system sometimes gives a backtrace with an extra 0x00000001 at the end. - if(nextAddress > 1) - { + if (nextAddress > 1) { cursor->stackEntry.address = kscpu_normaliseInstructionPointer(nextAddress); cursor->state.currentDepth++; return true; @@ -48,10 +46,10 @@ static bool advanceCursor(KSStackCursor *cursor) return false; } -void kssc_initWithBacktrace(KSStackCursor *cursor, const uintptr_t* backtrace, int backtraceLength, int skipEntries) +void kssc_initWithBacktrace(KSStackCursor *cursor, const uintptr_t *backtrace, int backtraceLength, int skipEntries) { kssc_initCursor(cursor, kssc_resetCursor, advanceCursor); - KSStackCursor_Backtrace_Context* context = (KSStackCursor_Backtrace_Context*)cursor->context; + KSStackCursor_Backtrace_Context *context = (KSStackCursor_Backtrace_Context *)cursor->context; context->skippedEntries = skipEntries; context->backtraceLength = backtraceLength; context->backtrace = backtrace; diff --git a/Sources/KSCrashRecordingCore/KSStackCursor_MachineContext.c b/Sources/KSCrashRecordingCore/KSStackCursor_MachineContext.c index 0dfa05757..289bc80c7 100644 --- a/Sources/KSCrashRecordingCore/KSStackCursor_MachineContext.c +++ b/Sources/KSCrashRecordingCore/KSStackCursor_MachineContext.c @@ -22,18 +22,16 @@ // THE SOFTWARE. // - #include "KSStackCursor_MachineContext.h" +#include + #include "KSCPU.h" #include "KSMemory.h" -#include - #define KSLogger_LocalLevel TRACE #include "KSLogger.h" - /** Represents an entry in a frame list. * This is modeled after the various i386/x64 frame walkers in the xnu source, * and seems to work fine in ARM as well. I haven't included the args pointer @@ -41,14 +39,14 @@ */ /* - + comment by @SecondDog - + try to explain why it is work in arm64: - + as we know ,arm stack layout is like this: so the pre FP should be *(current FP - 32) - + ------------- <---------- current FP | PC | ------------- <---------- current FP - 8 @@ -58,39 +56,36 @@ ------------- <---------- current FP - 24 | FP(pre) | ------------- <---------- current FP - 32 - + the struct FrameEntry is defined like this typedef struct FrameEntry { struct FrameEntry* previous; <----- this pointer is 8 byte in arm64 uintptr_t return_address; <------ this value is also 8 byte } FrameEntry; <----- 16byte total - - + + but the arm64 call stack is like this. ------------- | LR(x30) | ------------- | pre FP(x29) | ------------- <-----Current FP - + so copy 16 byte data to the FrameEntry is just fit in arm64,so it works fine in arm64 - + */ -typedef struct FrameEntry -{ +typedef struct FrameEntry { /** The previous frame in the list. */ - struct FrameEntry* previous; - + struct FrameEntry *previous; + /** The instruction address. */ uintptr_t return_address; } FrameEntry; - -typedef struct -{ - const struct KSMachineContext* machineContext; +typedef struct { + const struct KSMachineContext *machineContext; int maxStackDepth; FrameEntry currentFrame; uintptr_t instructionAddress; @@ -100,64 +95,56 @@ typedef struct static bool advanceCursor(KSStackCursor *cursor) { - MachineContextCursor* context = (MachineContextCursor*)cursor->context; + MachineContextCursor *context = (MachineContextCursor *)cursor->context; uintptr_t nextAddress = 0; - - if(cursor->state.currentDepth >= context->maxStackDepth) - { + + if (cursor->state.currentDepth >= context->maxStackDepth) { cursor->state.hasGivenUp = true; return false; } - - if(context->instructionAddress == 0 && cursor->state.currentDepth == 0) - { + + if (context->instructionAddress == 0 && cursor->state.currentDepth == 0) { context->instructionAddress = kscpu_instructionAddress(context->machineContext); nextAddress = context->instructionAddress; goto successfulExit; } - - if(context->linkRegister == 0 && !context->isPastFramePointer) - { + + if (context->linkRegister == 0 && !context->isPastFramePointer) { // Link register, if available, is the second address in the trace. context->linkRegister = kscpu_linkRegister(context->machineContext); - if(context->linkRegister != 0) - { + if (context->linkRegister != 0) { nextAddress = context->linkRegister; goto successfulExit; } } - if(context->currentFrame.previous == NULL) - { - if(context->isPastFramePointer) - { + if (context->currentFrame.previous == NULL) { + if (context->isPastFramePointer) { return false; } - context->currentFrame.previous = (struct FrameEntry*)kscpu_framePointer(context->machineContext); + context->currentFrame.previous = (struct FrameEntry *)kscpu_framePointer(context->machineContext); context->isPastFramePointer = true; } - if(!ksmem_copySafely(context->currentFrame.previous, &context->currentFrame, sizeof(context->currentFrame))) - { + if (!ksmem_copySafely(context->currentFrame.previous, &context->currentFrame, sizeof(context->currentFrame))) { return false; } - if(context->currentFrame.previous == 0 || context->currentFrame.return_address == 0) - { + if (context->currentFrame.previous == 0 || context->currentFrame.return_address == 0) { return false; } nextAddress = context->currentFrame.return_address; - + successfulExit: cursor->stackEntry.address = kscpu_normaliseInstructionPointer(nextAddress); cursor->state.currentDepth++; return true; } -static void resetCursor(KSStackCursor* cursor) +static void resetCursor(KSStackCursor *cursor) { kssc_resetCursor(cursor); - MachineContextCursor* context = (MachineContextCursor*)cursor->context; + MachineContextCursor *context = (MachineContextCursor *)cursor->context; context->currentFrame.previous = 0; context->currentFrame.return_address = 0; context->instructionAddress = 0; @@ -165,10 +152,11 @@ static void resetCursor(KSStackCursor* cursor) context->isPastFramePointer = 0; } -void kssc_initWithMachineContext(KSStackCursor *cursor, int maxStackDepth, const struct KSMachineContext* machineContext) +void kssc_initWithMachineContext(KSStackCursor *cursor, int maxStackDepth, + const struct KSMachineContext *machineContext) { kssc_initCursor(cursor, resetCursor, advanceCursor); - MachineContextCursor* context = (MachineContextCursor*)cursor->context; + MachineContextCursor *context = (MachineContextCursor *)cursor->context; context->machineContext = machineContext; context->maxStackDepth = maxStackDepth; context->instructionAddress = cursor->stackEntry.address; diff --git a/Sources/KSCrashRecordingCore/KSStackCursor_SelfThread.c b/Sources/KSCrashRecordingCore/KSStackCursor_SelfThread.c index 569a7e699..f6d92a8d8 100644 --- a/Sources/KSCrashRecordingCore/KSStackCursor_SelfThread.c +++ b/Sources/KSCrashRecordingCore/KSStackCursor_SelfThread.c @@ -22,26 +22,26 @@ // THE SOFTWARE. // - #include "KSStackCursor_SelfThread.h" -#include "KSStackCursor_Backtrace.h" + #include -//#define KSLogger_LocalLevel TRACE +#include "KSStackCursor_Backtrace.h" + +// #define KSLogger_LocalLevel TRACE #include "KSLogger.h" -#define MAX_BACKTRACE_LENGTH (KSSC_CONTEXT_SIZE - sizeof(KSStackCursor_Backtrace_Context) / sizeof(void*) - 1) +#define MAX_BACKTRACE_LENGTH (KSSC_CONTEXT_SIZE - sizeof(KSStackCursor_Backtrace_Context) / sizeof(void *) - 1) -typedef struct -{ +typedef struct { KSStackCursor_Backtrace_Context SelfThreadContextSpacer; uintptr_t backtrace[0]; } SelfThreadContext; void kssc_initSelfThread(KSStackCursor *cursor, int skipEntries) __attribute__((disable_tail_calls)) { - SelfThreadContext* context = (SelfThreadContext*)cursor->context; - int backtraceLength = backtrace((void**)context->backtrace, MAX_BACKTRACE_LENGTH); + SelfThreadContext *context = (SelfThreadContext *)cursor->context; + int backtraceLength = backtrace((void **)context->backtrace, MAX_BACKTRACE_LENGTH); kssc_initWithBacktrace(cursor, context->backtrace, backtraceLength, skipEntries + 1); - __asm__ __volatile__(""); // thwart tail-call optimization + __asm__ __volatile__(""); // thwart tail-call optimization } diff --git a/Sources/KSCrashRecordingCore/KSString.c b/Sources/KSCrashRecordingCore/KSString.c index 125c143cf..8a4f6413e 100644 --- a/Sources/KSCrashRecordingCore/KSString.c +++ b/Sources/KSCrashRecordingCore/KSString.c @@ -24,17 +24,18 @@ // THE SOFTWARE. // - #include "KSString.h" -#include + #include -#include "KSSystemCapabilities.h" +#include +#include "KSSystemCapabilities.h" // Compiler hints for "if" statements -#define likely_if(x) if(__builtin_expect(x,1)) -#define unlikely_if(x) if(__builtin_expect(x,0)) +#define likely_if(x) if (__builtin_expect(x, 1)) +#define unlikely_if(x) if (__builtin_expect(x, 0)) +// clang-format off static const int g_printableControlChars[0x20] = { // Only tab, CR, and LF are considered printable @@ -58,39 +59,24 @@ static const int g_continuationByteCount[0x40] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 0, 0, }; +// clang-format on -bool ksstring_isNullTerminatedUTF8String(const void* memory, - int minLength, - int maxLength) +bool ksstring_isNullTerminatedUTF8String(const void *memory, int minLength, int maxLength) { - const unsigned char* ptr = memory; - const unsigned char* const end = ptr + maxLength; + const unsigned char *ptr = memory; + const unsigned char *const end = ptr + maxLength; - for(; ptr < end; ptr++) - { + for (; ptr < end; ptr++) { unsigned char ch = *ptr; - unlikely_if(ch == 0) - { - return (ptr - (const unsigned char*)memory) >= minLength; - } + unlikely_if(ch == 0) { return (ptr - (const unsigned char *)memory) >= minLength; } unlikely_if(ch & 0x80) { - unlikely_if((ch & 0xc0) != 0xc0) - { - return false; - } + unlikely_if((ch & 0xc0) != 0xc0) { return false; } int continuationBytes = g_continuationByteCount[ch & 0x3f]; - unlikely_if(continuationBytes == 0 || ptr + continuationBytes >= end) - { - return false; - } - for(int i = 0; i < continuationBytes; i++) - { + unlikely_if(continuationBytes == 0 || ptr + continuationBytes >= end) { return false; } + for (int i = 0; i < continuationBytes; i++) { ptr++; - unlikely_if((*ptr & 0xc0) != 0x80) - { - return false; - } + unlikely_if((*ptr & 0xc0) != 0x80) { return false; } } } else unlikely_if(ch < 0x20 && !g_printableControlChars[ch]) @@ -101,71 +87,50 @@ bool ksstring_isNullTerminatedUTF8String(const void* memory, return false; } - #define INV 0xff /** Lookup table for converting hex values to integers. * INV (0x11111) is used to mark invalid characters so that any attempted * invalid nybble conversion is always > 0xffff. */ -static const unsigned int g_hexConversion[] = -{ - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, INV, INV, INV, INV, INV, INV, - INV, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, - INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, +static const unsigned int g_hexConversion[] = { + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, INV, INV, INV, INV, INV, INV, INV, 0xa, + 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, + INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, INV, }; -bool ksstring_extractHexValue(const char* string, int stringLength, uint64_t* const result) +bool ksstring_extractHexValue(const char *string, int stringLength, uint64_t *const result) { - if(stringLength > 0) - { - const unsigned char* current = (const unsigned char*)string; - const unsigned char* const end = current + stringLength; - for(;;) - { + if (stringLength > 0) { + const unsigned char *current = (const unsigned char *)string; + const unsigned char *const end = current + stringLength; + for (;;) { #if KSCRASH_HAS_STRNSTR - current = (const unsigned char*)strnstr((const char*)current, "0x", (unsigned)(end - current)); + current = (const unsigned char *)strnstr((const char *)current, "0x", (unsigned)(end - current)); #else - current = (const unsigned char*)strstr((const char*)current, "0x"); - unlikely_if(current >= end) - { - return false; - } + current = (const unsigned char *)strstr((const char *)current, "0x"); + unlikely_if(current >= end) { return false; } #endif - unlikely_if(!current) - { - return false; - } + unlikely_if(!current) { return false; } current += 2; - + // Must have at least one valid digit after "0x". - unlikely_if(g_hexConversion[*current] == INV) - { - continue; - } - + unlikely_if(g_hexConversion[*current] == INV) { continue; } + uint64_t accum = 0; unsigned int nybble = 0; - while(current < end) - { + while (current < end) { nybble = g_hexConversion[*current++]; - unlikely_if(nybble == INV) - { - break; - } + unlikely_if(nybble == INV) { break; } accum <<= 4; accum += nybble; } @@ -176,7 +141,7 @@ bool ksstring_extractHexValue(const char* string, int stringLength, uint64_t* co return false; } -int ksstring_safeStrcmp(const char* str1, const char* str2) +int ksstring_safeStrcmp(const char *str1, const char *str2) { if (str1 == NULL && str2 == NULL) { return 0; diff --git a/Sources/KSCrashRecordingCore/KSSymbolicator.c b/Sources/KSCrashRecordingCore/KSSymbolicator.c index b74c848dd..70d29ca62 100644 --- a/Sources/KSCrashRecordingCore/KSSymbolicator.c +++ b/Sources/KSCrashRecordingCore/KSSymbolicator.c @@ -22,10 +22,9 @@ // THE SOFTWARE. // - #include "KSSymbolicator.h" -#include "KSDynamicLinker.h" +#include "KSDynamicLinker.h" /** Remove any pointer tagging from an instruction address * On armv7 the least significant bit of the pointer distinguishes @@ -51,7 +50,6 @@ */ #define CALL_INSTRUCTION_FROM_RETURN_ADDRESS(A) (DETAG_INSTRUCTION_ADDRESS((A)) - 1) - uintptr_t kssymbolicator_callInstructionAddress(const uintptr_t returnAddress) { return CALL_INSTRUCTION_FROM_RETURN_ADDRESS(returnAddress); @@ -60,15 +58,14 @@ uintptr_t kssymbolicator_callInstructionAddress(const uintptr_t returnAddress) bool kssymbolicator_symbolicate(KSStackCursor *cursor) { Dl_info symbolsBuffer; - if(ksdl_dladdr(CALL_INSTRUCTION_FROM_RETURN_ADDRESS(cursor->stackEntry.address), &symbolsBuffer)) - { + if (ksdl_dladdr(CALL_INSTRUCTION_FROM_RETURN_ADDRESS(cursor->stackEntry.address), &symbolsBuffer)) { cursor->stackEntry.imageAddress = (uintptr_t)symbolsBuffer.dli_fbase; cursor->stackEntry.imageName = symbolsBuffer.dli_fname; cursor->stackEntry.symbolAddress = (uintptr_t)symbolsBuffer.dli_saddr; cursor->stackEntry.symbolName = symbolsBuffer.dli_sname; return true; } - + cursor->stackEntry.imageAddress = 0; cursor->stackEntry.imageName = 0; cursor->stackEntry.symbolAddress = 0; diff --git a/Sources/KSCrashRecordingCore/KSSysCtl.c b/Sources/KSCrashRecordingCore/KSSysCtl.c index a94645686..6adf33414 100644 --- a/Sources/KSCrashRecordingCore/KSSysCtl.c +++ b/Sources/KSCrashRecordingCore/KSSysCtl.c @@ -24,52 +24,41 @@ // THE SOFTWARE. // - #include "KSSysCtl.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - +// #define KSLogger_LocalLevel TRACE #include #include #include -#include #include +#include +#include "KSLogger.h" -#define CHECK_SYSCTL_NAME(TYPE, CALL) \ -if(0 != (CALL)) \ -{ \ - KSLOG_ERROR("Could not get %s value for %s: %s", \ - #CALL, name, strerror(errno)); \ - return 0; \ -} +#define CHECK_SYSCTL_NAME(TYPE, CALL) \ + if (0 != (CALL)) { \ + KSLOG_ERROR("Could not get %s value for %s: %s", #CALL, name, strerror(errno)); \ + return 0; \ + } -#define CHECK_SYSCTL_CMD(TYPE, CALL) \ -if(0 != (CALL)) \ -{ \ - KSLOG_ERROR("Could not get %s value for %d,%d: %s", \ - #CALL, major_cmd, minor_cmd, strerror(errno)); \ - return 0; \ -} +#define CHECK_SYSCTL_CMD(TYPE, CALL) \ + if (0 != (CALL)) { \ + KSLOG_ERROR("Could not get %s value for %d,%d: %s", #CALL, major_cmd, minor_cmd, strerror(errno)); \ + return 0; \ + } int32_t kssysctl_int32(const int major_cmd, const int minor_cmd) { - int cmd[2] = {major_cmd, minor_cmd}; + int cmd[2] = { major_cmd, minor_cmd }; int32_t value = 0; size_t size = sizeof(value); - CHECK_SYSCTL_CMD(int32, sysctl(cmd, - sizeof(cmd)/sizeof(*cmd), - &value, - &size, - NULL, - 0)); + CHECK_SYSCTL_CMD(int32, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); return value; } -int32_t kssysctl_int32ForName(const char* const name) +int32_t kssysctl_int32ForName(const char *const name) { int32_t value = 0; size_t size = sizeof(value); @@ -81,21 +70,16 @@ int32_t kssysctl_int32ForName(const char* const name) uint32_t kssysctl_uint32(const int major_cmd, const int minor_cmd) { - int cmd[2] = {major_cmd, minor_cmd}; + int cmd[2] = { major_cmd, minor_cmd }; uint32_t value = 0; size_t size = sizeof(value); - CHECK_SYSCTL_CMD(uint32, sysctl(cmd, - sizeof(cmd)/sizeof(*cmd), - &value, - &size, - NULL, - 0)); + CHECK_SYSCTL_CMD(uint32, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); return value; } -uint32_t kssysctl_uint32ForName(const char* const name) +uint32_t kssysctl_uint32ForName(const char *const name) { uint32_t value = 0; size_t size = sizeof(value); @@ -107,21 +91,16 @@ uint32_t kssysctl_uint32ForName(const char* const name) int64_t kssysctl_int64(const int major_cmd, const int minor_cmd) { - int cmd[2] = {major_cmd, minor_cmd}; + int cmd[2] = { major_cmd, minor_cmd }; int64_t value = 0; size_t size = sizeof(value); - CHECK_SYSCTL_CMD(int64, sysctl(cmd, - sizeof(cmd)/sizeof(*cmd), - &value, - &size, - NULL, - 0)); + CHECK_SYSCTL_CMD(int64, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); return value; } -int64_t kssysctl_int64ForName(const char* const name) +int64_t kssysctl_int64ForName(const char *const name) { int64_t value = 0; size_t size = sizeof(value); @@ -133,21 +112,16 @@ int64_t kssysctl_int64ForName(const char* const name) uint64_t kssysctl_uint64(const int major_cmd, const int minor_cmd) { - int cmd[2] = {major_cmd, minor_cmd}; + int cmd[2] = { major_cmd, minor_cmd }; uint64_t value = 0; size_t size = sizeof(value); - CHECK_SYSCTL_CMD(uint64, sysctl(cmd, - sizeof(cmd)/sizeof(*cmd), - &value, - &size, - NULL, - 0)); + CHECK_SYSCTL_CMD(uint64, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)); return value; } -uint64_t kssysctl_uint64ForName(const char* const name) +uint64_t kssysctl_uint64ForName(const char *const name) { uint64_t value = 0; size_t size = sizeof(value); @@ -157,27 +131,17 @@ uint64_t kssysctl_uint64ForName(const char* const name) return value; } -int kssysctl_string(const int major_cmd, - const int minor_cmd, - char*const value, - const int maxSize) +int kssysctl_string(const int major_cmd, const int minor_cmd, char *const value, const int maxSize) { - int cmd[2] = {major_cmd, minor_cmd}; + int cmd[2] = { major_cmd, minor_cmd }; size_t size = value == NULL ? 0 : (size_t)maxSize; - CHECK_SYSCTL_CMD(string, sysctl(cmd, - sizeof(cmd)/sizeof(*cmd), - value, - &size, - NULL, - 0)); + CHECK_SYSCTL_CMD(string, sysctl(cmd, sizeof(cmd) / sizeof(*cmd), value, &size, NULL, 0)); return (int)size; } -int kssysctl_stringForName(const char* const name, - char* const value, - const int maxSize) +int kssysctl_stringForName(const char *const name, char *const value, const int maxSize) { size_t size = value == NULL ? 0 : (size_t)maxSize; @@ -188,94 +152,71 @@ int kssysctl_stringForName(const char* const name, struct timeval kssysctl_timeval(const int major_cmd, const int minor_cmd) { - int cmd[2] = {major_cmd, minor_cmd}; - struct timeval value = {0}; + int cmd[2] = { major_cmd, minor_cmd }; + struct timeval value = { 0 }; size_t size = sizeof(value); - if(0 != sysctl(cmd, sizeof(cmd)/sizeof(*cmd), &value, &size, NULL, 0)) - { - KSLOG_ERROR("Could not get timeval value for %d,%d: %s", - major_cmd, minor_cmd, strerror(errno)); + if (0 != sysctl(cmd, sizeof(cmd) / sizeof(*cmd), &value, &size, NULL, 0)) { + KSLOG_ERROR("Could not get timeval value for %d,%d: %s", major_cmd, minor_cmd, strerror(errno)); } return value; } -struct timeval kssysctl_timevalForName(const char* const name) +struct timeval kssysctl_timevalForName(const char *const name) { - struct timeval value = {0}; + struct timeval value = { 0 }; size_t size = sizeof(value); - if(0 != sysctlbyname(name, &value, &size, NULL, 0)) - { - KSLOG_ERROR("Could not get timeval value for %s: %s", - name, strerror(errno)); + if (0 != sysctlbyname(name, &value, &size, NULL, 0)) { + KSLOG_ERROR("Could not get timeval value for %s: %s", name, strerror(errno)); } return value; } -bool kssysctl_getProcessInfo(const int pid, - struct kinfo_proc* const procInfo) +bool kssysctl_getProcessInfo(const int pid, struct kinfo_proc *const procInfo) { - int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; + int cmd[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; size_t size = sizeof(*procInfo); - if(0 != sysctl(cmd, sizeof(cmd)/sizeof(*cmd), procInfo, &size, NULL, 0)) - { - KSLOG_ERROR("Could not get the name for process %d: %s", - pid, strerror(errno)); + if (0 != sysctl(cmd, sizeof(cmd) / sizeof(*cmd), procInfo, &size, NULL, 0)) { + KSLOG_ERROR("Could not get the name for process %d: %s", pid, strerror(errno)); return false; } return true; } -bool kssysctl_getMacAddress(const char* const name, - char* const macAddressBuffer) +bool kssysctl_getMacAddress(const char *const name, char *const macAddressBuffer) { // Based off http://iphonedevelopertips.com/device/determine-mac-address.html - int mib[6] = - { - CTL_NET, - AF_ROUTE, - 0, - AF_LINK, - NET_RT_IFLIST, - (int)if_nametoindex(name) - }; - if(mib[5] == 0) - { - KSLOG_ERROR("Could not get interface index for %s: %s", - name, strerror(errno)); + int mib[6] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, (int)if_nametoindex(name) }; + if (mib[5] == 0) { + KSLOG_ERROR("Could not get interface index for %s: %s", name, strerror(errno)); return false; } size_t length; - if(sysctl(mib, 6, NULL, &length, NULL, 0) != 0) - { - KSLOG_ERROR("Could not get interface data for %s: %s", - name, strerror(errno)); + if (sysctl(mib, 6, NULL, &length, NULL, 0) != 0) { + KSLOG_ERROR("Could not get interface data for %s: %s", name, strerror(errno)); return false; } - void* ifBuffer = malloc(length); - if(ifBuffer == NULL) - { + void *ifBuffer = malloc(length); + if (ifBuffer == NULL) { KSLOG_ERROR("Out of memory"); return false; } - if(sysctl(mib, 6, ifBuffer, &length, NULL, 0) != 0) - { - KSLOG_ERROR("Could not get interface data for %s: %s", - name, strerror(errno)); + if (sysctl(mib, 6, ifBuffer, &length, NULL, 0) != 0) { + KSLOG_ERROR("Could not get interface data for %s: %s", name, strerror(errno)); free(ifBuffer); return false; } - struct if_msghdr* msgHdr = (struct if_msghdr*) ifBuffer; - struct sockaddr_dl* sockaddr = (struct sockaddr_dl*) &msgHdr[1]; + struct if_msghdr *msgHdr = (struct if_msghdr *)ifBuffer; + struct sockaddr_dl *sockaddr = (struct sockaddr_dl *)&msgHdr[1]; memcpy(macAddressBuffer, LLADDR(sockaddr), 6); free(ifBuffer); diff --git a/Sources/KSCrashRecordingCore/KSThread.c b/Sources/KSCrashRecordingCore/KSThread.c index 7a2b913e0..93860e661 100644 --- a/Sources/KSCrashRecordingCore/KSThread.c +++ b/Sources/KSCrashRecordingCore/KSThread.c @@ -24,20 +24,18 @@ // THE SOFTWARE. // - #include "KSThread.h" -#include "KSSystemCapabilities.h" #include "KSMemory.h" +#include "KSSystemCapabilities.h" -//#define KSLogger_LocalLevel TRACE -#include "KSLogger.h" - +// #define KSLogger_LocalLevel TRACE #include #include #include #include +#include "KSLogger.h" KSThread ksthread_self(void) { @@ -46,78 +44,72 @@ KSThread ksthread_self(void) return (KSThread)thread_self; } -bool ksthread_getThreadName(const KSThread thread, char* const buffer, int bufLength) +bool ksthread_getThreadName(const KSThread thread, char *const buffer, int bufLength) { // WARNING: This implementation is no longer async-safe! - + const pthread_t pthread = pthread_from_mach_thread_np((thread_t)thread); return pthread_getname_np(pthread, buffer, (unsigned)bufLength) == 0; } -bool ksthread_getQueueName(const KSThread thread, char* const buffer, int bufLength) +bool ksthread_getQueueName(const KSThread thread, char *const buffer, int bufLength) { // WARNING: This implementation is no longer async-safe! - - integer_t infoBuffer[THREAD_IDENTIFIER_INFO_COUNT] = {0}; + + integer_t infoBuffer[THREAD_IDENTIFIER_INFO_COUNT] = { 0 }; thread_info_t info = infoBuffer; mach_msg_type_number_t inOutSize = THREAD_IDENTIFIER_INFO_COUNT; kern_return_t kr = 0; - + kr = thread_info((thread_t)thread, THREAD_IDENTIFIER_INFO, info, &inOutSize); - if(kr != KERN_SUCCESS) - { - KSLOG_TRACE("Error getting thread_info with flavor THREAD_IDENTIFIER_INFO from mach thread : %s", mach_error_string(kr)); + if (kr != KERN_SUCCESS) { + KSLOG_TRACE("Error getting thread_info with flavor THREAD_IDENTIFIER_INFO from mach thread : %s", + mach_error_string(kr)); return false; } - + thread_identifier_info_t idInfo = (thread_identifier_info_t)info; - if(!ksmem_isMemoryReadable(idInfo, sizeof(*idInfo))) - { + if (!ksmem_isMemoryReadable(idInfo, sizeof(*idInfo))) { KSLOG_DEBUG("Thread %p has an invalid thread identifier info %p", thread, idInfo); return false; } - dispatch_queue_t* dispatch_queue_ptr = (dispatch_queue_t*)idInfo->dispatch_qaddr; - if(!ksmem_isMemoryReadable(dispatch_queue_ptr, sizeof(*dispatch_queue_ptr))) - { + dispatch_queue_t *dispatch_queue_ptr = (dispatch_queue_t *)idInfo->dispatch_qaddr; + if (!ksmem_isMemoryReadable(dispatch_queue_ptr, sizeof(*dispatch_queue_ptr))) { KSLOG_DEBUG("Thread %p has an invalid dispatch queue pointer %p", thread, dispatch_queue_ptr); return false; } - //thread_handle shouldn't be 0 also, because - //identifier_info->dispatch_qaddr = identifier_info->thread_handle + get_dispatchqueue_offset_from_proc(thread->task->bsd_info); - if(dispatch_queue_ptr == NULL || idInfo->thread_handle == 0 || *dispatch_queue_ptr == NULL) - { + // thread_handle shouldn't be 0 also, because + // identifier_info->dispatch_qaddr = identifier_info->thread_handle + + // get_dispatchqueue_offset_from_proc(thread->task->bsd_info); + if (dispatch_queue_ptr == NULL || idInfo->thread_handle == 0 || *dispatch_queue_ptr == NULL) { KSLOG_TRACE("This thread doesn't have a dispatch queue attached : %p", thread); return false; } - + dispatch_queue_t dispatch_queue = *dispatch_queue_ptr; - const char* queue_name = dispatch_queue_get_label(dispatch_queue); - if(queue_name == NULL) - { + const char *queue_name = dispatch_queue_get_label(dispatch_queue); + if (queue_name == NULL) { KSLOG_TRACE("Error while getting dispatch queue name : %p", dispatch_queue); return false; } KSLOG_TRACE("Dispatch queue name: %s", queue_name); int length = (int)strlen(queue_name); - + // Queue label must be a null terminated string. int iLabel; - for(iLabel = 0; iLabel < length + 1; iLabel++) - { - if(queue_name[iLabel] < ' ' || queue_name[iLabel] > '~') - { + for (iLabel = 0; iLabel < length + 1; iLabel++) { + if (queue_name[iLabel] < ' ' || queue_name[iLabel] > '~') { break; } } - if(queue_name[iLabel] != 0) - { + if (queue_name[iLabel] != 0) { // Found a non-null, invalid char. KSLOG_TRACE("Queue label contains invalid chars"); return false; } - bufLength = MIN(length, bufLength - 1);//just strlen, without null-terminator + bufLength = MIN(length, bufLength - 1); // just strlen, without null-terminator strncpy(buffer, queue_name, bufLength); - buffer[bufLength] = 0;//terminate string + buffer[bufLength] = 0; // terminate string KSLOG_TRACE("Queue label = %s", buffer); return true; } diff --git a/Sources/KSCrashRecordingCore/include/KSCPU.h b/Sources/KSCrashRecordingCore/include/KSCPU.h index 4166e836d..3d9f69dbe 100644 --- a/Sources/KSCrashRecordingCore/include/KSCPU.h +++ b/Sources/KSCrashRecordingCore/include/KSCPU.h @@ -27,11 +27,11 @@ #ifndef HDR_KSCPU_h #define HDR_KSCPU_h -#include "KSMachineContext.h" - #include #include +#include "KSMachineContext.h" + #ifdef __cplusplus extern "C" { #endif @@ -40,7 +40,7 @@ extern "C" { * * @return The current architecture. */ -const char* kscpu_currentArch(void); +const char *kscpu_currentArch(void); /** Get the CPU architecture for given major and minor codes. * @@ -49,7 +49,7 @@ const char* kscpu_currentArch(void); * * @return The architecture name. */ -const char* kscpu_archForCPU(cpu_type_t majorCode, cpu_subtype_t minorCode); +const char *kscpu_archForCPU(cpu_type_t majorCode, cpu_subtype_t minorCode); /** Get the frame pointer for a machine context. * The frame pointer marks the top of the call stack. @@ -58,7 +58,7 @@ const char* kscpu_archForCPU(cpu_type_t majorCode, cpu_subtype_t minorCode); * * @return The context's frame pointer. */ -uintptr_t kscpu_framePointer(const struct KSMachineContext* const context); +uintptr_t kscpu_framePointer(const struct KSMachineContext *const context); /** Get the current stack pointer for a machine context. * @@ -66,7 +66,7 @@ uintptr_t kscpu_framePointer(const struct KSMachineContext* const context); * * @return The context's stack pointer. */ -uintptr_t kscpu_stackPointer(const struct KSMachineContext* const context); +uintptr_t kscpu_stackPointer(const struct KSMachineContext *const context); /** Get the address of the instruction about to be, or being executed by a * machine context. @@ -75,7 +75,7 @@ uintptr_t kscpu_stackPointer(const struct KSMachineContext* const context); * * @return The context's next instruction address. */ -uintptr_t kscpu_instructionAddress(const struct KSMachineContext* const context); +uintptr_t kscpu_instructionAddress(const struct KSMachineContext *const context); /** Get the address stored in the link register (arm only). This may * contain the first return address of the stack. @@ -84,7 +84,7 @@ uintptr_t kscpu_instructionAddress(const struct KSMachineContext* const context) * * @return The link register value. */ -uintptr_t kscpu_linkRegister(const struct KSMachineContext* const context); +uintptr_t kscpu_linkRegister(const struct KSMachineContext *const context); /** Get the address whose access caused the last fault. * @@ -92,7 +92,7 @@ uintptr_t kscpu_linkRegister(const struct KSMachineContext* const context); * * @return The faulting address. */ -uintptr_t kscpu_faultAddress(const struct KSMachineContext* const context); +uintptr_t kscpu_faultAddress(const struct KSMachineContext *const context); /** Get the number of normal (not floating point or exception) registers the * currently running CPU has. @@ -107,7 +107,7 @@ int kscpu_numRegisters(void); * * @return The register's name or NULL if not found. */ -const char* kscpu_registerName(int regNumber); +const char *kscpu_registerName(int regNumber); /** Get the value stored in a normal register. * @@ -115,7 +115,7 @@ const char* kscpu_registerName(int regNumber); * * @return The register's current value. */ -uint64_t kscpu_registerValue(const struct KSMachineContext* const context, int regNumber); +uint64_t kscpu_registerValue(const struct KSMachineContext *const context, int regNumber); /** Get the number of exception registers the currently running CPU has. * @@ -129,7 +129,7 @@ int kscpu_numExceptionRegisters(void); * * @return The register's name or NULL if not found. */ -const char* kscpu_exceptionRegisterName(int regNumber); +const char *kscpu_exceptionRegisterName(int regNumber); /** Get the value stored in an exception register. * @@ -137,7 +137,7 @@ const char* kscpu_exceptionRegisterName(int regNumber); * * @return The register's current value. */ -uint64_t kscpu_exceptionRegisterValue(const struct KSMachineContext* const context, int regNumber); +uint64_t kscpu_exceptionRegisterValue(const struct KSMachineContext *const context, int regNumber); /** Get the direction in which the stack grows on the current architecture. * @@ -149,7 +149,7 @@ int kscpu_stackGrowDirection(void); * * @param destinationContext The context to fill. */ -void kscpu_getState(struct KSMachineContext* destinationContext); +void kscpu_getState(struct KSMachineContext *destinationContext); /** Strip PAC from an instruction pointer. * @@ -158,9 +158,9 @@ void kscpu_getState(struct KSMachineContext* destinationContext); * @return Instruction pointer without PAC. */ uintptr_t kscpu_normaliseInstructionPointer(uintptr_t ip); - + #ifdef __cplusplus } #endif -#endif // HDR_KSCPU_h +#endif // HDR_KSCPU_h diff --git a/Sources/KSCrashRecordingCore/include/KSCPU_Apple.h b/Sources/KSCrashRecordingCore/include/KSCPU_Apple.h index e74e8f557..aaf60f430 100644 --- a/Sources/KSCrashRecordingCore/include/KSCPU_Apple.h +++ b/Sources/KSCrashRecordingCore/include/KSCPU_Apple.h @@ -45,13 +45,11 @@ extern "C" { * * @return true if state fetching was successful. */ -bool kscpu_i_fillState(thread_t thread, - thread_state_t state, - thread_state_flavor_t flavor, +bool kscpu_i_fillState(thread_t thread, thread_state_t state, thread_state_flavor_t flavor, mach_msg_type_number_t stateCount); - + #ifdef __cplusplus } #endif -#endif // HDR_KSCPU_Apple_h +#endif // HDR_KSCPU_Apple_h diff --git a/Sources/KSCrashRecordingCore/include/KSCrashMonitor.h b/Sources/KSCrashRecordingCore/include/KSCrashMonitor.h index d135a528d..e1d552d4d 100644 --- a/Sources/KSCrashRecordingCore/include/KSCrashMonitor.h +++ b/Sources/KSCrashRecordingCore/include/KSCrashMonitor.h @@ -24,32 +24,29 @@ // THE SOFTWARE. // - /** Keeps watch for crashes and informs via callback when on occurs. */ - #ifndef HDR_KSCrashMonitor_h #define HDR_KSCrashMonitor_h -#include "KSThread.h" -#include "KSCrashMonitorFlag.h" - #include +#include "KSCrashMonitorFlag.h" +#include "KSThread.h" + #ifdef __cplusplus extern "C" { #endif struct KSCrash_MonitorContext; -typedef struct -{ - const char* (*monitorId)(void); +typedef struct { + const char *(*monitorId)(void); KSCrashMonitorFlag (*monitorFlags)(void); void (*setEnabled)(bool isEnabled); bool (*isEnabled)(void); - void (*addContextualInfoToEvent)(struct KSCrash_MonitorContext* eventContext); + void (*addContextualInfoToEvent)(struct KSCrash_MonitorContext *eventContext); void (*notifyPostSystemEnable)(void); } KSCrashMonitorAPI; @@ -89,7 +86,7 @@ void kscm_disableAllMonitors(void); * depends on various factors, including the environment, debugger presence, * and async safety requirements. */ -bool kscm_addMonitor(KSCrashMonitorAPI* api); +bool kscm_addMonitor(KSCrashMonitorAPI *api); /** * Removes a crash monitor from the system. @@ -98,7 +95,7 @@ bool kscm_addMonitor(KSCrashMonitorAPI* api); * * If the monitor is found, it is removed from the system. */ -void kscm_removeMonitor(const KSCrashMonitorAPI* api); +void kscm_removeMonitor(const KSCrashMonitorAPI *api); /** * Sets the callback for event capture. @@ -107,7 +104,7 @@ void kscm_removeMonitor(const KSCrashMonitorAPI* api); * * Registers a callback to be invoked when an event occurs. */ -void kscm_setEventCallback(void (*onEvent)(struct KSCrash_MonitorContext* monitorContext)); +void kscm_setEventCallback(void (*onEvent)(struct KSCrash_MonitorContext *monitorContext)); // Uncomment and implement if needed. /** @@ -115,7 +112,7 @@ void kscm_setEventCallback(void (*onEvent)(struct KSCrash_MonitorContext* monito * * @return Active monitors. */ -//KSCrashMonitorType kscm_getActiveMonitors(void); +// KSCrashMonitorType kscm_getActiveMonitors(void); // ============================================================================ #pragma mark - Internal API - @@ -132,10 +129,10 @@ bool kscm_notifyFatalExceptionCaptured(bool isAsyncSafeEnvironment); * * @param context Contextual information about the exception. */ -void kscm_handleException(struct KSCrash_MonitorContext* context); +void kscm_handleException(struct KSCrash_MonitorContext *context); #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitor_h +#endif // HDR_KSCrashMonitor_h diff --git a/Sources/KSCrashRecordingCore/include/KSCrashMonitorContext.h b/Sources/KSCrashRecordingCore/include/KSCrashMonitorContext.h index ccef8cb64..3887e248a 100644 --- a/Sources/KSCrashRecordingCore/include/KSCrashMonitorContext.h +++ b/Sources/KSCrashRecordingCore/include/KSCrashMonitorContext.h @@ -24,25 +24,22 @@ // THE SOFTWARE. // - #ifndef HDR_KSCrashMonitorContext_h #define HDR_KSCrashMonitorContext_h -#include "KSMachineContext.h" -#include "KSCrashMonitorFlag.h" - #include #include +#include "KSCrashMonitorFlag.h" +#include "KSMachineContext.h" + #ifdef __cplusplus extern "C" { #endif -typedef struct KSCrash_MonitorContext -{ - +typedef struct KSCrash_MonitorContext { /** Unique identifier for this event. */ - const char* eventID; + const char *eventID; /** If true, so reported user exception will have the current snapshot. */ @@ -52,225 +49,215 @@ typedef struct KSCrash_MonitorContext * functions should be used. */ bool requiresAsyncSafety; - + /** If true, the crash handling system is currently handling a crash. * When false, all values below this field are considered invalid. */ bool handlingCrash; - + /** If true, a second crash occurred while handling a crash. */ bool crashedDuringCrashHandling; - + /** If true, the registers contain valid information about the crash. */ bool registersAreValid; - + /** True if the crash system has detected a stack overflow. */ bool isStackOverflow; - + /** The machine context that generated the event. */ - struct KSMachineContext* offendingMachineContext; - + struct KSMachineContext *offendingMachineContext; + /** Address that caused the fault. */ uintptr_t faultAddress; - + /** Name of the monitor that captured the crash. * This determines which other fields are valid. */ - const char* monitorId; - + const char *monitorId; + /** Flags of the monitor that fired exception processing */ KSCrashMonitorFlag monitorFlags; /** The name of the exception that caused the crash, if any. */ - const char* exceptionName; - + const char *exceptionName; + /** Short description of why the crash occurred. */ - const char* crashReason; + const char *crashReason; /** The stack cursor for the trace leading up to the crash. * Note: Actual type is KSStackCursor* */ - void* stackCursor; - + void *stackCursor; + /** If true, don't output binary images. * This can be useful in cases where we have no stack. */ bool omitBinaryImages; - - struct - { + + struct { /** The mach exception type. */ int type; - + /** The mach exception code. */ int64_t code; - + /** The mach exception subcode. */ int64_t subcode; } mach; - - struct - { + + struct { /** The exception name. */ - const char* name; + const char *name; /** The exception userInfo. */ - const char* userInfo; + const char *userInfo; } NSException; - - struct - { + + struct { /** The exception name. */ - const char* name; - + const char *name; + } CPPException; - - struct - { + + struct { /** User context information. */ - const void* userContext; + const void *userContext; int signum; int sigcode; } signal; - - struct - { + + struct { /** The exception name. */ - const char* name; - + const char *name; + /** The language the exception occured in. */ - const char* language; - + const char *language; + /** The line of code where the exception occurred. Can be NULL. */ - const char* lineOfCode; - + const char *lineOfCode; + /** The user-supplied JSON encoded stack trace. */ - const char* customStackTrace; + const char *customStackTrace; } userException; - struct - { + struct { /** Total active time elapsed since the last crash. */ double activeDurationSinceLastCrash; - + /** Total time backgrounded elapsed since the last crash. */ double backgroundDurationSinceLastCrash; - + /** Number of app launches since the last crash. */ int launchesSinceLastCrash; - + /** Number of sessions (launch, resume from suspend) since last crash. */ int sessionsSinceLastCrash; - + /** Total active time elapsed since launch. */ double activeDurationSinceLaunch; - + /** Total time backgrounded elapsed since launch. */ double backgroundDurationSinceLaunch; - + /** Number of sessions (launch, resume from suspend) since app launch. */ int sessionsSinceLaunch; - + /** If true, the application crashed on the previous launch. */ bool crashedLastLaunch; - + /** If true, the application crashed on this launch. */ bool crashedThisLaunch; - + /** Timestamp for when the app state was last changed (active<->inactive, * background<->foreground) */ double appStateTransitionTime; - + /** If true, the application is currently active. */ bool applicationIsActive; - + /** If true, the application is currently in the foreground. */ bool applicationIsInForeground; - + } AppState; - + /* Misc system information */ - struct - { - const char* systemName; - const char* systemVersion; - const char* machine; - const char* model; - const char* kernelVersion; - const char* osVersion; + struct { + const char *systemName; + const char *systemVersion; + const char *machine; + const char *model; + const char *kernelVersion; + const char *osVersion; bool isJailbroken; - const char* bootTime; - const char* appStartTime; - const char* executablePath; - const char* executableName; - const char* bundleID; - const char* bundleName; - const char* bundleVersion; - const char* bundleShortVersion; - const char* appID; - const char* cpuArchitecture; + const char *bootTime; + const char *appStartTime; + const char *executablePath; + const char *executableName; + const char *bundleID; + const char *bundleName; + const char *bundleVersion; + const char *bundleShortVersion; + const char *appID; + const char *cpuArchitecture; int cpuType; int cpuSubType; int binaryCPUType; int binaryCPUSubType; - const char* timezone; - const char* processName; + const char *timezone; + const char *processName; int processID; int parentProcessID; - const char* deviceAppHash; - const char* buildType; + const char *deviceAppHash; + const char *buildType; uint64_t storageSize; uint64_t memorySize; uint64_t freeMemory; uint64_t usableMemory; } System; - - struct - { + + struct { /** Address of the last deallocated exception. */ uintptr_t address; /** Name of the last deallocated exception. */ - const char* name; + const char *name; /** Reason field from the last deallocated exception. */ - const char* reason; + const char *reason; } ZombieException; - - struct - { + + struct { /** measurement taken time in microseconds. */ int64_t timestamp; - + /** memory pressure `KSCrashAppMemoryPressure` */ - const char* pressure; - + const char *pressure; + /** amount of app memory used */ uint64_t footprint; - + /** amount of app memory remaining */ uint64_t remaining; - + /** high water mark for footprint (footprint + remaining)*/ uint64_t limit; - + /** memory level `KSCrashAppMemoryLevel` (KSCrashAppMemory.level) */ - const char* level; - + const char *level; + /** transition state of the app */ - const char* state; + const char *state; } AppMemory; - + /** Full path to the console log, if any. */ - const char* consoleLogPath; - + const char *consoleLogPath; + /** Absolute path where this report should be written (use default value if NULL)*/ - const char* reportPath; + const char *reportPath; } KSCrash_MonitorContext; - #ifdef __cplusplus } #endif -#endif // HDR_KSCrashMonitorContext_h +#endif // HDR_KSCrashMonitorContext_h diff --git a/Sources/KSCrashRecordingCore/include/KSCrashMonitorFlag.h b/Sources/KSCrashRecordingCore/include/KSCrashMonitorFlag.h index 0d572a084..dacee7871 100644 --- a/Sources/KSCrashRecordingCore/include/KSCrashMonitorFlag.h +++ b/Sources/KSCrashRecordingCore/include/KSCrashMonitorFlag.h @@ -31,8 +31,7 @@ extern "C" { #endif -typedef enum -{ +typedef enum { /** Indicates that no flags are set. */ KSCrashMonitorFlagNone = 0, diff --git a/Sources/KSCrashRecordingCore/include/KSCrashMonitorHelper.h b/Sources/KSCrashRecordingCore/include/KSCrashMonitorHelper.h index 90c160a87..0dd7615e4 100644 --- a/Sources/KSCrashRecordingCore/include/KSCrashMonitorHelper.h +++ b/Sources/KSCrashRecordingCore/include/KSCrashMonitorHelper.h @@ -33,53 +33,48 @@ extern "C" { #endif -static inline void kscm_setMonitorEnabled(const KSCrashMonitorAPI* api, bool isEnabled) +static inline void kscm_setMonitorEnabled(const KSCrashMonitorAPI *api, bool isEnabled) { - if (api != NULL && api->setEnabled != NULL) - { + if (api != NULL && api->setEnabled != NULL) { api->setEnabled(isEnabled); } } -static inline bool kscm_isMonitorEnabled(const KSCrashMonitorAPI* api) +static inline bool kscm_isMonitorEnabled(const KSCrashMonitorAPI *api) { - if (api != NULL && api->isEnabled != NULL) - { + if (api != NULL && api->isEnabled != NULL) { return api->isEnabled(); } return false; } -static inline const char* kscm_getMonitorId(const KSCrashMonitorAPI* api) +static inline const char *kscm_getMonitorId(const KSCrashMonitorAPI *api) { - if (api != NULL && api->monitorId != NULL) - { + if (api != NULL && api->monitorId != NULL) { return api->monitorId(); } return NULL; } -static inline KSCrashMonitorFlag kscm_getMonitorFlags(const KSCrashMonitorAPI* api) +static inline KSCrashMonitorFlag kscm_getMonitorFlags(const KSCrashMonitorAPI *api) { - if (api != NULL && api->monitorFlags != NULL) - { + if (api != NULL && api->monitorFlags != NULL) { return api->monitorFlags(); } return KSCrashMonitorFlagNone; } -static inline void kscm_addContextualInfoToEvent(const KSCrashMonitorAPI* api, struct KSCrash_MonitorContext* eventContext) +static inline void kscm_addContextualInfoToEvent(const KSCrashMonitorAPI *api, + struct KSCrash_MonitorContext *eventContext) { - if (api != NULL && api->addContextualInfoToEvent != NULL) - { + if (api != NULL && api->addContextualInfoToEvent != NULL) { api->addContextualInfoToEvent(eventContext); } } -static inline void kscm_notifyPostSystemEnable(const KSCrashMonitorAPI* api) +static inline void kscm_notifyPostSystemEnable(const KSCrashMonitorAPI *api) { - if (api != NULL && api->notifyPostSystemEnable != NULL) - { + if (api != NULL && api->notifyPostSystemEnable != NULL) { api->notifyPostSystemEnable(); } } diff --git a/Sources/KSCrashRecordingCore/include/KSDate.h b/Sources/KSCrashRecordingCore/include/KSDate.h index 1ba18b2f5..961d7f4ef 100644 --- a/Sources/KSCrashRecordingCore/include/KSDate.h +++ b/Sources/KSCrashRecordingCore/include/KSDate.h @@ -37,7 +37,7 @@ extern "C" { * * @param buffer21Chars A buffer of at least 21 chars to hold the RFC3339 date string. */ -void ksdate_utcStringFromTimestamp(time_t timestamp, char* buffer21Chars); +void ksdate_utcStringFromTimestamp(time_t timestamp, char *buffer21Chars); /** Convert microseconds returned from `gettimeofday` to an RFC3339 string representation. * @@ -45,7 +45,7 @@ void ksdate_utcStringFromTimestamp(time_t timestamp, char* buffer21Chars); * * @param buffer28Chars A buffer of at least 28 chars to hold the RFC3339 date string with milliseconds precision. */ -void ksdate_utcStringFromMicroseconds(int64_t microseconds, char* buffer28Chars); +void ksdate_utcStringFromMicroseconds(int64_t microseconds, char *buffer28Chars); /** Returns microseconds from `gettimeofday` * diff --git a/Sources/KSCrashRecordingCore/include/KSDebug.h b/Sources/KSCrashRecordingCore/include/KSDebug.h index 233444865..4e30869ed 100644 --- a/Sources/KSCrashRecordingCore/include/KSDebug.h +++ b/Sources/KSCrashRecordingCore/include/KSDebug.h @@ -24,28 +24,26 @@ // THE SOFTWARE. // - /* Utility functions for querying the mach kernel. */ - #ifndef HDR_KSDebug_h #define HDR_KSDebug_h - + #include #ifdef __cplusplus extern "C" { #endif - + /** Check if the current process is being traced or not. * * @return true if we're being traced. */ bool ksdebug_isBeingTraced(void); - + #ifdef __cplusplus } #endif -#endif // HDR_KSDebug_h +#endif // HDR_KSDebug_h diff --git a/Sources/KSCrashRecordingCore/include/KSDemangle_CPP.h b/Sources/KSCrashRecordingCore/include/KSDemangle_CPP.h index 414f8755f..b6116b6c7 100644 --- a/Sources/KSCrashRecordingCore/include/KSDemangle_CPP.h +++ b/Sources/KSCrashRecordingCore/include/KSDemangle_CPP.h @@ -38,10 +38,10 @@ extern "C" { * @return A demangled symbol, or NULL if demangling failed. * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on the returned value. */ -char* ksdm_demangleCPP(const char* mangledSymbol); +char *ksdm_demangleCPP(const char *mangledSymbol); #ifdef __cplusplus } #endif -#endif // HDR_KSDemangle_CPP_h +#endif // HDR_KSDemangle_CPP_h diff --git a/Sources/KSCrashRecordingCore/include/KSDemangle_Swift.h b/Sources/KSCrashRecordingCore/include/KSDemangle_Swift.h index f94abb0d9..f46cf8ad1 100644 --- a/Sources/KSCrashRecordingCore/include/KSDemangle_Swift.h +++ b/Sources/KSCrashRecordingCore/include/KSDemangle_Swift.h @@ -38,10 +38,10 @@ extern "C" { * @return A demangled symbol, or NULL if demangling failed. * MEMORY MANAGEMENT WARNING: User is responsible for calling free() on the returned value. */ -char* ksdm_demangleSwift(const char* mangledSymbol); - +char *ksdm_demangleSwift(const char *mangledSymbol); + #ifdef __cplusplus } #endif -#endif // HDR_KSDemangle_Swift_h +#endif // HDR_KSDemangle_Swift_h diff --git a/Sources/KSCrashRecordingCore/include/KSDynamicLinker.h b/Sources/KSCrashRecordingCore/include/KSDynamicLinker.h index 8161b2cb4..e6ee25254 100644 --- a/Sources/KSCrashRecordingCore/include/KSDynamicLinker.h +++ b/Sources/KSCrashRecordingCore/include/KSDynamicLinker.h @@ -35,22 +35,21 @@ extern "C" { #endif -typedef struct -{ +typedef struct { uint64_t address; uint64_t vmAddress; uint64_t size; - const char* name; - const uint8_t* uuid; + const char *name; + const uint8_t *uuid; int cpuType; int cpuSubType; uint64_t majorVersion; uint64_t minorVersion; uint64_t revisionVersion; - const char* crashInfoMessage; - const char* crashInfoMessage2; - const char* crashInfoBacktrace; - const char* crashInfoSignature; + const char *crashInfoMessage; + const char *crashInfoMessage2; + const char *crashInfoBacktrace; + const char *crashInfoSignature; } KSBinaryImage; /** Get the number of loaded binary images. @@ -65,7 +64,7 @@ int ksdl_imageCount(void); * * @return True if the image was successfully queried. */ -bool ksdl_getBinaryImage(int index, KSBinaryImage* buffer); +bool ksdl_getBinaryImage(int index, KSBinaryImage *buffer); /** Get information about a binary image based on mach_header. * @@ -77,7 +76,7 @@ bool ksdl_getBinaryImage(int index, KSBinaryImage* buffer); * * @return True if the image was successfully queried. */ -bool ksdl_getBinaryImageForHeader(const void* const header_ptr, const char* const image_name, KSBinaryImage* buffer); +bool ksdl_getBinaryImageForHeader(const void *const header_ptr, const char *const image_name, KSBinaryImage *buffer); /** Find a loaded binary image with the specified name. * @@ -87,7 +86,7 @@ bool ksdl_getBinaryImageForHeader(const void* const header_ptr, const char* cons * * @return the index of the matched image, or UINT32_MAX if not found. */ -uint32_t ksdl_imageNamed(const char* const imageName, bool exactMatch); +uint32_t ksdl_imageNamed(const char *const imageName, bool exactMatch); /** Get the UUID of a loaded binary image with the specified name. * @@ -98,7 +97,7 @@ uint32_t ksdl_imageNamed(const char* const imageName, bool exactMatch); * @return A pointer to the binary (16 byte) UUID of the image, or NULL if it * wasn't found. */ -const uint8_t* ksdl_imageUUID(const char* const imageName, bool exactMatch); +const uint8_t *ksdl_imageUUID(const char *const imageName, bool exactMatch); /** async-safe version of dladdr. * @@ -114,11 +113,10 @@ const uint8_t* ksdl_imageUUID(const char* const imageName, bool exactMatch); * @param info Gets filled out by this function. * @return true if at least some information was found. */ -bool ksdl_dladdr(const uintptr_t address, Dl_info* const info); - +bool ksdl_dladdr(const uintptr_t address, Dl_info *const info); #ifdef __cplusplus } #endif -#endif // HDR_KSDynamicLinker_h +#endif // HDR_KSDynamicLinker_h diff --git a/Sources/KSCrashRecordingCore/include/KSFileUtils.h b/Sources/KSCrashRecordingCore/include/KSFileUtils.h index 65eb3aae3..41f3b9b46 100644 --- a/Sources/KSCrashRecordingCore/include/KSFileUtils.h +++ b/Sources/KSCrashRecordingCore/include/KSFileUtils.h @@ -24,16 +24,14 @@ // THE SOFTWARE. // - /* Basic file reading/writing functions. */ - #ifndef HDR_KSFileUtils_h #define HDR_KSFileUtils_h -#include #include +#include #ifdef __cplusplus extern "C" { @@ -47,7 +45,7 @@ extern "C" { * * @return the last entry in the path. */ -const char* ksfu_lastPathEntry(const char* path); +const char *ksfu_lastPathEntry(const char *path); /** Write bytes to a file descriptor. * @@ -59,7 +57,7 @@ const char* ksfu_lastPathEntry(const char* path); * * @return true if the operation was successful. */ -bool ksfu_writeBytesToFD(const int fd, const char* bytes, int length); +bool ksfu_writeBytesToFD(const int fd, const char *bytes, int length); /** Read bytes from a file descriptor. * @@ -71,7 +69,7 @@ bool ksfu_writeBytesToFD(const int fd, const char* bytes, int length); * * @return true if the operation was successful. */ -bool ksfu_readBytesFromFD(const int fd, char* bytes, int length); +bool ksfu_readBytesFromFD(const int fd, char *bytes, int length); /** Read an entire file. Returns a buffer of file size + 1, null terminated. * @@ -87,7 +85,7 @@ bool ksfu_readBytesFromFD(const int fd, char* bytes, int length); * * @return true if the operation was successful. */ -bool ksfu_readEntireFile(const char* path, char** data, int* length, int maxLength); +bool ksfu_readEntireFile(const char *path, char **data, int *length, int maxLength); /** Write a string to a file. * @@ -97,7 +95,7 @@ bool ksfu_readEntireFile(const char* path, char** data, int* length, int maxLeng * * @return true if successful. */ -bool ksfu_writeStringToFD(const int fd, const char* string); +bool ksfu_writeStringToFD(const int fd, const char *string); /** Write a formatted string to a file. * @@ -107,7 +105,7 @@ bool ksfu_writeStringToFD(const int fd, const char* string); * * @return true if successful. */ -bool ksfu_writeFmtToFD(const int fd, const char* fmt, ...); +bool ksfu_writeFmtToFD(const int fd, const char *fmt, ...); /** Write a formatted string to a file. * @@ -119,7 +117,7 @@ bool ksfu_writeFmtToFD(const int fd, const char* fmt, ...); * * @return true if successful. */ -bool ksfu_writeFmtArgsToFD(const int fd, const char* fmt, va_list args); +bool ksfu_writeFmtArgsToFD(const int fd, const char *fmt, va_list args); /** Read a single line from a file. * @@ -131,7 +129,7 @@ bool ksfu_writeFmtArgsToFD(const int fd, const char* fmt, va_list args); * * @return The number of bytes read. */ -int ksfu_readLineFromFD(const int fd, char* buffer, int maxLength); +int ksfu_readLineFromFD(const int fd, char *buffer, int maxLength); /** Make all directories in a path. * @@ -139,7 +137,7 @@ int ksfu_readLineFromFD(const int fd, char* buffer, int maxLength); * * @return true if successful. */ -bool ksfu_makePath(const char* absolutePath); +bool ksfu_makePath(const char *absolutePath); /** Remove a file or directory. * @@ -149,7 +147,7 @@ bool ksfu_makePath(const char* absolutePath); * * @return true if successful. */ -bool ksfu_removeFile(const char* path, bool mustExist); +bool ksfu_removeFile(const char *path, bool mustExist); /** Delete the contents of a directory. * @@ -157,12 +155,11 @@ bool ksfu_removeFile(const char* path, bool mustExist); * * @return true if successful. */ -bool ksfu_deleteContentsOfPath(const char* path); +bool ksfu_deleteContentsOfPath(const char *path); /** Buffered writer structure. Everything inside should be considered internal use only. */ -typedef struct -{ - char* buffer; +typedef struct { + char *buffer; int bufferLength; int position; int fd; @@ -180,13 +177,14 @@ typedef struct * * @return True if the file was successfully opened. */ -bool ksfu_openBufferedWriter(KSBufferedWriter* writer, const char* const path, char* writeBuffer, int writeBufferLength); +bool ksfu_openBufferedWriter(KSBufferedWriter *writer, const char *const path, char *writeBuffer, + int writeBufferLength); /** Close a buffered writer. * * @param writer The writer to close. */ -void ksfu_closeBufferedWriter(KSBufferedWriter* writer); +void ksfu_closeBufferedWriter(KSBufferedWriter *writer); /** Write to a buffered writer. * @@ -198,7 +196,7 @@ void ksfu_closeBufferedWriter(KSBufferedWriter* writer); * * @return True if the data was successfully written. */ -bool ksfu_writeBufferedWriter(KSBufferedWriter* writer, const char* restrict const data, const int length); +bool ksfu_writeBufferedWriter(KSBufferedWriter *writer, const char *restrict const data, const int length); /** Flush a buffered writer, writing all uncommitted data to disk. * @@ -206,12 +204,11 @@ bool ksfu_writeBufferedWriter(KSBufferedWriter* writer, const char* restrict con * * @return True if the buffer was successfully flushed. */ -bool ksfu_flushBufferedWriter(KSBufferedWriter* writer); +bool ksfu_flushBufferedWriter(KSBufferedWriter *writer); /** Buffered reader structure. Everything inside should be considered internal use only. */ -typedef struct -{ - char* buffer; +typedef struct { + char *buffer; int bufferLength; int dataStartPos; int dataEndPos; @@ -230,13 +227,13 @@ typedef struct * * @return True if the file was successfully opened. */ -bool ksfu_openBufferedReader(KSBufferedReader* reader, const char* const path, char* readBuffer, int readBufferLength); +bool ksfu_openBufferedReader(KSBufferedReader *reader, const char *const path, char *readBuffer, int readBufferLength); /** Close a buffered reader. * * @param reader The reader to close. */ -void ksfu_closeBufferedReader(KSBufferedReader* reader); +void ksfu_closeBufferedReader(KSBufferedReader *reader); /** Read from a buffered reader. * @@ -248,7 +245,7 @@ void ksfu_closeBufferedReader(KSBufferedReader* reader); * * @return The number of bytes actually read. */ -int ksfu_readBufferedReader(KSBufferedReader* reader, char* dstBuffer, int byteCount); +int ksfu_readBufferedReader(KSBufferedReader *reader, char *dstBuffer, int byteCount); /** Read from a buffered reader until the specified character is encountered. * All bytes up to and including the character will be read. @@ -264,7 +261,7 @@ int ksfu_readBufferedReader(KSBufferedReader* reader, char* dstBuffer, int byteC * * @return True if the character was found before giving up. */ -bool ksfu_readBufferedReaderUntilChar(KSBufferedReader* reader, int ch, char* dstBuffer, int* length); +bool ksfu_readBufferedReaderUntilChar(KSBufferedReader *reader, int ch, char *dstBuffer, int *length); /** Memory maps an entire file of size and returns the mapped pointer. * @@ -277,10 +274,10 @@ bool ksfu_readBufferedReaderUntilChar(KSBufferedReader* reader, int ch, char* ds * with the returned pointer. It is ok to let the pointer live up to termination, * the system will unmap on termination if required. */ -void *ksfu_mmap(const char* path, int size); +void *ksfu_mmap(const char *path, int size); #ifdef __cplusplus } #endif -#endif // HDR_KSFileUtils_h +#endif // HDR_KSFileUtils_h diff --git a/Sources/KSCrashRecordingCore/include/KSID.h b/Sources/KSCrashRecordingCore/include/KSID.h index 896e72dbb..d5894a558 100644 --- a/Sources/KSCrashRecordingCore/include/KSID.h +++ b/Sources/KSCrashRecordingCore/include/KSID.h @@ -28,17 +28,15 @@ #ifdef __cplusplus extern "C" { #endif - /** Generate a new human readabale, null terminated, globally unique ID string. * * @param destinationBuffer37Bytes Buffer of at least 37 bytes to hold the ID. */ -void ksid_generate(char* destinationBuffer37Bytes); - - +void ksid_generate(char *destinationBuffer37Bytes); + #ifdef __cplusplus } #endif -#endif // HDR_KSID_h +#endif // HDR_KSID_h diff --git a/Sources/KSCrashRecordingCore/include/KSJSONCodec.h b/Sources/KSCrashRecordingCore/include/KSJSONCodec.h index f41503f56..cc588dfa3 100644 --- a/Sources/KSCrashRecordingCore/include/KSJSONCodec.h +++ b/Sources/KSCrashRecordingCore/include/KSJSONCodec.h @@ -24,11 +24,9 @@ // THE SOFTWARE. // - /* Reads and writes JSON encoded data. */ - #ifndef HDR_KSJSONCodec_h #define HDR_KSJSONCodec_h @@ -44,8 +42,7 @@ extern "C" { */ #define KSJSON_SIZE_AUTOMATIC -1 -enum -{ +enum { /** Encoding or decoding: Everything completed without error */ KSJSON_OK = 0, @@ -78,8 +75,7 @@ enum * * @return A string describing the error. */ -const char* ksjson_stringForError(const int error); - +const char *ksjson_stringForError(const int error); // ============================================================================ // Encode @@ -96,15 +92,14 @@ const char* ksjson_stringForError(const int error); * @return KSJSON_OK if the data was handled. * otherwise KSJSON_ERROR_CANNOT_ADD_DATA. */ -typedef int (*KSJSONAddDataFunc)(const char* data, int length, void* userData); +typedef int (*KSJSONAddDataFunc)(const char *data, int length, void *userData); -typedef struct -{ +typedef struct { /** Function to call to add more encoded JSON data. */ KSJSONAddDataFunc addJSONData; /** User-specified data */ - void* userData; + void *userData; /** How many containers deep we are. */ int containerLevel; @@ -119,7 +114,6 @@ typedef struct } KSJSONEncodeContext; - /** Begin a new encoding process. * * @param context The encoding context. @@ -130,16 +124,13 @@ typedef struct * * @param userData User-specified data which gets passed to addJSONData. */ -void ksjson_beginEncode(KSJSONEncodeContext* context, - bool prettyPrint, - KSJSONAddDataFunc addJSONData, - void* userData); +void ksjson_beginEncode(KSJSONEncodeContext *context, bool prettyPrint, KSJSONAddDataFunc addJSONData, void *userData); /** End the encoding process, ending any remaining open containers. * * @return KSJSON_OK if the process was successful. */ -int ksjson_endEncode(KSJSONEncodeContext* context); +int ksjson_endEncode(KSJSONEncodeContext *context); /** Add a boolean element. * @@ -151,9 +142,7 @@ int ksjson_endEncode(KSJSONEncodeContext* context); * * @return KSJSON_OK if the process was successful. */ -int ksjson_addBooleanElement(KSJSONEncodeContext* context, - const char* name, - bool value); +int ksjson_addBooleanElement(KSJSONEncodeContext *context, const char *name, bool value); /** Add an integer element. * @@ -165,9 +154,7 @@ int ksjson_addBooleanElement(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_addIntegerElement(KSJSONEncodeContext* context, - const char* name, - int64_t value); +int ksjson_addIntegerElement(KSJSONEncodeContext *context, const char *name, int64_t value); /** Add an unsigned integer element. * @@ -179,10 +166,8 @@ int ksjson_addIntegerElement(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_addUIntegerElement(KSJSONEncodeContext* const context, - const char* const name, - uint64_t value); - +int ksjson_addUIntegerElement(KSJSONEncodeContext *const context, const char *const name, uint64_t value); + /** Add a floating point element. * * @param context The encoding context. @@ -193,9 +178,7 @@ int ksjson_addUIntegerElement(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_addFloatingPointElement(KSJSONEncodeContext* context, - const char* name, - double value); +int ksjson_addFloatingPointElement(KSJSONEncodeContext *context, const char *name, double value); /** Add a null element. * @@ -205,8 +188,7 @@ int ksjson_addFloatingPointElement(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_addNullElement(KSJSONEncodeContext* context, - const char* name); +int ksjson_addNullElement(KSJSONEncodeContext *context, const char *name); /** Add a string element. * @@ -220,10 +202,7 @@ int ksjson_addNullElement(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_addStringElement(KSJSONEncodeContext* context, - const char* name, - const char* value, - int length); +int ksjson_addStringElement(KSJSONEncodeContext *context, const char *name, const char *value, int length); /** Start an incrementally-built string element. * @@ -235,8 +214,7 @@ int ksjson_addStringElement(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_beginStringElement(KSJSONEncodeContext* context, - const char* name); +int ksjson_beginStringElement(KSJSONEncodeContext *context, const char *name); /** Add a string fragment to an incrementally-built string element. * @@ -248,9 +226,7 @@ int ksjson_beginStringElement(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_appendStringElement(KSJSONEncodeContext* context, - const char* value, - int length); +int ksjson_appendStringElement(KSJSONEncodeContext *context, const char *value, int length); /** End an incrementally-built string element. * @@ -258,7 +234,7 @@ int ksjson_appendStringElement(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_endStringElement(KSJSONEncodeContext* context); +int ksjson_endStringElement(KSJSONEncodeContext *context); /** Add a string element. The element will be converted to string-coded hex. * @@ -272,10 +248,7 @@ int ksjson_endStringElement(KSJSONEncodeContext* context); * * @return KSJSON_OK if the process was successful. */ -int ksjson_addDataElement(KSJSONEncodeContext* const context, - const char* name, - const char* value, - int length); +int ksjson_addDataElement(KSJSONEncodeContext *const context, const char *name, const char *value, int length); /** Start an incrementally-built data element. The element will be converted * to string-coded hex. @@ -288,8 +261,7 @@ int ksjson_addDataElement(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_beginDataElement(KSJSONEncodeContext* const context, - const char* const name); +int ksjson_beginDataElement(KSJSONEncodeContext *const context, const char *const name); /** Add a data fragment to an incrementally-built data element. * @@ -301,9 +273,7 @@ int ksjson_beginDataElement(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_appendDataElement(KSJSONEncodeContext* const context, - const char* const value, - int length); +int ksjson_appendDataElement(KSJSONEncodeContext *const context, const char *const value, int length); /** End an incrementally-built data element. * @@ -311,7 +281,7 @@ int ksjson_appendDataElement(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_endDataElement(KSJSONEncodeContext* const context); +int ksjson_endDataElement(KSJSONEncodeContext *const context); /** Add a pre-formatted JSON element. * @@ -327,11 +297,8 @@ int ksjson_endDataElement(KSJSONEncodeContext* const context); * * @return KSJSON_OK if the process was successful. */ -int ksjson_addJSONElement(KSJSONEncodeContext* const encodeContext, - const char* restrict const name, - const char* restrict const jsonData, - const int jsonDataLength, - const bool closeLastContainer); +int ksjson_addJSONElement(KSJSONEncodeContext *const encodeContext, const char *restrict const name, + const char *restrict const jsonData, const int jsonDataLength, const bool closeLastContainer); /** Begin a new object container. * @@ -341,8 +308,7 @@ int ksjson_addJSONElement(KSJSONEncodeContext* const encodeContext, * * @return KSJSON_OK if the process was successful. */ -int ksjson_beginObject(KSJSONEncodeContext* context, - const char* name); +int ksjson_beginObject(KSJSONEncodeContext *context, const char *name); /** Begin a new array container. * @@ -352,8 +318,7 @@ int ksjson_beginObject(KSJSONEncodeContext* context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_beginArray(KSJSONEncodeContext* context, - const char* name); +int ksjson_beginArray(KSJSONEncodeContext *context, const char *name); /** Begin a generic JSON element, adding any necessary JSON preamble text, * including commas and names. @@ -363,8 +328,7 @@ int ksjson_beginArray(KSJSONEncodeContext* context, * * @param name The name of the next element (only needed if parent is a dictionary). */ -int ksjson_beginElement(KSJSONEncodeContext* const context, - const char* const name); +int ksjson_beginElement(KSJSONEncodeContext *const context, const char *const name); /** Add JSON data manually. * This function just passes your data directly through, even if it's malforned. @@ -377,9 +341,7 @@ int ksjson_beginElement(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_addRawJSONData(KSJSONEncodeContext* const context, - const char* const data, - const int length); +int ksjson_addRawJSONData(KSJSONEncodeContext *const context, const char *const data, const int length); /** End the current container and return to the next higher level. * @@ -387,7 +349,7 @@ int ksjson_addRawJSONData(KSJSONEncodeContext* const context, * * @return KSJSON_OK if the process was successful. */ -int ksjson_endContainer(KSJSONEncodeContext* context); +int ksjson_endContainer(KSJSONEncodeContext *context); /** Decode and add JSON data from a file. * @@ -399,23 +361,18 @@ int ksjson_endContainer(KSJSONEncodeContext* context); * * @param closeLastContainer If false, do not close the last container. */ -int ksjson_addJSONFromFile(KSJSONEncodeContext* const context, - const char* restrict const name, - const char* restrict const filename, - const bool closeLastContainer); - +int ksjson_addJSONFromFile(KSJSONEncodeContext *const context, const char *restrict const name, + const char *restrict const filename, const bool closeLastContainer); // ============================================================================ // Decode // ============================================================================ - /** * Callbacks called during a JSON decode process. * All function pointers must point to valid functions. */ -typedef struct KSJSONDecodeCallbacks -{ +typedef struct KSJSONDecodeCallbacks { /** Called when a boolean element is decoded. * * @param name The element's name. @@ -426,9 +383,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onBooleanElement)(const char* name, - bool value, - void* userData); + int (*onBooleanElement)(const char *name, bool value, void *userData); /** Called when a floating point element is decoded. * @@ -440,9 +395,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onFloatingPointElement)(const char* name, - double value, - void* userData); + int (*onFloatingPointElement)(const char *name, double value, void *userData); /** Called when an integer element is decoded. * @@ -454,9 +407,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onIntegerElement)(const char* name, - int64_t value, - void* userData); + int (*onIntegerElement)(const char *name, int64_t value, void *userData); /** Called when a null element is decoded. * @@ -466,8 +417,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onNullElement)(const char* name, - void* userData); + int (*onNullElement)(const char *name, void *userData); /** Called when a string element is decoded. * @@ -479,9 +429,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onStringElement)(const char* name, - const char* value, - void* userData); + int (*onStringElement)(const char *name, const char *value, void *userData); /** Called when a new object is encountered. * @@ -491,8 +439,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onBeginObject)(const char* name, - void* userData); + int (*onBeginObject)(const char *name, void *userData); /** Called when a new array is encountered. * @@ -502,8 +449,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onBeginArray)(const char* name, - void* userData); + int (*onBeginArray)(const char *name, void *userData); /** Called when leaving the current container and returning to the next * higher level container. @@ -512,7 +458,7 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onEndContainer)(void* userData); + int (*onEndContainer)(void *userData); /** Called when the end of the input data is reached. * @@ -520,11 +466,10 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if decoding should continue. */ - int (*onEndData)(void* userData); + int (*onEndData)(void *userData); } KSJSONDecodeCallbacks; - /** Read a JSON encoded file from the specified FD. * * @param data UTF-8 encoded JSON data. @@ -545,17 +490,11 @@ typedef struct KSJSONDecodeCallbacks * * @return KSJSON_OK if succesful. An error code otherwise. */ -int ksjson_decode(const char* data, - int length, - char* stringBuffer, - int stringBufferLength, - KSJSONDecodeCallbacks* callbacks, - void* userData, - int* errorOffset); - +int ksjson_decode(const char *data, int length, char *stringBuffer, int stringBufferLength, + KSJSONDecodeCallbacks *callbacks, void *userData, int *errorOffset); #ifdef __cplusplus } #endif -#endif // HDR_KSJSONCodec_h +#endif // HDR_KSJSONCodec_h diff --git a/Sources/KSCrashRecordingCore/include/KSJSONCodecObjC.h b/Sources/KSCrashRecordingCore/include/KSJSONCodecObjC.h index 60d54af98..3cd4d5ebf 100644 --- a/Sources/KSCrashRecordingCore/include/KSJSONCodecObjC.h +++ b/Sources/KSCrashRecordingCore/include/KSJSONCodecObjC.h @@ -74,9 +74,7 @@ typedef NS_ENUM(NSInteger, KSJSONDecodeOption) { * * @return The encoded UTF-8 JSON data or nil if an error occurred. */ -+ (NSData*) encode:(id) object - options:(KSJSONEncodeOption) options - error:(NSError**) error; ++ (NSData *)encode:(id)object options:(KSJSONEncodeOption)options error:(NSError **)error; /** Decode JSON data to an object. * @@ -90,9 +88,7 @@ typedef NS_ENUM(NSInteger, KSJSONDecodeOption) { * @return The decoded object or, if the KSJSONDecodeOptionKeepPartialFile * option is not set, nil when an error occurs. */ -+ (id) decode:(NSData*) JSONData - options:(KSJSONDecodeOption) options - error:(NSError**) error; ++ (id)decode:(NSData *)JSONData options:(KSJSONDecodeOption)options error:(NSError **)error; @end diff --git a/Sources/KSCrashRecordingCore/include/KSLogger.h b/Sources/KSCrashRecordingCore/include/KSLogger.h index 185d5a334..0d4bd1329 100644 --- a/Sources/KSCrashRecordingCore/include/KSLogger.h +++ b/Sources/KSCrashRecordingCore/include/KSLogger.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - /** * KSLogger * ======== @@ -52,7 +51,7 @@ * * Anything below the level specified for KSLogger_Level will not be compiled * or printed. - * + * * * Next, include the header file: * @@ -66,13 +65,14 @@ * KSLOG_ERROR(@"Some error message"); * * Prints: - * 2011-07-16 05:41:01.379 TestApp[4439:f803] ERROR: SomeClass.m (21): -[SomeFunction]: Some error message + * 2011-07-16 05:41:01.379 TestApp[4439:f803] ERROR: SomeClass.m (21): -[SomeFunction]: Some error message * * Code: * KSLOG_INFO(@"Info about %@", someObject); * * Prints: - * 2011-07-16 05:44:05.239 TestApp[4473:f803] INFO : SomeClass.m (20): -[SomeFunction]: Info about + * 2011-07-16 05:44:05.239 TestApp[4473:f803] INFO : SomeClass.m (20): -[SomeFunction]: Info about * * * The "BASIC" versions of the macros behave exactly like NSLog() or printf(), @@ -138,12 +138,10 @@ * default to 1024 if not specified during compilation. */ - // ============================================================================ #pragma mark - (internal) - // ============================================================================ - #ifndef HDR_KSLogger_h #define HDR_KSLogger_h @@ -157,92 +155,74 @@ extern "C" { #import -void i_kslog_logObjC(const char* level, - const char* file, - int line, - const char* function, - CFStringRef fmt, ...); +void i_kslog_logObjC(const char *level, const char *file, int line, const char *function, CFStringRef fmt, ...); void i_kslog_logObjCBasic(CFStringRef fmt, ...); -#define i_KSLOG_FULL(LEVEL,FILE,LINE,FUNCTION,FMT,...) i_kslog_logObjC(LEVEL,FILE,LINE,FUNCTION,(__bridge CFStringRef)FMT,##__VA_ARGS__) -#define i_KSLOG_BASIC(FMT, ...) i_kslog_logObjCBasic((__bridge CFStringRef)FMT,##__VA_ARGS__) +#define i_KSLOG_FULL(LEVEL, FILE, LINE, FUNCTION, FMT, ...) \ + i_kslog_logObjC(LEVEL, FILE, LINE, FUNCTION, (__bridge CFStringRef)FMT, ##__VA_ARGS__) +#define i_KSLOG_BASIC(FMT, ...) i_kslog_logObjCBasic((__bridge CFStringRef)FMT, ##__VA_ARGS__) -#else // __OBJC__ +#else // __OBJC__ -void i_kslog_logC(const char* level, - const char* file, - int line, - const char* function, - const char* fmt, ...); +void i_kslog_logC(const char *level, const char *file, int line, const char *function, const char *fmt, ...); -void i_kslog_logCBasic(const char* fmt, ...); +void i_kslog_logCBasic(const char *fmt, ...); #define i_KSLOG_FULL i_kslog_logC #define i_KSLOG_BASIC i_kslog_logCBasic -#endif // __OBJC__ - +#endif // __OBJC__ /* Back up any existing defines by the same name */ #ifdef KS_NONE - #define KSLOG_BAK_NONE KS_NONE - #undef KS_NONE +#define KSLOG_BAK_NONE KS_NONE +#undef KS_NONE #endif #ifdef ERROR - #define KSLOG_BAK_ERROR ERROR - #undef ERROR +#define KSLOG_BAK_ERROR ERROR +#undef ERROR #endif #ifdef WARN - #define KSLOG_BAK_WARN WARN - #undef WARN +#define KSLOG_BAK_WARN WARN +#undef WARN #endif #ifdef INFO - #define KSLOG_BAK_INFO INFO - #undef INFO +#define KSLOG_BAK_INFO INFO +#undef INFO #endif #ifdef DEBUG - #define KSLOG_BAK_DEBUG DEBUG - #undef DEBUG +#define KSLOG_BAK_DEBUG DEBUG +#undef DEBUG #endif #ifdef TRACE - #define KSLOG_BAK_TRACE TRACE - #undef TRACE +#define KSLOG_BAK_TRACE TRACE +#undef TRACE #endif - -#define KSLogger_Level_None 0 +#define KSLogger_Level_None 0 #define KSLogger_Level_Error 10 -#define KSLogger_Level_Warn 20 -#define KSLogger_Level_Info 30 +#define KSLogger_Level_Warn 20 +#define KSLogger_Level_Info 30 #define KSLogger_Level_Debug 40 #define KSLogger_Level_Trace 50 -#define KS_NONE KSLogger_Level_None +#define KS_NONE KSLogger_Level_None #define ERROR KSLogger_Level_Error -#define WARN KSLogger_Level_Warn -#define INFO KSLogger_Level_Info +#define WARN KSLogger_Level_Warn +#define INFO KSLogger_Level_Info #define DEBUG KSLogger_Level_Debug #define TRACE KSLogger_Level_Trace - #ifndef KSLogger_Level - #define KSLogger_Level KSLogger_Level_Error +#define KSLogger_Level KSLogger_Level_Error #endif #ifndef KSLogger_LocalLevel - #define KSLogger_LocalLevel KSLogger_Level_None +#define KSLogger_LocalLevel KSLogger_Level_None #endif -#define a_KSLOG_FULL(LEVEL, FMT, ...) \ - i_KSLOG_FULL(LEVEL, \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__, \ - FMT, \ - ##__VA_ARGS__) - - +#define a_KSLOG_FULL(LEVEL, FMT, ...) i_KSLOG_FULL(LEVEL, __FILE__, __LINE__, __PRETTY_FUNCTION__, FMT, ##__VA_ARGS__) // ============================================================================ #pragma mark - API - @@ -254,7 +234,7 @@ void i_kslog_logCBasic(const char* fmt, ...); * * @param overwrite If true, overwrite the log file. */ -bool kslog_setLogFilename(const char* filename, bool overwrite); +bool kslog_setLogFilename(const char *filename, bool overwrite); /** Clear the log file. */ bool kslog_clearLogFile(void); @@ -270,8 +250,7 @@ bool kslog_clearLogFile(void); * * @return TRUE if the logger would print at the specified level. */ -#define KSLOG_PRINTS_AT_LEVEL(LEVEL) \ - (KSLogger_Level >= LEVEL || KSLogger_LocalLevel >= LEVEL) +#define KSLOG_PRINTS_AT_LEVEL(LEVEL) (KSLogger_Level >= LEVEL || KSLogger_LocalLevel >= LEVEL) /** Log a message regardless of the log settings. * Normal version prints out full context. Basic version prints directly. @@ -281,18 +260,17 @@ bool kslog_clearLogFile(void); #define KSLOG_ALWAYS(FMT, ...) a_KSLOG_FULL("FORCE", FMT, ##__VA_ARGS__) #define KSLOGBASIC_ALWAYS(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) - /** Log an error. * Normal version prints out full context. Basic version prints directly. * * @param FMT The format specifier, followed by its arguments. */ #if KSLOG_PRINTS_AT_LEVEL(KSLogger_Level_Error) - #define KSLOG_ERROR(FMT, ...) a_KSLOG_FULL("ERROR", FMT, ##__VA_ARGS__) - #define KSLOGBASIC_ERROR(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) +#define KSLOG_ERROR(FMT, ...) a_KSLOG_FULL("ERROR", FMT, ##__VA_ARGS__) +#define KSLOGBASIC_ERROR(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) #else - #define KSLOG_ERROR(FMT, ...) - #define KSLOGBASIC_ERROR(FMT, ...) +#define KSLOG_ERROR(FMT, ...) +#define KSLOGBASIC_ERROR(FMT, ...) #endif /** Log a warning. @@ -301,11 +279,11 @@ bool kslog_clearLogFile(void); * @param FMT The format specifier, followed by its arguments. */ #if KSLOG_PRINTS_AT_LEVEL(KSLogger_Level_Warn) - #define KSLOG_WARN(FMT, ...) a_KSLOG_FULL("WARN ", FMT, ##__VA_ARGS__) - #define KSLOGBASIC_WARN(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) +#define KSLOG_WARN(FMT, ...) a_KSLOG_FULL("WARN ", FMT, ##__VA_ARGS__) +#define KSLOGBASIC_WARN(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) #else - #define KSLOG_WARN(FMT, ...) - #define KSLOGBASIC_WARN(FMT, ...) +#define KSLOG_WARN(FMT, ...) +#define KSLOGBASIC_WARN(FMT, ...) #endif /** Log an info message. @@ -314,11 +292,11 @@ bool kslog_clearLogFile(void); * @param FMT The format specifier, followed by its arguments. */ #if KSLOG_PRINTS_AT_LEVEL(KSLogger_Level_Info) - #define KSLOG_INFO(FMT, ...) a_KSLOG_FULL("INFO ", FMT, ##__VA_ARGS__) - #define KSLOGBASIC_INFO(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) +#define KSLOG_INFO(FMT, ...) a_KSLOG_FULL("INFO ", FMT, ##__VA_ARGS__) +#define KSLOGBASIC_INFO(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) #else - #define KSLOG_INFO(FMT, ...) - #define KSLOGBASIC_INFO(FMT, ...) +#define KSLOG_INFO(FMT, ...) +#define KSLOGBASIC_INFO(FMT, ...) #endif /** Log a debug message. @@ -327,11 +305,11 @@ bool kslog_clearLogFile(void); * @param FMT The format specifier, followed by its arguments. */ #if KSLOG_PRINTS_AT_LEVEL(KSLogger_Level_Debug) - #define KSLOG_DEBUG(FMT, ...) a_KSLOG_FULL("DEBUG", FMT, ##__VA_ARGS__) - #define KSLOGBASIC_DEBUG(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) +#define KSLOG_DEBUG(FMT, ...) a_KSLOG_FULL("DEBUG", FMT, ##__VA_ARGS__) +#define KSLOGBASIC_DEBUG(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) #else - #define KSLOG_DEBUG(FMT, ...) - #define KSLOGBASIC_DEBUG(FMT, ...) +#define KSLOG_DEBUG(FMT, ...) +#define KSLOGBASIC_DEBUG(FMT, ...) #endif /** Log a trace message. @@ -340,15 +318,13 @@ bool kslog_clearLogFile(void); * @param FMT The format specifier, followed by its arguments. */ #if KSLOG_PRINTS_AT_LEVEL(KSLogger_Level_Trace) - #define KSLOG_TRACE(FMT, ...) a_KSLOG_FULL("TRACE", FMT, ##__VA_ARGS__) - #define KSLOGBASIC_TRACE(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) +#define KSLOG_TRACE(FMT, ...) a_KSLOG_FULL("TRACE", FMT, ##__VA_ARGS__) +#define KSLOGBASIC_TRACE(FMT, ...) i_KSLOG_BASIC(FMT, ##__VA_ARGS__) #else - #define KSLOG_TRACE(FMT, ...) - #define KSLOGBASIC_TRACE(FMT, ...) +#define KSLOG_TRACE(FMT, ...) +#define KSLOGBASIC_TRACE(FMT, ...) #endif - - // ============================================================================ #pragma mark - (internal) - // ============================================================================ @@ -356,33 +332,32 @@ bool kslog_clearLogFile(void); /* Put everything back to the way we found it. */ #undef ERROR #ifdef KSLOG_BAK_ERROR - #define ERROR KSLOG_BAK_ERROR - #undef KSLOG_BAK_ERROR +#define ERROR KSLOG_BAK_ERROR +#undef KSLOG_BAK_ERROR #endif #undef WARNING #ifdef KSLOG_BAK_WARN - #define WARNING KSLOG_BAK_WARN - #undef KSLOG_BAK_WARN +#define WARNING KSLOG_BAK_WARN +#undef KSLOG_BAK_WARN #endif #undef INFO #ifdef KSLOG_BAK_INFO - #define INFO KSLOG_BAK_INFO - #undef KSLOG_BAK_INFO +#define INFO KSLOG_BAK_INFO +#undef KSLOG_BAK_INFO #endif #undef DEBUG #ifdef KSLOG_BAK_DEBUG - #define DEBUG KSLOG_BAK_DEBUG - #undef KSLOG_BAK_DEBUG +#define DEBUG KSLOG_BAK_DEBUG +#undef KSLOG_BAK_DEBUG #endif #undef TRACE #ifdef KSLOG_BAK_TRACE - #define TRACE KSLOG_BAK_TRACE - #undef KSLOG_BAK_TRACE +#define TRACE KSLOG_BAK_TRACE +#undef KSLOG_BAK_TRACE #endif - #ifdef __cplusplus } #endif -#endif // HDR_KSLogger_h +#endif // HDR_KSLogger_h diff --git a/Sources/KSCrashRecordingCore/include/KSMach-O.h b/Sources/KSCrashRecordingCore/include/KSMach-O.h index 0f307653f..d9d532e2e 100644 --- a/Sources/KSCrashRecordingCore/include/KSMach-O.h +++ b/Sources/KSCrashRecordingCore/include/KSMach-O.h @@ -25,9 +25,10 @@ #ifndef KSMachO_h #define KSMachO_h -#include "KSPlatformSpecificDefines.h" #include +#include "KSPlatformSpecificDefines.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -40,7 +41,7 @@ extern "C" { * @param command_type The type of the command to search for. * @return Pointer to the `load_command` structure if found, otherwise `NULL`. */ -const struct load_command* ksmacho_getCommandByTypeFromHeader(const mach_header_t* header, uint32_t command_type); +const struct load_command *ksmacho_getCommandByTypeFromHeader(const mach_header_t *header, uint32_t command_type); /** * This routine returns the `segment_command` structure for the named segment @@ -52,7 +53,7 @@ const struct load_command* ksmacho_getCommandByTypeFromHeader(const mach_header_ * @param seg_name The name of the segment to search for. * @return Pointer to the `segment_command` structure if found, otherwise `NULL`. */ -const segment_command_t* ksmacho_getSegmentByNameFromHeader(const mach_header_t* header, const char* seg_name); +const segment_command_t *ksmacho_getSegmentByNameFromHeader(const mach_header_t *header, const char *seg_name); /** * This routine returns the section structure for the specified `SECTION_TYPE` flag @@ -62,7 +63,7 @@ const segment_command_t* ksmacho_getSegmentByNameFromHeader(const mach_header_t* * @param flag The `SECTION_TYPE` flag of the section to search for. * @return Pointer to the section structure if found, otherwise `NULL`. */ -const section_t* ksmacho_getSectionByTypeFlagFromSegment(const segment_command_t* dataSegment, uint32_t flag); +const section_t *ksmacho_getSectionByTypeFlagFromSegment(const segment_command_t *dataSegment, uint32_t flag); /** * This routine returns the protection attributes for a given memory section. @@ -70,7 +71,7 @@ const section_t* ksmacho_getSectionByTypeFlagFromSegment(const segment_command_t * @param sectionStart Pointer to the start of the memory section. * @return Protection attributes of the section. */ -vm_prot_t ksmacho_getSectionProtection(void* sectionStart); +vm_prot_t ksmacho_getSectionProtection(void *sectionStart); #ifdef __cplusplus } diff --git a/Sources/KSCrashRecordingCore/include/KSMach.h b/Sources/KSCrashRecordingCore/include/KSMach.h index 29c774218..49773d59f 100644 --- a/Sources/KSCrashRecordingCore/include/KSMach.h +++ b/Sources/KSCrashRecordingCore/include/KSMach.h @@ -37,7 +37,7 @@ extern "C" { * * @return The exception's name or NULL if not found. */ -const char* ksmach_exceptionName(int64_t exceptionType); +const char *ksmach_exceptionName(int64_t exceptionType); /** Get the name of a mach kernel return code. * @@ -45,7 +45,7 @@ const char* ksmach_exceptionName(int64_t exceptionType); * * @return The code's name or NULL if not found. */ -const char* ksmach_kernelReturnCodeName(int64_t returnCode); +const char *ksmach_kernelReturnCodeName(int64_t returnCode); /** Get the signal equivalent of a mach exception. * @@ -65,9 +65,8 @@ int ksmach_signalForMachException(int exception, int64_t code); */ int ksmach_machExceptionForSignal(int signal); - #ifdef __cplusplus } #endif -#endif // HDR_KSMach_h +#endif // HDR_KSMach_h diff --git a/Sources/KSCrashRecordingCore/include/KSMachineContext.h b/Sources/KSCrashRecordingCore/include/KSMachineContext.h index 7ee8f69d9..fb8f7e7f1 100644 --- a/Sources/KSCrashRecordingCore/include/KSMachineContext.h +++ b/Sources/KSCrashRecordingCore/include/KSMachineContext.h @@ -24,13 +24,13 @@ // THE SOFTWARE. // - #ifndef HDR_KSMachineContext_h #define HDR_KSMachineContext_h -#include "KSThread.h" -#include #include +#include + +#include "KSThread.h" #ifdef __cplusplus extern "C" { @@ -54,9 +54,9 @@ void ksmc_resumeEnvironment(thread_act_array_t threads, mach_msg_type_number_t n * * @param NAME The C identifier to give the pointer. */ -#define KSMC_NEW_CONTEXT(NAME) \ +#define KSMC_NEW_CONTEXT(NAME) \ char ksmc_##NAME##_storage[ksmc_contextSize()]; \ - struct KSMachineContext* NAME = (struct KSMachineContext*)ksmc_##NAME##_storage + struct KSMachineContext *NAME = (struct KSMachineContext *)ksmc_##NAME##_storage struct KSMachineContext; @@ -72,7 +72,7 @@ int ksmc_contextSize(void); * * @return true if successful. */ -bool ksmc_getContextForThread(KSThread thread, struct KSMachineContext* destinationContext, bool isCrashedContext); +bool ksmc_getContextForThread(KSThread thread, struct KSMachineContext *destinationContext, bool isCrashedContext); /** Fill in a machine context from a signal handler. * A signal handler context is always assumed to be a crashed context. @@ -82,7 +82,7 @@ bool ksmc_getContextForThread(KSThread thread, struct KSMachineContext* destinat * * @return true if successful. */ -bool ksmc_getContextForSignal(void* signalUserContext, struct KSMachineContext* destinationContext); +bool ksmc_getContextForSignal(void *signalUserContext, struct KSMachineContext *destinationContext); /** Get the thread associated with a machine context. * @@ -90,7 +90,7 @@ bool ksmc_getContextForSignal(void* signalUserContext, struct KSMachineContext* * * @return The associated thread. */ -KSThread ksmc_getThreadFromContext(const struct KSMachineContext* const context); +KSThread ksmc_getThreadFromContext(const struct KSMachineContext *const context); /** Get the number of threads stored in a machine context. * @@ -98,7 +98,7 @@ KSThread ksmc_getThreadFromContext(const struct KSMachineContext* const context) * * @return The number of threads. */ -int ksmc_getThreadCount(const struct KSMachineContext* const context); +int ksmc_getThreadCount(const struct KSMachineContext *const context); /** Get a thread from a machine context. * @@ -107,7 +107,7 @@ int ksmc_getThreadCount(const struct KSMachineContext* const context); * * @return The thread. */ -KSThread ksmc_getThreadAtIndex(const struct KSMachineContext* const context, int index); +KSThread ksmc_getThreadAtIndex(const struct KSMachineContext *const context, int index); /** Get the index of a thread. * @@ -116,19 +116,19 @@ KSThread ksmc_getThreadAtIndex(const struct KSMachineContext* const context, int * * @return The thread's index, or -1 if it couldn't be determined. */ -int ksmc_indexOfThread(const struct KSMachineContext* const context, KSThread thread); +int ksmc_indexOfThread(const struct KSMachineContext *const context, KSThread thread); /** Check if this is a crashed context. */ -bool ksmc_isCrashedContext(const struct KSMachineContext* const context); +bool ksmc_isCrashedContext(const struct KSMachineContext *const context); /** Check if this context can have stored CPU state. */ -bool ksmc_canHaveCPUState(const struct KSMachineContext* const context); +bool ksmc_canHaveCPUState(const struct KSMachineContext *const context); /** Check if this context has valid exception registers. */ -bool ksmc_hasValidExceptionRegisters(const struct KSMachineContext* const context); +bool ksmc_hasValidExceptionRegisters(const struct KSMachineContext *const context); /** Add a thread to the reserved threads list. * @@ -136,9 +136,8 @@ bool ksmc_hasValidExceptionRegisters(const struct KSMachineContext* const contex */ void ksmc_addReservedThread(KSThread thread); - #ifdef __cplusplus } #endif -#endif // HDR_KSMachineContext_h +#endif // HDR_KSMachineContext_h diff --git a/Sources/KSCrashRecordingCore/include/KSMachineContext_Apple.h b/Sources/KSCrashRecordingCore/include/KSMachineContext_Apple.h index 094e24c80..c82ae2a77 100644 --- a/Sources/KSCrashRecordingCore/include/KSMachineContext_Apple.h +++ b/Sources/KSCrashRecordingCore/include/KSMachineContext_Apple.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #ifndef HDR_KSMachineContext_Apple_h #define HDR_KSMachineContext_Apple_h @@ -37,13 +36,12 @@ extern "C" { #endif #ifdef __arm64__ - #define STRUCT_MCONTEXT_L _STRUCT_MCONTEXT64 +#define STRUCT_MCONTEXT_L _STRUCT_MCONTEXT64 #else - #define STRUCT_MCONTEXT_L _STRUCT_MCONTEXT +#define STRUCT_MCONTEXT_L _STRUCT_MCONTEXT #endif -typedef struct KSMachineContext -{ +typedef struct KSMachineContext { thread_t thisThread; thread_t allThreads[100]; int threadCount; @@ -53,10 +51,9 @@ typedef struct KSMachineContext bool isSignalContext; STRUCT_MCONTEXT_L machineContext; } KSMachineContext; - - + #ifdef __cplusplus } #endif -#endif // HDR_KSMachineContext_Apple_h +#endif // HDR_KSMachineContext_Apple_h diff --git a/Sources/KSCrashRecordingCore/include/KSMemory.h b/Sources/KSCrashRecordingCore/include/KSMemory.h index 62c5d9c76..9fac4631c 100644 --- a/Sources/KSCrashRecordingCore/include/KSMemory.h +++ b/Sources/KSCrashRecordingCore/include/KSMemory.h @@ -24,11 +24,9 @@ // THE SOFTWARE. // - /* Utility functions for querying the mach kernel. */ - #ifndef HDR_ksmemory_h #define HDR_ksmemory_h @@ -45,7 +43,7 @@ extern "C" { * * @return True if the memory can be safely read. */ -bool ksmem_isMemoryReadable(const void* const memory, const int byteCount); +bool ksmem_isMemoryReadable(const void *const memory, const int byteCount); /** Test how much memory is readable from the specified pointer. * @@ -54,7 +52,7 @@ bool ksmem_isMemoryReadable(const void* const memory, const int byteCount); * * @return The number of bytes that are readable from that address. */ -int ksmem_maxReadableBytes(const void* const memory, const int tryByteCount); +int ksmem_maxReadableBytes(const void *const memory, const int tryByteCount); /** Copy memory safely. If the memory is not accessible, returns false * rather than crashing. @@ -67,7 +65,7 @@ int ksmem_maxReadableBytes(const void* const memory, const int tryByteCount); * * @return true if successful. */ -bool ksmem_copySafely(const void* restrict const src, void* restrict const dst, int byteCount); +bool ksmem_copySafely(const void *restrict const src, void *restrict const dst, int byteCount); /** Copies up to numBytes of data from src to dest, stopping if memory * becomes inaccessible. @@ -80,10 +78,10 @@ bool ksmem_copySafely(const void* restrict const src, void* restrict const dst, * * @return The number of bytes actually copied. */ -int ksmem_copyMaxPossible(const void* restrict const src, void* restrict const dst, int byteCount); +int ksmem_copyMaxPossible(const void *restrict const src, void *restrict const dst, int byteCount); #ifdef __cplusplus } #endif -#endif // HDR_ksmemory_h +#endif // HDR_ksmemory_h diff --git a/Sources/KSCrashRecordingCore/include/KSObjC.h b/Sources/KSCrashRecordingCore/include/KSObjC.h index 27da028d9..81f6baff4 100644 --- a/Sources/KSCrashRecordingCore/include/KSObjC.h +++ b/Sources/KSCrashRecordingCore/include/KSObjC.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #ifndef HDR_KSObjC_h #define HDR_KSObjC_h @@ -35,16 +34,14 @@ extern "C" { #endif -typedef enum -{ +typedef enum { KSObjCTypeUnknown = 0, KSObjCTypeClass, KSObjCTypeObject, KSObjCTypeBlock, } KSObjCType; -typedef enum -{ +typedef enum { KSObjCClassTypeUnknown = 0, KSObjCClassTypeString, KSObjCClassTypeDate, @@ -55,14 +52,12 @@ typedef enum KSObjCClassTypeException, } KSObjCClassType; -typedef struct -{ - const char* name; - const char* type; +typedef struct { + const char *name; + const char *type; int index; } KSObjCIvar; - //====================================================================== #pragma mark - Basic Objective-C Queries - //====================================================================== @@ -72,15 +67,15 @@ typedef struct * @param pointer The pointer to check. * @return true if it's a tagged pointer. */ -bool ksobjc_isTaggedPointer(const void* const pointer); +bool ksobjc_isTaggedPointer(const void *const pointer); /** Check if a pointer is a valid tagged pointer. * * @param pointer The pointer to check. * @return true if it's a valid tagged pointer. */ -bool ksobjc_isValidTaggedPointer(const void* const pointer); - +bool ksobjc_isValidTaggedPointer(const void *const pointer); + /** Query a pointer to see what kind of object it points to. * If the pointer points to a class, this method will verify that its basic * class data and ivars are valid, @@ -98,7 +93,7 @@ bool ksobjc_isValidTaggedPointer(const void* const pointer); * @return The type of object, or KSObjCTypeNone if it was not an object or * was inaccessible. */ -KSObjCType ksobjc_objectType(const void* objectOrClassPtr); +KSObjCType ksobjc_objectType(const void *objectOrClassPtr); /** Check that an object contains valid data. * If the object is of a recognized type (string, date, array, etc), @@ -110,7 +105,7 @@ KSObjCType ksobjc_objectType(const void* objectOrClassPtr); * * @return true if the object is valid. */ -bool ksobjc_isValidObject(const void* object); +bool ksobjc_isValidObject(const void *object); /** Fetch the isa pointer from an object or class. * @@ -118,7 +113,7 @@ bool ksobjc_isValidObject(const void* object); * * @return The isa pointer. */ -const void* ksobjc_isaPointer(const void* objectOrClassPtr); +const void *ksobjc_isaPointer(const void *objectOrClassPtr); /** Fetch the super class pointer from a class. * @@ -126,7 +121,7 @@ const void* ksobjc_isaPointer(const void* objectOrClassPtr); * * @return the super class. */ -const void* ksobjc_superClass(const void* classPtr); +const void *ksobjc_superClass(const void *classPtr); /** Get the base class this class is derived from. * It will always return the highest level non-root class in the hierarchy @@ -137,7 +132,7 @@ const void* ksobjc_superClass(const void* classPtr); * * @return The base class. */ -const void* ksobjc_baseClass(const void* const classPtr); +const void *ksobjc_baseClass(const void *const classPtr); /** Check if a class is a meta class. * @@ -145,7 +140,7 @@ const void* ksobjc_baseClass(const void* const classPtr); * * @return true if the class is a meta class. */ -bool ksobjc_isMetaClass(const void* classPtr); +bool ksobjc_isMetaClass(const void *classPtr); /** Check if a class is a root class. * @@ -153,7 +148,7 @@ bool ksobjc_isMetaClass(const void* classPtr); * * @return true if the class is a root class. */ -bool ksobjc_isRootClass(const void* classPtr); +bool ksobjc_isRootClass(const void *classPtr); /** Get the name of a class. * @@ -161,7 +156,7 @@ bool ksobjc_isRootClass(const void* classPtr); * * @return the name, or NULL if the name inaccessible. */ -const char* ksobjc_className(const void* classPtr); +const char *ksobjc_className(const void *classPtr); /** Get the name of an object's class. * This also handles tagged pointers. @@ -170,7 +165,7 @@ const char* ksobjc_className(const void* classPtr); * * @return the name, or NULL if the name is inaccessible. */ -const char* ksobjc_objectClassName(const void* objectPtr); +const char *ksobjc_objectClassName(const void *objectPtr); /** Check if a class has a specific name. * @@ -180,7 +175,7 @@ const char* ksobjc_objectClassName(const void* objectPtr); * * @return true if the class has the specified name. */ -bool ksobjc_isClassNamed(const void* const classPtr, const char* const className); +bool ksobjc_isClassNamed(const void *const classPtr, const char *const className); /** Check if a class is of the specified type or a subclass thereof. * Note: This function is considerably slower than ksobjc_baseClassName(). @@ -191,7 +186,7 @@ bool ksobjc_isClassNamed(const void* const classPtr, const char* const className * * @return true if the class is of the specified type or a subclass of that type. */ -bool ksobjc_isKindOfClass(const void* classPtr, const char* className); +bool ksobjc_isKindOfClass(const void *classPtr, const char *className); /** Get the number of ivars registered with a class. * @@ -199,7 +194,7 @@ bool ksobjc_isKindOfClass(const void* classPtr, const char* className); * * @return The number of ivars. */ -int ksobjc_ivarCount(const void* classPtr); +int ksobjc_ivarCount(const void *classPtr); /** Get information about ivars in a class. * @@ -211,7 +206,7 @@ int ksobjc_ivarCount(const void* classPtr); * * @return The number of ivars copied. */ -int ksobjc_ivarList(const void* classPtr, KSObjCIvar* dstIvars, int ivarsCount); +int ksobjc_ivarList(const void *classPtr, KSObjCIvar *dstIvars, int ivarsCount); /** Get ivar information by name/ * @@ -223,7 +218,7 @@ int ksobjc_ivarList(const void* classPtr, KSObjCIvar* dstIvars, int ivarsCount); * * @return true if the operation was successful. */ -bool ksobjc_ivarNamed(const void* const classPtr, const char* name, KSObjCIvar* dst); +bool ksobjc_ivarNamed(const void *const classPtr, const char *name, KSObjCIvar *dst); /** Get the value of an ivar in an object. * @@ -235,7 +230,7 @@ bool ksobjc_ivarNamed(const void* const classPtr, const char* name, KSObjCIvar* * * @return true if the operation was successful. */ -bool ksobjc_ivarValue(const void* objectPtr, int ivarIndex, void* dst); +bool ksobjc_ivarValue(const void *objectPtr, int ivarIndex, void *dst); /* Get the payload from a tagged pointer. * @@ -243,7 +238,7 @@ bool ksobjc_ivarValue(const void* objectPtr, int ivarIndex, void* dst); * * @return the payload value. */ -uintptr_t ksobjc_taggedPointerPayload(const void* taggedObjectPtr); +uintptr_t ksobjc_taggedPointerPayload(const void *taggedObjectPtr); /** Generate a description of an object. * @@ -263,7 +258,7 @@ uintptr_t ksobjc_taggedPointerPayload(const void* taggedObjectPtr); * * @return the number of bytes copied (not including null terminator). */ -int ksobjc_getDescription(void* object, char* buffer, int bufferLength); +int ksobjc_getDescription(void *object, char *buffer, int bufferLength); /** Get the class type of an object. * There are a number of common class types that KSObjC understamds, @@ -273,8 +268,7 @@ int ksobjc_getDescription(void* object, char* buffer, int bufferLength); * * @return The class type, or KSObjCClassTypeUnknown if it couldn't be determined. */ -KSObjCClassType ksobjc_objectClassType(const void* object); - +KSObjCClassType ksobjc_objectClassType(const void *object); //====================================================================== #pragma mark - Object-Specific Queries - @@ -285,14 +279,14 @@ KSObjCClassType ksobjc_objectClassType(const void* object); * @param object The number to query. * @return true if the number is floating point. */ -bool ksobjc_numberIsFloat(const void* object); +bool ksobjc_numberIsFloat(const void *object); /** Get the contents of a number as a floating point value. * * @param object The number. * @return The value. */ -double ksobjc_numberAsFloat(const void* object); +double ksobjc_numberAsFloat(const void *object); /** Get the contents of a number as an integer value. * If the number was stored as floating point, it will be @@ -301,7 +295,7 @@ double ksobjc_numberAsFloat(const void* object); * @param object The number. * @return The value. */ -int64_t ksobjc_numberAsInteger(const void* object); +int64_t ksobjc_numberAsInteger(const void *object); /** Copy the contents of a date object. * @@ -309,7 +303,7 @@ int64_t ksobjc_numberAsInteger(const void* object); * * @return Time interval since Jan 1 2001 00:00:00 GMT. */ -double ksobjc_dateContents(const void* datePtr); +double ksobjc_dateContents(const void *datePtr); /** Copy the contents of a URL object. * @@ -324,7 +318,7 @@ double ksobjc_dateContents(const void* datePtr); * * @return the number of bytes copied (not including null terminator). */ -int ksobjc_copyURLContents(const void* nsurl, char* dst, int maxLength); +int ksobjc_copyURLContents(const void *nsurl, char *dst, int maxLength); /** Get the length of a string in characters. * @@ -332,7 +326,7 @@ int ksobjc_copyURLContents(const void* nsurl, char* dst, int maxLength); * * @return The length of the string. */ -int ksobjc_stringLength(const void* const stringPtr); +int ksobjc_stringLength(const void *const stringPtr); /** Copy the contents of a string object. * @@ -347,7 +341,7 @@ int ksobjc_stringLength(const void* const stringPtr); * * @return the number of bytes copied (not including null terminator). */ -int ksobjc_copyStringContents(const void* string, char* dst, int maxLength); +int ksobjc_copyStringContents(const void *string, char *dst, int maxLength); /** Get an NSArray's count. * @@ -355,7 +349,7 @@ int ksobjc_copyStringContents(const void* string, char* dst, int maxLength); * * @return The array's count. */ -int ksobjc_arrayCount(const void* arrayPtr); +int ksobjc_arrayCount(const void *arrayPtr); /** Get an NSArray's contents. * @@ -367,8 +361,7 @@ int ksobjc_arrayCount(const void* arrayPtr); * * @return The number of items copied. */ -int ksobjc_arrayContents(const void* arrayPtr, uintptr_t* contents, int count); - +int ksobjc_arrayContents(const void *arrayPtr, uintptr_t *contents, int count); //====================================================================== #pragma mark - Broken/Unimplemented Stuff - @@ -386,15 +379,14 @@ int ksobjc_arrayContents(const void* arrayPtr, uintptr_t* contents, int count); * * @return true if the operation was successful. */ -bool ksobjc_dictionaryFirstEntry(const void* dict, uintptr_t* key, uintptr_t* value); +bool ksobjc_dictionaryFirstEntry(const void *dict, uintptr_t *key, uintptr_t *value); /** UNIMPLEMENTED */ -int ksobjc_dictionaryCount(const void* dict); - +int ksobjc_dictionaryCount(const void *dict); #ifdef __cplusplus } #endif -#endif // HDR_KSObjC_h +#endif // HDR_KSObjC_h diff --git a/Sources/KSCrashRecordingCore/include/KSPlatformSpecificDefines.h b/Sources/KSCrashRecordingCore/include/KSPlatformSpecificDefines.h index 144aedf1b..86c1c12d1 100644 --- a/Sources/KSCrashRecordingCore/include/KSPlatformSpecificDefines.h +++ b/Sources/KSCrashRecordingCore/include/KSPlatformSpecificDefines.h @@ -43,7 +43,7 @@ typedef struct nlist nlist_t; #endif /* __LP64__ */ #ifndef SEG_DATA_CONST -#define SEG_DATA_CONST "__DATA_CONST" +#define SEG_DATA_CONST "__DATA_CONST" #endif /* SEG_DATA_CONST */ #endif /* KSPlatformSpecificDefines_h */ diff --git a/Sources/KSCrashRecordingCore/include/KSSignalInfo.h b/Sources/KSCrashRecordingCore/include/KSSignalInfo.h index 6ed78841b..9c49d721c 100644 --- a/Sources/KSCrashRecordingCore/include/KSSignalInfo.h +++ b/Sources/KSCrashRecordingCore/include/KSSignalInfo.h @@ -24,11 +24,9 @@ // THE SOFTWARE. // - /* Information about the signals we are interested in for a crash reporter. */ - #ifndef HDR_KSSignalInfo_h #define HDR_KSSignalInfo_h @@ -44,7 +42,7 @@ extern "C" { * * @return The signal's name or NULL if not found. */ -const char* kssignal_signalName(int signal); +const char *kssignal_signalName(int signal); /** Get the name of a signal's subcode. * @@ -54,13 +52,13 @@ const char* kssignal_signalName(int signal); * * @return The code's name or NULL if not found. */ -const char* kssignal_signalCodeName(int signal, int code); +const char *kssignal_signalCodeName(int signal, int code); /** Get a list of fatal signals. * * @return A list of fatal signals. */ -const int* kssignal_fatalSignals(void); +const int *kssignal_fatalSignals(void); /** Get the size of the fatal signals list. * @@ -68,9 +66,8 @@ const int* kssignal_fatalSignals(void); */ int kssignal_numFatalSignals(void); - #ifdef __cplusplus } #endif -#endif // HDR_KSSignalInfo_h +#endif // HDR_KSSignalInfo_h diff --git a/Sources/KSCrashRecordingCore/include/KSStackCursor.h b/Sources/KSCrashRecordingCore/include/KSStackCursor.h index d634d57ae..0b7a28344 100644 --- a/Sources/KSCrashRecordingCore/include/KSStackCursor.h +++ b/Sources/KSCrashRecordingCore/include/KSStackCursor.h @@ -22,15 +22,14 @@ // THE SOFTWARE. // - #ifndef KSStackCursor_h #define KSStackCursor_h - -#include "KSMachineContext.h" #include #include +#include "KSMachineContext.h" + #ifdef __cplusplus extern "C" { #endif @@ -43,48 +42,44 @@ extern "C" { /** The max depth to search before giving up. */ #define KSSC_MAX_STACK_DEPTH 500 -typedef struct KSStackCursor -{ - struct - { +typedef struct KSStackCursor { + struct { /** Current address in the stack trace. */ uintptr_t address; - + /** The name (if any) of the binary image the current address falls inside. */ - const char* imageName; - + const char *imageName; + /** The starting address of the binary image the current address falls inside. */ uintptr_t imageAddress; - + /** The name (if any) of the closest symbol to the current address. */ - const char* symbolName; - + const char *symbolName; + /** The address of the closest symbol to the current address. */ uintptr_t symbolAddress; } stackEntry; - struct - { + struct { /** Current depth as we walk the stack (1-based). */ int currentDepth; - + /** If true, cursor has given up walking the stack. */ bool hasGivenUp; } state; /** Reset the cursor back to the beginning. */ - void (*resetCursor)(struct KSStackCursor*); + void (*resetCursor)(struct KSStackCursor *); /** Advance the cursor to the next stack entry. */ - bool (*advanceCursor)(struct KSStackCursor*); - + bool (*advanceCursor)(struct KSStackCursor *); + /** Attempt to symbolicate the current address, filling in the fields in stackEntry. */ - bool (*symbolicate)(struct KSStackCursor*); - + bool (*symbolicate)(struct KSStackCursor *); + /** Internal context-specific information. */ - void* context[KSSC_CONTEXT_SIZE]; + void *context[KSSC_CONTEXT_SIZE]; } KSStackCursor; - /** Common initialization routine for a stack cursor. * Note: This is intended primarily for other cursors to call. * @@ -94,9 +89,8 @@ typedef struct KSStackCursor * * @param advanceCursor Function to advance the cursor (NULL = default: Do nothing and return false). */ -void kssc_initCursor(KSStackCursor *cursor, - void (*resetCursor)(KSStackCursor*), - bool (*advanceCursor)(KSStackCursor*)); +void kssc_initCursor(KSStackCursor *cursor, void (*resetCursor)(KSStackCursor *), + bool (*advanceCursor)(KSStackCursor *)); /** Reset a cursor. * INTERNAL METHOD. Do not call! @@ -105,9 +99,8 @@ void kssc_initCursor(KSStackCursor *cursor, */ void kssc_resetCursor(KSStackCursor *cursor); - #ifdef __cplusplus } #endif -#endif // KSStackCursor_h +#endif // KSStackCursor_h diff --git a/Sources/KSCrashRecordingCore/include/KSStackCursor_Backtrace.h b/Sources/KSCrashRecordingCore/include/KSStackCursor_Backtrace.h index c89a7ddee..a4ec22c76 100644 --- a/Sources/KSCrashRecordingCore/include/KSStackCursor_Backtrace.h +++ b/Sources/KSCrashRecordingCore/include/KSStackCursor_Backtrace.h @@ -22,10 +22,9 @@ // THE SOFTWARE. // - #ifndef KSStackCursor_Backtrace_h #define KSStackCursor_Backtrace_h - + #include "KSStackCursor.h" #ifdef __cplusplus @@ -34,13 +33,11 @@ extern "C" { /** Exposed for other internal systems to use. */ -typedef struct -{ +typedef struct { int skippedEntries; int backtraceLength; - const uintptr_t* backtrace; + const uintptr_t *backtrace; } KSStackCursor_Backtrace_Context; - /** Initialize a stack cursor for an existing backtrace (array of addresses). * @@ -52,11 +49,10 @@ typedef struct * * @param skipEntries The number of stack entries to skip. */ -void kssc_initWithBacktrace(KSStackCursor *cursor, const uintptr_t* backtrace, int backtraceLength, int skipEntries); - - +void kssc_initWithBacktrace(KSStackCursor *cursor, const uintptr_t *backtrace, int backtraceLength, int skipEntries); + #ifdef __cplusplus } #endif -#endif // KSStackCursor_Backtrace_h +#endif // KSStackCursor_Backtrace_h diff --git a/Sources/KSCrashRecordingCore/include/KSStackCursor_MachineContext.h b/Sources/KSCrashRecordingCore/include/KSStackCursor_MachineContext.h index 531db2ae7..d252fc576 100644 --- a/Sources/KSCrashRecordingCore/include/KSStackCursor_MachineContext.h +++ b/Sources/KSCrashRecordingCore/include/KSStackCursor_MachineContext.h @@ -22,10 +22,9 @@ // THE SOFTWARE. // - #ifndef KSStackCursor_MachineContext_h #define KSStackCursor_MachineContext_h - + #include "KSStackCursor.h" #ifdef __cplusplus @@ -40,11 +39,11 @@ extern "C" { * * @param machineContext The machine context whose stack to walk. */ -void kssc_initWithMachineContext(KSStackCursor *cursor, int maxStackDepth, const struct KSMachineContext* machineContext); - - +void kssc_initWithMachineContext(KSStackCursor *cursor, int maxStackDepth, + const struct KSMachineContext *machineContext); + #ifdef __cplusplus } #endif -#endif // KSStackCursor_MachineContext_h +#endif // KSStackCursor_MachineContext_h diff --git a/Sources/KSCrashRecordingCore/include/KSStackCursor_SelfThread.h b/Sources/KSCrashRecordingCore/include/KSStackCursor_SelfThread.h index 20405ec8f..442828613 100644 --- a/Sources/KSCrashRecordingCore/include/KSStackCursor_SelfThread.h +++ b/Sources/KSCrashRecordingCore/include/KSStackCursor_SelfThread.h @@ -22,10 +22,9 @@ // THE SOFTWARE. // - #ifndef KSStackCursor_SelfThread_h #define KSStackCursor_SelfThread_h - + #include "KSStackCursor.h" #ifdef __cplusplus @@ -41,10 +40,9 @@ extern "C" { * @param skipEntries The number of stack entries to skip. */ void kssc_initSelfThread(KSStackCursor *cursor, int skipEntries); - - + #ifdef __cplusplus } #endif -#endif // KSStackCursor_SelfThread_h +#endif // KSStackCursor_SelfThread_h diff --git a/Sources/KSCrashRecordingCore/include/KSString.h b/Sources/KSCrashRecordingCore/include/KSString.h index 26efb2564..007808268 100644 --- a/Sources/KSCrashRecordingCore/include/KSString.h +++ b/Sources/KSCrashRecordingCore/include/KSString.h @@ -42,7 +42,7 @@ extern "C" { * * @param maxLength The maximum length to be considered a valid string. */ -bool ksstring_isNullTerminatedUTF8String(const void* memory, int minLength, int maxLength); +bool ksstring_isNullTerminatedUTF8String(const void *memory, int minLength, int maxLength); /** Extract a hex value in the form "0x123456789abcdef" from a string. * @@ -54,7 +54,7 @@ bool ksstring_isNullTerminatedUTF8String(const void* memory, int minLength, int * * @return true if the operation was successful. */ -bool ksstring_extractHexValue(const char* string, int stringLength, uint64_t* result); +bool ksstring_extractHexValue(const char *string, int stringLength, uint64_t *result); /** Safely compares two strings. * @@ -73,11 +73,10 @@ bool ksstring_extractHexValue(const char* string, int stringLength, uint64_t* re * - Returns a positive value if str1 is non-NULL and str2 is NULL, * or if both strings are non-NULL and str1 is greater than str2. */ -int ksstring_safeStrcmp(const char* str1, const char* str2); - +int ksstring_safeStrcmp(const char *str1, const char *str2); #ifdef __cplusplus } #endif -#endif // HDR_KSString_h +#endif // HDR_KSString_h diff --git a/Sources/KSCrashRecordingCore/include/KSSymbolicator.h b/Sources/KSCrashRecordingCore/include/KSSymbolicator.h index cc0614752..4693f9261 100644 --- a/Sources/KSCrashRecordingCore/include/KSSymbolicator.h +++ b/Sources/KSCrashRecordingCore/include/KSSymbolicator.h @@ -22,13 +22,13 @@ // THE SOFTWARE. // - #ifndef KSSymbolicator_h #define KSSymbolicator_h -#include "KSStackCursor.h" #include +#include "KSStackCursor.h" + #ifdef __cplusplus extern "C" { #endif @@ -49,9 +49,8 @@ uintptr_t kssymbolicator_callInstructionAddress(const uintptr_t returnAddress); */ bool kssymbolicator_symbolicate(KSStackCursor *cursor); - #ifdef __cplusplus } #endif -#endif // KSSymbolicator_h +#endif // KSSymbolicator_h diff --git a/Sources/KSCrashRecordingCore/include/KSSysCtl.h b/Sources/KSCrashRecordingCore/include/KSSysCtl.h index b819df49e..2a290ed62 100644 --- a/Sources/KSCrashRecordingCore/include/KSSysCtl.h +++ b/Sources/KSCrashRecordingCore/include/KSSysCtl.h @@ -24,11 +24,9 @@ // THE SOFTWARE. // - /* Convenience wrapper functions for sysctl calls. */ - #ifndef HDR_KSSysCtl_h #define HDR_KSSysCtl_h @@ -56,7 +54,7 @@ int32_t kssysctl_int32(int major_cmd, int minor_cmd); * * @return The value returned by sysctl. */ -int32_t kssysctl_int32ForName(const char* name); +int32_t kssysctl_int32ForName(const char *name); /** Get a uint32 value via sysctl. * @@ -74,7 +72,7 @@ uint32_t kssysctl_uint32(int major_cmd, int minor_cmd); * * @return The value returned by sysctl. */ -uint32_t kssysctl_uint32ForName(const char* name); +uint32_t kssysctl_uint32ForName(const char *name); /** Get an int64 value via sysctl. * @@ -92,7 +90,7 @@ int64_t kssysctl_int64(int major_cmd, int minor_cmd); * * @return The value returned by sysctl. */ -int64_t kssysctl_int64ForName(const char* name); +int64_t kssysctl_int64ForName(const char *name); /** Get a uint64 value via sysctl. * @@ -110,7 +108,7 @@ uint64_t kssysctl_uint64(int major_cmd, int minor_cmd); * * @return The value returned by sysctl. */ -uint64_t kssysctl_uint64ForName(const char* name); +uint64_t kssysctl_uint64ForName(const char *name); /** Get a string value via sysctl. * @@ -126,7 +124,7 @@ uint64_t kssysctl_uint64ForName(const char* name); * @return The number of bytes written (or that would have been written if * value is NULL). */ -int kssysctl_string(int major_cmd, int minor_cmd, char* value, int maxSize); +int kssysctl_string(int major_cmd, int minor_cmd, char *value, int maxSize); /** Get a string value via sysctl by name. * @@ -140,7 +138,7 @@ int kssysctl_string(int major_cmd, int minor_cmd, char* value, int maxSize); * @return The number of bytes written (or that would have been written if * value is NULL). */ -int kssysctl_stringForName(const char* name, char* value, int maxSize); +int kssysctl_stringForName(const char *name, char *value, int maxSize); /** Get a timeval value via sysctl. * @@ -158,7 +156,7 @@ struct timeval kssysctl_timeval(int major_cmd, int minor_cmd); * * @return The value returned by sysctl. */ -struct timeval kssysctl_timevalForName(const char* name); +struct timeval kssysctl_timevalForName(const char *name); /** Get information about a process. * @@ -168,7 +166,7 @@ struct timeval kssysctl_timevalForName(const char* name); * * @return true if the operation was successful. */ -bool kssysctl_getProcessInfo(int pid, struct kinfo_proc* procInfo); +bool kssysctl_getProcessInfo(int pid, struct kinfo_proc *procInfo); /** Get the MAC address of the specified interface. * Note: As of iOS 7 this will always return a fixed value of 02:00:00:00:00:00. @@ -179,11 +177,10 @@ bool kssysctl_getProcessInfo(int pid, struct kinfo_proc* procInfo); * * @return true if the address was successfully retrieved. */ -bool kssysctl_getMacAddress(const char* name, char* macAddressBuffer); - +bool kssysctl_getMacAddress(const char *name, char *macAddressBuffer); #ifdef __cplusplus } #endif -#endif // HDR_KSSysCtl_h +#endif // HDR_KSSysCtl_h diff --git a/Sources/KSCrashRecordingCore/include/KSThread.h b/Sources/KSCrashRecordingCore/include/KSThread.h index 3a4bbc3ff..2ca15b1d1 100644 --- a/Sources/KSCrashRecordingCore/include/KSThread.h +++ b/Sources/KSCrashRecordingCore/include/KSThread.h @@ -27,8 +27,8 @@ #ifndef HDR_KSThread_h #define HDR_KSThread_h -#include #include +#include #ifdef __cplusplus extern "C" { @@ -47,7 +47,7 @@ typedef uintptr_t KSThread; * * @return true if a name was found. */ -bool ksthread_getThreadName(const KSThread thread, char* const buffer, int bufLength); +bool ksthread_getThreadName(const KSThread thread, char *const buffer, int bufLength); /** Get the name of a thread's dispatch queue. Internally, a queue name will * never be more than 64 characters long. @@ -60,7 +60,7 @@ bool ksthread_getThreadName(const KSThread thread, char* const buffer, int bufLe * * @return true if a name or label was found. */ -bool ksthread_getQueueName(KSThread thread, char* buffer, int bufLength); +bool ksthread_getQueueName(KSThread thread, char *buffer, int bufLength); /* Get the current mach thread ID. * mach_thread_self() receives a send right for the thread port which needs to @@ -71,9 +71,8 @@ bool ksthread_getQueueName(KSThread thread, char* buffer, int bufLength); */ KSThread ksthread_self(void); - #ifdef __cplusplus } #endif -#endif // HDR_KSThread_h +#endif // HDR_KSThread_h diff --git a/Sources/KSCrashReportingCore/Container+DeepSearch.m b/Sources/KSCrashReportingCore/Container+DeepSearch.m index 757c587e2..8a4517fb9 100644 --- a/Sources/KSCrashReportingCore/Container+DeepSearch.m +++ b/Sources/KSCrashReportingCore/Container+DeepSearch.m @@ -24,244 +24,207 @@ // THE SOFTWARE. // - #import "Container+DeepSearch.h" - #pragma mark - Base functionality -static BOOL isNumericString(NSString* str) +static BOOL isNumericString(NSString *str) { - if([str length] == 0) - { + if ([str length] == 0) { return YES; } unichar ch = [str characterAtIndex:0]; return ch >= '0' && ch <= '9'; } -static id objectForDeepKey(id container, NSArray* deepKey) +static id objectForDeepKey(id container, NSArray *deepKey) { - for(id key in deepKey) - { - if([container respondsToSelector:@selector(objectForKey:)]) - { - container = [(NSDictionary*)container objectForKey:key]; - } - else - { - if([container respondsToSelector:@selector(objectAtIndex:)] && - [key respondsToSelector:@selector(intValue)]) - { - if([key isKindOfClass:[NSString class]] && !isNumericString(key)) - { + for (id key in deepKey) { + if ([container respondsToSelector:@selector(objectForKey:)]) { + container = [(NSDictionary *)container objectForKey:key]; + } else { + if ([container respondsToSelector:@selector(objectAtIndex:)] && + [key respondsToSelector:@selector(intValue)]) { + if ([key isKindOfClass:[NSString class]] && !isNumericString(key)) { return nil; } NSUInteger index = (NSUInteger)[key intValue]; container = [container objectAtIndex:index]; - } - else - { + } else { return nil; } } - if(container == nil) - { + if (container == nil) { break; } } return container; } -static id objectForKeyPath(id container, NSString* keyPath) +static id objectForKeyPath(id container, NSString *keyPath) { - while([keyPath length] > 0 && [keyPath characterAtIndex:0] == '/') - { + while ([keyPath length] > 0 && [keyPath characterAtIndex:0] == '/') { keyPath = [keyPath substringFromIndex:1]; } return objectForDeepKey(container, [keyPath componentsSeparatedByString:@"/"]); } -static id parentOfDeepKey(id container, NSArray* deepKey) +static id parentOfDeepKey(id container, NSArray *deepKey) { NSUInteger deepKeyCount = [deepKey count]; - if(deepKeyCount == 1) - { + if (deepKeyCount == 1) { return container; } - NSArray* parentKey = [deepKey subarrayWithRange:NSMakeRange(0, deepKeyCount - 1)]; + NSArray *parentKey = [deepKey subarrayWithRange:NSMakeRange(0, deepKeyCount - 1)]; id parent = objectForDeepKey(container, parentKey); - if(parent == nil) - { - NSString* reason = [NSString stringWithFormat: - @"Parent %@ does not resolve to a valid object", - parentKey]; - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:reason - userInfo:nil]; + if (parent == nil) { + NSString *reason = [NSString stringWithFormat:@"Parent %@ does not resolve to a valid object", parentKey]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil]; } return parent; } -static void setObjectForDeepKey(id container, id object, NSArray* deepKey) +static void setObjectForDeepKey(id container, id object, NSArray *deepKey) { - if([deepKey count] == 0) - { - @throw [NSException exceptionWithName:NSInvalidArgumentException - reason:[NSString stringWithFormat:@"deepKey %@ must contain at least one key", deepKey] - userInfo:nil]; + if ([deepKey count] == 0) { + @throw [NSException + exceptionWithName:NSInvalidArgumentException + reason:[NSString stringWithFormat:@"deepKey %@ must contain at least one key", deepKey] + userInfo:nil]; } - NSString* excFormat = nil; + NSString *excFormat = nil; id lastKey = [deepKey objectAtIndex:[deepKey count] - 1]; id parentContainer = parentOfDeepKey(container, deepKey); - if([parentContainer respondsToSelector:@selector(setObject:forKey:)]) - { - [(NSMutableDictionary*)parentContainer setObject:object forKey:lastKey]; + if ([parentContainer respondsToSelector:@selector(setObject:forKey:)]) { + [(NSMutableDictionary *)parentContainer setObject:object forKey:lastKey]; return; - } - else if([lastKey respondsToSelector:@selector(intValue)]) - { - if([parentContainer respondsToSelector:@selector(replaceObjectAtIndex:withObject:)]) - { + } else if ([lastKey respondsToSelector:@selector(intValue)]) { + if ([parentContainer respondsToSelector:@selector(replaceObjectAtIndex:withObject:)]) { NSUInteger index = (NSUInteger)[lastKey intValue]; - [(NSMutableArray*)parentContainer replaceObjectAtIndex:index withObject:object]; + [(NSMutableArray *)parentContainer replaceObjectAtIndex:index withObject:object]; return; + } else { + excFormat = @"Parent %@ of type %@ does not respond to \"setObject:forKey:\" or " + @"\"replaceObjectAtIndex:withObject:\""; } - else - { - excFormat = @"Parent %@ of type %@ does not respond to \"setObject:forKey:\" or \"replaceObjectAtIndex:withObject:\""; - } - } - else - { + } else { excFormat = @"Parent %@ of type %@ does not respond to \"setObject:forKey:\""; } - NSArray* parentKey = [deepKey subarrayWithRange:NSMakeRange(0, [deepKey count] - 1)]; - NSString* reason = [NSString stringWithFormat:excFormat, parentKey, [parentContainer class]]; - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:reason - userInfo:nil]; + NSArray *parentKey = [deepKey subarrayWithRange:NSMakeRange(0, [deepKey count] - 1)]; + NSString *reason = [NSString stringWithFormat:excFormat, parentKey, [parentContainer class]]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil]; } -static void setObjectForKeyPath(id container, id object, NSString* keyPath) +static void setObjectForKeyPath(id container, id object, NSString *keyPath) { setObjectForDeepKey(container, object, [keyPath componentsSeparatedByString:@"/"]); } -static void removeObjectForDeepKey(id container, NSArray* deepKey) +static void removeObjectForDeepKey(id container, NSArray *deepKey) { - NSString* excFormat = nil; + NSString *excFormat = nil; id lastKey = [deepKey objectAtIndex:[deepKey count] - 1]; id parentContainer = parentOfDeepKey(container, deepKey); - if([parentContainer respondsToSelector:@selector(removeObjectForKey:)]) - { - [(NSMutableDictionary*)parentContainer removeObjectForKey:lastKey]; + if ([parentContainer respondsToSelector:@selector(removeObjectForKey:)]) { + [(NSMutableDictionary *)parentContainer removeObjectForKey:lastKey]; return; - } - else if([lastKey respondsToSelector:@selector(intValue)]) - { - if([parentContainer respondsToSelector:@selector(removeObjectAtIndex:)]) - { + } else if ([lastKey respondsToSelector:@selector(intValue)]) { + if ([parentContainer respondsToSelector:@selector(removeObjectAtIndex:)]) { NSUInteger index = (NSUInteger)[lastKey intValue]; - [(NSMutableArray*)parentContainer removeObjectAtIndex:index]; + [(NSMutableArray *)parentContainer removeObjectAtIndex:index]; return; - } - else - { + } else { excFormat = @"Parent %@ of type %@ does not respond to \"removeObjectForKey:\" or \"removeObjectAtIndex:\""; } - } - else - { + } else { excFormat = @"Parent %@ of type %@ does not respond to \"removeObjectForKey:\""; } - NSArray* parentKey = [deepKey subarrayWithRange:NSMakeRange(0, [deepKey count] - 1)]; - NSString* reason = [NSString stringWithFormat:excFormat, parentKey, [parentContainer class]]; - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:reason - userInfo:nil]; + NSArray *parentKey = [deepKey subarrayWithRange:NSMakeRange(0, [deepKey count] - 1)]; + NSString *reason = [NSString stringWithFormat:excFormat, parentKey, [parentContainer class]]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil]; } -static void removeObjectForKeyPath(id container, NSString* keyPath) +static void removeObjectForKeyPath(id container, NSString *keyPath) { removeObjectForDeepKey(container, [keyPath componentsSeparatedByString:@"/"]); } - #pragma mark - NSDictionary Category @implementation NSDictionary (DeepSearch) -- (id) objectForDeepKey:(NSArray*) deepKey +- (id)objectForDeepKey:(NSArray *)deepKey { return objectForDeepKey(self, deepKey); } -- (id) objectForKeyPath:(NSString*) keyPath +- (id)objectForKeyPath:(NSString *)keyPath { return objectForKeyPath(self, keyPath); } -- (void) setObject:(id) anObject forDeepKey:(NSArray*) deepKey +- (void)setObject:(id)anObject forDeepKey:(NSArray *)deepKey { setObjectForDeepKey(self, anObject, deepKey); } -- (void) setObject:(id) anObject forKeyPath:(NSString*) keyPath +- (void)setObject:(id)anObject forKeyPath:(NSString *)keyPath { setObjectForKeyPath(self, anObject, keyPath); } -- (void) removeObjectForDeepKey:(NSArray*) deepKey +- (void)removeObjectForDeepKey:(NSArray *)deepKey { removeObjectForDeepKey(self, deepKey); } -- (void) removeObjectForKeyPath:(NSString*) keyPath +- (void)removeObjectForKeyPath:(NSString *)keyPath { removeObjectForKeyPath(self, keyPath); } @end - #pragma mark - NSArray Category @implementation NSArray (DeepSearch) -- (id) objectForDeepKey:(NSArray*) deepKey +- (id)objectForDeepKey:(NSArray *)deepKey { return objectForDeepKey(self, deepKey); } -- (id) objectForKeyPath:(NSString*) keyPath +- (id)objectForKeyPath:(NSString *)keyPath { return objectForKeyPath(self, keyPath); } -- (void) setObject:(id) anObject forDeepKey:(NSArray*) deepKey +- (void)setObject:(id)anObject forDeepKey:(NSArray *)deepKey { setObjectForDeepKey(self, anObject, deepKey); } -- (void) setObject:(id) anObject forKeyPath:(NSString*) keyPath +- (void)setObject:(id)anObject forKeyPath:(NSString *)keyPath { setObjectForKeyPath(self, anObject, keyPath); } -- (void) removeObjectForDeepKey:(NSArray*) deepKey +- (void)removeObjectForDeepKey:(NSArray *)deepKey { removeObjectForDeepKey(self, deepKey); } -- (void) removeObjectForKeyPath:(NSString*) keyPath +- (void)removeObjectForKeyPath:(NSString *)keyPath { removeObjectForKeyPath(self, keyPath); } @end -@interface DeepSearchP5EM1B9 : NSObject @end @implementation DeepSearchP5EM1B9 @end +@interface DeepSearchP5EM1B9 : NSObject +@end +@implementation DeepSearchP5EM1B9 +@end diff --git a/Sources/KSCrashReportingCore/KSCString.m b/Sources/KSCrashReportingCore/KSCString.m index a37f138d0..2c6f09ece 100644 --- a/Sources/KSCrashReportingCore/KSCString.m +++ b/Sources/KSCrashReportingCore/KSCString.m @@ -31,52 +31,50 @@ @implementation KSCString @synthesize length = _length; @synthesize bytes = _bytes; -+ (KSCString*) stringWithString:(NSString*) string ++ (KSCString *)stringWithString:(NSString *)string { return [[self alloc] initWithString:string]; } -+ (KSCString*) stringWithCString:(const char*) string ++ (KSCString *)stringWithCString:(const char *)string { return [[self alloc] initWithCString:string]; } -+ (KSCString*) stringWithData:(NSData*) data ++ (KSCString *)stringWithData:(NSData *)data { return [[self alloc] initWithData:data]; } -+ (KSCString*) stringWithData:(const char*) data length:(NSUInteger) length ++ (KSCString *)stringWithData:(const char *)data length:(NSUInteger)length { return [[self alloc] initWithData:data length:length]; } -- (id) initWithString:(NSString*) string +- (id)initWithString:(NSString *)string { return [self initWithCString:[string cStringUsingEncoding:NSUTF8StringEncoding]]; } -- (id) initWithCString:(const char*) string +- (id)initWithCString:(const char *)string { - if((self = [super init])) - { + if ((self = [super init])) { _bytes = strdup(string); _length = strlen(_bytes); } return self; } -- (id) initWithData:(NSData*) data +- (id)initWithData:(NSData *)data { return [self initWithData:data.bytes length:data.length]; } -- (id) initWithData:(const char*) data length:(NSUInteger) length +- (id)initWithData:(const char *)data length:(NSUInteger)length { - if((self = [super init])) - { + if ((self = [super init])) { _length = length; - char* bytes = malloc((unsigned)_length+1); + char *bytes = malloc((unsigned)_length + 1); memcpy(bytes, data, _length); bytes[_length] = 0; _bytes = bytes; @@ -84,11 +82,10 @@ - (id) initWithData:(const char*) data length:(NSUInteger) length return self; } -- (void) dealloc +- (void)dealloc { - if(_bytes != NULL) - { - free((void*)_bytes); + if (_bytes != NULL) { + free((void *)_bytes); } } diff --git a/Sources/KSCrashReportingCore/KSHTTPMultipartPostBody.m b/Sources/KSCrashReportingCore/KSHTTPMultipartPostBody.m index c4c9e6e2b..f2491428f 100644 --- a/Sources/KSCrashReportingCore/KSHTTPMultipartPostBody.m +++ b/Sources/KSCrashReportingCore/KSHTTPMultipartPostBody.m @@ -24,43 +24,40 @@ // THE SOFTWARE. // - #import "KSHTTPMultipartPostBody.h" #import "NSMutableData+AppendUTF8.h" #import "NSString+URLEncode.h" - /** * Represents a single field in a multipart HTTP body. */ -@interface KSHTTPPostField: NSObject +@interface KSHTTPPostField : NSObject /** This field's binary encoded contents. */ -@property(nonatomic,readonly,retain) NSData* data; +@property(nonatomic, readonly, retain) NSData *data; /** This field's name. */ -@property(nonatomic,readonly,retain) NSString* name; +@property(nonatomic, readonly, retain) NSString *name; /** This field's content-type. */ -@property(nonatomic,readonly,retain) NSString* contentType; +@property(nonatomic, readonly, retain) NSString *contentType; /** This field's filename. */ -@property(nonatomic,readonly,retain) NSString* filename; +@property(nonatomic, readonly, retain) NSString *filename; -+ (KSHTTPPostField*) data:(NSData*) data - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename; ++ (KSHTTPPostField *)data:(NSData *)data + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename; -- (id) initWithData:(NSData*) data - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename; +- (id)initWithData:(NSData *)data + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename; @end - @implementation KSHTTPPostField @synthesize data = _data; @@ -68,27 +65,23 @@ @implementation KSHTTPPostField @synthesize contentType = _contentType; @synthesize filename = _filename; -+ (KSHTTPPostField*) data:(NSData*) data - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename ++ (KSHTTPPostField *)data:(NSData *)data + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename { - return [[self alloc] initWithData:data - name:name - contentType:contentType - filename:filename]; + return [[self alloc] initWithData:data name:name contentType:contentType filename:filename]; } -- (id) initWithData:(NSData*) data - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename +- (id)initWithData:(NSData *)data + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename { NSParameterAssert(data); NSParameterAssert(name); - - if((self = [super init])) - { + + if ((self = [super init])) { _data = data; _name = name; _contentType = contentType; @@ -99,30 +92,27 @@ - (id) initWithData:(NSData*) data @end - @interface KSHTTPMultipartPostBody () -@property(nonatomic,readwrite,retain) NSMutableArray* fields; -@property(nonatomic,readwrite,retain) NSString* boundary; +@property(nonatomic, readwrite, retain) NSMutableArray *fields; +@property(nonatomic, readwrite, retain) NSString *boundary; @end - @implementation KSHTTPMultipartPostBody @synthesize contentType = _contentType; @synthesize fields = _fields; @synthesize boundary = _boundary; -+ (KSHTTPMultipartPostBody*) body ++ (KSHTTPMultipartPostBody *)body { return [[self alloc] init]; } -- (id) init +- (id)init { - if((self = [super init])) - { + if ((self = [super init])) { NSString *uuid = [[NSUUID UUID] UUIDString]; _boundary = [[uuid lowercaseString] stringByReplacingOccurrencesOfString:@"-" withString:@""]; _fields = [[NSMutableArray alloc] init]; @@ -131,74 +121,64 @@ - (id) init return self; } -- (void) appendData:(NSData*) data - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename +- (void)appendData:(NSData *)data + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename { - [_fields addObject:[KSHTTPPostField data:data - name:name - contentType:contentType - filename:filename]]; + [_fields addObject:[KSHTTPPostField data:data name:name contentType:contentType filename:filename]]; } -- (void) appendUTF8String:(NSString*) string - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename +- (void)appendUTF8String:(NSString *)string + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename { - const char* cString = [string cStringUsingEncoding:NSUTF8StringEncoding]; + const char *cString = [string cStringUsingEncoding:NSUTF8StringEncoding]; [self appendData:[NSData dataWithBytes:cString length:strlen(cString)] name:name contentType:contentType filename:filename]; } -- (NSString*) toStringWithQuotesEscaped:(NSString*) value +- (NSString *)toStringWithQuotesEscaped:(NSString *)value { return [value stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; } -- (NSData*) data +- (NSData *)data { NSUInteger baseSize = 0; - for(KSHTTPPostField* desc in _fields) - { + for (KSHTTPPostField *desc in _fields) { baseSize += [desc.data length] + 200; } - - NSMutableData* data = [NSMutableData dataWithCapacity:baseSize]; + + NSMutableData *data = [NSMutableData dataWithCapacity:baseSize]; BOOL firstFieldSent = NO; - for(KSHTTPPostField* field in _fields) - { + for (KSHTTPPostField *field in _fields) { if (firstFieldSent) { [data appendUTF8String:@"\r\n"]; } else { firstFieldSent = YES; } [data appendUTF8Format:@"--%@\r\n", _boundary]; - if(field.filename != nil) - { + if (field.filename != nil) { [data appendUTF8Format:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", - [self toStringWithQuotesEscaped:field.name], - [self toStringWithQuotesEscaped:field.filename]]; - } - else - { + [self toStringWithQuotesEscaped:field.name], + [self toStringWithQuotesEscaped:field.filename]]; + } else { [data appendUTF8Format:@"Content-Disposition: form-data; name=\"%@\"\r\n", - [self toStringWithQuotesEscaped:field.name]]; + [self toStringWithQuotesEscaped:field.name]]; } - if(field.contentType != nil) - { + if (field.contentType != nil) { [data appendUTF8Format:@"Content-Type: %@\r\n", field.contentType]; } [data appendUTF8Format:@"\r\n", _boundary]; [data appendData:field.data]; } [data appendUTF8Format:@"\r\n--%@--\r\n", _boundary]; - + return data; } @end - diff --git a/Sources/KSCrashReportingCore/KSHTTPRequestSender.m b/Sources/KSCrashReportingCore/KSHTTPRequestSender.m index f74e76b53..b9ec2a637 100644 --- a/Sources/KSCrashReportingCore/KSHTTPRequestSender.m +++ b/Sources/KSCrashReportingCore/KSHTTPRequestSender.m @@ -24,85 +24,73 @@ // THE SOFTWARE. // - #import "KSHTTPRequestSender.h" #import "NSError+SimpleConstructor.h" - @implementation KSHTTPRequestSender -+ (KSHTTPRequestSender*) sender ++ (KSHTTPRequestSender *)sender { return [[self alloc] init]; } -- (void) handleResponse:(NSURLResponse*) response - data:(NSData*) data - error:(NSError*) error - onSuccess:(void(^)(NSHTTPURLResponse* response, NSData* data)) successBlock - onFailure:(void(^)(NSHTTPURLResponse* response, NSData* data)) failureBlock - onError:(void(^)(NSError* error)) errorBlock +- (void)handleResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *)error + onSuccess:(void (^)(NSHTTPURLResponse *response, NSData *data))successBlock + onFailure:(void (^)(NSHTTPURLResponse *response, NSData *data))failureBlock + onError:(void (^)(NSError *error))errorBlock { - if(error == nil) - { - if(response == nil) - { - error = [NSError errorWithDomain:[[self class] description] - code:0 - description:@"Response was nil"]; + if (error == nil) { + if (response == nil) { + error = [NSError errorWithDomain:[[self class] description] code:0 description:@"Response was nil"]; } - - if(![response isKindOfClass:[NSHTTPURLResponse class]]) - { + + if (![response isKindOfClass:[NSHTTPURLResponse class]]) { error = [NSError errorWithDomain:[[self class] description] code:0 - description:@"Response was of type %@. Expected NSHTTPURLResponse", - [response class]]; + description:@"Response was of type %@. Expected NSHTTPURLResponse", [response class]]; } } - - if(error == nil) - { - NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; - if((httpResponse.statusCode / 100) != 2) - { - if(failureBlock != nil) - { - dispatch_async(dispatch_get_main_queue(), ^ - { - failureBlock(httpResponse, data); - }); + + if (error == nil) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if ((httpResponse.statusCode / 100) != 2) { + if (failureBlock != nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + failureBlock(httpResponse, data); + }); } + } else if (successBlock != nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + successBlock(httpResponse, data); + }); } - else if(successBlock != nil) - { - dispatch_async(dispatch_get_main_queue(), ^ - { - successBlock(httpResponse, data); - }); - } - } - else - { - if(errorBlock != nil) - { - dispatch_async(dispatch_get_main_queue(), ^ - { - errorBlock(error); - }); + } else { + if (errorBlock != nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + errorBlock(error); + }); } } } -- (void) sendRequest:(NSURLRequest*) request - onSuccess:(void(^)(NSHTTPURLResponse* response, NSData* data)) successBlock - onFailure:(void(^)(NSHTTPURLResponse* response, NSData* data)) failureBlock - onError:(void(^)(NSError* error)) errorBlock +- (void)sendRequest:(NSURLRequest *)request + onSuccess:(void (^)(NSHTTPURLResponse *response, NSData *data))successBlock + onFailure:(void (^)(NSHTTPURLResponse *response, NSData *data))failureBlock + onError:(void (^)(NSError *error))errorBlock { - NSURLSession* session = [NSURLSession sharedSession]; - NSURLSessionTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { - [self handleResponse:response data:data error:error onSuccess:successBlock onFailure:failureBlock onError:errorBlock]; - }]; + NSURLSession *session = [NSURLSession sharedSession]; + NSURLSessionTask *task = [session + dataTaskWithRequest:request + completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { + [self handleResponse:response + data:data + error:error + onSuccess:successBlock + onFailure:failureBlock + onError:errorBlock]; + }]; [task resume]; } diff --git a/Sources/KSCrashReportingCore/KSReachabilityKSCrash.m b/Sources/KSCrashReportingCore/KSReachabilityKSCrash.m index edec61f00..6f9a12b28 100644 --- a/Sources/KSCrashReportingCore/KSReachabilityKSCrash.m +++ b/Sources/KSCrashReportingCore/KSReachabilityKSCrash.m @@ -24,42 +24,37 @@ // THE SOFTWARE. // - #import "KSReachabilityKSCrash.h" #import - -#define kKVOProperty_Flags @"flags" +#define kKVOProperty_Flags @"flags" #define kKVOProperty_Reachable @"reachable" -#define kKVOProperty_WWANOnly @"WWANOnly" +#define kKVOProperty_WWANOnly @"WWANOnly" #if KSCRASH_HAS_REACHABILITY @interface KSReachabilityKSCrash () -@property(nonatomic,readwrite,retain) NSString* hostname; -@property(nonatomic,readwrite,assign) SCNetworkReachabilityFlags flags; -@property(nonatomic,readwrite,assign) BOOL reachable; -@property(nonatomic,readwrite,assign) BOOL WWANOnly; -@property(nonatomic,readwrite,assign) SCNetworkReachabilityRef reachabilityRef; +@property(nonatomic, readwrite, retain) NSString *hostname; +@property(nonatomic, readwrite, assign) SCNetworkReachabilityFlags flags; +@property(nonatomic, readwrite, assign) BOOL reachable; +@property(nonatomic, readwrite, assign) BOOL WWANOnly; +@property(nonatomic, readwrite, assign) SCNetworkReachabilityRef reachabilityRef; -- (id) initWithReachabilityRef:(SCNetworkReachabilityRef) reachabilityRef; +- (id)initWithReachabilityRef:(SCNetworkReachabilityRef)reachabilityRef; -- (id) initWithAddress:(const struct sockaddr*) address; +- (id)initWithAddress:(const struct sockaddr *)address; -- (id) initWithHost:(NSString*) hostname; +- (id)initWithHost:(NSString *)hostname; -- (NSString*) extractHostName:(NSString*) potentialURL; +- (NSString *)extractHostName:(NSString *)potentialURL; -- (void) onReachabilityFlagsChanged:(SCNetworkReachabilityFlags) flags; +- (void)onReachabilityFlagsChanged:(SCNetworkReachabilityFlags)flags; -static void onReachabilityChanged(SCNetworkReachabilityRef target, - SCNetworkReachabilityFlags flags, - void* info); +static void onReachabilityChanged(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info); @end - @implementation KSReachabilityKSCrash @synthesize onReachabilityChanged = _onReachabilityChanged; @@ -70,94 +65,72 @@ @implementation KSReachabilityKSCrash @synthesize hostname = _hostname; @synthesize notificationName = _notificationName; -+ (KSReachabilityKSCrash*) reachabilityToHost:(NSString*) hostname ++ (KSReachabilityKSCrash *)reachabilityToHost:(NSString *)hostname { return [[self alloc] initWithHost:hostname]; } - -+ (KSReachabilityKSCrash*) reachabilityToLocalNetwork ++ (KSReachabilityKSCrash *)reachabilityToLocalNetwork { struct sockaddr_in address; bzero(&address, sizeof(address)); address.sin_len = sizeof(address); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); - - return [[self alloc] initWithAddress:(const struct sockaddr*)&address]; + + return [[self alloc] initWithAddress:(const struct sockaddr *)&address]; } -- (id) initWithHost:(NSString*) hostname +- (id)initWithHost:(NSString *)hostname { hostname = [self extractHostName:hostname]; - if([hostname length] == 0) - { + if ([hostname length] == 0) { struct sockaddr_in address; bzero(&address, sizeof(address)); address.sin_len = sizeof(address); address.sin_family = AF_INET; - - return [self initWithAddress:(const struct sockaddr*)&address]; + + return [self initWithAddress:(const struct sockaddr *)&address]; } - - return [self initWithReachabilityRef: - SCNetworkReachabilityCreateWithName(NULL, (const char* _Nonnull)[hostname UTF8String])]; + + return [self + initWithReachabilityRef:SCNetworkReachabilityCreateWithName(NULL, (const char *_Nonnull)[hostname UTF8String])]; } -- (id) initWithAddress:(const struct sockaddr*) address +- (id)initWithAddress:(const struct sockaddr *)address { - return [self initWithReachabilityRef: - SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, address)]; + return [self initWithReachabilityRef:SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, address)]; } -- (id) initWithReachabilityRef:(SCNetworkReachabilityRef) reachabilityRef +- (id)initWithReachabilityRef:(SCNetworkReachabilityRef)reachabilityRef { - if((self = [super init])) - { - if(reachabilityRef == NULL) - { + if ((self = [super init])) { + if (reachabilityRef == NULL) { goto failed; } - SCNetworkReachabilityContext context = - { - 0, - (__bridge void*)self, - NULL, - NULL, - NULL - }; + SCNetworkReachabilityContext context = { 0, (__bridge void *)self, NULL, NULL, NULL }; - if(!SCNetworkReachabilitySetCallback(reachabilityRef, - onReachabilityChanged, - &context)) - { + if (!SCNetworkReachabilitySetCallback(reachabilityRef, onReachabilityChanged, &context)) { goto failed; } - if(!SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, - CFRunLoopGetCurrent(), - kCFRunLoopDefaultMode)) - { + if (!SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) { goto failed; } - dispatch_async(dispatch_get_global_queue(0,0), ^ - { - @autoreleasepool { - - SCNetworkReachabilityFlags flags; - if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { - dispatch_async(dispatch_get_main_queue(), ^ - { - @autoreleasepool { - [self onReachabilityFlagsChanged:flags]; - } - }); - } - } - }); + dispatch_async(dispatch_get_global_queue(0, 0), ^{ + @autoreleasepool { + SCNetworkReachabilityFlags flags; + if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { + dispatch_async(dispatch_get_main_queue(), ^{ + @autoreleasepool { + [self onReachabilityFlagsChanged:flags]; + } + }); + } + } + }); self.reachabilityRef = reachabilityRef; @@ -165,165 +138,141 @@ - (id) initWithReachabilityRef:(SCNetworkReachabilityRef) reachabilityRef } failed: - if(reachabilityRef) - { + if (reachabilityRef) { CFRelease(reachabilityRef); } self.reachabilityRef = NULL; return nil; } -- (void) dealloc +- (void)dealloc { - if(_reachabilityRef != NULL) - { - SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, - CFRunLoopGetCurrent(), - kCFRunLoopDefaultMode); + if (_reachabilityRef != NULL) { + SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFRelease(_reachabilityRef); } } -- (NSString*) extractHostName:(NSString*) potentialURL +- (NSString *)extractHostName:(NSString *)potentialURL { - if(potentialURL == nil) - { + if (potentialURL == nil) { return nil; } - NSString* host = [[NSURL URLWithString:potentialURL] host]; - if(host != nil) - { + NSString *host = [[NSURL URLWithString:potentialURL] host]; + if (host != nil) { return host; } return potentialURL; } -- (BOOL) isReachableWithFlags:(SCNetworkReachabilityFlags) flags +- (BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags { - if(!(flags & kSCNetworkReachabilityFlagsReachable)) - { + if (!(flags & kSCNetworkReachabilityFlagsReachable)) { // Not reachable at all. return NO; } - - if(!(flags & kSCNetworkReachabilityFlagsConnectionRequired)) - { + + if (!(flags & kSCNetworkReachabilityFlagsConnectionRequired)) { // Reachable with no connection required. return YES; } - - if((flags & (kSCNetworkReachabilityFlagsConnectionOnDemand | - kSCNetworkReachabilityFlagsConnectionOnTraffic)) && - !(flags & kSCNetworkReachabilityFlagsInterventionRequired)) - { + + if ((flags & (kSCNetworkReachabilityFlagsConnectionOnDemand | kSCNetworkReachabilityFlagsConnectionOnTraffic)) && + !(flags & kSCNetworkReachabilityFlagsInterventionRequired)) { // Automatic connection with no user intervention required. return YES; } - + return NO; } -- (void) onReachabilityFlagsChanged:(SCNetworkReachabilityFlags) flags +- (void)onReachabilityFlagsChanged:(SCNetworkReachabilityFlags)flags { - if(_flags != flags) - { + if (_flags != flags) { BOOL reachable = [self isReachableWithFlags:flags]; #if TARGET_OS_IPHONE BOOL WWANOnly = reachable && (flags & kSCNetworkReachabilityFlagsIsWWAN) != 0; #else BOOL WWANOnly = NO; #endif - + BOOL rChanged = _reachable != reachable; BOOL wChanged = _WWANOnly != WWANOnly; - + [self willChangeValueForKey:kKVOProperty_Flags]; - if(rChanged) [self willChangeValueForKey:kKVOProperty_Reachable]; - if(wChanged) [self willChangeValueForKey:kKVOProperty_WWANOnly]; - + if (rChanged) [self willChangeValueForKey:kKVOProperty_Reachable]; + if (wChanged) [self willChangeValueForKey:kKVOProperty_WWANOnly]; + _flags = flags; _reachable = reachable; _WWANOnly = WWANOnly; - + [self didChangeValueForKey:kKVOProperty_Flags]; - if(rChanged) [self didChangeValueForKey:kKVOProperty_Reachable]; - if(wChanged) [self didChangeValueForKey:kKVOProperty_WWANOnly]; - - if(self.onReachabilityChanged != nil) - { + if (rChanged) [self didChangeValueForKey:kKVOProperty_Reachable]; + if (wChanged) [self didChangeValueForKey:kKVOProperty_WWANOnly]; + + if (self.onReachabilityChanged != nil) { self.onReachabilityChanged(self); } - - if(self.notificationName != nil) - { - NSNotificationCenter* nCenter = [NSNotificationCenter defaultCenter]; + + if (self.notificationName != nil) { + NSNotificationCenter *nCenter = [NSNotificationCenter defaultCenter]; [nCenter postNotificationName:self.notificationName object:self]; } } } -- (BOOL) updateFlags +- (BOOL)updateFlags { SCNetworkReachabilityFlags flags; - if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) - { + if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) { [self onReachabilityFlagsChanged:flags]; return YES; } return NO; } -static void onReachabilityChanged(__unused SCNetworkReachabilityRef target, - SCNetworkReachabilityFlags flags, - void* info) +static void onReachabilityChanged(__unused SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, + void *info) { - KSReachabilityKSCrash* reachability = (__bridge KSReachabilityKSCrash*) info; - - dispatch_async(dispatch_get_main_queue(), ^ - { - @autoreleasepool { - [reachability onReachabilityFlagsChanged:flags]; - } - }); + KSReachabilityKSCrash *reachability = (__bridge KSReachabilityKSCrash *)info; + + dispatch_async(dispatch_get_main_queue(), ^{ + @autoreleasepool { + [reachability onReachabilityFlagsChanged:flags]; + } + }); } @end - @interface KSReachableOperationKSCrash () -@property(nonatomic,readwrite,retain) KSReachabilityKSCrash* reachability; +@property(nonatomic, readwrite, retain) KSReachabilityKSCrash *reachability; @end - @implementation KSReachableOperationKSCrash @synthesize reachability = _reachability; -+ (KSReachableOperationKSCrash*) operationWithHost:(NSString*) host - allowWWAN:(BOOL) allowWWAN - block:(void(^)(void)) block ++ (KSReachableOperationKSCrash *)operationWithHost:(NSString *)host + allowWWAN:(BOOL)allowWWAN + block:(void (^)(void))block { return [[self alloc] initWithHost:host allowWWAN:allowWWAN block:block]; } -- (id) initWithHost:(NSString*) host - allowWWAN:(BOOL) allowWWAN - block:(void(^)(void)) block +- (id)initWithHost:(NSString *)host allowWWAN:(BOOL)allowWWAN block:(void (^)(void))block { - if((self = [super init])) - { + if ((self = [super init])) { self.reachability = [KSReachabilityKSCrash reachabilityToHost:host]; - - __unsafe_unretained KSReachableOperationKSCrash* blockSelf = self; - self.reachability.onReachabilityChanged = ^(KSReachabilityKSCrash* reachability) - { - if(reachability.reachable) - { - if(allowWWAN || !reachability.WWANOnly) - { + + __unsafe_unretained KSReachableOperationKSCrash *blockSelf = self; + self.reachability.onReachabilityChanged = ^(KSReachabilityKSCrash *reachability) { + if (reachability.reachable) { + if (allowWWAN || !reachability.WWANOnly) { block(); blockSelf.reachability = nil; } @@ -345,18 +294,17 @@ @implementation KSReachabilityKSCrash @synthesize hostname = _hostname; @synthesize notificationName = _notificationName; -+ (KSReachabilityKSCrash*) reachabilityToHost:(__unused NSString*) hostname ++ (KSReachabilityKSCrash *)reachabilityToHost:(__unused NSString *)hostname { return [[self alloc] init]; } - -+ (KSReachabilityKSCrash*) reachabilityToLocalNetwork ++ (KSReachabilityKSCrash *)reachabilityToLocalNetwork { return [[self alloc] init]; } -- (BOOL) updateFlags +- (BOOL)updateFlags { return NO; } @@ -365,21 +313,18 @@ - (BOOL) updateFlags @implementation KSReachableOperationKSCrash -+ (KSReachableOperationKSCrash*) operationWithHost:(NSString*) host - allowWWAN:(BOOL) allowWWAN - block:(void(^)(void)) block; ++ (KSReachableOperationKSCrash *)operationWithHost:(NSString *)host + allowWWAN:(BOOL)allowWWAN + block:(void (^)(void))block; { return [[self alloc] initWithHost:host allowWWAN:allowWWAN block:block]; } -- (id) initWithHost:(__unused NSString*) hostname - allowWWAN:(__unused BOOL) allowWWAN - block:(void(^)(void)) block; +- (id)initWithHost:(__unused NSString *)hostname allowWWAN:(__unused BOOL)allowWWAN block:(void (^)(void))block; { - if((self = [super init])) - { + if ((self = [super init])) { // Just lie and pretend that we always have reachability. - dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block); } return self; } diff --git a/Sources/KSCrashReportingCore/NSData+KSGZip.m b/Sources/KSCrashReportingCore/NSData+KSGZip.m index d47feb884..d27aff087 100644 --- a/Sources/KSCrashReportingCore/NSData+KSGZip.m +++ b/Sources/KSCrashReportingCore/NSData+KSGZip.m @@ -24,20 +24,16 @@ // THE SOFTWARE. // - #import "NSData+KSGZip.h" -#import "NSError+SimpleConstructor.h" #import - +#import "NSError+SimpleConstructor.h" #define kBufferSize 4096 - -static NSString* zlibError(int errorCode) +static NSString *zlibError(int errorCode) { - switch (errorCode) - { + switch (errorCode) { case Z_OK: return @"OK"; case Z_STREAM_END: @@ -62,30 +58,22 @@ @implementation NSData (KSGZip) -- (NSData*) gzippedWithCompressionLevel:(int) compressionLevel - error:(NSError* __autoreleasing *) error +- (NSData *)gzippedWithCompressionLevel:(int)compressionLevel error:(NSError *__autoreleasing *)error { uInt length = (uInt)[self length]; - if(length == 0) - { + if (length == 0) { [NSError clearError:error]; return [NSData data]; } - z_stream stream = {0}; - stream.next_in = (Bytef*)[self bytes]; + z_stream stream = { 0 }; + stream.next_in = (Bytef *)[self bytes]; stream.avail_in = length; int err; - err = deflateInit2(&stream, - compressionLevel, - Z_DEFLATED, - (16+MAX_WBITS), - 9, - Z_DEFAULT_STRATEGY); - if(err != Z_OK) - { + err = deflateInit2(&stream, compressionLevel, Z_DEFLATED, (16 + MAX_WBITS), 9, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { [NSError fillError:error withDomain:[[self class] description] code:0 @@ -93,19 +81,17 @@ - (NSData*) gzippedWithCompressionLevel:(int) compressionLevel return nil; } - NSMutableData* compressedData = [NSMutableData dataWithLength:(NSUInteger)(length * 1.02 + 50)]; - Bytef* compressedBytes = [compressedData mutableBytes]; + NSMutableData *compressedData = [NSMutableData dataWithLength:(NSUInteger)(length * 1.02 + 50)]; + Bytef *compressedBytes = [compressedData mutableBytes]; NSUInteger compressedLength = [compressedData length]; - while(err == Z_OK) - { + while (err == Z_OK) { stream.next_out = compressedBytes + stream.total_out; stream.avail_out = (uInt)(compressedLength - stream.total_out); err = deflate(&stream, Z_FINISH); } - if(err != Z_STREAM_END) - { + if (err != Z_STREAM_END) { [NSError fillError:error withDomain:[[self class] description] code:0 @@ -121,24 +107,22 @@ - (NSData*) gzippedWithCompressionLevel:(int) compressionLevel return compressedData; } -- (NSData*) gunzippedWithError:(NSError* __autoreleasing *) error +- (NSData *)gunzippedWithError:(NSError *__autoreleasing *)error { uInt length = (uInt)[self length]; - if(length == 0) - { + if (length == 0) { [NSError clearError:error]; return [NSData data]; } - z_stream stream = {0}; - stream.next_in = (Bytef*)[self bytes]; + z_stream stream = { 0 }; + stream.next_in = (Bytef *)[self bytes]; stream.avail_in = length; int err; - err = inflateInit2(&stream, 16+MAX_WBITS); - if(err != Z_OK) - { + err = inflateInit2(&stream, 16 + MAX_WBITS); + if (err != Z_OK) { [NSError fillError:error withDomain:[[self class] description] code:0 @@ -146,17 +130,15 @@ - (NSData*) gunzippedWithError:(NSError* __autoreleasing *) error return nil; } - NSMutableData* expandedData = [NSMutableData dataWithCapacity:length * 2]; + NSMutableData *expandedData = [NSMutableData dataWithCapacity:length * 2]; Bytef buffer[kBufferSize]; stream.avail_out = sizeof(buffer); - while(err != Z_STREAM_END) - { + while (err != Z_STREAM_END) { stream.avail_out = sizeof(buffer); stream.next_out = buffer; err = inflate(&stream, Z_NO_FLUSH); - if(err != Z_OK && err != Z_STREAM_END) - { + if (err != Z_OK && err != Z_STREAM_END) { [NSError fillError:error withDomain:[[self class] description] code:0 @@ -164,8 +146,7 @@ - (NSData*) gunzippedWithError:(NSError* __autoreleasing *) error inflateEnd(&stream); return nil; } - [expandedData appendBytes:buffer - length:sizeof(buffer) - stream.avail_out]; + [expandedData appendBytes:buffer length:sizeof(buffer) - stream.avail_out]; } [NSError clearError:error]; @@ -176,4 +157,7 @@ - (NSData*) gunzippedWithError:(NSError* __autoreleasing *) error @end // Make this category auto-link -@interface NSData_GZip_A0THJ4 : NSObject @end @implementation NSData_GZip_A0THJ4 @end +@interface NSData_GZip_A0THJ4 : NSObject +@end +@implementation NSData_GZip_A0THJ4 +@end diff --git a/Sources/KSCrashReportingCore/NSMutableData+AppendUTF8.m b/Sources/KSCrashReportingCore/NSMutableData+AppendUTF8.m index 56881d900..92135b503 100644 --- a/Sources/KSCrashReportingCore/NSMutableData+AppendUTF8.m +++ b/Sources/KSCrashReportingCore/NSMutableData+AppendUTF8.m @@ -24,28 +24,29 @@ // THE SOFTWARE. // - #import "NSMutableData+AppendUTF8.h" - @implementation NSMutableData (AppendUTF8) -- (void) appendUTF8String:(NSString*) string +- (void)appendUTF8String:(NSString *)string { - const char* cstring = [string UTF8String]; + const char *cstring = [string UTF8String]; [self appendBytes:cstring length:strlen(cstring)]; } -- (void) appendUTF8Format:(NSString*) format, ... +- (void)appendUTF8Format:(NSString *)format, ... { va_list args; va_start(args, format); - NSString* string = [[NSString alloc] initWithFormat:format arguments:args]; + NSString *string = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); - const char* cstring = [string UTF8String]; + const char *cstring = [string UTF8String]; [self appendBytes:cstring length:strlen(cstring)]; } @end -@interface NSMutableData_AppendUTF8_GHO92D : NSObject @end @implementation NSMutableData_AppendUTF8_GHO92D @end +@interface NSMutableData_AppendUTF8_GHO92D : NSObject +@end +@implementation NSMutableData_AppendUTF8_GHO92D +@end diff --git a/Sources/KSCrashReportingCore/NSString+URLEncode.m b/Sources/KSCrashReportingCore/NSString+URLEncode.m index 8abac1a89..0b7ad7940 100644 --- a/Sources/KSCrashReportingCore/NSString+URLEncode.m +++ b/Sources/KSCrashReportingCore/NSString+URLEncode.m @@ -28,7 +28,7 @@ @implementation NSString (URLEncode) -- (NSString*) URLEncoded +- (NSString *)URLEncoded { return [self stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet]; } diff --git a/Sources/KSCrashReportingCore/include/Container+DeepSearch.h b/Sources/KSCrashReportingCore/include/Container+DeepSearch.h index cd03da4ff..cb9946c35 100644 --- a/Sources/KSCrashReportingCore/include/Container+DeepSearch.h +++ b/Sources/KSCrashReportingCore/include/Container+DeepSearch.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - /** Deep key search based methods for hierarchical container structures. * * A deep key search works like a normal search, except that the "key" is @@ -51,10 +50,8 @@ * result = [result objectAtIndex:[currentKey intValue]]; */ - #import - #pragma mark - NSDictionary - /** @@ -71,8 +68,7 @@ * * @param deepKey A set of keys to drill down with. */ -- (id) objectForDeepKey:(NSArray*) deepKey; - +- (id)objectForDeepKey:(NSArray *)deepKey; /** Do a deep search using the specified keys. * @@ -81,8 +77,7 @@ * * @param keyPath A full key path, separated by slash (e.g. @"a/b/c") */ -- (id) objectForKeyPath:(NSString*) keyPath; - +- (id)objectForKeyPath:(NSString *)keyPath; #pragma mark - Mutators @@ -95,7 +90,7 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) setObject:(id) anObject forDeepKey:(NSArray*) deepKey; +- (void)setObject:(id)anObject forDeepKey:(NSArray *)deepKey; /** Set an associated object at the specified key path. * @@ -106,7 +101,7 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) setObject:(id) anObject forKeyPath:(NSString*) keyPath; +- (void)setObject:(id)anObject forKeyPath:(NSString *)keyPath; /** Remove an associated object at the specified deep key. * @@ -117,7 +112,7 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) removeObjectForDeepKey:(NSArray*) deepKey; +- (void)removeObjectForDeepKey:(NSArray *)deepKey; /** Remove an associated object at the specified key path. * @@ -128,11 +123,10 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) removeObjectForKeyPath:(NSString*) keyPath; +- (void)removeObjectForKeyPath:(NSString *)keyPath; @end - #pragma mark - NSArray - /** @@ -149,8 +143,7 @@ * * @param deepKey A set of keys to drill down with. */ -- (id) objectForDeepKey:(NSArray*) deepKey; - +- (id)objectForDeepKey:(NSArray *)deepKey; /** Do a deep search using the specified keys. * @@ -159,8 +152,7 @@ * * @param keyPath A full key path, separated by slash (e.g. @"a/b/c") */ -- (id) objectForKeyPath:(NSString*) keyPath; - +- (id)objectForKeyPath:(NSString *)keyPath; #pragma mark - Mutators @@ -173,7 +165,7 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) setObject:(id) anObject forDeepKey:(NSArray*) deepKey; +- (void)setObject:(id)anObject forDeepKey:(NSArray *)deepKey; /** Set an associated object at the specified key path. * @@ -184,7 +176,7 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) setObject:(id) anObject forKeyPath:(NSString*) keyPath; +- (void)setObject:(id)anObject forKeyPath:(NSString *)keyPath; /** Remove an associated object at the specified deep key. * @@ -195,7 +187,7 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) removeObjectForDeepKey:(NSArray*) deepKey; +- (void)removeObjectForDeepKey:(NSArray *)deepKey; /** Remove an associated object at the specified key path. * @@ -206,6 +198,6 @@ * If the lookup fails at any level, it will throw an exception describing which * object in the hierarchy did not respond to any object accessor methods. */ -- (void) removeObjectForKeyPath:(NSString*) keyPath; +- (void)removeObjectForKeyPath:(NSString *)keyPath; @end diff --git a/Sources/KSCrashReportingCore/include/KSCString.h b/Sources/KSCrashReportingCore/include/KSCString.h index 73975280e..10fec4055 100644 --- a/Sources/KSCrashReportingCore/include/KSCString.h +++ b/Sources/KSCrashReportingCore/include/KSCString.h @@ -32,26 +32,26 @@ @interface KSCString : NSObject /** Length of the string in bytes (not characters!). Length does not include null terminator. */ -@property(nonatomic,readonly,assign) NSUInteger length; +@property(nonatomic, readonly, assign) NSUInteger length; /** String contents, including null terminator */ -@property(nonatomic,readonly,assign) const char* bytes; +@property(nonatomic, readonly, assign) const char *bytes; /** Constructor for NSString */ -+ (KSCString*) stringWithString:(NSString*) string; ++ (KSCString *)stringWithString:(NSString *)string; /** Constructor for null-terminated C string (assumes UTF-8 encoding). */ -+ (KSCString*) stringWithCString:(const char*) string; ++ (KSCString *)stringWithCString:(const char *)string; /** Constructor for string contained in NSData (assumes UTF-8 encoding). */ -+ (KSCString*) stringWithData:(NSData*) data; ++ (KSCString *)stringWithData:(NSData *)data; /** Constructor for non-terminated string (assumes UTF-8 encoding). */ -+ (KSCString*) stringWithData:(const char*) data length:(NSUInteger) length; ++ (KSCString *)stringWithData:(const char *)data length:(NSUInteger)length; -- (id) initWithString:(NSString*) string; -- (id) initWithCString:(const char*) string; -- (id) initWithData:(NSData*) data; -- (id) initWithData:(const char*) data length:(NSUInteger) length; +- (id)initWithString:(NSString *)string; +- (id)initWithCString:(const char *)string; +- (id)initWithData:(NSData *)data; +- (id)initWithData:(const char *)data length:(NSUInteger)length; @end diff --git a/Sources/KSCrashReportingCore/include/KSHTTPMultipartPostBody.h b/Sources/KSCrashReportingCore/include/KSHTTPMultipartPostBody.h index 02ff33a10..991860fdb 100644 --- a/Sources/KSCrashReportingCore/include/KSHTTPMultipartPostBody.h +++ b/Sources/KSCrashReportingCore/include/KSHTTPMultipartPostBody.h @@ -24,26 +24,24 @@ // THE SOFTWARE. // - #import - /** * Builds a multipart MIME HTTP body. */ -@interface KSHTTPMultipartPostBody: NSObject +@interface KSHTTPMultipartPostBody : NSObject /** The content-type identifier for this body. */ -@property(nonatomic,readonly,retain) NSString* contentType; +@property(nonatomic, readonly, retain) NSString *contentType; /** Constructor. * * @return A new body. */ -+ (KSHTTPMultipartPostBody*) body; ++ (KSHTTPMultipartPostBody *)body; /** This body's data, encoded for sending in an HTTP request. */ -- (NSData*) data; +- (NSData *)data; /** Append a new data field to the body. * @@ -55,10 +53,10 @@ * * @param filename The field's filename (nil = omit). */ -- (void) appendData:(NSData*) data - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename; +- (void)appendData:(NSData *)data + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename; /** Append a new UTF-8 encoded string field to the body. * @@ -70,9 +68,9 @@ * * @param filename The field's filename (nil = omit). */ -- (void) appendUTF8String:(NSString*) string - name:(NSString*) name - contentType:(NSString*) contentType - filename:(NSString*) filename; +- (void)appendUTF8String:(NSString *)string + name:(NSString *)name + contentType:(NSString *)contentType + filename:(NSString *)filename; @end diff --git a/Sources/KSCrashReportingCore/include/KSHTTPRequestSender.h b/Sources/KSCrashReportingCore/include/KSHTTPRequestSender.h index f12c6c22b..ea00b3e0f 100644 --- a/Sources/KSCrashReportingCore/include/KSHTTPRequestSender.h +++ b/Sources/KSCrashReportingCore/include/KSHTTPRequestSender.h @@ -24,10 +24,8 @@ // THE SOFTWARE. // - #import - /** * Sends HTTP requests via the global dispatch queue, informing the caller of * success, failure, or errors via blocks. @@ -36,7 +34,7 @@ /** Constructor. */ -+ (KSHTTPRequestSender*) sender; ++ (KSHTTPRequestSender *)sender; /** Send an HTTP request. * The request gets sent via the global dispatch queue using default priority. @@ -52,9 +50,9 @@ * @param errorBlock Gets executed if an error prevents the request from being * sent or an invalid (non-HTTP) response is received. */ -- (void) sendRequest:(NSURLRequest*) request - onSuccess:(void(^)(NSHTTPURLResponse* response, NSData* data)) successBlock - onFailure:(void(^)(NSHTTPURLResponse* response, NSData* data)) failureBlock - onError:(void(^)(NSError* error)) errorBlock; +- (void)sendRequest:(NSURLRequest *)request + onSuccess:(void (^)(NSHTTPURLResponse *response, NSData *data))successBlock + onFailure:(void (^)(NSHTTPURLResponse *response, NSData *data))failureBlock + onError:(void (^)(NSError *error))errorBlock; @end diff --git a/Sources/KSCrashReportingCore/include/KSReachabilityKSCrash.h b/Sources/KSCrashReportingCore/include/KSReachabilityKSCrash.h index a38cde4fd..4346d04a4 100644 --- a/Sources/KSCrashReportingCore/include/KSReachabilityKSCrash.h +++ b/Sources/KSCrashReportingCore/include/KSReachabilityKSCrash.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import #import "KSSystemCapabilities.h" #if KSCRASH_HAS_REACHABILITY @@ -34,7 +33,6 @@ /** This is the notification name used in the Apple reachability example. */ #define kDefaultNetworkReachabilityChangedNotification @"kNetworkReachabilityChangedNotification" - /** Monitors network connectivity. * * Note: Upon construction, this object will fetch its initial reachability @@ -57,45 +55,41 @@ * @param hostname The name or IP address of the host to monitor. If nil or * empty string, check reachability to the internet in general. */ -+ (KSReachabilityKSCrash*) reachabilityToHost:(NSString*) hostname; ++ (KSReachabilityKSCrash *)reachabilityToHost:(NSString *)hostname; /** Reachability to the local (wired or wifi) network. */ -+ (KSReachabilityKSCrash*) reachabilityToLocalNetwork; - ++ (KSReachabilityKSCrash *)reachabilityToLocalNetwork; #pragma mark General Information /** The host we are monitoring reachability to, if any. */ -@property(nonatomic,readonly,retain) NSString* hostname; - +@property(nonatomic, readonly, retain) NSString *hostname; #pragma mark Notifications and Callbacks /** If non-nil, called whenever reachability flags change. * Block will be invoked on the main thread. */ -@property(nonatomic,readwrite,copy) void(^onReachabilityChanged)(KSReachabilityKSCrash* reachability); +@property(nonatomic, readwrite, copy) void (^onReachabilityChanged)(KSReachabilityKSCrash *reachability); /** The notification to send when reachability changes (nil = don't send). * Default = nil */ -@property(nonatomic,readwrite,retain) NSString* notificationName; - +@property(nonatomic, readwrite, retain) NSString *notificationName; #pragma mark KVO Compliant Status Properties /** The current reachability flags. */ #if KSCRASH_HAS_REACHABILITY -@property(nonatomic,readonly,assign) SCNetworkReachabilityFlags flags; +@property(nonatomic, readonly, assign) SCNetworkReachabilityFlags flags; #endif /** Whether the host is reachable or not. */ -@property(nonatomic,readonly,assign) BOOL reachable; +@property(nonatomic, readonly, assign) BOOL reachable; /* If YES, the host is only reachable by WWAN (iOS only). */ -@property(nonatomic,readonly,assign) BOOL WWANOnly; - +@property(nonatomic, readonly, assign) BOOL WWANOnly; #pragma mark Utility @@ -104,17 +98,15 @@ * * @return YES if the flags were successfully updated. */ -- (BOOL) updateFlags; +- (BOOL)updateFlags; @end - - /** A one-time operation to perform as soon as a host is deemed reachable. * The operation will only be performed once, regardless of how many times a * host becomes reachable. */ -@interface KSReachableOperationKSCrash: NSObject +@interface KSReachableOperationKSCrash : NSObject /** Constructor. * @@ -128,9 +120,9 @@ * @param block The block to invoke when the host becomes reachable. * Block will be invoked on the main thread. */ -+ (KSReachableOperationKSCrash*) operationWithHost:(NSString*) hostname - allowWWAN:(BOOL) allowWWAN - block:(void(^)(void)) block; ++ (KSReachableOperationKSCrash *)operationWithHost:(NSString *)hostname + allowWWAN:(BOOL)allowWWAN + block:(void (^)(void))block; /** Constructor. * @@ -144,8 +136,6 @@ * @param block The block to invoke when the host becomes reachable. * Block will be invoked on the main thread. */ -- (id) initWithHost:(NSString*) hostname - allowWWAN:(BOOL) allowWWAN - block:(void(^)(void)) block; +- (id)initWithHost:(NSString *)hostname allowWWAN:(BOOL)allowWWAN block:(void (^)(void))block; @end diff --git a/Sources/KSCrashReportingCore/include/KSVarArgs.h b/Sources/KSCrashReportingCore/include/KSVarArgs.h index f871fddcf..c32e67814 100644 --- a/Sources/KSCrashReportingCore/include/KSVarArgs.h +++ b/Sources/KSCrashReportingCore/include/KSVarArgs.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - /* KSVarArgs is a set of macros designed to make dealing with variable arguments * easier in Objective-C. All macros assume that the varargs list contains only * objective-c objects or object-like structures (assignable to type id). @@ -35,31 +34,28 @@ * The other macros are for convenience when converting to common collections. */ - /** Block type used by ksva_iterate_list. * * @param entry The current argument in the vararg list. */ typedef void (^KSVA_Block)(id entry); - /** * Iterate over a va_list, executing the specified code block for each entry. * * @param FIRST_ARG_NAME The name of the first argument in the vararg list. * @param BLOCK A code block of type KSVA_Block. */ -#define ksva_iterate_list(FIRST_ARG_NAME, BLOCK) \ -{ \ - KSVA_Block ksva_block = BLOCK; \ - va_list ksva_args; \ - va_start(ksva_args,FIRST_ARG_NAME); \ - for(id ksva_arg = FIRST_ARG_NAME; ksva_arg != nil; ksva_arg = va_arg(ksva_args, id)) \ - { \ - ksva_block(ksva_arg); \ - } \ - va_end(ksva_args); \ -} +#define ksva_iterate_list(FIRST_ARG_NAME, BLOCK) \ + { \ + KSVA_Block ksva_block = BLOCK; \ + va_list ksva_args; \ + va_start(ksva_args, FIRST_ARG_NAME); \ + for (id ksva_arg = FIRST_ARG_NAME; ksva_arg != nil; ksva_arg = va_arg(ksva_args, id)) { \ + ksva_block(ksva_arg); \ + } \ + va_end(ksva_args); \ + } /** * Convert a variable argument list into an array. An autoreleased @@ -69,10 +65,9 @@ typedef void (^KSVA_Block)(id entry); * @param ARRAY_NAME The name of the array to create in the current scope. */ #define ksva_list_to_nsarray(FIRST_ARG_NAME, ARRAY_NAME) \ - NSMutableArray* ARRAY_NAME = [NSMutableArray array]; \ - ksva_iterate_list(FIRST_ARG_NAME, ^(id entry) \ - { \ - [ARRAY_NAME addObject:entry]; \ + NSMutableArray *ARRAY_NAME = [NSMutableArray array]; \ + ksva_iterate_list(FIRST_ARG_NAME, ^(id entry) { \ + [ARRAY_NAME addObject:entry]; \ }) /** @@ -84,20 +79,16 @@ typedef void (^KSVA_Block)(id entry); * @param FIRST_ARG_NAME The name of the first argument in the vararg list. * @param DICT_NAME The name of the dictionary to create in the current scope. */ -#define ksva_list_to_nsdictionary(FIRST_ARG_NAME, DICT_NAME) \ - NSMutableDictionary* DICT_NAME = [NSMutableDictionary dictionary]; \ - { \ - __block id ksva_object = nil; \ - ksva_iterate_list(FIRST_ARG_NAME, ^(id entry) \ - { \ - if(ksva_object == nil) \ - { \ - ksva_object = entry; \ - } \ - else \ - { \ - [DICT_NAME setObject:ksva_object forKey:entry]; \ - ksva_object = nil; \ - } \ - }); \ +#define ksva_list_to_nsdictionary(FIRST_ARG_NAME, DICT_NAME) \ + NSMutableDictionary *DICT_NAME = [NSMutableDictionary dictionary]; \ + { \ + __block id ksva_object = nil; \ + ksva_iterate_list(FIRST_ARG_NAME, ^(id entry) { \ + if (ksva_object == nil) { \ + ksva_object = entry; \ + } else { \ + [DICT_NAME setObject:ksva_object forKey:entry]; \ + ksva_object = nil; \ + } \ + }); \ } diff --git a/Sources/KSCrashReportingCore/include/NSData+KSGZip.h b/Sources/KSCrashReportingCore/include/NSData+KSGZip.h index ee74721d0..ebdb83a19 100644 --- a/Sources/KSCrashReportingCore/include/NSData+KSGZip.h +++ b/Sources/KSCrashReportingCore/include/NSData+KSGZip.h @@ -24,10 +24,8 @@ // THE SOFTWARE. // - #import - /** * GNU zip/unzip support for NSData. */ @@ -47,8 +45,7 @@ * * @return A new NSData with the gzipped contents of this object. */ -- (NSData*) gzippedWithCompressionLevel:(int) compressionLevel - error:(NSError**) error; +- (NSData *)gzippedWithCompressionLevel:(int)compressionLevel error:(NSError **)error; /** * Gunzip the data in this object (no header). @@ -58,6 +55,6 @@ * * @return A new NSData with the gunzipped contents of this object. */ -- (NSData*) gunzippedWithError:(NSError**) error; +- (NSData *)gunzippedWithError:(NSError **)error; @end diff --git a/Sources/KSCrashReportingCore/include/NSMutableData+AppendUTF8.h b/Sources/KSCrashReportingCore/include/NSMutableData+AppendUTF8.h index cfa60ec45..07e73affb 100644 --- a/Sources/KSCrashReportingCore/include/NSMutableData+AppendUTF8.h +++ b/Sources/KSCrashReportingCore/include/NSMutableData+AppendUTF8.h @@ -24,10 +24,8 @@ // THE SOFTWARE. // - #import - /** Encodes strings to UTF-8 format. */ @interface NSMutableData (AppendUTF8) @@ -36,12 +34,12 @@ * * @param format Printf-stype format. */ -- (void) appendUTF8Format:(NSString*) format, ...; +- (void)appendUTF8Format:(NSString *)format, ...; /** Append a string encoded as UTF-8. * * @param string The string to append. */ -- (void) appendUTF8String:(NSString*) string; +- (void)appendUTF8String:(NSString *)string; @end diff --git a/Sources/KSCrashReportingCore/include/NSString+URLEncode.h b/Sources/KSCrashReportingCore/include/NSString+URLEncode.h index 241df83eb..a79eef67f 100644 --- a/Sources/KSCrashReportingCore/include/NSString+URLEncode.h +++ b/Sources/KSCrashReportingCore/include/NSString+URLEncode.h @@ -28,6 +28,6 @@ @interface NSString (URLEncode) -- (NSString*) URLEncoded; +- (NSString *)URLEncoded; @end diff --git a/Sources/KSCrashSinks/KSCrashReportSinkConsole.m b/Sources/KSCrashSinks/KSCrashReportSinkConsole.m index 85ba07fa8..f60c4f272 100644 --- a/Sources/KSCrashSinks/KSCrashReportSinkConsole.m +++ b/Sources/KSCrashSinks/KSCrashReportSinkConsole.m @@ -24,39 +24,33 @@ // THE SOFTWARE. // - #import "KSCrashReportSinkConsole.h" +#import "KSCrashReport.h" #import "KSCrashReportFilterAppleFmt.h" #import "KSCrashReportFilterBasic.h" -#import "KSCrashReport.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" - @implementation KSCrashReportSinkConsole -+ (instancetype) filter ++ (instancetype)filter { return [[self alloc] init]; } -- (id ) defaultCrashReportFilterSet +- (id)defaultCrashReportFilterSet { - return [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterAppleFmt filterWithReportStyle:KSAppleReportStyleSymbolicated], - self, - nil]; + return [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterAppleFmt filterWithReportStyle:KSAppleReportStyleSymbolicated], self, + nil]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { int i = 0; - for(KSCrashReport* report in reports) - { - if(report.stringValue == nil) - { + for (KSCrashReport *report in reports) { + if (report.stringValue == nil) { KSLOG_ERROR(@"Unexpected non-string report: %@", report); continue; } @@ -66,5 +60,4 @@ - (void) filterReports:(NSArray*) reports kscrash_callCompletion(onCompletion, reports, YES, nil); } - @end diff --git a/Sources/KSCrashSinks/KSCrashReportSinkEMail.m b/Sources/KSCrashSinks/KSCrashReportSinkEMail.m index 0ae233119..6e3536da5 100644 --- a/Sources/KSCrashSinks/KSCrashReportSinkEMail.m +++ b/Sources/KSCrashSinks/KSCrashReportSinkEMail.m @@ -24,40 +24,38 @@ // THE SOFTWARE. // - #import "KSCrashReportSinkEMail.h" +#import "KSCrashReport.h" #import "KSCrashReportFilterAppleFmt.h" #import "KSCrashReportFilterBasic.h" #import "KSCrashReportFilterGZip.h" #import "KSCrashReportFilterJSON.h" -#import "NSError+SimpleConstructor.h" #import "KSSystemCapabilities.h" -#import "KSCrashReport.h" +#import "NSError+SimpleConstructor.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" #if KSCRASH_HAS_MESSAGEUI #import - @interface KSCrashMailProcess : NSObject -@property(nonatomic,readwrite,copy) NSArray* reports; -@property(nonatomic,readwrite,copy) KSCrashReportFilterCompletion onCompletion; +@property(nonatomic, readwrite, copy) NSArray *reports; +@property(nonatomic, readwrite, copy) KSCrashReportFilterCompletion onCompletion; -@property(nonatomic,readwrite,retain) UIViewController* dummyVC; +@property(nonatomic, readwrite, retain) UIViewController *dummyVC; -+ (KSCrashMailProcess*) process; ++ (KSCrashMailProcess *)process; -- (void) startWithController:(MFMailComposeViewController*) controller - reports:(NSArray*) reports - filenameFmt:(NSString*) filenameFmt - onCompletion:(KSCrashReportFilterCompletion) onCompletion; +- (void)startWithController:(MFMailComposeViewController *)controller + reports:(NSArray *)reports + filenameFmt:(NSString *)filenameFmt + onCompletion:(KSCrashReportFilterCompletion)onCompletion; -- (void) presentModalVC:(UIViewController*) vc; -- (void) dismissModalVC; +- (void)presentModalVC:(UIViewController *)vc; +- (void)dismissModalVC; @end @@ -67,15 +65,15 @@ @implementation KSCrashMailProcess @synthesize onCompletion = _onCompletion; @synthesize dummyVC = _dummyVC; -+ (KSCrashMailProcess*) process ++ (KSCrashMailProcess *)process { return [[self alloc] init]; } -- (void) startWithController:(MFMailComposeViewController*) controller - reports:(NSArray*) reports - filenameFmt:(NSString*) filenameFmt - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)startWithController:(MFMailComposeViewController *)controller + reports:(NSArray *)reports + filenameFmt:(NSString *)filenameFmt + onCompletion:(KSCrashReportFilterCompletion)onCompletion { self.reports = [reports copy]; self.onCompletion = onCompletion; @@ -83,30 +81,25 @@ - (void) startWithController:(MFMailComposeViewController*) controller controller.mailComposeDelegate = self; int i = 1; - for(KSCrashReport* report in reports) - { - NSData* data = report.dataValue; - if(data == nil) - { + for (KSCrashReport *report in reports) { + NSData *data = report.dataValue; + if (data == nil) { KSLOG_ERROR(@"Unexpected non-data report: %@", report); continue; } - [controller addAttachmentData:data - mimeType:@"binary" - fileName:[NSString stringWithFormat:filenameFmt, i++]]; + [controller addAttachmentData:data mimeType:@"binary" fileName:[NSString stringWithFormat:filenameFmt, i++]]; } [self presentModalVC:controller]; } -- (void) mailComposeController:(__unused MFMailComposeViewController*) mailController - didFinishWithResult:(MFMailComposeResult) result - error:(NSError*) error +- (void)mailComposeController:(__unused MFMailComposeViewController *)mailController + didFinishWithResult:(MFMailComposeResult)result + error:(NSError *)error { [self dismissModalVC]; - switch (result) - { + switch (result) { case MFMailComposeResultSent: kscrash_callCompletion(self.onCompletion, self.reports, YES, nil); break; @@ -115,37 +108,33 @@ - (void) mailComposeController:(__unused MFMailComposeViewController*) mailContr break; case MFMailComposeResultCancelled: kscrash_callCompletion(self.onCompletion, self.reports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"User cancelled"]); + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"User cancelled"]); break; case MFMailComposeResultFailed: kscrash_callCompletion(self.onCompletion, self.reports, NO, error); break; - default: - { + default: { kscrash_callCompletion(self.onCompletion, self.reports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"Unknown MFMailComposeResult: %d", result]); + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"Unknown MFMailComposeResult: %d", result]); } } } -- (void) presentModalVC:(UIViewController*) vc +- (void)presentModalVC:(UIViewController *)vc { - self.dummyVC = [[UIViewController alloc] initWithNibName:nil bundle:nil]; - self.dummyVC.view = [[UIView alloc] init]; + self.dummyVC = [[UIViewController alloc] initWithNibName:nil bundle:nil]; + self.dummyVC.view = [[UIView alloc] init]; - UIWindow* window = [[[UIApplication sharedApplication] delegate] window]; + UIWindow *window = [[[UIApplication sharedApplication] delegate] window]; [window addSubview:self.dummyVC.view]; - if([self.dummyVC respondsToSelector:@selector(presentViewController:animated:completion:)]) - { + if ([self.dummyVC respondsToSelector:@selector(presentViewController:animated:completion:)]) { [self.dummyVC presentViewController:vc animated:YES completion:nil]; - } - else - { + } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [self.dummyVC presentModalViewController:vc animated:YES]; @@ -153,18 +142,15 @@ - (void) presentModalVC:(UIViewController*) vc } } -- (void) dismissModalVC +- (void)dismissModalVC { - if([self.dummyVC respondsToSelector:@selector(dismissViewControllerAnimated:completion:)]) - { - [self.dummyVC dismissViewControllerAnimated:YES completion:^ - { - [self.dummyVC.view removeFromSuperview]; - self.dummyVC = nil; - }]; - } - else - { + if ([self.dummyVC respondsToSelector:@selector(dismissViewControllerAnimated:completion:)]) { + [self.dummyVC dismissViewControllerAnimated:YES + completion:^{ + [self.dummyVC.view removeFromSuperview]; + self.dummyVC = nil; + }]; + } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [self.dummyVC dismissModalViewControllerAnimated:NO]; @@ -176,20 +162,18 @@ - (void) dismissModalVC @end - @interface KSCrashReportSinkEMail () -@property(nonatomic,readwrite,retain) NSArray* recipients; +@property(nonatomic, readwrite, retain) NSArray *recipients; -@property(nonatomic,readwrite,retain) NSString* subject; +@property(nonatomic, readwrite, retain) NSString *subject; -@property(nonatomic,readwrite,retain) NSString* message; +@property(nonatomic, readwrite, retain) NSString *message; -@property(nonatomic,readwrite,retain) NSString* filenameFmt; +@property(nonatomic, readwrite, retain) NSString *filenameFmt; @end - @implementation KSCrashReportSinkEMail @synthesize recipients = _recipients; @@ -197,24 +181,20 @@ @implementation KSCrashReportSinkEMail @synthesize message = _message; @synthesize filenameFmt = _filenameFmt; -+ (instancetype) sinkWithRecipients:(NSArray*) recipients - subject:(NSString*) subject - message:(nullable NSString*) message - filenameFmt:(NSString*) filenameFmt ++ (instancetype)sinkWithRecipients:(NSArray *)recipients + subject:(NSString *)subject + message:(nullable NSString *)message + filenameFmt:(NSString *)filenameFmt { - return [[self alloc] initWithRecipients:recipients - subject:subject - message:message - filenameFmt:filenameFmt]; + return [[self alloc] initWithRecipients:recipients subject:subject message:message filenameFmt:filenameFmt]; } -- (instancetype) initWithRecipients:(NSArray*) recipients - subject:(NSString*) subject - message:(nullable NSString*) message - filenameFmt:(NSString*) filenameFmt +- (instancetype)initWithRecipients:(NSArray *)recipients + subject:(NSString *)subject + message:(nullable NSString *)message + filenameFmt:(NSString *)filenameFmt { - if((self = [super init])) - { + if ((self = [super init])) { self.recipients = recipients; self.subject = subject; self.message = message; @@ -223,73 +203,61 @@ - (instancetype) initWithRecipients:(NSArray*) recipients return self; } -- (id ) defaultCrashReportFilterSet +- (id)defaultCrashReportFilterSet { - return [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterJSONEncode filterWithOptions:KSJSONEncodeOptionSorted | KSJSONEncodeOptionPretty], - [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], - self, - nil]; + return [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterJSONEncode + filterWithOptions:KSJSONEncodeOptionSorted | KSJSONEncodeOptionPretty], + [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], self, nil]; } -- (id ) defaultCrashReportFilterSetAppleFmt +- (id)defaultCrashReportFilterSetAppleFmt { - return [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterAppleFmt filterWithReportStyle:KSAppleReportStyleSymbolicatedSideBySide], - [KSCrashReportFilterStringToData filter], - [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], - self, - nil]; + return [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterAppleFmt filterWithReportStyle:KSAppleReportStyleSymbolicatedSideBySide], + [KSCrashReportFilterStringToData filter], + [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], self, nil]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - if(![MFMailComposeViewController canSendMail]) - { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Email Error" - message:@"This device is not configured to send email." - preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:nil]; + if (![MFMailComposeViewController canSendMail]) { + UIAlertController *alertController = + [UIAlertController alertControllerWithTitle:@"Email Error" + message:@"This device is not configured to send email." + preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; [alertController addAction:okAction]; UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; [keyWindow.rootViewController presentViewController:alertController animated:YES completion:NULL]; kscrash_callCompletion(onCompletion, reports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"E-Mail not enabled on device"]); + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"E-Mail not enabled on device"]); return; } - MFMailComposeViewController* mailController = [[MFMailComposeViewController alloc] init]; + MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init]; [mailController setToRecipients:self.recipients]; [mailController setSubject:self.subject]; - if(self.message != nil) - { + if (self.message != nil) { [mailController setMessageBody:self.message isHTML:NO]; } - NSString* filenameFmt = self.filenameFmt; - - dispatch_async(dispatch_get_main_queue(), ^ - { - __block KSCrashMailProcess* process = [[KSCrashMailProcess alloc] init]; - [process startWithController:mailController - reports:reports - filenameFmt:filenameFmt - onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { + NSString *filenameFmt = self.filenameFmt; + + dispatch_async(dispatch_get_main_queue(), ^{ + __block KSCrashMailProcess *process = [[KSCrashMailProcess alloc] init]; + [process startWithController:mailController + reports:reports + filenameFmt:filenameFmt + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { kscrash_callCompletion(onCompletion, filteredReports, completed, error); - dispatch_async(dispatch_get_main_queue(), ^ - { - process = nil; - }); + dispatch_async(dispatch_get_main_queue(), ^{ + process = nil; + }); }]; - }); + }); } @end @@ -300,55 +268,47 @@ - (void) filterReports:(NSArray*) reports @implementation KSCrashReportSinkEMail -+ (KSCrashReportSinkEMail*) sinkWithRecipients:(NSArray*) recipients - subject:(NSString*) subject - message:(NSString*) message - filenameFmt:(NSString*) filenameFmt ++ (KSCrashReportSinkEMail *)sinkWithRecipients:(NSArray *)recipients + subject:(NSString *)subject + message:(NSString *)message + filenameFmt:(NSString *)filenameFmt { - return [[self alloc] initWithRecipients:recipients - subject:subject - message:message - filenameFmt:filenameFmt]; + return [[self alloc] initWithRecipients:recipients subject:subject message:message filenameFmt:filenameFmt]; } -- (id) initWithRecipients:(__unused NSArray*) recipients - subject:(__unused NSString*) subject - message:(__unused NSString*) message - filenameFmt:(__unused NSString*) filenameFmt +- (id)initWithRecipients:(__unused NSArray *)recipients + subject:(__unused NSString *)subject + message:(__unused NSString *)message + filenameFmt:(__unused NSString *)filenameFmt { return [super init]; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - for(KSCrashReport* report in reports) - { + for (KSCrashReport *report in reports) { NSLog(@"Report\n%@", report); } kscrash_callCompletion(onCompletion, reports, NO, - [NSError errorWithDomain:[[self class] description] - code:0 - description:@"Cannot send mail on this platform"]); + [NSError errorWithDomain:[[self class] description] + code:0 + description:@"Cannot send mail on this platform"]); } -- (id ) defaultCrashReportFilterSet +- (id)defaultCrashReportFilterSet { - return [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterJSONEncode filterWithOptions:KSJSONEncodeOptionSorted | KSJSONEncodeOptionPretty], - [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], - self, - nil]; + return [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterJSONEncode + filterWithOptions:KSJSONEncodeOptionSorted | KSJSONEncodeOptionPretty], + [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], self, nil]; } -- (id ) defaultCrashReportFilterSetAppleFmt +- (id)defaultCrashReportFilterSetAppleFmt { - return [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterAppleFmt filterWithReportStyle:KSAppleReportStyleSymbolicatedSideBySide], - [KSCrashReportFilterStringToData filter], - [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], - self, - nil]; + return [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterAppleFmt filterWithReportStyle:KSAppleReportStyleSymbolicatedSideBySide], + [KSCrashReportFilterStringToData filter], + [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1], self, nil]; } @end diff --git a/Sources/KSCrashSinks/KSCrashReportSinkStandard.m b/Sources/KSCrashSinks/KSCrashReportSinkStandard.m index 14302c04d..2a2040f0e 100644 --- a/Sources/KSCrashSinks/KSCrashReportSinkStandard.m +++ b/Sources/KSCrashSinks/KSCrashReportSinkStandard.m @@ -24,129 +24,111 @@ // THE SOFTWARE. // - #import "KSCrashReportSinkStandard.h" +#import "KSCrashReport.h" #import "KSHTTPMultipartPostBody.h" #import "KSHTTPRequestSender.h" -#import "NSData+KSGZip.h" #import "KSJSONCodecObjC.h" #import "KSReachabilityKSCrash.h" +#import "NSData+KSGZip.h" #import "NSError+SimpleConstructor.h" -#import "KSCrashReport.h" -//#define KSLogger_LocalLevel TRACE +// #define KSLogger_LocalLevel TRACE #import "KSLogger.h" - @interface KSCrashReportSinkStandard () -@property(nonatomic,readwrite,retain) NSURL* url; - -@property(nonatomic,readwrite,retain) KSReachableOperationKSCrash* reachableOperation; +@property(nonatomic, readwrite, retain) NSURL *url; +@property(nonatomic, readwrite, retain) KSReachableOperationKSCrash *reachableOperation; @end - @implementation KSCrashReportSinkStandard @synthesize url = _url; @synthesize reachableOperation = _reachableOperation; -+ (instancetype) sinkWithURL:(NSURL*) url ++ (instancetype)sinkWithURL:(NSURL *)url { return [[self alloc] initWithURL:url]; } -- (instancetype) initWithURL:(NSURL*) url +- (instancetype)initWithURL:(NSURL *)url { - if((self = [super init])) - { + if ((self = [super init])) { self.url = url; } return self; } -- (id ) defaultCrashReportFilterSet +- (id)defaultCrashReportFilterSet { return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { - NSError* error = nil; - NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:self.url + NSError *error = nil; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15]; - KSHTTPMultipartPostBody* body = [KSHTTPMultipartPostBody body]; - NSMutableArray* jsonArray = [NSMutableArray array]; - for (KSCrashReport* report in reports) - { - if(report.dictionaryValue != nil) - { + KSHTTPMultipartPostBody *body = [KSHTTPMultipartPostBody body]; + NSMutableArray *jsonArray = [NSMutableArray array]; + for (KSCrashReport *report in reports) { + if (report.dictionaryValue != nil) { [jsonArray addObject:report.dictionaryValue]; - } - else if (report.stringValue != nil) - { + } else if (report.stringValue != nil) { [jsonArray addObject:report.stringValue]; - } - else - { + } else { KSLOG_ERROR(@"Unexpected non-dictionary/non-string report: %@", report); } } - NSData* jsonData = [KSJSONCodec encode:jsonArray - options:KSJSONEncodeOptionSorted - error:&error]; - if(jsonData == nil) - { + NSData *jsonData = [KSJSONCodec encode:jsonArray options:KSJSONEncodeOptionSorted error:&error]; + if (jsonData == nil) { kscrash_callCompletion(onCompletion, reports, NO, error); return; } - [body appendData:jsonData - name:@"reports" - contentType:@"application/json" - filename:@"reports.json"]; + [body appendData:jsonData name:@"reports" contentType:@"application/json" filename:@"reports.json"]; // TODO: Disabled gzip compression until support is added server side, // and I've fixed a bug in appendUTF8String. -// [body appendUTF8String:@"json" -// name:@"encoding" -// contentType:@"string" -// filename:nil]; + // [body appendUTF8String:@"json" + // name:@"encoding" + // contentType:@"string" + // filename:nil]; request.HTTPMethod = @"POST"; request.HTTPBody = [body data]; [request setValue:body.contentType forHTTPHeaderField:@"Content-Type"]; [request setValue:@"KSCrashReporter" forHTTPHeaderField:@"User-Agent"]; -// [request setHTTPBody:[[body data] gzippedWithError:nil]]; -// [request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; - - self.reachableOperation = [KSReachableOperationKSCrash operationWithHost:[self.url host] - allowWWAN:YES - block:^ - { - [[KSHTTPRequestSender sender] sendRequest:request - onSuccess:^(__unused NSHTTPURLResponse* response, __unused NSData* data) - { - kscrash_callCompletion(onCompletion, reports, YES, nil); - } onFailure:^(NSHTTPURLResponse* response, NSData* data) - { - NSString* text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - kscrash_callCompletion(onCompletion, reports, NO, - [NSError errorWithDomain:[[self class] description] - code:response.statusCode - userInfo:[NSDictionary dictionaryWithObject:text - forKey:NSLocalizedDescriptionKey] - ]); - } onError:^(NSError* error2) - { - kscrash_callCompletion(onCompletion, reports, NO, error2); - }]; - }]; + // [request setHTTPBody:[[body data] gzippedWithError:nil]]; + // [request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + + self.reachableOperation = [KSReachableOperationKSCrash + operationWithHost:[self.url host] + allowWWAN:YES + block:^{ + [[KSHTTPRequestSender sender] sendRequest:request + onSuccess:^(__unused NSHTTPURLResponse *response, __unused NSData *data) { + kscrash_callCompletion(onCompletion, reports, YES, nil); + } + onFailure:^(NSHTTPURLResponse *response, NSData *data) { + NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + kscrash_callCompletion( + onCompletion, reports, NO, + [NSError + errorWithDomain:[[self class] description] + code:response.statusCode + userInfo:[NSDictionary dictionaryWithObject:text + forKey:NSLocalizedDescriptionKey]]); + } + onError:^(NSError *error2) { + kscrash_callCompletion(onCompletion, reports, NO, error2); + }]; + }]; } @end diff --git a/Sources/KSCrashSinks/include/KSCrashReportSinkConsole.h b/Sources/KSCrashSinks/include/KSCrashReportSinkConsole.h index 923f7cb53..39e50b975 100644 --- a/Sources/KSCrashSinks/include/KSCrashReportSinkConsole.h +++ b/Sources/KSCrashSinks/include/KSCrashReportSinkConsole.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashReportFilter.h" #import @@ -41,10 +40,10 @@ NS_SWIFT_NAME(CrashReportSinkConsole) @interface KSCrashReportSinkConsole : NSObject /** Creates a new filter for printing reports to the console. */ -+ (instancetype) filter; ++ (instancetype)filter; /** Returns the default crash report filter set. */ -- (id ) defaultCrashReportFilterSet; +- (id)defaultCrashReportFilterSet; @end diff --git a/Sources/KSCrashSinks/include/KSCrashReportSinkEMail.h b/Sources/KSCrashSinks/include/KSCrashReportSinkEMail.h index 5bb7381fd..e96de20e4 100644 --- a/Sources/KSCrashSinks/include/KSCrashReportSinkEMail.h +++ b/Sources/KSCrashSinks/include/KSCrashReportSinkEMail.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import #import "KSCrashReportFilter.h" @@ -47,10 +46,10 @@ NS_SWIFT_NAME(CrashReportSinkEmail) * Note: With the default filter set, files are gzipped text. * @return A new instance of KSCrashReportSinkEMail configured with the specified parameters. */ -+ (instancetype) sinkWithRecipients:(NSArray*) recipients - subject:(NSString*) subject - message:(nullable NSString*) message - filenameFmt:(NSString*) filenameFmt; ++ (instancetype)sinkWithRecipients:(NSArray *)recipients + subject:(NSString *)subject + message:(nullable NSString *)message + filenameFmt:(NSString *)filenameFmt; /** * @param recipients List of email addresses to send to. @@ -60,13 +59,13 @@ NS_SWIFT_NAME(CrashReportSinkEmail) * when multiple reports are sent at once. * Note: With the default filter set, files are gzipped text. */ -- (instancetype) initWithRecipients:(NSArray*) recipients - subject:(NSString*) subject - message:(nullable NSString*) message - filenameFmt:(NSString*) filenameFmt; +- (instancetype)initWithRecipients:(NSArray *)recipients + subject:(NSString *)subject + message:(nullable NSString *)message + filenameFmt:(NSString *)filenameFmt; -- (id ) defaultCrashReportFilterSet; -- (id ) defaultCrashReportFilterSetAppleFmt; +- (id)defaultCrashReportFilterSet; +- (id)defaultCrashReportFilterSetAppleFmt; @end diff --git a/Sources/KSCrashSinks/include/KSCrashReportSinkStandard.h b/Sources/KSCrashSinks/include/KSCrashReportSinkStandard.h index 7cb3d44ec..9e594ea62 100644 --- a/Sources/KSCrashSinks/include/KSCrashReportSinkStandard.h +++ b/Sources/KSCrashSinks/include/KSCrashReportSinkStandard.h @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "KSCrashReportFilter.h" #import @@ -44,15 +43,15 @@ NS_SWIFT_NAME(CrashReportSinkStandard) * * @param url The URL to connect to. */ -+ (instancetype) sinkWithURL:(NSURL*) url; ++ (instancetype)sinkWithURL:(NSURL *)url; /** Constructor. * * @param url The URL to connect to. */ -- (instancetype) initWithURL:(NSURL*) url; +- (instancetype)initWithURL:(NSURL *)url; -- (id ) defaultCrashReportFilterSet; +- (id)defaultCrashReportFilterSet; @end diff --git a/Sources/KSCrashTestTools/FileBasedTestCase.m b/Sources/KSCrashTestTools/FileBasedTestCase.m index b59bb84fd..a2d35be0a 100644 --- a/Sources/KSCrashTestTools/FileBasedTestCase.m +++ b/Sources/KSCrashTestTools/FileBasedTestCase.m @@ -24,40 +24,38 @@ // THE SOFTWARE. // - #import "FileBasedTestCase.h" #import "XCTestCase+KSCrash.h" - @implementation FileBasedTestCase @synthesize tempPath = _tempPath; -- (void) setUp +- (void)setUp { [super setUp]; self.tempPath = [self createTempPath]; } -- (void) tearDown +- (void)tearDown { [super tearDown]; [self removePath:self.tempPath]; } -- (NSString*) generateTempFilePath +- (NSString *)generateTempFilePath { return [[self createTempPath] stringByAppendingPathComponent:@"temp.txt"]; } -- (NSString*) generateFileWithData:(NSData*) data +- (NSString *)generateFileWithData:(NSData *)data { - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; [data writeToFile:path atomically:YES]; return path; } -- (NSString*) generateFileWithString:(NSString*) string +- (NSString *)generateFileWithString:(NSString *)string { return [self generateFileWithData:[string dataUsingEncoding:NSUTF8StringEncoding]]; } diff --git a/Sources/KSCrashTestTools/TestThread.m b/Sources/KSCrashTestTools/TestThread.m index 1dd366ca9..5764296c7 100644 --- a/Sources/KSCrashTestTools/TestThread.m +++ b/Sources/KSCrashTestTools/TestThread.m @@ -24,20 +24,17 @@ // THE SOFTWARE. // - #import "TestThread.h" #import "KSThread.h" - @implementation TestThread @synthesize thread = _thread; -- (void) main +- (void)main { self.thread = (thread_t)ksthread_self(); - while(!self.isCancelled) - { + while (!self.isCancelled) { [[self class] sleepForTimeInterval:0.1]; } } diff --git a/Sources/KSCrashTestTools/XCTestCase+KSCrash.m b/Sources/KSCrashTestTools/XCTestCase+KSCrash.m index 3e487b5fb..c3d74688e 100644 --- a/Sources/KSCrashTestTools/XCTestCase+KSCrash.m +++ b/Sources/KSCrashTestTools/XCTestCase+KSCrash.m @@ -24,46 +24,40 @@ // THE SOFTWARE. // - #import "XCTestCase+KSCrash.h" - @implementation XCTestCase (XCTestCase_KSCrash) -- (NSString*) createTempPath +- (NSString *)createTempPath { - NSString* path = [NSTemporaryDirectory() stringByAppendingString: [[NSProcessInfo processInfo] globallyUniqueString]]; - NSFileManager* fm = [NSFileManager defaultManager]; - if(![fm fileExistsAtPath:path]) - { + NSString *path = + [NSTemporaryDirectory() stringByAppendingString:[[NSProcessInfo processInfo] globallyUniqueString]]; + NSFileManager *fm = [NSFileManager defaultManager]; + if (![fm fileExistsAtPath:path]) { [fm createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil]; } return path; } -- (void) removePath:(NSString*) path +- (void)removePath:(NSString *)path { [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; } - -- (void) createTempReportsAtPath:(NSString*) reportsPath - prefix:(NSString*) reportPrefix +- (void)createTempReportsAtPath:(NSString *)reportsPath prefix:(NSString *)reportPrefix { - NSError* error = nil; - NSFileManager* fm = [NSFileManager defaultManager]; + NSError *error = nil; + NSFileManager *fm = [NSFileManager defaultManager]; [fm createDirectoryAtPath:reportsPath withIntermediateDirectories:YES attributes:nil error:&error]; XCTAssertNil(error, @""); - NSString* bundlePath = [[NSBundle bundleForClass:[self class]] resourcePath]; - NSArray* files = [fm contentsOfDirectoryAtPath:bundlePath error:&error]; + NSString *bundlePath = [[NSBundle bundleForClass:[self class]] resourcePath]; + NSArray *files = [fm contentsOfDirectoryAtPath:bundlePath error:&error]; XCTAssertNil(error, @""); - for(NSString* filename in files) - { - if([filename rangeOfString:reportPrefix].location != NSNotFound) - { + for (NSString *filename in files) { + if ([filename rangeOfString:reportPrefix].location != NSNotFound) { [fm copyItemAtPath:[bundlePath stringByAppendingPathComponent:filename] toPath:[reportsPath stringByAppendingPathComponent:filename] error:&error]; @@ -72,9 +66,9 @@ - (void) createTempReportsAtPath:(NSString*) reportsPath } } -- (void) deleteTempReports:(NSString*) tempReportsPath +- (void)deleteTempReports:(NSString *)tempReportsPath { - NSError* error = nil; + NSError *error = nil; [[NSFileManager defaultManager] removeItemAtPath:tempReportsPath error:&error]; } diff --git a/Sources/KSCrashTestTools/include/FileBasedTestCase.h b/Sources/KSCrashTestTools/include/FileBasedTestCase.h index 0553d7c1a..5a2a4fa9f 100644 --- a/Sources/KSCrashTestTools/include/FileBasedTestCase.h +++ b/Sources/KSCrashTestTools/include/FileBasedTestCase.h @@ -24,16 +24,14 @@ // THE SOFTWARE. // - #import - @interface FileBasedTestCase : XCTestCase -@property(nonatomic,readwrite,retain) NSString* tempPath; +@property(nonatomic, readwrite, retain) NSString *tempPath; -- (NSString*) generateTempFilePath; -- (NSString*) generateFileWithData:(NSData*) data; -- (NSString*) generateFileWithString:(NSString*) string; +- (NSString *)generateTempFilePath; +- (NSString *)generateFileWithData:(NSData *)data; +- (NSString *)generateFileWithString:(NSString *)string; @end diff --git a/Sources/KSCrashTestTools/include/TestThread.h b/Sources/KSCrashTestTools/include/TestThread.h index 6d30031ef..19d40dab6 100644 --- a/Sources/KSCrashTestTools/include/TestThread.h +++ b/Sources/KSCrashTestTools/include/TestThread.h @@ -24,12 +24,10 @@ // THE SOFTWARE. // - #import #import - -@interface TestThread: NSThread +@interface TestThread : NSThread @property(nonatomic, readwrite, assign) thread_t thread; diff --git a/Sources/KSCrashTestTools/include/XCTestCase+KSCrash.h b/Sources/KSCrashTestTools/include/XCTestCase+KSCrash.h index 81449afbe..6bc144121 100644 --- a/Sources/KSCrashTestTools/include/XCTestCase+KSCrash.h +++ b/Sources/KSCrashTestTools/include/XCTestCase+KSCrash.h @@ -24,17 +24,14 @@ // THE SOFTWARE. // - #import - @interface XCTestCase (XCTestCase_KSCrash) -- (NSString*) createTempPath; +- (NSString *)createTempPath; -- (void) removePath:(NSString*) path; +- (void)removePath:(NSString *)path; -- (void) createTempReportsAtPath:(NSString*) reportsPath - prefix:(NSString*) reportPrefix; +- (void)createTempReportsAtPath:(NSString *)reportsPath prefix:(NSString *)reportPrefix; @end diff --git a/Tests/KSCrashBootTimeMonitorTests/KSCrashMonitor_BootTime_Tests.m b/Tests/KSCrashBootTimeMonitorTests/KSCrashMonitor_BootTime_Tests.m index f43c41d4c..db7d15198 100644 --- a/Tests/KSCrashBootTimeMonitorTests/KSCrashMonitor_BootTime_Tests.m +++ b/Tests/KSCrashBootTimeMonitorTests/KSCrashMonitor_BootTime_Tests.m @@ -44,7 +44,7 @@ - (void)setUp - (void)testMonitorActivation { - KSCrashMonitorAPI* bootTimeMonitor = kscm_boottime_getAPI(); + KSCrashMonitorAPI *bootTimeMonitor = kscm_boottime_getAPI(); XCTAssertFalse(bootTimeMonitor->isEnabled(), @"Boot time monitor should be initially disabled."); bootTimeMonitor->setEnabled(true); @@ -55,7 +55,7 @@ - (void)testMonitorActivation - (void)testAddContextualInfoWhenEnabled { - KSCrashMonitorAPI* bootTimeMonitor = kscm_boottime_getAPI(); + KSCrashMonitorAPI *bootTimeMonitor = kscm_boottime_getAPI(); bootTimeMonitor->setEnabled(true); KSCrash_MonitorContext context = { 0 }; @@ -65,12 +65,12 @@ - (void)testAddContextualInfoWhenEnabled @"Boot time should be added to the context when the monitor is enabled."); // Clean up - free((void*)context.System.bootTime); + free((void *)context.System.bootTime); } - (void)testNoContextualInfoWhenDisabled { - KSCrashMonitorAPI* bootTimeMonitor = kscm_boottime_getAPI(); + KSCrashMonitorAPI *bootTimeMonitor = kscm_boottime_getAPI(); bootTimeMonitor->setEnabled(false); KSCrash_MonitorContext context = { 0 }; @@ -82,7 +82,7 @@ - (void)testNoContextualInfoWhenDisabled - (void)testDateSysctlFunctionIndirectly { - KSCrashMonitorAPI* bootTimeMonitor = kscm_boottime_getAPI(); + KSCrashMonitorAPI *bootTimeMonitor = kscm_boottime_getAPI(); bootTimeMonitor->setEnabled(true); KSCrash_MonitorContext context = { 0 }; @@ -91,24 +91,23 @@ - (void)testDateSysctlFunctionIndirectly XCTAssertFalse(context.System.bootTime == NULL, @"The boot time string should not be NULL when monitor is enabled."); - NSString* bootTimeString = [NSString stringWithUTF8String:context.System.bootTime]; - NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init]; + NSString *bootTimeString = [NSString stringWithUTF8String:context.System.bootTime]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; // Format from ksdate_utcStringFromTimestamp dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; - NSDate* bootTimeDate = [dateFormatter dateFromString:bootTimeString]; + NSDate *bootTimeDate = [dateFormatter dateFromString:bootTimeString]; XCTAssertNotNil(bootTimeDate, @"The boot time string should be a valid date string."); // Clean up - free((void*)context.System.bootTime); + free((void *)context.System.bootTime); } - (void)testMonitorName { - KSCrashMonitorAPI* bootTimeMonitor = kscm_boottime_getAPI(); - XCTAssertEqual(strcmp(bootTimeMonitor->monitorId(), "BootTime"), 0, - @"The monitor name should be 'BootTime'."); + KSCrashMonitorAPI *bootTimeMonitor = kscm_boottime_getAPI(); + XCTAssertEqual(strcmp(bootTimeMonitor->monitorId(), "BootTime"), 0, @"The monitor name should be 'BootTime'."); } @end diff --git a/Tests/KSCrashCoreTests/NSError+SimpleConstructor_Tests.m b/Tests/KSCrashCoreTests/NSError+SimpleConstructor_Tests.m index 17d630e86..bd110b8a5 100644 --- a/Tests/KSCrashCoreTests/NSError+SimpleConstructor_Tests.m +++ b/Tests/KSCrashCoreTests/NSError+SimpleConstructor_Tests.m @@ -24,54 +24,52 @@ // THE SOFTWARE. // - #import #import "NSError+SimpleConstructor.h" - -@interface NSError_SimpleConstructor_Tests : XCTestCase @end - +@interface NSError_SimpleConstructor_Tests : XCTestCase +@end @implementation NSError_SimpleConstructor_Tests -- (void) testErrorWithDomain +- (void)testErrorWithDomain { - NSError* error = [NSError errorWithDomain:@"Domain" code:10 description:@"A description %d", 1]; - NSString* expectedDomain = @"Domain"; + NSError *error = [NSError errorWithDomain:@"Domain" code:10 description:@"A description %d", 1]; + NSString *expectedDomain = @"Domain"; NSInteger expectedCode = 10; - NSString* expectedDescription = @"A description 1"; + NSString *expectedDescription = @"A description 1"; XCTAssertEqualObjects(error.domain, expectedDomain, @""); XCTAssertEqual(error.code, expectedCode, @""); XCTAssertEqualObjects(error.localizedDescription, expectedDescription, @""); } -- (void) testFillError +- (void)testFillError { - NSError* error = nil; + NSError *error = nil; [NSError fillError:&error withDomain:@"Domain" code:10 description:@"A description %d", 1]; - NSString* expectedDomain = @"Domain"; + NSString *expectedDomain = @"Domain"; NSInteger expectedCode = 10; - NSString* expectedDescription = @"A description 1"; + NSString *expectedDescription = @"A description 1"; XCTAssertEqualObjects(error.domain, expectedDomain, @""); XCTAssertEqual(error.code, expectedCode, @""); XCTAssertEqualObjects(error.localizedDescription, expectedDescription, @""); } -- (void) testFillErrorNil +- (void)testFillErrorNil { [NSError fillError:nil withDomain:@"Domain" code:10 description:@"A description %d", 1]; } -- (void) testClearError +- (void)testClearError { - NSError* error = [NSError errorWithDomain:@"" code:1 description:@""]; + NSError *error = [NSError errorWithDomain:@"" code:1 description:@""]; XCTAssertNotNil(error, @""); [NSError clearError:&error]; XCTAssertNil(error, @""); } -- (void) testClearErrorNil +- (void)testClearErrorNil { [NSError clearError:nil]; } diff --git a/Tests/KSCrashDiscSpaceMonitorTests/KSCrashMonitor_DiscSpace_Tests.m b/Tests/KSCrashDiscSpaceMonitorTests/KSCrashMonitor_DiscSpace_Tests.m index 4fafb1812..02977449e 100644 --- a/Tests/KSCrashDiscSpaceMonitorTests/KSCrashMonitor_DiscSpace_Tests.m +++ b/Tests/KSCrashDiscSpaceMonitorTests/KSCrashMonitor_DiscSpace_Tests.m @@ -45,7 +45,7 @@ - (void)setUp - (void)testMonitorActivation { - KSCrashMonitorAPI* discSpaceMonitor = kscm_discspace_getAPI(); + KSCrashMonitorAPI *discSpaceMonitor = kscm_discspace_getAPI(); XCTAssertFalse(discSpaceMonitor->isEnabled(), @"Disc space monitor should be initially disabled."); discSpaceMonitor->setEnabled(true); @@ -56,7 +56,7 @@ - (void)testMonitorActivation - (void)testAddContextualInfoWhenEnabled { - KSCrashMonitorAPI* discSpaceMonitor = kscm_discspace_getAPI(); + KSCrashMonitorAPI *discSpaceMonitor = kscm_discspace_getAPI(); discSpaceMonitor->setEnabled(true); KSCrash_MonitorContext context = { 0 }; @@ -69,7 +69,7 @@ - (void)testAddContextualInfoWhenEnabled - (void)testNoContextualInfoWhenDisabled { - KSCrashMonitorAPI* discSpaceMonitor = kscm_discspace_getAPI(); + KSCrashMonitorAPI *discSpaceMonitor = kscm_discspace_getAPI(); discSpaceMonitor->setEnabled(false); KSCrash_MonitorContext context = { 0 }; @@ -81,9 +81,8 @@ - (void)testNoContextualInfoWhenDisabled - (void)testMonitorName { - KSCrashMonitorAPI* discSpaceMonitor = kscm_discspace_getAPI(); - XCTAssertEqual(strcmp(discSpaceMonitor->monitorId(), "DiscSpace"), 0, - @"The monitor name should be 'DiscSpace'."); + KSCrashMonitorAPI *discSpaceMonitor = kscm_discspace_getAPI(); + XCTAssertEqual(strcmp(discSpaceMonitor->monitorId(), "DiscSpace"), 0, @"The monitor name should be 'DiscSpace'."); } @end diff --git a/Tests/KSCrashFiltersTests/KSCrashReportFilterAlert_Tests.m b/Tests/KSCrashFiltersTests/KSCrashReportFilterAlert_Tests.m index 58033471f..ba9e4f29b 100644 --- a/Tests/KSCrashFiltersTests/KSCrashReportFilterAlert_Tests.m +++ b/Tests/KSCrashFiltersTests/KSCrashReportFilterAlert_Tests.m @@ -24,35 +24,31 @@ // THE SOFTWARE. // - #import #import "KSCrashReportFilterAlert.h" - -@interface KSCrashReportFilterAlert_Tests : XCTestCase @end - +@interface KSCrashReportFilterAlert_Tests : XCTestCase +@end @implementation KSCrashReportFilterAlert_Tests -- (void) testAlert +- (void)testAlert { id filter = [KSCrashReportFilterAlert filterWithTitle:@"title" message:@"message" yesAnswer:@"YES" noAnswer:@"NO"]; - + XCTestExpectation *expectation = [self expectationWithDescription:@"Filter completion"]; - [filter filterReports:[NSArray array] onCompletion:^(__unused NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - [expectation fulfill]; - }]; - - [self waitForExpectations:@[expectation] timeout:0.2]; + [filter filterReports:[NSArray array] + onCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[ expectation ] timeout:0.2]; } @end diff --git a/Tests/KSCrashFiltersTests/KSCrashReportFilterGZip_Tests.m b/Tests/KSCrashFiltersTests/KSCrashReportFilterGZip_Tests.m index 70d409c9e..e71b69f2a 100644 --- a/Tests/KSCrashFiltersTests/KSCrashReportFilterGZip_Tests.m +++ b/Tests/KSCrashFiltersTests/KSCrashReportFilterGZip_Tests.m @@ -24,25 +24,22 @@ // THE SOFTWARE. // - #import +#import "KSCrashReport.h" #import "KSCrashReportFilterGZip.h" #import "NSData+KSGZip.h" -#import "KSCrashReport.h" - @interface KSCrashReportFilterGZip_Tests : XCTestCase -@property (nonatomic, copy) NSArray* decompressedReports; -@property (nonatomic, copy) NSArray* compressedReports; +@property(nonatomic, copy) NSArray *decompressedReports; +@property(nonatomic, copy) NSArray *compressedReports; @end - @implementation KSCrashReportFilterGZip_Tests -- (void) setUp +- (void)setUp { self.decompressedReports = @[ [KSCrashReport reportWithData:[@"this is a test" dataUsingEncoding:NSUTF8StringEncoding]], @@ -50,40 +47,35 @@ - (void) setUp [KSCrashReport reportWithData:[@"testing is fun!" dataUsingEncoding:NSUTF8StringEncoding]], ]; - NSError* error = nil; - NSMutableArray* compressed = [NSMutableArray array]; - for(KSCrashReport* report in self.decompressedReports) - { - NSData* newData = [report.dataValue gzippedWithCompressionLevel:-1 error:&error]; + NSError *error = nil; + NSMutableArray *compressed = [NSMutableArray array]; + for (KSCrashReport *report in self.decompressedReports) { + NSData *newData = [report.dataValue gzippedWithCompressionLevel:-1 error:&error]; [compressed addObject:[KSCrashReport reportWithData:newData]]; } self.compressedReports = [compressed copy]; } -- (void) testFilterGZipCompress +- (void)testFilterGZipCompress { id filter = [KSCrashReportFilterGZipCompress filterWithCompressionLevel:-1]; - [filter filterReports:self.decompressedReports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error2) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error2, @""); - XCTAssertEqualObjects(filteredReports, self.compressedReports, @""); - }]; + [filter filterReports:self.decompressedReports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error2) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error2, @""); + XCTAssertEqualObjects(filteredReports, self.compressedReports, @""); + }]; } -- (void) testFilterGZipDecompress +- (void)testFilterGZipDecompress { id filter = [KSCrashReportFilterGZipDecompress filter]; - [filter filterReports:self.compressedReports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error2) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error2, @""); - XCTAssertEqualObjects(filteredReports, self.decompressedReports, @""); - }]; + [filter filterReports:self.compressedReports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error2) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error2, @""); + XCTAssertEqualObjects(filteredReports, self.decompressedReports, @""); + }]; } @end diff --git a/Tests/KSCrashFiltersTests/KSCrashReportFilterJSON_Tests.m b/Tests/KSCrashFiltersTests/KSCrashReportFilterJSON_Tests.m index d2e66de27..68db47bda 100644 --- a/Tests/KSCrashFiltersTests/KSCrashReportFilterJSON_Tests.m +++ b/Tests/KSCrashFiltersTests/KSCrashReportFilterJSON_Tests.m @@ -24,29 +24,26 @@ // THE SOFTWARE. // - #import -#import "KSCrashReportFilterJSON.h" #import "KSCrashReport.h" - +#import "KSCrashReportFilterJSON.h" @interface KSCrashReportFilterJSON_Tests : XCTestCase -@property (nonatomic, copy) NSArray* decodedReports; -@property (nonatomic, copy) NSArray* encodedReports; +@property(nonatomic, copy) NSArray *decodedReports; +@property(nonatomic, copy) NSArray *encodedReports; @end - @implementation KSCrashReportFilterJSON_Tests -- (void) setUp +- (void)setUp { self.decodedReports = @[ - [KSCrashReport reportWithDictionary:@{ @"a": @"b" }], - [KSCrashReport reportWithDictionary:@{ @"1": @{ @"2": @"3" } }], - [KSCrashReport reportWithDictionary:@{ @"?": @[ @1, @2, @3 ] }], + [KSCrashReport reportWithDictionary:@{ @"a" : @"b" }], + [KSCrashReport reportWithDictionary:@{ @"1" : @ { @"2" : @"3" } }], + [KSCrashReport reportWithDictionary:@{ @"?" : @[ @1, @2, @3 ] }], ]; self.encodedReports = @[ [KSCrashReport reportWithData:[@"{\"a\":\"b\"}" dataUsingEncoding:NSUTF8StringEncoding]], @@ -55,62 +52,54 @@ - (void) setUp ]; } -- (void) testFilterJSONEncode +- (void)testFilterJSONEncode { id filter = [KSCrashReportFilterJSONEncode filterWithOptions:0]; - [filter filterReports:self.decodedReports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error2) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error2, @""); - XCTAssertEqualObjects(filteredReports, self.encodedReports, @""); - }]; + [filter filterReports:self.decodedReports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error2) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error2, @""); + XCTAssertEqualObjects(filteredReports, self.encodedReports, @""); + }]; } -- (void) testFilterJSONEncodeInvalid +- (void)testFilterJSONEncodeInvalid { - NSArray* decoded = @[ - [KSCrashReport reportWithDictionary:@{ @1: @2 }], // Not a JSON + NSArray *decoded = @[ + [KSCrashReport reportWithDictionary:@{ @1 : @2 }], // Not a JSON ]; id filter = [KSCrashReportFilterJSONEncode filterWithOptions:0]; - [filter filterReports:decoded onCompletion:^(__unused NSArray* filteredReports, - BOOL completed, - NSError* error2) - { - XCTAssertFalse(completed, @""); - XCTAssertNotNil(error2, @""); - }]; + [filter filterReports:decoded + onCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error2) { + XCTAssertFalse(completed, @""); + XCTAssertNotNil(error2, @""); + }]; } -- (void) testFilterJSONDencode +- (void)testFilterJSONDencode { id filter = [KSCrashReportFilterJSONDecode filterWithOptions:0]; - [filter filterReports:self.encodedReports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error2) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error2, @""); - XCTAssertEqualObjects(filteredReports, self.decodedReports, @""); - }]; + [filter filterReports:self.encodedReports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error2) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error2, @""); + XCTAssertEqualObjects(filteredReports, self.decodedReports, @""); + }]; } -- (void) testFilterJSONDencodeInvalid +- (void)testFilterJSONDencodeInvalid { - NSArray* encoded = @[ + NSArray *encoded = @[ [KSCrashReport reportWithData:[@"[\"1\"\",\"2\",\"3\"]" dataUsingEncoding:NSUTF8StringEncoding]], ]; - + id filter = [KSCrashReportFilterJSONDecode filterWithOptions:0]; - [filter filterReports:encoded onCompletion:^(__unused NSArray* filteredReports, - BOOL completed, - NSError* error2) - { - XCTAssertFalse(completed, @""); - XCTAssertNotNil(error2, @""); - }]; + [filter filterReports:encoded + onCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error2) { + XCTAssertFalse(completed, @""); + XCTAssertNotNil(error2, @""); + }]; } @end diff --git a/Tests/KSCrashFiltersTests/KSCrashReportFilter_Tests.m b/Tests/KSCrashFiltersTests/KSCrashReportFilter_Tests.m index ed6702c68..f57c49322 100644 --- a/Tests/KSCrashFiltersTests/KSCrashReportFilter_Tests.m +++ b/Tests/KSCrashFiltersTests/KSCrashReportFilter_Tests.m @@ -24,45 +24,42 @@ // THE SOFTWARE. // - #import +#import "KSCrashReport.h" #import "KSCrashReportFilter.h" #import "KSCrashReportFilterBasic.h" #import "KSCrashReportFilterGZip.h" #import "KSCrashReportFilterJSON.h" #import "NSData+KSGZip.h" #import "NSError+SimpleConstructor.h" -#import "KSCrashReport.h" - -@interface KSCrash_TestNilFilter: NSObject +@interface KSCrash_TestNilFilter : NSObject @end @implementation KSCrash_TestNilFilter -+ (KSCrash_TestNilFilter*) filter ++ (KSCrash_TestNilFilter *)filter { return [[self alloc] init]; } -- (void) filterReports:(__unused NSArray*) reports onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(__unused NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { onCompletion(nil, YES, nil); } @end +@interface KSCrash_TestFilter : NSObject -@interface KSCrash_TestFilter: NSObject - -@property(nonatomic,readwrite,assign) NSTimeInterval delay; -@property(nonatomic,readwrite,assign) BOOL completed; -@property(nonatomic,readwrite,retain) NSError* error; -@property(nonatomic,readwrite,retain) NSTimer* timer; -@property(nonatomic,readwrite,retain) NSArray* reports; -@property(nonatomic,readwrite,copy) KSCrashReportFilterCompletion onCompletion; +@property(nonatomic, readwrite, assign) NSTimeInterval delay; +@property(nonatomic, readwrite, assign) BOOL completed; +@property(nonatomic, readwrite, retain) NSError *error; +@property(nonatomic, readwrite, retain) NSTimer *timer; +@property(nonatomic, readwrite, retain) NSArray *reports; +@property(nonatomic, readwrite, copy) KSCrashReportFilterCompletion onCompletion; @end @@ -75,19 +72,14 @@ @implementation KSCrash_TestFilter @synthesize timer = _timer; @synthesize onCompletion = _onCompletion; -+ (KSCrash_TestFilter*) filterWithDelay:(NSTimeInterval) delay - completed:(BOOL) completed - error:(NSError*) error ++ (KSCrash_TestFilter *)filterWithDelay:(NSTimeInterval)delay completed:(BOOL)completed error:(NSError *)error { return [[self alloc] initWithDelay:delay completed:completed error:error]; } -- (id) initWithDelay:(NSTimeInterval) delay - completed:(BOOL) completed - error:(NSError*) error +- (id)initWithDelay:(NSTimeInterval)delay completed:(BOOL)completed error:(NSError *)error { - if((self = [super init])) - { + if ((self = [super init])) { self.delay = delay; self.completed = completed; self.error = error; @@ -95,34 +87,33 @@ - (id) initWithDelay:(NSTimeInterval) delay return self; } -- (void) filterReports:(NSArray*) reports - onCompletion:(KSCrashReportFilterCompletion) onCompletion +- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion { self.reports = reports; self.onCompletion = onCompletion; - if(self.delay > 0) - { - self.timer = [NSTimer timerWithTimeInterval:self.delay target:self selector:@selector(onTimeUp) userInfo:nil repeats:NO]; - } - else - { + if (self.delay > 0) { + self.timer = [NSTimer timerWithTimeInterval:self.delay + target:self + selector:@selector(onTimeUp) + userInfo:nil + repeats:NO]; + } else { [self onTimeUp]; } } -- (void) onTimeUp +- (void)onTimeUp { kscrash_callCompletion(self.onCompletion, self.reports, self.completed, self.error); } @end - @interface KSCrashReportFilter_Tests : XCTestCase -@property (nonatomic, copy) NSArray *reports; -@property (nonatomic, copy) NSArray *reportsWithData; -@property (nonatomic, copy) NSArray *reportsWithDict; +@property(nonatomic, copy) NSArray *reports; +@property(nonatomic, copy) NSArray *reportsWithData; +@property(nonatomic, copy) NSArray *reportsWithDict; @end @@ -144,472 +135,390 @@ - (void)setUp ]; self.reportsWithDict = @[ [KSCrashReport reportWithDictionary:@{ - @"first": @"1", - @"second": @"a", - @"third": @"b", + @"first" : @"1", + @"second" : @"a", + @"third" : @"b", }], ]; } -- (void) testPassthroughLeak +- (void)testPassthroughLeak { - __block NSArray* reports = @[[KSCrashReport reportWithString:@""]]; + __block NSArray *reports = @[ [KSCrashReport reportWithString:@""] ]; __weak id weakRef = reports; - __block KSCrashReportFilterPassthrough* filter = [KSCrashReportFilterPassthrough filter]; + __block KSCrashReportFilterPassthrough *filter = [KSCrashReportFilterPassthrough filter]; [filter filterReports:reports - onCompletion:^(__unused NSArray* filteredReports, - __unused BOOL completed, - __unused NSError* error) - { - filter = nil; - reports = nil; - dispatch_async(dispatch_get_main_queue(), ^ - { - XCTAssertNil(weakRef, @"Object leaked"); - }); - }]; + onCompletion:^(__unused NSArray *filteredReports, __unused BOOL completed, __unused NSError *error) { + filter = nil; + reports = nil; + dispatch_async(dispatch_get_main_queue(), ^{ + XCTAssertNil(weakRef, @"Object leaked"); + }); + }]; } -- (void) testPipeline +- (void)testPipeline { - id filter = [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterPassthrough filter], - [KSCrashReportFilterPassthrough filter], - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects(filteredReports, self.reports, @""); - }]; + id filter = [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterPassthrough filter], [KSCrashReportFilterPassthrough filter], nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects(filteredReports, self.reports, @""); + }]; } -- (void) testPipelineInit +- (void)testPipelineInit { - id filter = [[KSCrashReportFilterPipeline alloc] initWithFilters: - [KSCrashReportFilterPassthrough filter], - [KSCrashReportFilterPassthrough filter], - nil]; + id filter = [[KSCrashReportFilterPipeline alloc] + initWithFilters:[KSCrashReportFilterPassthrough filter], [KSCrashReportFilterPassthrough filter], nil]; filter = filter; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects(filteredReports, self.reports, @""); - }]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects(filteredReports, self.reports, @""); + }]; } -- (void) testPipelineNoFilters +- (void)testPipelineNoFilters { - id filter = [KSCrashReportFilterPipeline filterWithFilters: - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects(filteredReports, self.reports, @""); - }]; + id filter = [KSCrashReportFilterPipeline filterWithFilters:nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects(filteredReports, self.reports, @""); + }]; } -- (void) testFilterPipelineIncomplete +- (void)testFilterPipelineIncomplete { - id filter = [KSCrashReportFilterPipeline filterWithFilters: - [KSCrash_TestFilter filterWithDelay:0 completed:NO error:nil], - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertNotNil(filteredReports, @""); - XCTAssertFalse(completed, @""); - XCTAssertNil(error, @""); - }]; + id filter = [KSCrashReportFilterPipeline + filterWithFilters:[KSCrash_TestFilter filterWithDelay:0 completed:NO error:nil], nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertNotNil(filteredReports, @""); + XCTAssertFalse(completed, @""); + XCTAssertNil(error, @""); + }]; } -- (void) testFilterPipelineNilReports +- (void)testFilterPipelineNilReports { - id filter = [KSCrashReportFilterPipeline filterWithFilters: - [KSCrash_TestNilFilter filter], - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertNil(filteredReports, @""); - XCTAssertFalse(completed, @""); - XCTAssertNotNil(error, @""); - }]; + id filter = + [KSCrashReportFilterPipeline filterWithFilters:[KSCrash_TestNilFilter filter], nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertNil(filteredReports, @""); + XCTAssertFalse(completed, @""); + XCTAssertNotNil(error, @""); + }]; } -- (void) testPiplelineLeak1 +- (void)testPiplelineLeak1 { - __block NSArray* reports = [NSArray arrayWithArray:self.reports]; + __block NSArray *reports = [NSArray arrayWithArray:self.reports]; __block id filter = [KSCrash_TestFilter filterWithDelay:0.1 completed:YES error:nil]; __weak id weakReports = reports; __weak id weakFilter = filter; - __block KSCrashReportFilterPipeline* pipeline = [KSCrashReportFilterPipeline filterWithFilters:filter, nil]; + __block KSCrashReportFilterPipeline *pipeline = [KSCrashReportFilterPipeline filterWithFilters:filter, nil]; [pipeline filterReports:reports - onCompletion:^(__unused NSArray* filteredReports, - __unused BOOL completed, - __unused NSError* error) - { - reports = nil; - filter = nil; - pipeline = nil; - XCTAssertTrue(completed, @""); - dispatch_async(dispatch_get_main_queue(), ^ - { - XCTAssertNil(weakReports, @"Object leaked"); - XCTAssertNil(weakFilter, @"Object leaked"); - }); - }]; + onCompletion:^(__unused NSArray *filteredReports, __unused BOOL completed, __unused NSError *error) { + reports = nil; + filter = nil; + pipeline = nil; + XCTAssertTrue(completed, @""); + dispatch_async(dispatch_get_main_queue(), ^{ + XCTAssertNil(weakReports, @"Object leaked"); + XCTAssertNil(weakFilter, @"Object leaked"); + }); + }]; } -- (void) testPiplelineLeak2 +- (void)testPiplelineLeak2 { - __block NSArray* reports = [NSArray arrayWithArray:self.reports]; + __block NSArray *reports = [NSArray arrayWithArray:self.reports]; __block id filter = [KSCrash_TestFilter filterWithDelay:0.1 completed:NO error:nil]; __weak id weakReports = reports; __weak id weakFilter = filter; - __block KSCrashReportFilterPipeline* pipeline = [KSCrashReportFilterPipeline filterWithFilters:filter, nil]; + __block KSCrashReportFilterPipeline *pipeline = [KSCrashReportFilterPipeline filterWithFilters:filter, nil]; [pipeline filterReports:reports - onCompletion:^(__unused NSArray* filteredReports, - __unused BOOL completed, - __unused NSError* error) - { - reports = nil; - filter = nil; - pipeline = nil; - XCTAssertFalse(completed, @""); - dispatch_async(dispatch_get_main_queue(), ^ - { - XCTAssertNil(weakReports, @"Object leaked"); - XCTAssertNil(weakFilter, @"Object leaked"); - }); - }]; + onCompletion:^(__unused NSArray *filteredReports, __unused BOOL completed, __unused NSError *error) { + reports = nil; + filter = nil; + pipeline = nil; + XCTAssertFalse(completed, @""); + dispatch_async(dispatch_get_main_queue(), ^{ + XCTAssertNil(weakReports, @"Object leaked"); + XCTAssertNil(weakFilter, @"Object leaked"); + }); + }]; } #endif -- (void) testFilterPassthrough +- (void)testFilterPassthrough { id filter = [KSCrashReportFilterPassthrough filter]; - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects(filteredReports, self.reports, @""); - }]; + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects(filteredReports, self.reports, @""); + }]; } -- (void) testFilterStringToData +- (void)testFilterStringToData { id filter = [KSCrashReportFilterStringToData filter]; - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects(filteredReports, self.reportsWithData, @""); - }]; + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects(filteredReports, self.reportsWithData, @""); + }]; } -- (void) testFilterDataToString +- (void)testFilterDataToString { id filter = [KSCrashReportFilterDataToString filter]; - [filter filterReports:self.reportsWithData onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects(filteredReports, self.reports, @""); - }]; + [filter filterReports:self.reportsWithData + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects(filteredReports, self.reports, @""); + }]; } -- (void) testFilterPipeline +- (void)testFilterPipeline { - id filter = [KSCrashReportFilterPipeline filterWithFilters: - [KSCrashReportFilterStringToData filter], - [KSCrashReportFilterDataToString filter], - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects(filteredReports, self.reports, @""); - }]; + id filter = [KSCrashReportFilterPipeline + filterWithFilters:[KSCrashReportFilterStringToData filter], [KSCrashReportFilterDataToString filter], nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects(filteredReports, self.reports, @""); + }]; } -- (void) testFilterCombine +- (void)testFilterCombine { - id filter = [KSCrashReportFilterCombine filterWithFiltersAndKeys: - [KSCrashReportFilterPassthrough filter], - @"normal", - [KSCrashReportFilterStringToData filter], - @"data", - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - for(NSUInteger i = 0; i < self.reports.count; i++) - { - id exp1 = [[self.reports objectAtIndex:i] stringValue]; - id exp2 = [[self.reportsWithData objectAtIndex:i] dataValue]; - KSCrashReport* entry = [filteredReports objectAtIndex:i]; - id result1 = entry.dictionaryValue[@"normal"]; - id result2 = entry.dictionaryValue[@"data"]; - XCTAssertNotNil(result1); - XCTAssertNotNil(result2); - XCTAssertEqualObjects(result1, exp1, @""); - XCTAssertEqualObjects(result2, exp2, @""); - } - }]; + id filter = + [KSCrashReportFilterCombine filterWithFiltersAndKeys:[KSCrashReportFilterPassthrough filter], @"normal", + [KSCrashReportFilterStringToData filter], @"data", nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + for (NSUInteger i = 0; i < self.reports.count; i++) { + id exp1 = [[self.reports objectAtIndex:i] stringValue]; + id exp2 = [[self.reportsWithData objectAtIndex:i] dataValue]; + KSCrashReport *entry = [filteredReports objectAtIndex:i]; + id result1 = entry.dictionaryValue[@"normal"]; + id result2 = entry.dictionaryValue[@"data"]; + XCTAssertNotNil(result1); + XCTAssertNotNil(result2); + XCTAssertEqualObjects(result1, exp1, @""); + XCTAssertEqualObjects(result2, exp2, @""); + } + }]; } -- (void) testFilterCombineInit +- (void)testFilterCombineInit { - id filter = [[KSCrashReportFilterCombine alloc] initWithFiltersAndKeys: - [KSCrashReportFilterPassthrough filter], - @"normal", - [KSCrashReportFilterStringToData filter], - @"data", - nil]; + id filter = [[KSCrashReportFilterCombine alloc] + initWithFiltersAndKeys:[KSCrashReportFilterPassthrough filter], @"normal", + [KSCrashReportFilterStringToData filter], @"data", nil]; filter = filter; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - for(NSUInteger i = 0; i < [self.reports count]; i++) - { - id exp1 = [[self.reports objectAtIndex:i] stringValue]; - id exp2 = [[self.reportsWithData objectAtIndex:i] dataValue]; - KSCrashReport* entry = [filteredReports objectAtIndex:i]; - id result1 = entry.dictionaryValue[@"normal"]; - id result2 = entry.dictionaryValue[@"data"]; - XCTAssertNotNil(result1); - XCTAssertNotNil(result2); - XCTAssertEqualObjects(result1, exp1, @""); - XCTAssertEqualObjects(result2, exp2, @""); - } - }]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + for (NSUInteger i = 0; i < [self.reports count]; i++) { + id exp1 = [[self.reports objectAtIndex:i] stringValue]; + id exp2 = [[self.reportsWithData objectAtIndex:i] dataValue]; + KSCrashReport *entry = [filteredReports objectAtIndex:i]; + id result1 = entry.dictionaryValue[@"normal"]; + id result2 = entry.dictionaryValue[@"data"]; + XCTAssertNotNil(result1); + XCTAssertNotNil(result2); + XCTAssertEqualObjects(result1, exp1, @""); + XCTAssertEqualObjects(result2, exp2, @""); + } + }]; } -- (void) testFilterCombineNoFilters +- (void)testFilterCombineNoFilters { - id filter = [KSCrashReportFilterCombine filterWithFiltersAndKeys: - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - for(NSUInteger i = 0; i < [self.reports count]; i++) - { - id exp = [self.reports objectAtIndex:i]; - NSString* entry = [filteredReports objectAtIndex:i]; - XCTAssertEqualObjects(entry, exp, @""); - } - }]; + id filter = [KSCrashReportFilterCombine filterWithFiltersAndKeys:nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + for (NSUInteger i = 0; i < [self.reports count]; i++) { + id exp = [self.reports objectAtIndex:i]; + NSString *entry = [filteredReports objectAtIndex:i]; + XCTAssertEqualObjects(entry, exp, @""); + } + }]; } -- (void) testFilterCombineIncomplete +- (void)testFilterCombineIncomplete { - id filter = [KSCrashReportFilterCombine filterWithFiltersAndKeys: - [KSCrash_TestFilter filterWithDelay:0 completed:NO error:nil], - @"Blah", - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertNotNil(filteredReports, @""); - XCTAssertFalse(completed, @""); - XCTAssertNil(error, @""); - }]; + id filter = [KSCrashReportFilterCombine + filterWithFiltersAndKeys:[KSCrash_TestFilter filterWithDelay:0 completed:NO error:nil], @"Blah", nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertNotNil(filteredReports, @""); + XCTAssertFalse(completed, @""); + XCTAssertNil(error, @""); + }]; } -- (void) testFilterCombineNilReports +- (void)testFilterCombineNilReports { - id filter = [KSCrashReportFilterCombine filterWithFiltersAndKeys: - [KSCrash_TestNilFilter filter], - @"Blah", - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertNil(filteredReports, @""); - XCTAssertFalse(completed, @""); - XCTAssertNotNil(error, @""); - }]; + id filter = + [KSCrashReportFilterCombine filterWithFiltersAndKeys:[KSCrash_TestNilFilter filter], @"Blah", nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertNil(filteredReports, @""); + XCTAssertFalse(completed, @""); + XCTAssertNotNil(error, @""); + }]; } -- (void) testFilterCombineArray +- (void)testFilterCombineArray { - id filter = [KSCrashReportFilterCombine filterWithFiltersAndKeys: - [NSArray arrayWithObject:[KSCrashReportFilterPassthrough filter]], - @"normal", - [NSArray arrayWithObject:[KSCrashReportFilterStringToData filter]], - @"data", - nil]; - - [filter filterReports:self.reports onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - for(NSUInteger i = 0; i < [self.reports count]; i++) - { - id exp1 = [[self.reports objectAtIndex:i] stringValue]; - id exp2 = [[self.reportsWithData objectAtIndex:i] dataValue]; - KSCrashReport* entry = [filteredReports objectAtIndex:i]; - id result1 = entry.dictionaryValue[@"normal"]; - id result2 = entry.dictionaryValue[@"data"]; - XCTAssertNotNil(result1); - XCTAssertNotNil(result2); - XCTAssertEqualObjects(result1, exp1, @""); - XCTAssertEqualObjects(result2, exp2, @""); - } - }]; + id filter = [KSCrashReportFilterCombine + filterWithFiltersAndKeys:[NSArray arrayWithObject:[KSCrashReportFilterPassthrough filter]], @"normal", + [NSArray arrayWithObject:[KSCrashReportFilterStringToData filter]], @"data", nil]; + + [filter filterReports:self.reports + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + for (NSUInteger i = 0; i < [self.reports count]; i++) { + id exp1 = [[self.reports objectAtIndex:i] stringValue]; + id exp2 = [[self.reportsWithData objectAtIndex:i] dataValue]; + KSCrashReport *entry = [filteredReports objectAtIndex:i]; + id result1 = entry.dictionaryValue[@"normal"]; + id result2 = entry.dictionaryValue[@"data"]; + XCTAssertNotNil(result1); + XCTAssertNotNil(result2); + XCTAssertEqualObjects(result1, exp1, @""); + XCTAssertEqualObjects(result2, exp2, @""); + } + }]; } -- (void) testFilterCombineMissingKey +- (void)testFilterCombineMissingKey { - id filter = [KSCrashReportFilterCombine filterWithFiltersAndKeys: - [KSCrashReportFilterPassthrough filter], - @"normal", - [KSCrashReportFilterStringToData filter], - // Missing key - nil]; - - [filter filterReports:self.reports onCompletion:^(__unused NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertFalse(completed, @""); - XCTAssertNotNil(error, @""); - }]; + id filter = + [KSCrashReportFilterCombine filterWithFiltersAndKeys:[KSCrashReportFilterPassthrough filter], @"normal", + [KSCrashReportFilterStringToData filter], + // Missing key + nil]; + + [filter filterReports:self.reports + onCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertFalse(completed, @""); + XCTAssertNotNil(error, @""); + }]; } -- (void) testConcatenate +- (void)testConcatenate { - NSString* expected = @"1,a"; + NSString *expected = @"1,a"; id filter = [KSCrashReportFilterConcatenate filterWithSeparatorFmt:@"," keys:@"first", @"second", nil]; - - [filter filterReports:self.reportsWithDict onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); - }]; + + [filter filterReports:self.reportsWithDict + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); + }]; } -- (void) testConcatenateInit +- (void)testConcatenateInit { - NSString* expected = @"1,a"; - id filter = [[KSCrashReportFilterConcatenate alloc] initWithSeparatorFmt:@"," - keys:@"first", @"second", nil]; + NSString *expected = @"1,a"; + id filter = + [[KSCrashReportFilterConcatenate alloc] initWithSeparatorFmt:@"," keys:@"first", @"second", nil]; filter = filter; - - [filter filterReports:self.reportsWithDict onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); - }]; + + [filter filterReports:self.reportsWithDict + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); + }]; } -- (void) testSubset +- (void)testSubset { - KSCrashReport* expected = [KSCrashReport reportWithDictionary:@{ - @"first": @"1", - @"third": @"b", + KSCrashReport *expected = [KSCrashReport reportWithDictionary:@{ + @"first" : @"1", + @"third" : @"b", }]; id filter = [KSCrashReportFilterSubset filterWithKeys:@"first", @"third", nil]; - - [filter filterReports:self.reportsWithDict onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); - }]; + + [filter filterReports:self.reportsWithDict + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); + }]; } -- (void) testSubsetBadKeyPath +- (void)testSubsetBadKeyPath { id filter = [KSCrashReportFilterSubset filterWithKeys:@"first", @"aaa", nil]; - - [filter filterReports:self.reportsWithDict onCompletion:^(__unused NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertFalse(completed, @""); - XCTAssertNotNil(error, @""); - }]; + + [filter filterReports:self.reportsWithDict + onCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertFalse(completed, @""); + XCTAssertNotNil(error, @""); + }]; } -- (void) testSubsetInit +- (void)testSubsetInit { - KSCrashReport* expected = [KSCrashReport reportWithDictionary:@{ - @"first": @"1", - @"third": @"b", + KSCrashReport *expected = [KSCrashReport reportWithDictionary:@{ + @"first" : @"1", + @"third" : @"b", }]; id filter = [[KSCrashReportFilterSubset alloc] initWithKeys:@"first", @"third", nil]; filter = filter; - - [filter filterReports:self.reportsWithDict onCompletion:^(NSArray* filteredReports, - BOOL completed, - NSError* error) - { - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); - }]; + + [filter filterReports:self.reportsWithDict + onCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + XCTAssertEqualObjects([filteredReports objectAtIndex:0], expected, @""); + }]; } @end diff --git a/Tests/KSCrashInstallationsTests/KSCrashInstallationEmail_Tests.m b/Tests/KSCrashInstallationsTests/KSCrashInstallationEmail_Tests.m index 5c59ee0db..01c471e46 100644 --- a/Tests/KSCrashInstallationsTests/KSCrashInstallationEmail_Tests.m +++ b/Tests/KSCrashInstallationsTests/KSCrashInstallationEmail_Tests.m @@ -24,38 +24,35 @@ // THE SOFTWARE. // - #import #import "KSCrashInstallation+Alert.h" #import "KSCrashInstallationEmail.h" - -@interface KSCrashInstallationEmail_Tests : XCTestCase @end - +@interface KSCrashInstallationEmail_Tests : XCTestCase +@end @implementation KSCrashInstallationEmail_Tests -- (void) testInstall +- (void)testInstall { - KSCrashInstallationEmail* installation = [KSCrashInstallationEmail sharedInstance]; + KSCrashInstallationEmail *installation = [KSCrashInstallationEmail sharedInstance]; installation.recipients = [NSArray arrayWithObjects:@"nobody", nil]; installation.subject = @"subject"; installation.message = @"message"; installation.filenameFmt = @"someFile.txt.gz"; [installation addConditionalAlertWithTitle:@"title" message:@"message" yesAnswer:@"Yes" noAnswer:@"No"]; [installation installWithConfiguration:nil]; - [installation sendAllReportsWithCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) - { - // There are no reports, so this will succeed. - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - }]; + [installation sendAllReportsWithCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) { + // There are no reports, so this will succeed. + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + }]; } -- (void) testInstallInvalid +- (void)testInstallInvalid { - KSCrashInstallationEmail* installation = [KSCrashInstallationEmail sharedInstance]; + KSCrashInstallationEmail *installation = [KSCrashInstallationEmail sharedInstance]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" installation.recipients = nil; @@ -65,11 +62,10 @@ - (void) testInstallInvalid #pragma clang diagnostic pop [installation addUnconditionalAlertWithTitle:@"title" message:@"message" dismissButtonText:@"dismiss"]; [installation installWithConfiguration:nil]; - [installation sendAllReportsWithCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) - { - XCTAssertFalse(completed, @""); - XCTAssertNotNil(error, @""); - }]; + [installation sendAllReportsWithCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) { + XCTAssertFalse(completed, @""); + XCTAssertNotNil(error, @""); + }]; } @end diff --git a/Tests/KSCrashInstallationsTests/KSCrashInstallationStandard_Tests.m b/Tests/KSCrashInstallationsTests/KSCrashInstallationStandard_Tests.m index d39db5ecc..5ffb8fe3f 100644 --- a/Tests/KSCrashInstallationsTests/KSCrashInstallationStandard_Tests.m +++ b/Tests/KSCrashInstallationsTests/KSCrashInstallationStandard_Tests.m @@ -24,28 +24,25 @@ // THE SOFTWARE. // - #import #import "KSCrashInstallationStandard.h" - -@interface KSCrashInstallationStandard_Tests : XCTestCase @end - +@interface KSCrashInstallationStandard_Tests : XCTestCase +@end @implementation KSCrashInstallationStandard_Tests -- (void) testInstall +- (void)testInstall { - KSCrashInstallationStandard* installation = [KSCrashInstallationStandard sharedInstance]; + KSCrashInstallationStandard *installation = [KSCrashInstallationStandard sharedInstance]; installation.url = [NSURL URLWithString:@"www.google.com"]; [installation installWithConfiguration:nil]; - [installation sendAllReportsWithCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) - { - // There are no reports, so this will succeed. - XCTAssertTrue(completed, @""); - XCTAssertNil(error, @""); - }]; + [installation sendAllReportsWithCompletion:^(__unused NSArray *filteredReports, BOOL completed, NSError *error) { + // There are no reports, so this will succeed. + XCTAssertTrue(completed, @""); + XCTAssertNil(error, @""); + }]; } @end diff --git a/Tests/KSCrashRecordingCoreTests/KSCPU_Tests.m b/Tests/KSCrashRecordingCoreTests/KSCPU_Tests.m index 5229f869c..eff594e42 100644 --- a/Tests/KSCrashRecordingCoreTests/KSCPU_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSCPU_Tests.m @@ -24,44 +24,43 @@ // THE SOFTWARE. // - #import -#import "KSSystemCapabilities.h" #import "KSCPU.h" #import "KSMachineContext.h" +#import "KSSystemCapabilities.h" #import "TestThread.h" #import #if KSCRASH_HAS_THREADS_API -@interface KSCPU_Tests : XCTestCase @end +@interface KSCPU_Tests : XCTestCase +@end @implementation KSCPU_Tests -- (void) testCPUState +- (void)testCPUState { - TestThread* thread = [[TestThread alloc] init]; + TestThread *thread = [[TestThread alloc] init]; [thread start]; [NSThread sleepForTimeInterval:0.1]; kern_return_t kr; kr = thread_suspend(thread.thread); XCTAssertTrue(kr == KERN_SUCCESS, @""); - + KSMC_NEW_CONTEXT(machineContext); ksmc_getContextForThread(thread.thread, machineContext, NO); kscpu_getState(machineContext); - + int numRegisters = kscpu_numRegisters(); - for(int i = 0; i < numRegisters; i++) - { - const char* name = kscpu_registerName(i); + for (int i = 0; i < numRegisters; i++) { + const char *name = kscpu_registerName(i); XCTAssertTrue(name != NULL, @"Register %d was NULL", i); kscpu_registerValue(machineContext, i); } - - const char* name = kscpu_registerName(1000000); + + const char *name = kscpu_registerName(1000000); XCTAssertTrue(name == NULL, @""); uint64_t value = kscpu_registerValue(machineContext, 1000000); XCTAssertTrue(value == 0, @""); @@ -75,25 +74,24 @@ - (void) testCPUState XCTAssertTrue(address != 0, @""); numRegisters = kscpu_numExceptionRegisters(); - for(int i = 0; i < numRegisters; i++) - { + for (int i = 0; i < numRegisters; i++) { name = kscpu_exceptionRegisterName(i); XCTAssertTrue(name != NULL, @"Register %d was NULL", i); kscpu_exceptionRegisterValue(machineContext, i); } - + name = kscpu_exceptionRegisterName(1000000); XCTAssertTrue(name == NULL, @""); value = kscpu_exceptionRegisterValue(machineContext, 1000000); XCTAssertTrue(value == 0, @""); - + kscpu_faultAddress(machineContext); thread_resume(thread.thread); [thread cancel]; } -- (void) testStackGrowDirection +- (void)testStackGrowDirection { kscpu_stackGrowDirection(); } diff --git a/Tests/KSCrashRecordingCoreTests/KSCrashMonitor_Tests.m b/Tests/KSCrashRecordingCoreTests/KSCrashMonitor_Tests.m index e5b89d7a2..f320bdaa8 100644 --- a/Tests/KSCrashRecordingCoreTests/KSCrashMonitor_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSCrashMonitor_Tests.m @@ -38,19 +38,18 @@ @implementation KSCrashMonitor_Tests // First monitor static bool g_dummyEnabledState = false; static bool g_dummyPostSystemEnabled = false; -static const char* const g_eventID = "TestEventID"; +static const char *const g_eventID = "TestEventID"; -static const char* dummyMonitorId(void) { return "Dummy Monitor"; } -static const char* newMonitorId(void) { return "New Monitor"; } +static const char *dummyMonitorId(void) { return "Dummy Monitor"; } +static const char *newMonitorId(void) { return "New Monitor"; } static KSCrashMonitorFlag dummyMonitorFlags(void) { return KSCrashMonitorFlagAsyncSafe; } static void dummySetEnabled(bool isEnabled) { g_dummyEnabledState = isEnabled; } static bool dummyIsEnabled(void) { return g_dummyEnabledState; } -static void dummyAddContextualInfoToEvent(struct KSCrash_MonitorContext* eventContext) +static void dummyAddContextualInfoToEvent(struct KSCrash_MonitorContext *eventContext) { - if (eventContext != NULL) - { + if (eventContext != NULL) { eventContext->eventID = g_eventID; } } @@ -58,10 +57,10 @@ static void dummyAddContextualInfoToEvent(struct KSCrash_MonitorContext* eventCo static void dummyNotifyPostSystemEnable(void) { g_dummyPostSystemEnabled = true; } // Second monitor -static const char* secondDummyMonitorId(void) { return "Second Dummy Monitor"; } +static const char *secondDummyMonitorId(void) { return "Second Dummy Monitor"; } static bool g_secondDummyEnabledState = false; -static const char* const g_secondEventID = "SecondEventID"; +static const char *const g_secondEventID = "SecondEventID"; static void secondDummySetEnabled(bool isEnabled) { g_secondDummyEnabledState = isEnabled; } static bool secondDummyIsEnabled(void) { return g_secondDummyEnabledState; } @@ -73,14 +72,14 @@ static void dummyAddContextualInfoToEvent(struct KSCrash_MonitorContext* eventCo static BOOL g_exceptionHandled = NO; -static void myEventCallback(struct KSCrash_MonitorContext* context) { g_exceptionHandled = YES; } +static void myEventCallback(struct KSCrash_MonitorContext *context) { g_exceptionHandled = YES; } extern void kscm_resetState(void); - (void)setUp { [super setUp]; -// First monitor + // First monitor g_dummyMonitor.monitorId = dummyMonitorId; g_dummyMonitor.monitorFlags = dummyMonitorFlags; g_dummyMonitor.setEnabled = dummySetEnabled; @@ -90,12 +89,12 @@ - (void)setUp g_dummyEnabledState = false; g_dummyPostSystemEnabled = false; g_exceptionHandled = NO; -// Second monitor + // Second monitor g_secondDummyMonitor.monitorId = secondDummyMonitorId; g_secondDummyMonitor.setEnabled = secondDummySetEnabled; g_secondDummyMonitor.isEnabled = secondDummyIsEnabled; g_secondDummyEnabledState = false; - + kscm_resetState(); } @@ -104,7 +103,7 @@ - (void)setUp - (void)testAddingAndActivatingMonitors { XCTAssertTrue(kscm_addMonitor(&g_dummyMonitor), @"Monitor should be successfully added."); - kscm_activateMonitors(); // Activate all monitors + kscm_activateMonitors(); // Activate all monitors XCTAssertTrue(g_dummyMonitor.isEnabled(), @"The monitor should be enabled after activation."); } @@ -232,7 +231,7 @@ - (void)testHandleExceptionRestoresOriginalHandlers kscm_activateMonitors(); XCTAssertTrue(g_dummyMonitor.isEnabled(), @"The monitor should be enabled after activation."); struct KSCrash_MonitorContext context = { 0 }; - context.currentSnapshotUserReported = false; // Simulate that the exception is not user-reported + context.currentSnapshotUserReported = false; // Simulate that the exception is not user-reported context.monitorFlags = KSCrashMonitorFlagFatal; // Indicate that the exception is fatal kscm_handleException(&context); XCTAssertTrue(g_dummyMonitor.isEnabled(), @@ -253,8 +252,8 @@ - (void)testHandleExceptionCrashedDuringExceptionHandling kscm_notifyFatalExceptionCaptured(false); // Set g_crashedDuringExceptionHandling to true kscm_handleException(&context); // Handle the exception XCTAssertTrue( - context.crashedDuringCrashHandling, - @"The context's crashedDuringCrashHandling should be true when g_crashedDuringExceptionHandling is true."); + context.crashedDuringCrashHandling, + @"The context's crashedDuringCrashHandling should be true when g_crashedDuringExceptionHandling is true."); } - (void)testHandleExceptionCurrentSnapshotUserReported @@ -263,10 +262,10 @@ - (void)testHandleExceptionCurrentSnapshotUserReported kscm_activateMonitors(); XCTAssertTrue(g_dummyMonitor.isEnabled(), @"The monitor should be enabled after activation."); struct KSCrash_MonitorContext context = { 0 }; - context.currentSnapshotUserReported = true; // Simulate that the snapshot is user-reported + context.currentSnapshotUserReported = true; // Simulate that the snapshot is user-reported context.monitorFlags = KSCrashMonitorFlagFatal; // Indicate that the exception is fatal - kscm_notifyFatalExceptionCaptured(false); // Simulate capturing a fatal exception - kscm_handleException(&context); // Handle the exception + kscm_notifyFatalExceptionCaptured(false); // Simulate capturing a fatal exception + kscm_handleException(&context); // Handle the exception // Since we can't access g_handlingFatalException directly, we indirectly check its effect // by ensuring that the monitor is still enabled because g_handlingFatalException should be false now @@ -315,13 +314,14 @@ - (void)testRemovingMonitor - (void)testRemoveMonitorNotAdded { KSCrashMonitorAPI newMonitor = g_dummyMonitor; - newMonitor.monitorId = newMonitorId; // Set monitorId as a function pointer + newMonitor.monitorId = newMonitorId; // Set monitorId as a function pointer - kscm_removeMonitor(&newMonitor); // Remove without adding + kscm_removeMonitor(&newMonitor); // Remove without adding kscm_activateMonitors(); // Verify that no crash occurred and the state remains unchanged - XCTAssertFalse(newMonitor.isEnabled ? newMonitor.isEnabled() : NO, @"The new monitor should not be enabled, as it was never added."); + XCTAssertFalse(newMonitor.isEnabled ? newMonitor.isEnabled() : NO, + @"The new monitor should not be enabled, as it was never added."); XCTAssertFalse(g_dummyMonitor.isEnabled(), @"The dummy monitor should still be disabled as it's not related."); } @@ -332,7 +332,8 @@ - (void)testRemoveNullMonitor kscm_activateMonitors(); // Verify that no crash occurred and no state was altered - XCTAssertFalse(g_dummyMonitor.isEnabled(), @"The dummy monitor should still be disabled, as NULL removal is a no-op."); + XCTAssertFalse(g_dummyMonitor.isEnabled(), + @"The dummy monitor should still be disabled, as NULL removal is a no-op."); } - (void)testRemoveMonitorTwice diff --git a/Tests/KSCrashRecordingCoreTests/KSDebug_Tests.m b/Tests/KSCrashRecordingCoreTests/KSDebug_Tests.m index 78e58fb7d..894ad2a53 100644 --- a/Tests/KSCrashRecordingCoreTests/KSDebug_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSDebug_Tests.m @@ -24,17 +24,16 @@ // THE SOFTWARE. // - #import #import "KSDebug.h" - -@interface KSDebug_Tests : XCTestCase @end +@interface KSDebug_Tests : XCTestCase +@end @implementation KSDebug_Tests -- (void) testIsBeingTraced +- (void)testIsBeingTraced { bool traced = ksdebug_isBeingTraced(); XCTAssertTrue(traced, @""); diff --git a/Tests/KSCrashRecordingCoreTests/KSDynamicLinker_Tests.m b/Tests/KSCrashRecordingCoreTests/KSDynamicLinker_Tests.m index 90e6cfd30..db896df85 100644 --- a/Tests/KSCrashRecordingCoreTests/KSDynamicLinker_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSDynamicLinker_Tests.m @@ -24,47 +24,46 @@ // THE SOFTWARE. // - #import #include #import "KSDynamicLinker.h" -@interface KSDynamicLinker_Tests : XCTestCase @end +@interface KSDynamicLinker_Tests : XCTestCase +@end @implementation KSDynamicLinker_Tests -- (void) testImageUUID +- (void)testImageUUID { // Just abritrarily grab the name of the 4th image... - const char* name = _dyld_get_image_name(4); - const uint8_t* uuidBytes = ksdl_imageUUID(name, true); + const char *name = _dyld_get_image_name(4); + const uint8_t *uuidBytes = ksdl_imageUUID(name, true); XCTAssertTrue(uuidBytes != NULL, @""); } -- (void) testImageUUIDInvalidName +- (void)testImageUUIDInvalidName { - const uint8_t* uuidBytes = ksdl_imageUUID("sdfgserghwerghwrh", true); + const uint8_t *uuidBytes = ksdl_imageUUID("sdfgserghwerghwrh", true); XCTAssertTrue(uuidBytes == NULL, @""); } -- (void) testImageUUIDNULLName +- (void)testImageUUIDNULLName { - const uint8_t* uuidBytes = ksdl_imageUUID(NULL, true); + const uint8_t *uuidBytes = ksdl_imageUUID(NULL, true); XCTAssertTrue(uuidBytes == NULL, @""); } -- (void) testImageUUIDPartialMatch +- (void)testImageUUIDPartialMatch { - const uint8_t* uuidBytes = ksdl_imageUUID("libSystem", false); + const uint8_t *uuidBytes = ksdl_imageUUID("libSystem", false); XCTAssertTrue(uuidBytes != NULL, @""); } -- (void) testGetImageNameNULL +- (void)testGetImageNameNULL { uint32_t imageIdx = ksdl_imageNamed(NULL, false); XCTAssertEqual(imageIdx, UINT32_MAX, @""); } - @end diff --git a/Tests/KSCrashRecordingCoreTests/KSFileUtils_Tests.m b/Tests/KSCrashRecordingCoreTests/KSFileUtils_Tests.m index 517a87430..472476cde 100644 --- a/Tests/KSCrashRecordingCoreTests/KSFileUtils_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSFileUtils_Tests.m @@ -24,30 +24,28 @@ // THE SOFTWARE. // - -#import "FileBasedTestCase.h" -#include #include +#include +#import "FileBasedTestCase.h" #import "KSFileUtils.h" - -@interface KSFileUtils_Tests : FileBasedTestCase @end - +@interface KSFileUtils_Tests : FileBasedTestCase +@end @implementation KSFileUtils_Tests -- (void) testReadBuffered_EmptyFile +- (void)testReadBuffered_EmptyFile { int readBufferSize = 10; int dstBufferSize = 5; int readSize = 5; int expectedBytesRead = 0; - NSString* fileContents = @""; - NSString* expectedDataRead = @""; + NSString *fileContents = @""; + NSString *expectedDataRead = @""; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; int bytesRead = ksfu_readBufferedReader(&reader, dstBuffer, readSize); @@ -57,17 +55,17 @@ - (void) testReadBuffered_EmptyFile ksfu_closeBufferedReader(&reader); } -- (void) testReadBuffered_SameSize +- (void)testReadBuffered_SameSize { int readBufferSize = 10; int dstBufferSize = 5; int readSize = 5; int expectedBytesRead = 5; - NSString* fileContents = @"12345"; - NSString* expectedDataRead = @"12345"; + NSString *fileContents = @"12345"; + NSString *expectedDataRead = @"12345"; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; int bytesRead = ksfu_readBufferedReader(&reader, dstBuffer, readSize); @@ -77,17 +75,17 @@ - (void) testReadBuffered_SameSize ksfu_closeBufferedReader(&reader); } -- (void) testReadBuffered_FileIsBigger +- (void)testReadBuffered_FileIsBigger { int readBufferSize = 10; int dstBufferSize = 5; int readSize = 5; int expectedBytesRead = 5; - NSString* fileContents = @"123456789"; - NSString* expectedDataRead = @"12345"; + NSString *fileContents = @"123456789"; + NSString *expectedDataRead = @"12345"; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; int bytesRead = ksfu_readBufferedReader(&reader, dstBuffer, readSize); @@ -97,17 +95,17 @@ - (void) testReadBuffered_FileIsBigger ksfu_closeBufferedReader(&reader); } -- (void) testReadBuffered_ReadBufferIsSmaller +- (void)testReadBuffered_ReadBufferIsSmaller { int readBufferSize = 3; int dstBufferSize = 5; int readSize = 5; int expectedBytesRead = 5; - NSString* fileContents = @"12345"; - NSString* expectedDataRead = @"12345"; + NSString *fileContents = @"12345"; + NSString *expectedDataRead = @"12345"; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; int bytesRead = ksfu_readBufferedReader(&reader, dstBuffer, readSize); @@ -117,17 +115,17 @@ - (void) testReadBuffered_ReadBufferIsSmaller ksfu_closeBufferedReader(&reader); } -- (void) testReadBuffered_ReadBufferIsMuchSmaller +- (void)testReadBuffered_ReadBufferIsMuchSmaller { int readBufferSize = 3; int dstBufferSize = 16; int readSize = 16; int expectedBytesRead = 16; - NSString* fileContents = @"1234567890abcdef"; - NSString* expectedDataRead = @"1234567890abcdef"; + NSString *fileContents = @"1234567890abcdef"; + NSString *expectedDataRead = @"1234567890abcdef"; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; int bytesRead = ksfu_readBufferedReader(&reader, dstBuffer, readSize); @@ -137,18 +135,18 @@ - (void) testReadBuffered_ReadBufferIsMuchSmaller ksfu_closeBufferedReader(&reader); } -- (void) testReadBufferedUntilChar_Halfway +- (void)testReadBufferedUntilChar_Halfway { int readBufferSize = 10; int dstBufferSize = 5; - NSString* fileContents = @"12345"; + NSString *fileContents = @"12345"; int ch = '3'; - NSString* expectedDataRead = @"123"; + NSString *expectedDataRead = @"123"; int expectedBytesRead = (int)expectedDataRead.length; int bytesRead = dstBufferSize; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; bool result = ksfu_readBufferedReaderUntilChar(&reader, ch, dstBuffer, &bytesRead); @@ -159,18 +157,18 @@ - (void) testReadBufferedUntilChar_Halfway ksfu_closeBufferedReader(&reader); } -- (void) testReadBufferedUntilChar_Beginning +- (void)testReadBufferedUntilChar_Beginning { int readBufferSize = 10; int dstBufferSize = 5; - NSString* fileContents = @"12345"; + NSString *fileContents = @"12345"; int ch = '1'; - NSString* expectedDataRead = @"1"; + NSString *expectedDataRead = @"1"; int expectedBytesRead = (int)expectedDataRead.length; int bytesRead = dstBufferSize; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; bool result = ksfu_readBufferedReaderUntilChar(&reader, ch, dstBuffer, &bytesRead); @@ -181,18 +179,18 @@ - (void) testReadBufferedUntilChar_Beginning ksfu_closeBufferedReader(&reader); } -- (void) testReadBufferedUntilChar_End +- (void)testReadBufferedUntilChar_End { int readBufferSize = 10; int dstBufferSize = 5; - NSString* fileContents = @"12345"; + NSString *fileContents = @"12345"; int ch = '5'; - NSString* expectedDataRead = @"12345"; + NSString *expectedDataRead = @"12345"; int expectedBytesRead = (int)expectedDataRead.length; int bytesRead = dstBufferSize; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; bool result = ksfu_readBufferedReaderUntilChar(&reader, ch, dstBuffer, &bytesRead); @@ -203,18 +201,18 @@ - (void) testReadBufferedUntilChar_End ksfu_closeBufferedReader(&reader); } -- (void) testReadBufferedUntilChar_SmallDstBuffer +- (void)testReadBufferedUntilChar_SmallDstBuffer { int readBufferSize = 10; int dstBufferSize = 3; - NSString* fileContents = @"12345"; + NSString *fileContents = @"12345"; int ch = '5'; - NSString* expectedDataRead = @"123"; + NSString *expectedDataRead = @"123"; int expectedBytesRead = (int)expectedDataRead.length; int bytesRead = dstBufferSize; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; bool result = ksfu_readBufferedReaderUntilChar(&reader, ch, dstBuffer, &bytesRead); @@ -225,18 +223,18 @@ - (void) testReadBufferedUntilChar_SmallDstBuffer ksfu_closeBufferedReader(&reader); } -- (void) testReadBufferedUntilChar_SmallReadBuffer +- (void)testReadBufferedUntilChar_SmallReadBuffer { int readBufferSize = 4; int dstBufferSize = 10; - NSString* fileContents = @"1234567890"; + NSString *fileContents = @"1234567890"; int ch = '9'; - NSString* expectedDataRead = @"123456789"; + NSString *expectedDataRead = @"123456789"; int expectedBytesRead = (int)expectedDataRead.length; int bytesRead = dstBufferSize; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; bool result = ksfu_readBufferedReaderUntilChar(&reader, ch, dstBuffer, &bytesRead); @@ -247,18 +245,18 @@ - (void) testReadBufferedUntilChar_SmallReadBuffer ksfu_closeBufferedReader(&reader); } -- (void) testReadBufferedUntilChar_NotFound +- (void)testReadBufferedUntilChar_NotFound { int readBufferSize = 3; int dstBufferSize = 8; - NSString* fileContents = @"12345"; + NSString *fileContents = @"12345"; int ch = '9'; - NSString* expectedDataRead = @"12345"; + NSString *expectedDataRead = @"12345"; int expectedBytesRead = (int)expectedDataRead.length; int bytesRead = dstBufferSize; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; bool result = ksfu_readBufferedReaderUntilChar(&reader, ch, dstBuffer, &bytesRead); @@ -269,18 +267,18 @@ - (void) testReadBufferedUntilChar_NotFound ksfu_closeBufferedReader(&reader); } -- (void) testReadBufferedUntilChar_NotFound_LargeFile +- (void)testReadBufferedUntilChar_NotFound_LargeFile { int readBufferSize = 4; int dstBufferSize = 8; - NSString* fileContents = @"1234567890"; + NSString *fileContents = @"1234567890"; int ch = 'a'; - NSString* expectedDataRead = @"12345678"; + NSString *expectedDataRead = @"12345678"; int expectedBytesRead = (int)expectedDataRead.length; int bytesRead = dstBufferSize; char readBuffer[readBufferSize]; KSBufferedReader reader; - NSString* path = [self generateFileWithString:fileContents]; + NSString *path = [self generateFileWithString:fileContents]; XCTAssertTrue(ksfu_openBufferedReader(&reader, path.UTF8String, readBuffer, readBufferSize)); char dstBuffer[dstBufferSize + 1]; bool result = ksfu_readBufferedReaderUntilChar(&reader, ch, dstBuffer, &bytesRead); @@ -291,108 +289,107 @@ - (void) testReadBufferedUntilChar_NotFound_LargeFile ksfu_closeBufferedReader(&reader); } -- (void) testWriteBuffered +- (void)testWriteBuffered { int writeBufferSize = 5; int writeSize = 5; - NSString* fileContents = @"12345"; + NSString *fileContents = @"12345"; char writeBuffer[writeBufferSize]; KSBufferedWriter writer; - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; XCTAssertTrue(ksfu_openBufferedWriter(&writer, path.UTF8String, writeBuffer, writeBufferSize)); XCTAssertTrue(ksfu_writeBufferedWriter(&writer, fileContents.UTF8String, writeSize)); ksfu_closeBufferedWriter(&writer); - NSError* error = nil; - NSString* actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error); XCTAssertEqualObjects(actualFileContents, fileContents); } -- (void) testWriteBuffered_Flush +- (void)testWriteBuffered_Flush { int writeBufferSize = 5; int writeSize = 5; - NSString* fileContents = @"12345"; + NSString *fileContents = @"12345"; char writeBuffer[writeBufferSize]; KSBufferedWriter writer; - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; XCTAssertTrue(ksfu_openBufferedWriter(&writer, path.UTF8String, writeBuffer, writeBufferSize)); XCTAssertTrue(ksfu_writeBufferedWriter(&writer, fileContents.UTF8String, writeSize)); ksfu_flushBufferedWriter(&writer); - NSError* error = nil; - NSString* actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error); XCTAssertEqualObjects(actualFileContents, fileContents); ksfu_closeBufferedWriter(&writer); } -- (void) testWriteBuffered_BufferIsSmaller +- (void)testWriteBuffered_BufferIsSmaller { int writeBufferSize = 4; int writeSize = 10; - NSString* fileContents = @"1234567890"; + NSString *fileContents = @"1234567890"; char writeBuffer[writeBufferSize]; KSBufferedWriter writer; - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; XCTAssertTrue(ksfu_openBufferedWriter(&writer, path.UTF8String, writeBuffer, writeBufferSize)); XCTAssertTrue(ksfu_writeBufferedWriter(&writer, fileContents.UTF8String, writeSize)); ksfu_closeBufferedWriter(&writer); - NSError* error = nil; - NSString* actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error); XCTAssertEqualObjects(actualFileContents, fileContents); } -- (void) testWriteBuffered_DataIsSmaller +- (void)testWriteBuffered_DataIsSmaller { int writeBufferSize = 10; int writeSize = 3; - NSString* fileContents = @"123"; + NSString *fileContents = @"123"; char writeBuffer[writeBufferSize]; KSBufferedWriter writer; - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; XCTAssertTrue(ksfu_openBufferedWriter(&writer, path.UTF8String, writeBuffer, writeBufferSize)); XCTAssertTrue(ksfu_writeBufferedWriter(&writer, fileContents.UTF8String, writeSize)); ksfu_closeBufferedWriter(&writer); - NSError* error = nil; - NSString* actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error); XCTAssertEqualObjects(actualFileContents, fileContents); } -- (void) testLastPathEntry +- (void)testLastPathEntry { - NSString* path = @"some/kind/of/path"; - NSString* expected = @"path"; - NSString* actual = [NSString stringWithCString:ksfu_lastPathEntry([path cStringUsingEncoding:NSUTF8StringEncoding]) + NSString *path = @"some/kind/of/path"; + NSString *expected = @"path"; + NSString *actual = [NSString stringWithCString:ksfu_lastPathEntry([path cStringUsingEncoding:NSUTF8StringEncoding]) encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected, @""); } -- (void) testWriteBytesToFD +- (void)testWriteBytesToFD { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; - NSString* expected = @"testing a bunch of stuff.\nOh look, a newline!"; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSString *expected = @"testing a bunch of stuff.\nOh look, a newline!"; int stringLength = (int)[expected length]; int fd = open([path UTF8String], O_RDWR | O_CREAT | O_EXCL, 0644); XCTAssertTrue(fd >= 0, @""); bool result = ksfu_writeBytesToFD(fd, [expected cStringUsingEncoding:NSUTF8StringEncoding], stringLength); XCTAssertTrue(result, @""); - NSString* actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSString *actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (void) testWriteBytesToFDBig +- (void)testWriteBytesToFDBig { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; int length = 1000000; - NSMutableData* expected = [NSMutableData dataWithCapacity:(NSUInteger)length]; - for(int i = 0; i < length; i++) - { + NSMutableData *expected = [NSMutableData dataWithCapacity:(NSUInteger)length]; + for (int i = 0; i < length; i++) { unsigned char byte = (unsigned char)i; [expected appendBytes:&byte length:1]; } @@ -401,38 +398,37 @@ - (void) testWriteBytesToFDBig XCTAssertTrue(fd >= 0, @""); bool result = ksfu_writeBytesToFD(fd, [expected bytes], length); XCTAssertTrue(result, @""); - NSMutableData* actual = [NSMutableData dataWithContentsOfFile:path options:0 error:&error]; + NSMutableData *actual = [NSMutableData dataWithContentsOfFile:path options:0 error:&error]; XCTAssertNil(error, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (void) testReadBytesFromFD +- (void)testReadBytesFromFD { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; - NSString* expected = @"testing a bunch of stuff.\nOh look, a newline!"; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSString *expected = @"testing a bunch of stuff.\nOh look, a newline!"; int stringLength = (int)[expected length]; [expected writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); int fd = open([path UTF8String], O_RDONLY); XCTAssertTrue(fd >= 0, @""); - NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)stringLength]; + NSMutableData *data = [NSMutableData dataWithLength:(NSUInteger)stringLength]; bool result = ksfu_readBytesFromFD(fd, [data mutableBytes], stringLength); XCTAssertTrue(result, @""); - NSString* actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSString *actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; XCTAssertNil(error, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (void) testReadBytesFromFDBig +- (void)testReadBytesFromFDBig { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; int length = 1000000; - NSMutableData* expected = [NSMutableData dataWithCapacity:(NSUInteger)length]; - for(int i = 0; i < length; i++) - { + NSMutableData *expected = [NSMutableData dataWithCapacity:(NSUInteger)length]; + for (int i = 0; i < length; i++) { unsigned char byte = (unsigned char)i; [expected appendBytes:&byte length:1]; } @@ -441,40 +437,39 @@ - (void) testReadBytesFromFDBig int fd = open([path UTF8String], O_RDONLY); XCTAssertTrue(fd >= 0, @""); - NSMutableData* actual = [NSMutableData dataWithLength:(NSUInteger)length]; + NSMutableData *actual = [NSMutableData dataWithLength:(NSUInteger)length]; bool result = ksfu_readBytesFromFD(fd, [actual mutableBytes], length); XCTAssertTrue(result, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (void) testReadEntireFile +- (void)testReadEntireFile { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; - NSString* expected = @"testing a bunch of stuff.\nOh look, a newline!"; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSString *expected = @"testing a bunch of stuff.\nOh look, a newline!"; [expected writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); int fd = open([path UTF8String], O_RDONLY); XCTAssertTrue(fd >= 0, @""); - char* bytes; + char *bytes; int readLength; bool result = ksfu_readEntireFile([path UTF8String], &bytes, &readLength, 0); XCTAssertTrue(result, @""); - NSMutableData* data = [NSMutableData dataWithBytesNoCopy:bytes length:(unsigned)readLength freeWhenDone:YES]; - NSString* actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSMutableData *data = [NSMutableData dataWithBytesNoCopy:bytes length:(unsigned)readLength freeWhenDone:YES]; + NSString *actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; XCTAssertNil(error, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (void) testReadEntireFileBig +- (void)testReadEntireFileBig { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; int length = 1000000; - NSMutableData* expected = [NSMutableData dataWithCapacity:(NSUInteger)length]; - for(int i = 0; i < length; i++) - { + NSMutableData *expected = [NSMutableData dataWithCapacity:(NSUInteger)length]; + for (int i = 0; i < length; i++) { unsigned char byte = (unsigned char)i; [expected appendBytes:&byte length:1]; } @@ -483,45 +478,45 @@ - (void) testReadEntireFileBig int fd = open([path UTF8String], O_RDONLY); XCTAssertTrue(fd >= 0, @""); - char* bytes; + char *bytes; int readLength; bool result = ksfu_readEntireFile([path UTF8String], &bytes, &readLength, 0); XCTAssertTrue(result, @""); - NSMutableData* actual = [NSMutableData dataWithBytesNoCopy:bytes length:(unsigned)readLength freeWhenDone:YES]; + NSMutableData *actual = [NSMutableData dataWithBytesNoCopy:bytes length:(unsigned)readLength freeWhenDone:YES]; XCTAssertEqualObjects(actual, expected, @""); } -- (void) testWriteStringToFD +- (void)testWriteStringToFD { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; - NSString* expected = @"testing a bunch of stuff.\nOh look, a newline!"; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSString *expected = @"testing a bunch of stuff.\nOh look, a newline!"; int fd = open([path UTF8String], O_RDWR | O_CREAT | O_EXCL, 0644); XCTAssertTrue(fd >= 0, @""); bool result = ksfu_writeStringToFD(fd, [expected cStringUsingEncoding:NSUTF8StringEncoding]); XCTAssertTrue(result, @""); - NSString* actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSString *actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (void) testWriteFmtToFD +- (void)testWriteFmtToFD { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; - NSString* expected = @"test test testing 1 2.0 3"; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSString *expected = @"test test testing 1 2.0 3"; int fd = open([path UTF8String], O_RDWR | O_CREAT | O_EXCL, 0644); XCTAssertTrue(fd >= 0, @""); bool result = ksfu_writeFmtToFD(fd, "test test testing %d %.1f %s", 1, 2.0f, "3"); XCTAssertTrue(result, @""); - NSString* actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSString *actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (bool) writeToFD:(int) fd fmt:(char*) fmt, ... +- (bool)writeToFD:(int)fd fmt:(char *)fmt, ... { va_list args; va_start(args, fmt); @@ -530,72 +525,66 @@ - (bool) writeToFD:(int) fd fmt:(char*) fmt, ... return result; } -- (void) testWriteFmtArgsToFD +- (void)testWriteFmtArgsToFD { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; - NSString* expected = @"test test testing 1 2.0 3"; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSString *expected = @"test test testing 1 2.0 3"; int fd = open([path UTF8String], O_RDWR | O_CREAT | O_EXCL, 0644); XCTAssertTrue(fd >= 0, @""); - bool result = [self writeToFD:fd fmt: "test test testing %d %.1f %s", 1, 2.0f, "3"]; + bool result = [self writeToFD:fd fmt:"test test testing %d %.1f %s", 1, 2.0f, "3"]; XCTAssertTrue(result, @""); - NSString* actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSString *actual = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); XCTAssertEqualObjects(actual, expected, @""); } -- (void) testReadLineFromFD +- (void)testReadLineFromFD { - NSError* error = nil; - NSString* path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; - NSString* source = @"line 1\nline 2\nline 3"; - NSString* expected1 = @"line 1"; - NSString* expected2 = @"line 2"; - NSString* expected3 = @"line 3"; + NSError *error = nil; + NSString *path = [self.tempPath stringByAppendingPathComponent:@"test.txt"]; + NSString *source = @"line 1\nline 2\nline 3"; + NSString *expected1 = @"line 1"; + NSString *expected2 = @"line 2"; + NSString *expected3 = @"line 3"; [source writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); int fd = open([path UTF8String], O_RDONLY); XCTAssertTrue(fd >= 0, @""); - NSMutableData* data = [NSMutableData dataWithLength:100]; + NSMutableData *data = [NSMutableData dataWithLength:100]; int bytesRead; - NSString* actual; + NSString *actual; bytesRead = ksfu_readLineFromFD(fd, [data mutableBytes], 100); XCTAssertTrue(bytesRead > 0, @""); - actual = [[NSString alloc] initWithBytes:[data bytes] - length:(NSUInteger)bytesRead - encoding:NSUTF8StringEncoding]; + actual = [[NSString alloc] initWithBytes:[data bytes] length:(NSUInteger)bytesRead encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected1, @""); bytesRead = ksfu_readLineFromFD(fd, [data mutableBytes], 100); XCTAssertTrue(bytesRead > 0, @""); - actual = [[NSString alloc] initWithBytes:[data bytes] - length:(NSUInteger)bytesRead - encoding:NSUTF8StringEncoding]; + actual = [[NSString alloc] initWithBytes:[data bytes] length:(NSUInteger)bytesRead encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected2, @""); bytesRead = ksfu_readLineFromFD(fd, [data mutableBytes], 100); XCTAssertTrue(bytesRead > 0, @""); - actual = [[NSString alloc] initWithBytes:[data bytes] - length:(NSUInteger)bytesRead - encoding:NSUTF8StringEncoding]; + actual = [[NSString alloc] initWithBytes:[data bytes] length:(NSUInteger)bytesRead encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected3, @""); bytesRead = ksfu_readLineFromFD(fd, [data mutableBytes], 100); XCTAssertTrue(bytesRead == 0, @""); } -- (void) testWriteBuffered_OrderOfEntries +- (void)testWriteBuffered_OrderOfEntries { int writeBufferSize = 10; - NSString* logEntry1 = @"Log1"; - NSString* logEntry2 = @"Log2"; - NSString* logEntry3 = @"Log3"; + NSString *logEntry1 = @"Log1"; + NSString *logEntry2 = @"Log2"; + NSString *logEntry3 = @"Log3"; char writeBuffer[writeBufferSize]; KSBufferedWriter writer; - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; XCTAssertTrue(ksfu_openBufferedWriter(&writer, path.UTF8String, writeBuffer, writeBufferSize)); XCTAssertTrue(ksfu_writeBufferedWriter(&writer, logEntry1.UTF8String, (int)logEntry1.length)); @@ -603,22 +592,22 @@ - (void) testWriteBuffered_OrderOfEntries XCTAssertTrue(ksfu_writeBufferedWriter(&writer, logEntry3.UTF8String, (int)logEntry3.length)); ksfu_closeBufferedWriter(&writer); - NSError* error = nil; - NSString* actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error); - NSString* expectedContents = @"Log1Log2Log3"; + NSString *expectedContents = @"Log1Log2Log3"; XCTAssertEqualObjects(actualFileContents, expectedContents); } -- (void) testWriteBuffered_OrderWithLargeData +- (void)testWriteBuffered_OrderWithLargeData { int writeBufferSize = 10; - NSString* logEntry1 = @"Small1"; - NSString* logEntry2 = @"ThisIsLargeData"; - NSString* logEntry3 = @"Small3"; + NSString *logEntry1 = @"Small1"; + NSString *logEntry2 = @"ThisIsLargeData"; + NSString *logEntry3 = @"Small3"; char writeBuffer[writeBufferSize]; KSBufferedWriter writer; - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; XCTAssertTrue(ksfu_openBufferedWriter(&writer, path.UTF8String, writeBuffer, writeBufferSize)); XCTAssertTrue(ksfu_writeBufferedWriter(&writer, logEntry1.UTF8String, (int)logEntry1.length)); @@ -626,23 +615,23 @@ - (void) testWriteBuffered_OrderWithLargeData XCTAssertTrue(ksfu_writeBufferedWriter(&writer, logEntry3.UTF8String, (int)logEntry3.length)); ksfu_closeBufferedWriter(&writer); - NSError* error = nil; - NSString* actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error); - NSString* expectedContents = @"Small1ThisIsLargeDataSmall3"; + NSString *expectedContents = @"Small1ThisIsLargeDataSmall3"; XCTAssertEqualObjects(actualFileContents, expectedContents); } -- (void) testWriteBuffered_FlushAndLargeWriteOrder +- (void)testWriteBuffered_FlushAndLargeWriteOrder { int writeBufferSize = 10; - NSString* logEntry1 = @"Buffer1"; - NSString* logEntry2 = @"Buffer2"; - NSString* largeEntry = @"ThisIsLargeDataThatExceedsBufferSize"; - NSString* logEntry3 = @"EndData"; + NSString *logEntry1 = @"Buffer1"; + NSString *logEntry2 = @"Buffer2"; + NSString *largeEntry = @"ThisIsLargeDataThatExceedsBufferSize"; + NSString *logEntry3 = @"EndData"; char writeBuffer[writeBufferSize]; KSBufferedWriter writer; - NSString* path = [self generateTempFilePath]; + NSString *path = [self generateTempFilePath]; XCTAssertTrue(ksfu_openBufferedWriter(&writer, path.UTF8String, writeBuffer, writeBufferSize)); XCTAssertTrue(ksfu_writeBufferedWriter(&writer, logEntry1.UTF8String, (int)logEntry1.length)); @@ -652,10 +641,10 @@ - (void) testWriteBuffered_FlushAndLargeWriteOrder XCTAssertTrue(ksfu_writeBufferedWriter(&writer, logEntry3.UTF8String, (int)logEntry3.length)); ksfu_closeBufferedWriter(&writer); - NSError* error = nil; - NSString* actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *actualFileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error); - NSString* expectedContents = @"Buffer1Buffer2ThisIsLargeDataThatExceedsBufferSizeEndData"; + NSString *expectedContents = @"Buffer1Buffer2ThisIsLargeDataThatExceedsBufferSizeEndData"; XCTAssertEqualObjects(actualFileContents, expectedContents); } diff --git a/Tests/KSCrashRecordingCoreTests/KSJSONCodec_Tests.m b/Tests/KSCrashRecordingCoreTests/KSJSONCodec_Tests.m index 0892c0ff6..0a723542d 100644 --- a/Tests/KSCrashRecordingCoreTests/KSJSONCodec_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSJSONCodec_Tests.m @@ -24,32 +24,28 @@ // THE SOFTWARE. // - #import #import "FileBasedTestCase.h" -#import "KSJSONCodecObjC.h" #import "KSJSONCodec.h" +#import "KSJSONCodecObjC.h" - -@interface KSJSONCodec_Tests : FileBasedTestCase @end - +@interface KSJSONCodec_Tests : FileBasedTestCase +@end @implementation KSJSONCodec_Tests -static NSData* toData(NSString* string) +static NSData *toData(NSString *string) { - if(string == nil) - { + if (string == nil) { return nil; } return [string dataUsingEncoding:NSUTF8StringEncoding]; } -static NSString* toString(NSData* data) +static NSString *toString(NSData *data) { - if(data == nil) - { + if (data == nil) { return nil; } return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; @@ -57,12 +53,10 @@ @implementation KSJSONCodec_Tests - (void)testSerializeDeserializeArrayEmpty { - NSError* error = (NSError*)self; - NSString* expected = @"[]"; + NSError *error = (NSError *)self; + NSString *expected = @"[]"; id original = [NSArray array]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -72,16 +66,12 @@ - (void)testSerializeDeserializeArrayEmpty XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeArrayNull +- (void)testSerializeDeserializeArrayNull { - NSError* error = (NSError*)self; - NSString* expected = @"[null]"; - id original = [NSArray arrayWithObjects: - [NSNull null], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[null]"; + id original = [NSArray arrayWithObjects:[NSNull null], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -91,16 +81,12 @@ - (void) testSerializeDeserializeArrayNull XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeArrayBoolTrue +- (void)testSerializeDeserializeArrayBoolTrue { - NSError* error = (NSError*)self; - NSString* expected = @"[true]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithBool:YES], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[true]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithBool:YES], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -110,16 +96,12 @@ - (void) testSerializeDeserializeArrayBoolTrue XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeArrayBoolFalse +- (void)testSerializeDeserializeArrayBoolFalse { - NSError* error = (NSError*)self; - NSString* expected = @"[false]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithBool:NO], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[false]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithBool:NO], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -129,16 +111,12 @@ - (void) testSerializeDeserializeArrayBoolFalse XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeArrayInteger +- (void)testSerializeDeserializeArrayInteger { - NSError* error = (NSError*)self; - NSString* expected = @"[1]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithInt:1], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[1]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -148,16 +126,12 @@ - (void) testSerializeDeserializeArrayInteger XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeArrayFloat +- (void)testSerializeDeserializeArrayFloat { - NSError* error = (NSError*)self; - NSString* expected = @"[-0.2]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithFloat:-0.2f], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[-0.2]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithFloat:-0.2f], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -166,19 +140,15 @@ - (void) testSerializeDeserializeArrayFloat XCTAssertNil(error, @""); XCTAssertEqual([[result objectAtIndex:0] floatValue], -0.2f, @""); // This always fails on NSNumber filled with float. - //XCTAssertEqualObjects(result, original, @""); + // XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeArrayFloat2 +- (void)testSerializeDeserializeArrayFloat2 { - NSError* error = (NSError*)self; - NSString* expected = @"[-2e-15]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithFloat:-2e-15f], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[-2e-15]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithFloat:-2e-15f], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -187,19 +157,15 @@ - (void) testSerializeDeserializeArrayFloat2 XCTAssertNil(error, @""); XCTAssertEqual([[result objectAtIndex:0] floatValue], -2e-15f, @""); // This always fails on NSNumber filled with float. - //XCTAssertEqualObjects(result, original, @""); + // XCTAssertEqualObjects(result, original, @""); } - (void)testSerializeDeserializeArrayString { - NSError* error = (NSError*)self; - NSString* expected = @"[\"One\"]"; - id original = [NSArray arrayWithObjects: - @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[\"One\"]"; + id original = [NSArray arrayWithObjects:@"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -211,14 +177,10 @@ - (void)testSerializeDeserializeArrayString - (void)testSerializeDeserializeArrayStringIntl { - NSError* error = (NSError*)self; - NSString* expected = @"[\"テスト\"]"; - id original = [NSArray arrayWithObjects: - @"テスト", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[\"テスト\"]"; + id original = [NSArray arrayWithObjects:@"テスト", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -230,16 +192,10 @@ - (void)testSerializeDeserializeArrayStringIntl - (void)testSerializeDeserializeArrayMultipleEntries { - NSError* error = (NSError*)self; - NSString* expected = @"[\"One\",1000,true]"; - id original = [NSArray arrayWithObjects: - @"One", - [NSNumber numberWithInt:1000], - [NSNumber numberWithBool:YES], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[\"One\",1000,true]"; + id original = [NSArray arrayWithObjects:@"One", [NSNumber numberWithInt:1000], [NSNumber numberWithBool:YES], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -251,14 +207,10 @@ - (void)testSerializeDeserializeArrayMultipleEntries - (void)testSerializeDeserializeArrayWithArray { - NSError* error = (NSError*)self; - NSString* expected = @"[[]]"; - id original = [NSArray arrayWithObjects: - [NSArray array], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[[]]"; + id original = [NSArray arrayWithObjects:[NSArray array], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -270,14 +222,10 @@ - (void)testSerializeDeserializeArrayWithArray - (void)testSerializeDeserializeArrayWithArray2 { - NSError* error = (NSError*)self; - NSString* expected = @"[[\"Blah\"]]"; - id original = [NSArray arrayWithObjects: - [NSArray arrayWithObjects:@"Blah", nil], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[[\"Blah\"]]"; + id original = [NSArray arrayWithObjects:[NSArray arrayWithObjects:@"Blah", nil], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -289,14 +237,10 @@ - (void)testSerializeDeserializeArrayWithArray2 - (void)testSerializeDeserializeArrayWithDictionary { - NSError* error = (NSError*)self; - NSString* expected = @"[{}]"; - id original = [NSArray arrayWithObjects: - [NSDictionary dictionary], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[{}]"; + id original = [NSArray arrayWithObjects:[NSDictionary dictionary], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -308,16 +252,11 @@ - (void)testSerializeDeserializeArrayWithDictionary - (void)testSerializeDeserializeArrayWithDictionary2 { - NSError* error = (NSError*)self; - NSString* expected = @"[{\"Blah\":true}]"; - id original = [NSArray arrayWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], @"Blah", - nil], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[{\"Blah\":true}]"; + id original = [NSArray + arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"Blah", nil], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -327,15 +266,12 @@ - (void)testSerializeDeserializeArrayWithDictionary2 XCTAssertEqualObjects(result, original, @""); } - - (void)testSerializeDeserializeDictionaryEmpty { - NSError* error = (NSError*)self; - NSString* expected = @"{}"; + NSError *error = (NSError *)self; + NSString *expected = @"{}"; id original = [NSDictionary dictionary]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -345,16 +281,12 @@ - (void)testSerializeDeserializeDictionaryEmpty XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeDictionaryNull +- (void)testSerializeDeserializeDictionaryNull { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":null}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNull null], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":null}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSNull null], @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -364,16 +296,12 @@ - (void) testSerializeDeserializeDictionaryNull XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeDictionaryBoolTrue +- (void)testSerializeDeserializeDictionaryBoolTrue { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":true}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":true}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -383,16 +311,12 @@ - (void) testSerializeDeserializeDictionaryBoolTrue XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeDictionaryBoolFalse +- (void)testSerializeDeserializeDictionaryBoolFalse { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":false}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:NO], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":false}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -402,16 +326,12 @@ - (void) testSerializeDeserializeDictionaryBoolFalse XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeDictionaryInteger +- (void)testSerializeDeserializeDictionaryInteger { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":1}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:1], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":1}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -421,58 +341,46 @@ - (void) testSerializeDeserializeDictionaryInteger XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeDictionaryFloat +- (void)testSerializeDeserializeDictionaryFloat { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":54.918}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithFloat:54.918f], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":54.918}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:54.918f], @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - XCTAssertEqual([[(NSDictionary*)result objectForKey:@"One"] floatValue], 54.918f, @""); + XCTAssertEqual([[(NSDictionary *)result objectForKey:@"One"] floatValue], 54.918f, @""); // This always fails on NSNumber filled with float. - //XCTAssertEqualObjects(result, original, @""); + // XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeDictionaryFloat2 +- (void)testSerializeDeserializeDictionaryFloat2 { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":5e+20}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithFloat:5e20f], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":5e+20}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:5e20f], @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - XCTAssertEqual([[(NSDictionary*)result objectForKey:@"One"] floatValue], 5e20f, @""); + XCTAssertEqual([[(NSDictionary *)result objectForKey:@"One"] floatValue], 5e20f, @""); // This always fails on NSNumber filled with float. - //XCTAssertEqualObjects(result, original, @""); + // XCTAssertEqualObjects(result, original, @""); } - (void)testSerializeDeserializeDictionaryString { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":\"Value\"}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - @"Value", @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":\"Value\"}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:@"Value", @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -484,16 +392,11 @@ - (void)testSerializeDeserializeDictionaryString - (void)testSerializeDeserializeDictionaryMultipleEntries { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":\"Value\",\"Three\":true,\"Two\":1000}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - @"Value", @"One", - [NSNumber numberWithInt:1000], @"Two", - [NSNumber numberWithBool:YES], @"Three", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":\"Value\",\"Three\":true,\"Two\":1000}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:@"Value", @"One", [NSNumber numberWithInt:1000], @"Two", + [NSNumber numberWithBool:YES], @"Three", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -505,14 +408,10 @@ - (void)testSerializeDeserializeDictionaryMultipleEntries - (void)testSerializeDeserializeDictionaryWithDictionary { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":{}}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionary], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":{}}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSDictionary dictionary], @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -524,16 +423,13 @@ - (void)testSerializeDeserializeDictionaryWithDictionary - (void)testSerializeDeserializeDictionaryWithDictionary2 { - NSError* error = (NSError*)self; - NSString* expected = @"{\"One\":{\"Blah\":1}}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:1], @"Blah", - nil], @"One", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"One\":{\"Blah\":1}}"; + id original = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1], @"Blah", nil], + @"One", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -545,14 +441,10 @@ - (void)testSerializeDeserializeDictionaryWithDictionary2 - (void)testSerializeDeserializeDictionaryWithArray { - NSError* error = (NSError*)self; - NSString* expected = @"{\"Key\":[]}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray array], @"Key", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"Key\":[]}"; + id original = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray array], @"Key", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -564,14 +456,11 @@ - (void)testSerializeDeserializeDictionaryWithArray - (void)testSerializeDeserializeDictionaryWithArray2 { - NSError* error = (NSError*)self; - NSString* expected = @"{\"Blah\":[true]}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObject:[NSNumber numberWithBool:YES]], @"Blah", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"Blah\":[true]}"; + id original = [NSDictionary + dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:[NSNumber numberWithBool:YES]], @"Blah", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -583,72 +472,19 @@ - (void)testSerializeDeserializeDictionaryWithArray2 - (void)testSerializeDeserializeBigDictionary { - NSError* error = (NSError*)self; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - @"0", @"0", - @"1", @"1", - @"2", @"2", - @"3", @"3", - @"4", @"4", - @"5", @"5", - @"6", @"6", - @"7", @"7", - @"8", @"8", - @"9", @"9", - @"10", @"10", - @"11", @"11", - @"12", @"12", - @"13", @"13", - @"14", @"14", - @"15", @"15", - @"16", @"16", - @"17", @"17", - @"18", @"18", - @"19", @"19", - @"20", @"20", - @"21", @"21", - @"22", @"22", - @"23", @"23", - @"24", @"24", - @"25", @"25", - @"26", @"26", - @"27", @"27", - @"28", @"28", - @"29", @"29", - @"30", @"30", - @"31", @"31", - @"32", @"32", - @"33", @"33", - @"34", @"34", - @"35", @"35", - @"36", @"36", - @"37", @"37", - @"38", @"38", - @"39", @"39", - @"40", @"40", - @"41", @"41", - @"42", @"42", - @"43", @"43", - @"44", @"44", - @"45", @"45", - @"46", @"46", - @"47", @"47", - @"48", @"48", - @"49", @"49", - @"50", @"50", - @"51", @"51", - @"52", @"52", - @"53", @"53", - @"54", @"54", - @"55", @"55", - @"56", @"56", - @"57", @"57", - @"58", @"58", - @"59", @"59", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + id original = [NSDictionary + dictionaryWithObjectsAndKeys:@"0", @"0", @"1", @"1", @"2", @"2", @"3", @"3", @"4", @"4", @"5", @"5", @"6", @"6", + @"7", @"7", @"8", @"8", @"9", @"9", @"10", @"10", @"11", @"11", @"12", @"12", + @"13", @"13", @"14", @"14", @"15", @"15", @"16", @"16", @"17", @"17", @"18", @"18", + @"19", @"19", @"20", @"20", @"21", @"21", @"22", @"22", @"23", @"23", @"24", @"24", + @"25", @"25", @"26", @"26", @"27", @"27", @"28", @"28", @"29", @"29", @"30", @"30", + @"31", @"31", @"32", @"32", @"33", @"33", @"34", @"34", @"35", @"35", @"36", @"36", + @"37", @"37", @"38", @"38", @"39", @"39", @"40", @"40", @"41", @"41", @"42", @"42", + @"43", @"43", @"44", @"44", @"45", @"45", @"46", @"46", @"47", @"47", @"48", @"48", + @"49", @"49", @"50", @"50", @"51", @"51", @"52", @"52", @"53", @"53", @"54", @"54", + @"55", @"55", @"56", @"56", @"57", @"57", @"58", @"58", @"59", @"59", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; @@ -659,26 +495,26 @@ - (void)testSerializeDeserializeBigDictionary - (void)testSerializeDeserializeDeep { - NSError* error = (NSError*)self; - NSString* expected = @"{\"a0\":\"A0\",\"a1\":{\"b0\":{\"c0\":\"C0\",\"c1\":{\"d0\":[[],[],[]],\"d1\":\"D1\"}},\"b1\":\"B1\"},\"a2\":\"A2\"}"; - id original = [NSDictionary dictionaryWithObjectsAndKeys: - @"A0", @"a0", - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - @"C0", @"c0", - [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObjects:[NSArray array], [NSArray array], [NSArray array], nil], @"d0", - @"D1", @"d1", - nil], @"c1", - nil], @"b0", - @"B1", @"b1", - nil], @"a1", - @"A2", @"a2", - nil]; - - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"{\"a0\":\"A0\",\"a1\":{\"b0\":{\"c0\":\"C0\",\"c1\":{\"d0\":[[],[],[]],\"d1\":\"D1\"}}," + @"\"b1\":\"B1\"},\"a2\":\"A2\"}"; + id original = [NSDictionary + dictionaryWithObjectsAndKeys: + @"A0", @"a0", + [NSDictionary + dictionaryWithObjectsAndKeys: + [NSDictionary + dictionaryWithObjectsAndKeys: + @"C0", @"c0", + [NSDictionary + dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:[NSArray array], [NSArray array], + [NSArray array], nil], + @"d0", @"D1", @"d1", nil], + @"c1", nil], + @"b0", @"B1", @"b1", nil], + @"a1", @"A2", @"a2", nil]; + + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -688,101 +524,97 @@ - (void)testSerializeDeserializeDeep XCTAssertEqualObjects(result, original, @""); } -- (void) testDeserializeUnicode +- (void)testDeserializeUnicode { - NSError* error = (NSError*)self; - NSString* json = @"[\"\\u00dcOne\"]"; - NSString* expected = @"\u00dcOne"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"\\u00dcOne\"]"; + NSString *expected = @"\u00dcOne"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result objectAtIndex:0]; + NSString *value = [result objectAtIndex:0]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testDeserializeUnicode2 +- (void)testDeserializeUnicode2 { - NSError* error = (NSError*)self; - NSString* json = @"[\"\\u827e\\u5c0f\\u8587\"]"; - NSString* expected = @"\u827e\u5c0f\u8587"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"\\u827e\\u5c0f\\u8587\"]"; + NSString *expected = @"\u827e\u5c0f\u8587"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result objectAtIndex:0]; + NSString *value = [result objectAtIndex:0]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testDeserializeUnicodeExtended +- (void)testDeserializeUnicodeExtended { // 𐌣 = 0x10323 = 0x40,0x323 = 0xd840,0xdf23 - NSError* error = (NSError*)self; - NSString* json = @"[\"ABC\\ud840\\udf23DEFGHIJ\"]"; - NSString* expected = @"ABC𐌣DEFGHIJ"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"ABC\\ud840\\udf23DEFGHIJ\"]"; + NSString *expected = @"ABC𐌣DEFGHIJ"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result objectAtIndex:0]; + NSString *value = [result objectAtIndex:0]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testDeserializeUnicodeExtendedLoneTrailSurrogate +- (void)testDeserializeUnicodeExtendedLoneTrailSurrogate { - NSError* error = (NSError*)self; - NSString* json = @"[\"ABC\\ud840DEFGHIJ\"]"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"ABC\\ud840DEFGHIJ\"]"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testDeserializeUnicodeExtendedMissingTrailSurrogate +- (void)testDeserializeUnicodeExtendedMissingTrailSurrogate { - NSError* error = (NSError*)self; - NSString* json = @"[\"ABC\\udf23DEFGHIJ\"]"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"ABC\\udf23DEFGHIJ\"]"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testDeserializeUnicodeExtendedMissingTrailSurrogate2 +- (void)testDeserializeUnicodeExtendedMissingTrailSurrogate2 { - NSError* error = (NSError*)self; - NSString* json = @"[\"ABC\\udf23\\u1234DEFGHIJ\"]"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"ABC\\udf23\\u1234DEFGHIJ\"]"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testDeserializeUnicodeExtendedCutOff +- (void)testDeserializeUnicodeExtendedCutOff { - NSError* error = (NSError*)self; - NSString* json = @"[\"ABC\\udf23\"]"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"ABC\\udf23\"]"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testDeserializeControlChars +- (void)testDeserializeControlChars { - NSError* error = (NSError*)self; - NSString* json = @"[\"\\b\\f\\n\\r\\t\"]"; - NSString* expected = @"\b\f\n\r\t"; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"\\b\\f\\n\\r\\t\"]"; + NSString *expected = @"\b\f\n\r\t"; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result objectAtIndex:0]; + NSString *value = [result objectAtIndex:0]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testSerializeDeserializeControlChars2 +- (void)testSerializeDeserializeControlChars2 { - NSError* error = (NSError*)self; - NSString* expected = @"[\"\\b\\f\\n\\r\\t\"]"; - id original = [NSArray arrayWithObjects: - @"\b\f\n\r\t", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[\"\\b\\f\\n\\r\\t\"]"; + id original = [NSArray arrayWithObjects:@"\b\f\n\r\t", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -792,16 +624,12 @@ - (void) testSerializeDeserializeControlChars2 XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeControlChars3 +- (void)testSerializeDeserializeControlChars3 { - NSError* error = (NSError*)self; - NSString* expected = @"[\"Testing\\b escape \\f chars\\n\"]"; - id original = [NSArray arrayWithObjects: - @"Testing\b escape \f chars\n", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[\"Testing\\b escape \\f chars\\n\"]"; + id original = [NSArray arrayWithObjects:@"Testing\b escape \f chars\n", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -811,16 +639,12 @@ - (void) testSerializeDeserializeControlChars3 XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeEscapedChars +- (void)testSerializeDeserializeEscapedChars { - NSError* error = (NSError*)self; - NSString* expected = @"[\"\\\"\\\\\"]"; - id original = [NSArray arrayWithObjects: - @"\"\\", - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[\"\\\"\\\\\"]"; + id original = [NSArray arrayWithObjects:@"\"\\", nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -830,54 +654,42 @@ - (void) testSerializeDeserializeEscapedChars XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeFloat +- (void)testSerializeDeserializeFloat { - NSError* error = (NSError*)self; - NSString* expected = @"[1.2]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithFloat:1.2f], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[1.2]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithFloat:1.2f], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - XCTAssertTrue([[result objectAtIndex:0] floatValue] == [[original objectAtIndex:0] floatValue], @""); + XCTAssertTrue([[result objectAtIndex:0] floatValue] == [[original objectAtIndex:0] floatValue], @""); } -- (void) testSerializeDeserializeDouble +- (void)testSerializeDeserializeDouble { - NSError* error = (NSError*)self; - NSString* expected = @"[0.1]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithDouble:0.1], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[0.1]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithDouble:0.1], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - XCTAssertTrue([[result objectAtIndex:0] floatValue] == [[original objectAtIndex:0] floatValue], @""); + XCTAssertTrue([[result objectAtIndex:0] floatValue] == [[original objectAtIndex:0] floatValue], @""); } -- (void) testSerializeDeserializeChar +- (void)testSerializeDeserializeChar { - NSError* error = (NSError*)self; - NSString* expected = @"[20]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithChar:20], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[20]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithChar:20], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -887,16 +699,12 @@ - (void) testSerializeDeserializeChar XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeShort +- (void)testSerializeDeserializeShort { - NSError* error = (NSError*)self; - NSString* expected = @"[2000]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithShort:2000], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[2000]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithShort:2000], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -906,16 +714,12 @@ - (void) testSerializeDeserializeShort XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeLong +- (void)testSerializeDeserializeLong { - NSError* error = (NSError*)self; - NSString* expected = @"[2000000000]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithLong:2000000000], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[2000000000]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithLong:2000000000], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -925,16 +729,12 @@ - (void) testSerializeDeserializeLong XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeLongLong +- (void)testSerializeDeserializeLongLong { - NSError* error = (NSError*)self; - NSString* expected = @"[200000000000]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithLongLong:200000000000], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[200000000000]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithLongLong:200000000000], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -944,16 +744,12 @@ - (void) testSerializeDeserializeLongLong XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeNegative +- (void)testSerializeDeserializeNegative { - NSError* error = (NSError*)self; - NSString* expected = @"[-2000]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithInt:-2000], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[-2000]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithInt:-2000], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -963,16 +759,12 @@ - (void) testSerializeDeserializeNegative XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserialize0 +- (void)testSerializeDeserialize0 { - NSError* error = (NSError*)self; - NSString* expected = @"[0]"; - id original = [NSArray arrayWithObjects: - [NSNumber numberWithInt:0], - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *expected = @"[0]"; + id original = [NSArray arrayWithObjects:[NSNumber numberWithInt:0], nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -982,17 +774,13 @@ - (void) testSerializeDeserialize0 XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeEmptyString +- (void)testSerializeDeserializeEmptyString { - NSError* error = (NSError*)self; - NSString* string = @""; - NSString* expected = @"[\"\"]"; - id original = [NSArray arrayWithObjects: - string, - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSError *error = (NSError *)self; + NSString *string = @""; + NSString *expected = @"[\"\"]"; + id original = [NSArray arrayWithObjects:string, nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -1002,24 +790,19 @@ - (void) testSerializeDeserializeEmptyString XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeBigString +- (void)testSerializeDeserializeBigString { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; int length = 500; - NSMutableString* string = [NSMutableString stringWithCapacity:(NSUInteger)length]; - for(int i = 0; i < length; i++) - { - [string appendFormat:@"%d", i%10]; + NSMutableString *string = [NSMutableString stringWithCapacity:(NSUInteger)length]; + for (int i = 0; i < length; i++) { + [string appendFormat:@"%d", i % 10]; } - NSString* expected = [NSString stringWithFormat:@"[\"%@\"]", string]; - id original = [NSArray arrayWithObjects: - string, - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *expected = [NSString stringWithFormat:@"[\"%@\"]", string]; + id original = [NSArray arrayWithObjects:string, nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(jsonString, expected, @""); @@ -1029,20 +812,16 @@ - (void) testSerializeDeserializeBigString XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeHugeString +- (void)testSerializeDeserializeHugeString { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; char buff[5000]; memset(buff, '2', sizeof(buff)); - buff[sizeof(buff)-1] = 0; - NSString* string = [NSString stringWithCString:buff encoding:NSUTF8StringEncoding]; - - id original = [NSArray arrayWithObjects: - string, - nil]; - NSString* jsonString = toString([KSJSONCodec encode:original - options:KSJSONEncodeOptionSorted - error:&error]); + buff[sizeof(buff) - 1] = 0; + NSString *string = [NSString stringWithCString:buff encoding:NSUTF8StringEncoding]; + + id original = [NSArray arrayWithObjects:string, nil]; + NSString *jsonString = toString([KSJSONCodec encode:original options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(jsonString, @""); XCTAssertNil(error, @""); id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; @@ -1051,28 +830,25 @@ - (void) testSerializeDeserializeHugeString XCTAssertEqualObjects(result, original, @""); } -- (void) testSerializeDeserializeLargeArray +- (void)testSerializeDeserializeLargeArray { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; unsigned int numEntries = 2000; - NSMutableString* jsonString = [NSMutableString string]; + NSMutableString *jsonString = [NSMutableString string]; [jsonString appendString:@"["]; - for(unsigned int i = 0; i < numEntries; i++) - { - [jsonString appendFormat:@"%d,", i%10]; + for (unsigned int i = 0; i < numEntries; i++) { + [jsonString appendFormat:@"%d,", i % 10]; } - [jsonString deleteCharactersInRange:NSMakeRange([jsonString length]-1, 1)]; + [jsonString deleteCharactersInRange:NSMakeRange([jsonString length] - 1, 1)]; [jsonString appendString:@"]"]; - NSArray* deserialized = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; + NSArray *deserialized = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; unsigned int deserializedCount = (unsigned int)[deserialized count]; XCTAssertNotNil(deserialized, @""); XCTAssertNil(error, @""); XCTAssertEqual(deserializedCount, numEntries, @""); - NSString* serialized = toString([KSJSONCodec encode:deserialized - options:0 - error:&error]); + NSString *serialized = toString([KSJSONCodec encode:deserialized options:0 error:&error]); XCTAssertNotNil(serialized, @""); XCTAssertNil(error, @""); XCTAssertEqualObjects(serialized, jsonString, @""); @@ -1082,40 +858,37 @@ - (void) testSerializeDeserializeLargeArray XCTAssertEqual(value, 9, @""); } -- (void) testSerializeDeserializeLargeDictionary +- (void)testSerializeDeserializeLargeDictionary { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; unsigned int numEntries = 2000; - NSMutableString* jsonString = [NSMutableString string]; + NSMutableString *jsonString = [NSMutableString string]; [jsonString appendString:@"{"]; - for(unsigned int i = 0; i < numEntries; i++) - { + for (unsigned int i = 0; i < numEntries; i++) { [jsonString appendFormat:@"\"%d\":%d,", i, i]; } - [jsonString deleteCharactersInRange:NSMakeRange([jsonString length]-1, 1)]; + [jsonString deleteCharactersInRange:NSMakeRange([jsonString length] - 1, 1)]; [jsonString appendString:@"}"]; - NSDictionary* deserialized = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; + NSDictionary *deserialized = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; unsigned int deserializedCount = (unsigned int)[deserialized count]; XCTAssertNotNil(deserialized, @""); XCTAssertNil(error, @""); XCTAssertEqual(deserializedCount, numEntries, @""); - int value = [[(NSDictionary*)deserialized objectForKey:@"1"] intValue]; + int value = [[(NSDictionary *)deserialized objectForKey:@"1"] intValue]; XCTAssertEqual(value, 1, @""); - NSString* serialized = toString([KSJSONCodec encode:deserialized - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *serialized = toString([KSJSONCodec encode:deserialized options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNotNil(serialized, @""); XCTAssertNil(error, @""); XCTAssertTrue([serialized length] == [jsonString length], @""); } -- (void) testDeserializeArrayMissingTerminator +- (void)testDeserializeArrayMissingTerminator { - NSError* error = (NSError*)self; - NSString* json = @"[\"blah\""; - NSArray* result = [KSJSONCodec decode:toData(json) options:0 error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[\"blah\""; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } @@ -1129,54 +902,46 @@ - (void) testDeserializeArrayMissingTerminator // XCTAssertNotNil(error, @""); //} -- (void) testSerializeArrayBadType +- (void)testSerializeArrayBadType { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; id source = [NSArray arrayWithObject:[NSValue valueWithPointer:NULL]]; - NSString* result = toString([KSJSONCodec encode:source - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *result = toString([KSJSONCodec encode:source options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testSerializeDictionaryBadType +- (void)testSerializeDictionaryBadType { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; id source = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:NULL] forKey:@"blah"]; - NSString* result = toString([KSJSONCodec encode:source - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *result = toString([KSJSONCodec encode:source options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testSerializeDictionaryBadCharacter +- (void)testSerializeDictionaryBadCharacter { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; id source = [NSDictionary dictionaryWithObject:@"blah" forKey:@"blah\x01blah"]; - NSString* result = toString([KSJSONCodec encode:source - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *result = toString([KSJSONCodec encode:source options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testSerializeArrayBadCharacter +- (void)testSerializeArrayBadCharacter { - NSError* error = (NSError*)self; + NSError *error = (NSError *)self; id source = [NSArray arrayWithObject:@"test\x01ing"]; - NSString* result = toString([KSJSONCodec encode:source - options:KSJSONEncodeOptionSorted - error:&error]); + NSString *result = toString([KSJSONCodec encode:source options:KSJSONEncodeOptionSorted error:&error]); XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } - (void)testDeserializeArrayInvalidUnicodeSequence { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"One\\ubarfTwo\"]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"One\\ubarfTwo\"]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1184,8 +949,8 @@ - (void)testDeserializeArrayInvalidUnicodeSequence - (void)testDeserializeArrayInvalidUnicodeSequence2 { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"One\\u123gTwo\"]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"One\\u123gTwo\"]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1193,8 +958,8 @@ - (void)testDeserializeArrayInvalidUnicodeSequence2 - (void)testDeserializeArrayUnterminatedEscape { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"One\\u123\"]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"One\\u123\"]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1202,8 +967,8 @@ - (void)testDeserializeArrayUnterminatedEscape - (void)testDeserializeArrayUnterminatedEscape2 { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"One\\\"]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"One\\\"]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1211,8 +976,8 @@ - (void)testDeserializeArrayUnterminatedEscape2 - (void)testDeserializeArrayUnterminatedEscape3 { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"One\\u\"]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"One\\u\"]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1220,8 +985,8 @@ - (void)testDeserializeArrayUnterminatedEscape3 - (void)testDeserializeArrayInvalidEscape { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"One\\qTwo\"]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"One\\qTwo\"]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1229,8 +994,8 @@ - (void)testDeserializeArrayInvalidEscape - (void)testDeserializeArrayUnterminatedString { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"One]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"One]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1238,8 +1003,8 @@ - (void)testDeserializeArrayUnterminatedString - (void)testDeserializeArrayTruncatedFalse { - NSError* error = (NSError*)self; - NSString* jsonString = @"[f]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[f]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1247,8 +1012,8 @@ - (void)testDeserializeArrayTruncatedFalse - (void)testDeserializeArrayInvalidFalse { - NSError* error = (NSError*)self; - NSString* jsonString = @"[falst]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[falst]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1256,8 +1021,8 @@ - (void)testDeserializeArrayInvalidFalse - (void)testDeserializeArrayTruncatedTrue { - NSError* error = (NSError*)self; - NSString* jsonString = @"[t]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[t]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1265,8 +1030,8 @@ - (void)testDeserializeArrayTruncatedTrue - (void)testDeserializeArrayInvalidTrue { - NSError* error = (NSError*)self; - NSString* jsonString = @"[ture]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[ture]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1274,8 +1039,8 @@ - (void)testDeserializeArrayInvalidTrue - (void)testDeserializeArrayTruncatedNull { - NSError* error = (NSError*)self; - NSString* jsonString = @"[n]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[n]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1283,8 +1048,8 @@ - (void)testDeserializeArrayTruncatedNull - (void)testDeserializeArrayInvalidNull { - NSError* error = (NSError*)self; - NSString* jsonString = @"[nlll]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[nlll]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1292,8 +1057,8 @@ - (void)testDeserializeArrayInvalidNull - (void)testDeserializeArrayInvalidElement { - NSError* error = (NSError*)self; - NSString* jsonString = @"[-blah]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[-blah]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1301,8 +1066,8 @@ - (void)testDeserializeArrayInvalidElement - (void)testDeserializeArrayUnterminated { - NSError* error = (NSError*)self; - NSString* jsonString = @"[\"blah\""; + NSError *error = (NSError *)self; + NSString *jsonString = @"[\"blah\""; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1310,8 +1075,8 @@ - (void)testDeserializeArrayUnterminated - (void)testDeserializeArrayNumberOverflow { - NSError* error = (NSError*)self; - NSString* jsonString = @"[123456789012345678901234567890]"; + NSError *error = (NSError *)self; + NSString *jsonString = @"[123456789012345678901234567890]"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); @@ -1319,8 +1084,8 @@ - (void)testDeserializeArrayNumberOverflow - (void)testDeserializeDictionaryInvalidKey { - NSError* error = (NSError*)self; - NSString* jsonString = @"{blah:\"blah\"}"; + NSError *error = (NSError *)self; + NSString *jsonString = @"{blah:\"blah\"}"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1328,8 +1093,8 @@ - (void)testDeserializeDictionaryInvalidKey - (void)testDeserializeDictionaryMissingSeparator { - NSError* error = (NSError*)self; - NSString* jsonString = @"{\"blah\"\"blah\"}"; + NSError *error = (NSError *)self; + NSString *jsonString = @"{\"blah\"\"blah\"}"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1337,8 +1102,8 @@ - (void)testDeserializeDictionaryMissingSeparator - (void)testDeserializeDictionaryBadElement { - NSError* error = (NSError*)self; - NSString* jsonString = @"{\"blah\":blah\"}"; + NSError *error = (NSError *)self; + NSString *jsonString = @"{\"blah\":blah\"}"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1346,8 +1111,8 @@ - (void)testDeserializeDictionaryBadElement - (void)testDeserializeDictionaryUnterminated { - NSError* error = (NSError*)self; - NSString* jsonString = @"{\"blah\":\"blah\""; + NSError *error = (NSError *)self; + NSString *jsonString = @"{\"blah\":\"blah\""; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); @@ -1355,122 +1120,106 @@ - (void)testDeserializeDictionaryUnterminated - (void)testDeserializeInvalidData { - NSError* error = (NSError*)self; - NSString* jsonString = @"X{\"blah\":\"blah\"}"; + NSError *error = (NSError *)self; + NSString *jsonString = @"X{\"blah\":\"blah\"}"; id result = [KSJSONCodec decode:toData(jsonString) options:0 error:&error]; XCTAssertNil(result, @""); XCTAssertNotNil(error, @""); } -- (void) testDeserializeArrayWithNull +- (void)testDeserializeArrayWithNull { - NSError* error = (NSError*)self; - NSString* json = @"[null]"; + NSError *error = (NSError *)self; + NSString *json = @"[null]"; id expected = [NSNull null]; - NSArray* result = [KSJSONCodec decode:toData(json) - options:0 - error:&error]; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result objectAtIndex:0]; + NSString *value = [result objectAtIndex:0]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testDeserializeArrayWithNullIgnoreNullInArray +- (void)testDeserializeArrayWithNullIgnoreNullInArray { - NSError* error = (NSError*)self; - NSString* json = @"[null]"; - NSArray* result = [KSJSONCodec decode:toData(json) - options:KSJSONDecodeOptionIgnoreNullInArray - error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[null]"; + NSArray *result = [KSJSONCodec decode:toData(json) options:KSJSONDecodeOptionIgnoreNullInArray error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); XCTAssertTrue([result count] == 0, @""); } -- (void) testDeserializeArrayWithNullIgnoreNullInObject +- (void)testDeserializeArrayWithNullIgnoreNullInObject { - NSError* error = (NSError*)self; - NSString* json = @"[null]"; + NSError *error = (NSError *)self; + NSString *json = @"[null]"; id expected = [NSNull null]; - NSArray* result = [KSJSONCodec decode:toData(json) - options:KSJSONDecodeOptionIgnoreNullInObject - error:&error]; + NSArray *result = [KSJSONCodec decode:toData(json) options:KSJSONDecodeOptionIgnoreNullInObject error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result objectAtIndex:0]; + NSString *value = [result objectAtIndex:0]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testDeserializeArrayWithNullIgnoreAllNulls +- (void)testDeserializeArrayWithNullIgnoreAllNulls { - NSError* error = (NSError*)self; - NSString* json = @"[null]"; - NSArray* result = [KSJSONCodec decode:toData(json) - options:KSJSONDecodeOptionIgnoreAllNulls - error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"[null]"; + NSArray *result = [KSJSONCodec decode:toData(json) options:KSJSONDecodeOptionIgnoreAllNulls error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); XCTAssertTrue([result count] == 0, @""); } -- (void) testDeserializeObjectWithNull +- (void)testDeserializeObjectWithNull { - NSError* error = (NSError*)self; - NSString* json = @"{\"blah\":null}"; + NSError *error = (NSError *)self; + NSString *json = @"{\"blah\":null}"; id expected = [NSNull null]; - NSArray* result = [KSJSONCodec decode:toData(json) - options:0 - error:&error]; + NSArray *result = [KSJSONCodec decode:toData(json) options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result valueForKey:@"blah"]; + NSString *value = [result valueForKey:@"blah"]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testDeserializeObjectWithNullIgnoreNullInArray +- (void)testDeserializeObjectWithNullIgnoreNullInArray { - NSError* error = (NSError*)self; - NSString* json = @"{\"blah\":null}"; + NSError *error = (NSError *)self; + NSString *json = @"{\"blah\":null}"; id expected = [NSNull null]; - NSArray* result = [KSJSONCodec decode:toData(json) - options:KSJSONDecodeOptionIgnoreNullInArray - error:&error]; + NSArray *result = [KSJSONCodec decode:toData(json) options:KSJSONDecodeOptionIgnoreNullInArray error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); - NSString* value = [result valueForKey:@"blah"]; + NSString *value = [result valueForKey:@"blah"]; XCTAssertEqualObjects(value, expected, @""); } -- (void) testDeserializeObjectWithNullIgnoreNullInObject +- (void)testDeserializeObjectWithNullIgnoreNullInObject { - NSError* error = (NSError*)self; - NSString* json = @"{\"blah\":null}"; - NSArray* result = [KSJSONCodec decode:toData(json) - options:KSJSONDecodeOptionIgnoreNullInObject - error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"{\"blah\":null}"; + NSArray *result = [KSJSONCodec decode:toData(json) options:KSJSONDecodeOptionIgnoreNullInObject error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); XCTAssertTrue([result count] == 0, @""); } -- (void) testDeserializeObjectWithNullIgnoreAllNulls +- (void)testDeserializeObjectWithNullIgnoreAllNulls { - NSError* error = (NSError*)self; - NSString* json = @"{\"blah\":null}"; - NSArray* result = [KSJSONCodec decode:toData(json) - options:KSJSONDecodeOptionIgnoreAllNulls - error:&error]; + NSError *error = (NSError *)self; + NSString *json = @"{\"blah\":null}"; + NSArray *result = [KSJSONCodec decode:toData(json) options:KSJSONDecodeOptionIgnoreAllNulls error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); XCTAssertTrue([result count] == 0, @""); } -- (void) testFloatParsingDoesntOverflow +- (void)testFloatParsingDoesntOverflow { - NSError *error = (NSError*)self; + NSError *error = (NSError *)self; - char * buffer = malloc(0x1000000); + char *buffer = malloc(0x1000000); for (int i = 0; i < 0x1000000; i++) { buffer[i] = ';'; } @@ -1479,151 +1228,151 @@ - (void) testFloatParsingDoesntOverflow NSData *data = [NSData dataWithBytesNoCopy:buffer length:0x1000000 freeWhenDone:YES]; - NSDictionary *result = [KSJSONCodec decode: data - options:0 - error:&error]; + NSDictionary *result = [KSJSONCodec decode:data options:0 error:&error]; XCTAssertNotNil(result, @""); XCTAssertNil(error, @""); XCTAssertTrue([result count] == 1, @""); - } -static int addJSONData(const char* data, int length, void* userData) +static int addJSONData(const char *data, int length, void *userData) { - NSMutableData* nsdata = (__bridge NSMutableData*)userData; + NSMutableData *nsdata = (__bridge NSMutableData *)userData; [nsdata appendBytes:data length:(unsigned)length]; return KSJSON_OK; } -- (void) serializeObject:(id) object toFile:(NSString*) filename +- (void)serializeObject:(id)object toFile:(NSString *)filename { - NSError* error = nil; - NSData* savedData = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error]; + NSError *error = nil; + NSData *savedData = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error]; XCTAssertNotNil(savedData); XCTAssertNil(error); XCTAssertTrue([savedData writeToFile:filename atomically:YES]); } -- (void) expectData:(NSData*) data encodesObject:(id) expectedObject +- (void)expectData:(NSData *)data encodesObject:(id)expectedObject { - NSError* error = nil; + NSError *error = nil; id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; XCTAssertNotNil(object); XCTAssertNil(error); XCTAssertEqualObjects(object, expectedObject); } -- (id) decodeJSON:(const char*) jsonBytes +- (id)decodeJSON:(const char *)jsonBytes { - NSError* error = nil; - NSData* jsonData = [NSData dataWithBytes:jsonBytes length:strlen(jsonBytes)]; + NSError *error = nil; + NSData *jsonData = [NSData dataWithBytes:jsonBytes length:strlen(jsonBytes)]; id object = [KSJSONCodec decode:jsonData options:KSJSONDecodeOptionKeepPartialObject error:&error]; XCTAssertNil(error); XCTAssertNotNil(object); return object; } -- (void) expectEquivalentJSON:(const char*) jsonCompareBytes toJSON:(const char*) jsonExpectedBytes +- (void)expectEquivalentJSON:(const char *)jsonCompareBytes toJSON:(const char *)jsonExpectedBytes { id objectCompare = [self decodeJSON:jsonCompareBytes]; id objectExpect = [self decodeJSON:jsonExpectedBytes]; XCTAssertEqualObjects(objectCompare, objectExpect); } -- (void) testAddJSONFromFile +- (void)testAddJSONFromFile { - NSString* savedFilename = [self.tempPath stringByAppendingPathComponent:@"saved.json"]; - id savedObject = @{@"loaded": @"yes"}; + NSString *savedFilename = [self.tempPath stringByAppendingPathComponent:@"saved.json"]; + id savedObject = @{ @"loaded" : @"yes" }; [self serializeObject:savedObject toFile:savedFilename]; - id expectedObject = @{@"1": @"one", @"from_file": savedObject}; - - NSMutableData* encodedData = [NSMutableData data]; - KSJSONEncodeContext context = {0}; + id expectedObject = @{ @"1" : @"one", @"from_file" : savedObject }; + + NSMutableData *encodedData = [NSMutableData data]; + KSJSONEncodeContext context = { 0 }; ksjson_beginEncode(&context, false, addJSONData, (__bridge void *)(encodedData)); ksjson_beginObject(&context, NULL); ksjson_addStringElement(&context, "1", "one", KSJSON_SIZE_AUTOMATIC); ksjson_addJSONFromFile(&context, "from_file", savedFilename.UTF8String, true); ksjson_endContainer(&context); ksjson_endEncode(&context); - + [self expectData:encodedData encodesObject:expectedObject]; } -- (void) testAddJSONFromBigFile +- (void)testAddJSONFromBigFile { - NSString* savedFilename = [self.tempPath stringByAppendingPathComponent:@"big.json"]; + NSString *savedFilename = [self.tempPath stringByAppendingPathComponent:@"big.json"]; id savedObject = @{ - @"an_array": @[@1, @2, @3, @4], - @"lines": @[ - @"I cannot describe to you my sensations on the near prospect of my undertaking.", - @"It is impossible to communicate to you a conception of the trembling sensation, half pleasurable and half fearful, with which I am preparing to depart.", - @"I am going to unexplored regions, to \"the land of mist and snow,\" but I shall kill no albatross; therefore do not be alarmed for my safety or if I should come back to you as worn and woeful as the \"Ancient Mariner.\"", - @"You will smile at my allusion, but I will disclose a secret.", - @"I have often attributed my attachment to, my passionate enthusiasm for, the dangerous mysteries of ocean to that production of the most imaginative of modern poets.", - @"There is something at work in my soul which I do not understand.", - @"I am practically industrious—painstaking, a workman to execute with perseverance and labour—but besides this there is a love for the marvellous, a belief in the marvellous, intertwined in all my projects, which hurries me out of the common pathways of men, even to the wild sea and unvisited regions I am about to explore.", - @"But to return to dearer considerations.", - @"Shall I meet you again, after having traversed immense seas, and returned by the most southern cape of Africa or America? I dare not expect such success, yet I cannot bear to look on the reverse of the picture.", - @"Continue for the present to write to me by every opportunity: I may receive your letters on some occasions when I need them most to support my spirits.", - @"I love you very tenderly.", - @"Remember me with affection, should you never hear from me again.", - ], - }; + @"an_array" : @[ @1, @2, @3, @4 ], + @"lines" : @[ + @"I cannot describe to you my sensations on the near prospect of my undertaking.", + @"It is impossible to communicate to you a conception of the trembling sensation, half pleasurable and half fearful, with which I am preparing to depart.", + @"I am going to unexplored regions, to \"the land of mist and snow,\" but I shall kill no albatross; therefore do not be alarmed for my safety or if I should come back to you as worn and woeful as the \"Ancient Mariner.\"", + @"You will smile at my allusion, but I will disclose a secret.", + @"I have often attributed my attachment to, my passionate enthusiasm for, the dangerous mysteries of ocean to that production of the most imaginative of modern poets.", + @"There is something at work in my soul which I do not understand.", + @"I am practically industrious—painstaking, a workman to execute with perseverance and labour—but besides this there is a love for the marvellous, a belief in the marvellous, intertwined in all my projects, which hurries me out of the common pathways of men, even to the wild sea and unvisited regions I am about to explore.", + @"But to return to dearer considerations.", + @"Shall I meet you again, after having traversed immense seas, and returned by the most southern cape of Africa or America? I dare not expect such success, yet I cannot bear to look on the reverse of the picture.", + @"Continue for the present to write to me by every opportunity: I may receive your letters on some occasions when I need them most to support my spirits.", + @"I love you very tenderly.", + @"Remember me with affection, should you never hear from me again.", + ], + }; [self serializeObject:savedObject toFile:savedFilename]; - id expectedObject = @{@"testing": @"this", @"from_file": savedObject}; - - NSMutableData* encodedData = [NSMutableData data]; - KSJSONEncodeContext context = {0}; + id expectedObject = @{ @"testing" : @"this", @"from_file" : savedObject }; + + NSMutableData *encodedData = [NSMutableData data]; + KSJSONEncodeContext context = { 0 }; ksjson_beginEncode(&context, false, addJSONData, (__bridge void *)(encodedData)); ksjson_beginObject(&context, NULL); ksjson_addStringElement(&context, "testing", "this", KSJSON_SIZE_AUTOMATIC); ksjson_addJSONFromFile(&context, "from_file", savedFilename.UTF8String, true); ksjson_endContainer(&context); ksjson_endEncode(&context); - + [self expectData:encodedData encodesObject:expectedObject]; } -- (void) testAddJSONFromBrokenFile +- (void)testAddJSONFromBrokenFile { - NSString* savedFilename = [self.tempPath stringByAppendingPathComponent:@"broken.json"]; - char* savedJSON = "{" - "\"an_object\": {"; - char* expectedJSON = "{" - "\"1\": \"one\"," - "\"from_file\": {" - "\"an_object\": {" - "}" - "}" - "}"; + NSString *savedFilename = [self.tempPath stringByAppendingPathComponent:@"broken.json"]; + char *savedJSON = "{" + "\"an_object\": {"; + char *expectedJSON = "{" + "\"1\": \"one\"," + "\"from_file\": {" + "\"an_object\": {" + "}" + "}" + "}"; - NSData* data = [NSData dataWithBytes:savedJSON length:strlen(savedJSON)]; + NSData *data = [NSData dataWithBytes:savedJSON length:strlen(savedJSON)]; XCTAssertTrue([data writeToFile:savedFilename atomically:YES]); - - NSError* error = nil; - NSData* expectedObject = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:expectedJSON length:strlen(expectedJSON)] options:0 error:&error]; + + NSError *error = nil; + NSData *expectedObject = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:expectedJSON + length:strlen(expectedJSON)] + options:0 + error:&error]; XCTAssertNotNil(expectedObject); XCTAssertNil(error); - - NSMutableData* encodedData = [NSMutableData data]; - KSJSONEncodeContext context = {0}; + + NSMutableData *encodedData = [NSMutableData data]; + KSJSONEncodeContext context = { 0 }; ksjson_beginEncode(&context, false, addJSONData, (__bridge void *)(encodedData)); ksjson_beginObject(&context, NULL); ksjson_addStringElement(&context, "1", "one", KSJSON_SIZE_AUTOMATIC); ksjson_addJSONFromFile(&context, "from_file", savedFilename.UTF8String, true); ksjson_endContainer(&context); ksjson_endEncode(&context); - + [self expectData:encodedData encodesObject:expectedObject]; } -- (void) testDontCloseLastContainer +- (void)testDontCloseLastContainer { - char* jsonData = "{\"a\":\"1\"}"; - char* expectedJson = "{\"a_container\": {\"a\":\"1\", \"testing\":\"this\"}}"; - - NSMutableData* encodedData = [NSMutableData data]; - KSJSONEncodeContext context = {0}; + char *jsonData = "{\"a\":\"1\"}"; + char *expectedJson = "{\"a_container\": {\"a\":\"1\", \"testing\":\"this\"}}"; + + NSMutableData *encodedData = [NSMutableData data]; + KSJSONEncodeContext context = { 0 }; ksjson_beginEncode(&context, false, addJSONData, (__bridge void *)(encodedData)); ksjson_beginObject(&context, NULL); ksjson_addJSONElement(&context, "a_container", jsonData, (int)strlen(jsonData), false); diff --git a/Tests/KSCrashRecordingCoreTests/KSLogger_Tests.m b/Tests/KSCrashRecordingCoreTests/KSLogger_Tests.m index 4fdb7e962..d1149db1b 100644 --- a/Tests/KSCrashRecordingCoreTests/KSLogger_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSLogger_Tests.m @@ -24,89 +24,86 @@ // THE SOFTWARE. // - #import #import "XCTestCase+KSCrash.h" #import "KSLogger.h" - @interface KSLogger_Tests : XCTestCase -@property(nonatomic, readwrite, retain) NSString* tempDir; +@property(nonatomic, readwrite, retain) NSString *tempDir; @end - @implementation KSLogger_Tests @synthesize tempDir = _tempDir; -- (void) setUp +- (void)setUp { [super setUp]; self.tempDir = [self createTempPath]; } -- (void) tearDown +- (void)tearDown { [self removePath:self.tempDir]; } -- (void) testLogError +- (void)testLogError { KSLOG_ERROR(@"TEST"); } -- (void) testLogErrorNull +- (void)testLogErrorNull { - NSString* str = nil; + NSString *str = nil; KSLOG_ERROR(str); } -- (void) testLogAlways +- (void)testLogAlways { KSLOG_ALWAYS(@"TEST"); } -- (void) testLogAlwaysNull +- (void)testLogAlwaysNull { - NSString* str = nil; + NSString *str = nil; KSLOG_ALWAYS(str); } -- (void) testLogBasicError +- (void)testLogBasicError { KSLOGBASIC_ERROR(@"TEST"); } -- (void) testLogBasicErrorNull +- (void)testLogBasicErrorNull { - NSString* str = nil; + NSString *str = nil; KSLOGBASIC_ERROR(str); } -- (void) testLogBasicAlways +- (void)testLogBasicAlways { KSLOGBASIC_ALWAYS(@"TEST"); } -- (void) testLogBasicAlwaysNull +- (void)testLogBasicAlwaysNull { - NSString* str = nil; + NSString *str = nil; KSLOGBASIC_ALWAYS(str); } -- (void) testSetLogFilename +- (void)testSetLogFilename { - NSString* expected = @"TEST"; - NSString* logFileName = [self.tempDir stringByAppendingPathComponent:@"log.txt"]; + NSString *expected = @"TEST"; + NSString *logFileName = [self.tempDir stringByAppendingPathComponent:@"log.txt"]; kslog_setLogFilename([logFileName UTF8String], true); KSLOGBASIC_ALWAYS(expected); kslog_setLogFilename(nil, true); - NSError* error = nil; - NSString* result = [NSString stringWithContentsOfFile:logFileName encoding:NSUTF8StringEncoding error:&error]; + NSError *error = nil; + NSString *result = [NSString stringWithContentsOfFile:logFileName encoding:NSUTF8StringEncoding error:&error]; XCTAssertNil(error, @""); result = [[result componentsSeparatedByString:@"\x0a"] objectAtIndex:0]; XCTAssertEqualObjects(result, expected, @""); diff --git a/Tests/KSCrashRecordingCoreTests/KSMach-O_Tests.m b/Tests/KSCrashRecordingCoreTests/KSMach-O_Tests.m index 51a54b565..6df7df67f 100644 --- a/Tests/KSCrashRecordingCoreTests/KSMach-O_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSMach-O_Tests.m @@ -5,9 +5,9 @@ // Created by Gleb Linnik on 24.05.2024. // -#import "KSMach-O.h" #import #import +#import "KSMach-O.h" @interface KSMach_O_Tests : XCTestCase @end @@ -31,10 +31,10 @@ - (void)testGetSegmentByNameFromHeader_TextSegment memcpy(buffer, &header, sizeof(header)); memcpy(buffer + sizeof(header), &seg1, sizeof(seg1)); - const mach_header_t* testHeader = (mach_header_t*)buffer; + const mach_header_t *testHeader = (mach_header_t *)buffer; // Verify that the segment is found correctly - const segment_command_t* result = ksmacho_getSegmentByNameFromHeader(testHeader, "__TEXT"); + const segment_command_t *result = ksmacho_getSegmentByNameFromHeader(testHeader, "__TEXT"); XCTAssertNotEqual(result, NULL); XCTAssertEqual(strcmp(result->segname, "__TEXT"), 0); } @@ -56,10 +56,10 @@ - (void)testGetSegmentByNameFromHeader_DataSegment memcpy(buffer, &header, sizeof(header)); memcpy(buffer + sizeof(header), &seg2, sizeof(seg2)); - const mach_header_t* testHeader = (mach_header_t*)buffer; + const mach_header_t *testHeader = (mach_header_t *)buffer; // Verify that the segment is found correctly - const segment_command_t* result = ksmacho_getSegmentByNameFromHeader(testHeader, "__DATA"); + const segment_command_t *result = ksmacho_getSegmentByNameFromHeader(testHeader, "__DATA"); XCTAssertNotEqual(result, NULL); XCTAssertEqual(strcmp(result->segname, "__DATA"), 0); } @@ -81,17 +81,17 @@ - (void)testGetSegmentByNameFromHeader_NotFound memcpy(buffer, &header, sizeof(header)); memcpy(buffer + sizeof(header), &seg1, sizeof(seg1)); - const mach_header_t* testHeader = (mach_header_t*)buffer; + const mach_header_t *testHeader = (mach_header_t *)buffer; // Verify that the segment is not found for an invalid name - const segment_command_t* result = ksmacho_getSegmentByNameFromHeader(testHeader, "__INVALID"); + const segment_command_t *result = ksmacho_getSegmentByNameFromHeader(testHeader, "__INVALID"); XCTAssertEqual(result, NULL); } - (void)testGetSegmentByNameFromHeader_InvalidHeader { // Test with an invalid header - const segment_command_t* result = ksmacho_getSegmentByNameFromHeader(NULL, "__TEXT"); + const segment_command_t *result = ksmacho_getSegmentByNameFromHeader(NULL, "__TEXT"); XCTAssertEqual(result, NULL); } @@ -111,10 +111,10 @@ - (void)testGetCommandByTypeFromHeader_SegmentArchDependent memcpy(buffer, &header, sizeof(header)); memcpy(buffer + sizeof(header), &cmd1, sizeof(cmd1)); - const mach_header_t* testHeader = (mach_header_t*)buffer; + const mach_header_t *testHeader = (mach_header_t *)buffer; // Verify that the command is found correctly - const struct load_command* result = ksmacho_getCommandByTypeFromHeader(testHeader, LC_SEGMENT_ARCH_DEPENDENT); + const struct load_command *result = ksmacho_getCommandByTypeFromHeader(testHeader, LC_SEGMENT_ARCH_DEPENDENT); XCTAssertNotEqual(result, NULL); XCTAssertEqual(result->cmd, LC_SEGMENT_ARCH_DEPENDENT); } @@ -135,10 +135,10 @@ - (void)testGetCommandByTypeFromHeader_Symtab memcpy(buffer, &header, sizeof(header)); memcpy(buffer + sizeof(header), &cmd2, sizeof(cmd2)); - const mach_header_t* testHeader = (mach_header_t*)buffer; + const mach_header_t *testHeader = (mach_header_t *)buffer; // Verify that the command is found correctly - const struct load_command* result = ksmacho_getCommandByTypeFromHeader(testHeader, LC_SYMTAB); + const struct load_command *result = ksmacho_getCommandByTypeFromHeader(testHeader, LC_SYMTAB); XCTAssertNotEqual(result, NULL); XCTAssertEqual(result->cmd, LC_SYMTAB); } @@ -159,17 +159,17 @@ - (void)testGetCommandByTypeFromHeader_NotFound memcpy(buffer, &header, sizeof(header)); memcpy(buffer + sizeof(header), &cmd1, sizeof(cmd1)); - const mach_header_t* testHeader = (mach_header_t*)buffer; + const mach_header_t *testHeader = (mach_header_t *)buffer; // Verify that the command is not found for a different type - const struct load_command* result = ksmacho_getCommandByTypeFromHeader(testHeader, LC_DYSYMTAB); + const struct load_command *result = ksmacho_getCommandByTypeFromHeader(testHeader, LC_DYSYMTAB); XCTAssertEqual(result, NULL); } - (void)testGetCommandByTypeFromHeader_InvalidHeader { // Test with an invalid header - const struct load_command* result = ksmacho_getCommandByTypeFromHeader(NULL, LC_SEGMENT_ARCH_DEPENDENT); + const struct load_command *result = ksmacho_getCommandByTypeFromHeader(NULL, LC_SEGMENT_ARCH_DEPENDENT); XCTAssertEqual(result, NULL); } @@ -190,10 +190,10 @@ - (void)testGetSectionByTypeFlagFromSegment_NonLazySymbolPointers memcpy(buffer, &segment, sizeof(segment)); memcpy(buffer + sizeof(segment), §1, sizeof(sect1)); - const segment_command_t* testSegment = (segment_command_t*)buffer; + const segment_command_t *testSegment = (segment_command_t *)buffer; // Verify that the section is found correctly - const section_t* result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_NON_LAZY_SYMBOL_POINTERS); + const section_t *result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_NON_LAZY_SYMBOL_POINTERS); XCTAssertNotEqual(result, NULL); XCTAssertEqual(result->flags & SECTION_TYPE, S_NON_LAZY_SYMBOL_POINTERS); XCTAssertEqual(strcmp(result->sectname, "__nl_symbol_ptr"), 0); @@ -216,10 +216,10 @@ - (void)testGetSectionByTypeFlagFromSegment_LazySymbolPointers memcpy(buffer, &segment, sizeof(segment)); memcpy(buffer + sizeof(segment), §2, sizeof(sect2)); - const segment_command_t* testSegment = (segment_command_t*)buffer; + const segment_command_t *testSegment = (segment_command_t *)buffer; // Verify that the section is found correctly - const section_t* result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_LAZY_SYMBOL_POINTERS); + const section_t *result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_LAZY_SYMBOL_POINTERS); XCTAssertNotEqual(result, NULL); XCTAssertEqual(result->flags & SECTION_TYPE, S_LAZY_SYMBOL_POINTERS); XCTAssertEqual(strcmp(result->sectname, "__la_symbol_ptr"), 0); @@ -242,10 +242,10 @@ - (void)testGetSectionByTypeFlagFromSegment_Regular memcpy(buffer, &segment, sizeof(segment)); memcpy(buffer + sizeof(segment), §3, sizeof(sect3)); - const segment_command_t* testSegment = (segment_command_t*)buffer; + const segment_command_t *testSegment = (segment_command_t *)buffer; // Verify that the section is found correctly - const section_t* result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_REGULAR); + const section_t *result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_REGULAR); XCTAssertNotEqual(result, NULL); XCTAssertEqual(result->flags & SECTION_TYPE, S_REGULAR); XCTAssertEqual(strcmp(result->sectname, "__const"), 0); @@ -268,17 +268,17 @@ - (void)testGetSectionByTypeFlagFromSegment_NotFound memcpy(buffer, &segment, sizeof(segment)); memcpy(buffer + sizeof(segment), §1, sizeof(sect1)); - const segment_command_t* testSegment = (segment_command_t*)buffer; + const segment_command_t *testSegment = (segment_command_t *)buffer; // Verify that the section is not found for a different type flag - const section_t* result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_ATTR_DEBUG); + const section_t *result = ksmacho_getSectionByTypeFlagFromSegment(testSegment, S_ATTR_DEBUG); XCTAssertEqual(result, NULL); } - (void)testGetSectionByTypeFlagFromSegment_InvalidSegment { // Test with an invalid segment - const section_t* result = ksmacho_getSectionByTypeFlagFromSegment(NULL, S_NON_LAZY_SYMBOL_POINTERS); + const section_t *result = ksmacho_getSectionByTypeFlagFromSegment(NULL, S_NON_LAZY_SYMBOL_POINTERS); XCTAssertEqual(result, NULL); } @@ -295,7 +295,7 @@ - (void)testGetSectionProtection_ReadOnlyProtection XCTAssertEqual(result, KERN_SUCCESS); // Call the function under test - vm_prot_t actualProtection = ksmacho_getSectionProtection((void*)address); + vm_prot_t actualProtection = ksmacho_getSectionProtection((void *)address); // Verify the expected protection XCTAssertEqual(actualProtection, expectedProtection); @@ -318,7 +318,7 @@ - (void)testGetSectionProtection_ExecutableProtection XCTAssertEqual(result, KERN_SUCCESS); // Call the function under test - vm_prot_t actualProtection = ksmacho_getSectionProtection((void*)address); + vm_prot_t actualProtection = ksmacho_getSectionProtection((void *)address); // Verify the expected protection XCTAssertEqual(actualProtection, expectedProtection); @@ -341,7 +341,7 @@ - (void)testGetSectionProtection_NoAccessProtection XCTAssertEqual(result, KERN_SUCCESS); // Call the function under test - vm_prot_t actualProtection = ksmacho_getSectionProtection((void*)address); + vm_prot_t actualProtection = ksmacho_getSectionProtection((void *)address); // Verify the expected protection XCTAssertEqual(actualProtection, expectedProtection); @@ -355,7 +355,7 @@ - (void)testGetSectionProtection_FailureScenario { // Call the function under test with an invalid memory address vm_address_t invalidAddress = 0xFFFFFFFFFFFFFFFFULL; - vm_prot_t actualProtection = ksmacho_getSectionProtection((void*)invalidAddress); + vm_prot_t actualProtection = ksmacho_getSectionProtection((void *)invalidAddress); // Verify the expected default protection value XCTAssertEqual(actualProtection, VM_PROT_READ, @"Expected default protection value of VM_PROT_READ"); diff --git a/Tests/KSCrashRecordingCoreTests/KSMach_Tests.m b/Tests/KSCrashRecordingCoreTests/KSMach_Tests.m index 83b43ebc2..82a3014d7 100644 --- a/Tests/KSCrashRecordingCoreTests/KSMach_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSMach_Tests.m @@ -24,51 +24,49 @@ // THE SOFTWARE. // - #import -#import "KSMach.h" #include #include +#import "KSMach.h" - -@interface KSMach_Tests : XCTestCase @end +@interface KSMach_Tests : XCTestCase +@end @implementation KSMach_Tests -- (void) testExceptionName +- (void)testExceptionName { - NSString* expected = @"EXC_ARITHMETIC"; - NSString* actual = [NSString stringWithCString:ksmach_exceptionName(EXC_ARITHMETIC) - encoding:NSUTF8StringEncoding]; + NSString *expected = @"EXC_ARITHMETIC"; + NSString *actual = [NSString stringWithCString:ksmach_exceptionName(EXC_ARITHMETIC) encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected, @""); } -- (void) testVeryHighExceptionName +- (void)testVeryHighExceptionName { - const char* result = ksmach_exceptionName(100000); + const char *result = ksmach_exceptionName(100000); XCTAssertTrue(result == NULL, @""); } -- (void) testKernReturnCodeName +- (void)testKernReturnCodeName { - NSString* expected = @"KERN_FAILURE"; - NSString* actual = [NSString stringWithCString:ksmach_kernelReturnCodeName(KERN_FAILURE) + NSString *expected = @"KERN_FAILURE"; + NSString *actual = [NSString stringWithCString:ksmach_kernelReturnCodeName(KERN_FAILURE) encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected, @""); } -- (void) testVeryHighKernReturnCodeName +- (void)testVeryHighKernReturnCodeName { - const char* result = ksmach_kernelReturnCodeName(100000); + const char *result = ksmach_kernelReturnCodeName(100000); XCTAssertTrue(result == NULL, @""); } #define EXC_UNIX_BAD_SYSCALL 0x10000 /* SIGSYS */ -#define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ -#define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ +#define EXC_UNIX_BAD_PIPE 0x10001 /* SIGPIPE */ +#define EXC_UNIX_ABORT 0x10002 /* SIGABRT */ -- (void) testMachExeptionsForSignals +- (void)testMachExeptionsForSignals { [self assertMachException:EXC_ARITHMETIC code:0 matchesSignal:SIGFPE]; [self assertMachException:EXC_BAD_ACCESS code:0 matchesSignal:SIGBUS]; @@ -84,7 +82,7 @@ - (void) testMachExeptionsForSignals [self assertMachException:1000000000 code:0 matchesSignal:0]; } -- (void) testSignalsForMachExeptions +- (void)testSignalsForMachExeptions { [self assertSignal:SIGFPE matchesMachException:EXC_ARITHMETIC]; [self assertSignal:SIGSEGV matchesMachException:EXC_BAD_ACCESS]; @@ -99,13 +97,13 @@ - (void) testSignalsForMachExeptions [self assertSignal:1000000000 matchesMachException:0]; } -- (void) assertMachException:(int) exception code:(int) code matchesSignal:(int) signal +- (void)assertMachException:(int)exception code:(int)code matchesSignal:(int)signal { int result = ksmach_signalForMachException(exception, code); XCTAssertEqual(result, signal, @""); } -- (void) assertSignal:(int) signal matchesMachException:(int) exception +- (void)assertSignal:(int)signal matchesMachException:(int)exception { int result = ksmach_machExceptionForSignal(signal); XCTAssertEqual(result, exception, @""); diff --git a/Tests/KSCrashRecordingCoreTests/KSMachineContext_Tests.m b/Tests/KSCrashRecordingCoreTests/KSMachineContext_Tests.m index 708f5fbf3..bc1563c79 100644 --- a/Tests/KSCrashRecordingCoreTests/KSMachineContext_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSMachineContext_Tests.m @@ -28,11 +28,12 @@ #import "KSCrashMonitorContext.h" -@interface KSMachineContext_Tests : XCTestCase @end +@interface KSMachineContext_Tests : XCTestCase +@end @implementation KSMachineContext_Tests -- (void) testSuspendResumeThreads +- (void)testSuspendResumeThreads { thread_act_array_t threads1 = NULL; mach_msg_type_number_t numThreads1 = 0; diff --git a/Tests/KSCrashRecordingCoreTests/KSMemory_Tests.m b/Tests/KSCrashRecordingCoreTests/KSMemory_Tests.m index 037d2e220..f1238d606 100644 --- a/Tests/KSCrashRecordingCoreTests/KSMemory_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSMemory_Tests.m @@ -24,71 +24,70 @@ // THE SOFTWARE. // - #import #import "KSMemory.h" #import "TestThread.h" - -@interface KSMemory_Tests : XCTestCase @end +@interface KSMemory_Tests : XCTestCase +@end @implementation KSMemory_Tests -- (void) testCopyMem +- (void)testCopyMem { char buff[100]; - char buff2[100] = {1,2,3,4,5}; - + char buff2[100] = { 1, 2, 3, 4, 5 }; + bool result = ksmem_copySafely(buff2, buff, sizeof(buff)); XCTAssertTrue(result, @""); int memCmpResult = memcmp(buff, buff2, sizeof(buff)); XCTAssertEqual(memCmpResult, 0, @""); } -- (void) testCopyMemNull +- (void)testCopyMemNull { char buff[100]; - char* buff2 = NULL; - + char *buff2 = NULL; + bool result = ksmem_copySafely(buff2, buff, sizeof(buff)); XCTAssertFalse(result, @""); } -- (void) testCopyMemBad +- (void)testCopyMemBad { char buff[100]; - char* buff2 = (char*)-1; - + char *buff2 = (char *)-1; + bool result = ksmem_copySafely(buff2, buff, sizeof(buff)); XCTAssertFalse(result, @""); } -- (void) testCopyMaxPossibleMem +- (void)testCopyMaxPossibleMem { char buff[1000]; - char buff2[5] = {1,2,3,4,5}; - + char buff2[5] = { 1, 2, 3, 4, 5 }; + int copied = ksmem_copyMaxPossible(buff2, buff, sizeof(buff)); XCTAssertTrue(copied >= 5, @""); int memCmpResult = memcmp(buff, buff2, sizeof(buff2)); XCTAssertEqual(memCmpResult, 0, @""); } -- (void) testCopyMaxPossibleMemNull +- (void)testCopyMaxPossibleMemNull { char buff[1000]; - char* buff2 = NULL; - + char *buff2 = NULL; + int copied = ksmem_copyMaxPossible(buff2, buff, sizeof(buff)); XCTAssertTrue(copied == 0, @""); } -- (void) testCopyMaxPossibleMemBad +- (void)testCopyMaxPossibleMemBad { char buff[1000]; - char* buff2 = (char*)-1; - + char *buff2 = (char *)-1; + int copied = ksmem_copyMaxPossible(buff2, buff, sizeof(buff)); XCTAssertTrue(copied == 0, @""); } diff --git a/Tests/KSCrashRecordingCoreTests/KSObjC_Tests.m b/Tests/KSCrashRecordingCoreTests/KSObjC_Tests.m index 5b113acb5..7511d027f 100644 --- a/Tests/KSCrashRecordingCoreTests/KSObjC_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSObjC_Tests.m @@ -24,20 +24,17 @@ // THE SOFTWARE. // - #import #import #import "KSObjC.h" - -@interface SomeObjCClass: NSObject -{ +@interface SomeObjCClass : NSObject { int someIvar; id anotherIvar; } -@property(nonatomic,readwrite,assign) int someIvar; +@property(nonatomic, readwrite, assign) int someIvar; @end @@ -47,7 +44,7 @@ @implementation SomeObjCClass @end -@interface SomeSubclass: SomeObjCClass +@interface SomeSubclass : SomeObjCClass @end @@ -55,405 +52,422 @@ @implementation SomeSubclass @end -@interface KSObjC_Tests : XCTestCase @end +@interface KSObjC_Tests : XCTestCase +@end @implementation KSObjC_Tests -static NSArray* g_test_strings; - +static NSArray *g_test_strings; -+ (void) initialize ++ (void)initialize { g_test_strings = @[ - @"a", - @"ab", - @"abc", - @"abcd", - @"abcde", - @"abcdef", - @"abcdefg", - @"abcdefgh", - @"abcdefghi", - @"abcdefghij", - @"abcdefghijk", - @"abcdefghijkl", - @"abcdefghijklm", - @"abcdefghijklmn", - @"abcdefghijklmno", - @"abcdefghijklmnop", - ]; -} - -- (NSArray*) componentsOfBasicDescription:(NSString*) description -{ - NSError* error = nil; - NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"^<(\\w+): [^>]+>" options:0 error:&error]; - NSTextCheckingResult* result = [regex firstMatchInString:description options:0 range:NSMakeRange(0, [description length])]; - NSString* className = [description substringWithRange:[result rangeAtIndex:1]]; + @"a", + @"ab", + @"abc", + @"abcd", + @"abcde", + @"abcdef", + @"abcdefg", + @"abcdefgh", + @"abcdefghi", + @"abcdefghij", + @"abcdefghijk", + @"abcdefghijkl", + @"abcdefghijklm", + @"abcdefghijklmn", + @"abcdefghijklmno", + @"abcdefghijklmnop", + ]; +} + +- (NSArray *)componentsOfBasicDescription:(NSString *)description +{ + NSError *error = nil; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^<(\\w+): [^>]+>" + options:0 + error:&error]; + NSTextCheckingResult *result = [regex firstMatchInString:description + options:0 + range:NSMakeRange(0, [description length])]; + NSString *className = [description substringWithRange:[result rangeAtIndex:1]]; return [NSArray arrayWithObjects:className, nil]; } -- (NSArray*) componentsOfComplexDescription:(NSString*) description +- (NSArray *)componentsOfComplexDescription:(NSString *)description { - NSError* error = nil; - NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"^<(\\w+): [^>]+>: (.*)$" options:0 error:&error]; - NSTextCheckingResult* result = [regex firstMatchInString:description options:0 range:NSMakeRange(0, [description length])]; - NSString* className = [description substringWithRange:[result rangeAtIndex:1]]; - NSString* theRest = [description substringWithRange:[result rangeAtIndex:2]]; + NSError *error = nil; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^<(\\w+): [^>]+>: (.*)$" + options:0 + error:&error]; + NSTextCheckingResult *result = [regex firstMatchInString:description + options:0 + range:NSMakeRange(0, [description length])]; + NSString *className = [description substringWithRange:[result rangeAtIndex:1]]; + NSString *theRest = [description substringWithRange:[result rangeAtIndex:2]]; return [NSArray arrayWithObjects:className, theRest, nil]; } -- (void) testObjectTypeInvalidMemory +- (void)testObjectTypeInvalidMemory { uintptr_t pointer = (uintptr_t)-1; pointer >>= 9; pointer <<= 8; - void* ptr = (void*)pointer; + void *ptr = (void *)pointer; KSObjCType type = ksobjc_objectType(ptr); XCTAssertEqual(type, KSObjCTypeUnknown, @"Type was %d", type); } -- (void) testObjectTypeNullPtr +- (void)testObjectTypeNullPtr { - void* ptr = NULL; + void *ptr = NULL; KSObjCType type = ksobjc_objectType(ptr); XCTAssertEqual(type, KSObjCTypeUnknown, @"Type was %d", type); } -- (void) testObjectTypeCorrupt +- (void)testObjectTypeCorrupt { struct objc_object objcClass; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - objcClass.isa = (__bridge Class)((void*)-1); + objcClass.isa = (__bridge Class)((void *)-1); #pragma clang diagnostic pop KSObjCType type = ksobjc_objectType(&objcClass); XCTAssertEqual(type, KSObjCTypeUnknown, @"Type was %d", type); } -- (void) testObjectTypeClass +- (void)testObjectTypeClass { Class cls = [KSObjC_Tests class]; - void* clsPtr = (__bridge void*)cls; + void *clsPtr = (__bridge void *)cls; KSObjCType type = ksobjc_objectType(clsPtr); XCTAssertTrue(type == KSObjCTypeClass, @"Type was %d", type); } -- (void) testObjectTypeObject +- (void)testObjectTypeObject { id object = [KSObjC_Tests new]; KSObjCType type = ksobjc_objectType((__bridge void *)(object)); XCTAssertTrue(type == KSObjCTypeObject, @"Type was %d", type); } -- (void) testObjectTypeObject2 +- (void)testObjectTypeObject2 { id object = @"Test"; KSObjCType type = ksobjc_objectType((__bridge void *)(object)); XCTAssertTrue(type == KSObjCTypeObject, @"Type was %d", type); } -- (void) testObjectTypeBlock +- (void)testObjectTypeBlock { dispatch_block_t block; - const void* blockPtr; - const void* isaPtr; + const void *blockPtr; + const void *isaPtr; KSObjCType type; - - block = ^{}; - blockPtr = (__bridge void*)block; + + block = ^{ + }; + blockPtr = (__bridge void *)block; isaPtr = ksobjc_isaPointer(blockPtr); type = ksobjc_objectType(isaPtr); XCTAssertTrue(type == KSObjCTypeBlock, @""); - - block = [^{} copy]; - blockPtr = (__bridge void*)block; + + block = [^{ + } copy]; + blockPtr = (__bridge void *)block; isaPtr = ksobjc_isaPointer(blockPtr); type = ksobjc_objectType(isaPtr); XCTAssertTrue(type == KSObjCTypeBlock, @""); - - block = ^{NSLog(@"%d", type);}; - blockPtr = (__bridge void*)block; + + block = ^{ + NSLog(@"%d", type); + }; + blockPtr = (__bridge void *)block; isaPtr = ksobjc_isaPointer(blockPtr); type = ksobjc_objectType(isaPtr); XCTAssertTrue(type == KSObjCTypeBlock, @""); - - block = [^{NSLog(@"%d", type);} copy]; - blockPtr = (__bridge void*)block; + + block = [^{ + NSLog(@"%d", type); + } copy]; + blockPtr = (__bridge void *)block; isaPtr = ksobjc_isaPointer(blockPtr); type = ksobjc_objectType(isaPtr); XCTAssertTrue(type == KSObjCTypeBlock, @""); - + __block int value = 0; - - block = ^{value = 1;}; - blockPtr = (__bridge void*)block; + + block = ^{ + value = 1; + }; + blockPtr = (__bridge void *)block; isaPtr = ksobjc_isaPointer(blockPtr); type = ksobjc_objectType(isaPtr); XCTAssertTrue(type == KSObjCTypeBlock, @""); - - block = [^{value = 1;} copy]; - blockPtr = (__bridge void*)block; + + block = [^{ + value = 1; + } copy]; + blockPtr = (__bridge void *)block; isaPtr = ksobjc_isaPointer(blockPtr); type = ksobjc_objectType(isaPtr); XCTAssertTrue(type == KSObjCTypeBlock, @""); } -- (void) testGetClassName +- (void)testGetClassName { Class cls = [NSString class]; - const char* expected = "NSString"; - const char* actual = ksobjc_className((__bridge void *)(cls)); + const char *expected = "NSString"; + const char *actual = ksobjc_className((__bridge void *)(cls)); XCTAssertTrue(actual != NULL, @"result was NULL"); - if(actual != NULL) - { - bool equal = strncmp(expected, actual, strlen(expected)+1) == 0; + if (actual != NULL) { + bool equal = strncmp(expected, actual, strlen(expected) + 1) == 0; XCTAssertTrue(equal, @"expected %s but got %s", expected, actual); } } -- (void) testGetObjectClassName +- (void)testGetObjectClassName { - NSObject* obj = [NSObject new]; - void* objPtr = (__bridge void*)obj; + NSObject *obj = [NSObject new]; + void *objPtr = (__bridge void *)obj; KSObjCType type = ksobjc_objectType(objPtr); XCTAssertEqual(type, KSObjCTypeObject, @""); - const char* expected = "NSObject"; - const void* classPtr = ksobjc_isaPointer(objPtr); - const char* actual = ksobjc_className(classPtr); + const char *expected = "NSObject"; + const void *classPtr = ksobjc_isaPointer(objPtr); + const char *actual = ksobjc_className(classPtr); XCTAssertTrue(actual != NULL, @"result was NULL"); - if(actual != NULL) - { - bool equal = strncmp(expected, actual, strlen(expected)+1) == 0; + if (actual != NULL) { + bool equal = strncmp(expected, actual, strlen(expected) + 1) == 0; XCTAssertTrue(equal, @"expected %s but got %s", expected, actual); } } -- (void) testStringIsValid +- (void)testStringIsValid { - NSString* string = @"test"; - void* stringPtr = (__bridge void*)string; + NSString *string = @"test"; + void *stringPtr = (__bridge void *)string; bool valid = ksobjc_isValidObject(stringPtr); XCTAssertTrue(valid, @""); } -- (void) testStringIsValid2 +- (void)testStringIsValid2 { - NSString* string = [NSString stringWithFormat:@"%d", 1]; - void* stringPtr = (__bridge void*)string; + NSString *string = [NSString stringWithFormat:@"%d", 1]; + void *stringPtr = (__bridge void *)string; bool valid = ksobjc_isValidObject(stringPtr); XCTAssertTrue(valid, @""); } -- (void) testStringIsValid3 +- (void)testStringIsValid3 { - NSMutableString* string = [NSMutableString stringWithFormat:@"%d", 1]; - void* stringPtr = (__bridge void*)string; + NSMutableString *string = [NSMutableString stringWithFormat:@"%d", 1]; + void *stringPtr = (__bridge void *)string; bool valid = ksobjc_isValidObject(stringPtr); XCTAssertTrue(valid, @""); } -- (void) testCFStringIsValid +- (void)testCFStringIsValid { - char* expected = "test"; + char *expected = "test"; int expectedLength = (int)strlen(expected); - CFStringRef stringPtr = CFStringCreateWithBytes(NULL, (uint8_t*)expected, expectedLength, kCFStringEncodingUTF8, FALSE); + CFStringRef stringPtr = + CFStringCreateWithBytes(NULL, (uint8_t *)expected, expectedLength, kCFStringEncodingUTF8, FALSE); bool valid = ksobjc_isValidObject(stringPtr); XCTAssertTrue(valid, @""); CFRelease(stringPtr); } -- (void) testStringLength +- (void)testStringLength { - NSString* string = @"test"; - void* stringPtr = (__bridge void*)string; + NSString *string = @"test"; + void *stringPtr = (__bridge void *)string; int expectedLength = (int)string.length; int length = ksobjc_stringLength(stringPtr); XCTAssertEqual(length, expectedLength, @""); } -- (void) testStringLength2 +- (void)testStringLength2 { - NSString* string = [NSString stringWithFormat:@"%d", 1]; - void* stringPtr = (__bridge void*)string; + NSString *string = [NSString stringWithFormat:@"%d", 1]; + void *stringPtr = (__bridge void *)string; int expectedLength = (int)string.length; int length = ksobjc_stringLength(stringPtr); XCTAssertEqual(length, expectedLength, @""); } -- (void) testStringLength3 +- (void)testStringLength3 { - NSMutableString* string = [NSMutableString stringWithFormat:@"%d", 1]; - void* stringPtr = (__bridge void*)string; + NSMutableString *string = [NSMutableString stringWithFormat:@"%d", 1]; + void *stringPtr = (__bridge void *)string; int expectedLength = (int)string.length; int length = ksobjc_stringLength(stringPtr); XCTAssertEqual(length, expectedLength, @""); } -- (void) testCFStringLength +- (void)testCFStringLength { - char* expected = "test"; + char *expected = "test"; int expectedLength = (int)strlen(expected); - CFStringRef stringPtr = CFStringCreateWithBytes(NULL, (uint8_t*)expected, expectedLength, kCFStringEncodingUTF8, FALSE); + CFStringRef stringPtr = + CFStringCreateWithBytes(NULL, (uint8_t *)expected, expectedLength, kCFStringEncodingUTF8, FALSE); int length = ksobjc_stringLength(stringPtr); XCTAssertEqual(length, expectedLength, @""); } -- (void) testCopyStringContents +- (void)testCopyStringContents { - NSString* string = @"test"; - const char* expected = [string UTF8String]; + NSString *string = @"test"; + const char *expected = [string UTF8String]; int expectedLength = (int)string.length; char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContents2 +- (void)testCopyStringContents2 { - NSString* string = [NSString stringWithFormat:@"%d", 1]; - const char* expected = [string UTF8String]; + NSString *string = [NSString stringWithFormat:@"%d", 1]; + const char *expected = [string UTF8String]; int expectedLength = (int)string.length; char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContents3 +- (void)testCopyStringContents3 { - NSMutableString* string = [NSMutableString stringWithFormat:@"%d", 1]; - const char* expected = [string UTF8String]; + NSMutableString *string = [NSMutableString stringWithFormat:@"%d", 1]; + const char *expected = [string UTF8String]; int expectedLength = (int)string.length; char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsEmpty +- (void)testCopyStringContentsEmpty { - NSString* string = @""; - const char* expected = [string UTF8String]; + NSString *string = @""; + const char *expected = [string UTF8String]; int expectedLength = (int)string.length; char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsTruncate +- (void)testCopyStringContentsTruncate { - NSString* string = @"A longish string"; - const char* expected = "A lo"; + NSString *string = @"A longish string"; + const char *expected = "A lo"; int expectedLength = 4; char actual[5]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContents0Length +- (void)testCopyStringContents0Length { - NSString* string = @"A longish string"; + NSString *string = @"A longish string"; const char expected = 0x7f; int expectedLength = 0; char actual = expected; - int copied = ksobjc_copyStringContents((__bridge void*)string, &actual, 0); + int copied = ksobjc_copyStringContents((__bridge void *)string, &actual, 0); XCTAssertEqual(copied, expectedLength, @""); XCTAssertEqual(actual, expected, @""); } -- (void) testCopyStringContentsUTF16 +- (void)testCopyStringContentsUTF16 { - NSString* string = @"123 テスト 123"; - const char* expected = [string UTF8String]; + NSString *string = @"123 テスト 123"; + const char *expected = [string UTF8String]; int expectedLength = (int)strlen(expected); char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsUTF16_2Byte +- (void)testCopyStringContentsUTF16_2Byte { - NSString* string = @"Ÿ"; - const char* expected = [string UTF8String]; + NSString *string = @"Ÿ"; + const char *expected = [string UTF8String]; int expectedLength = (int)strlen(expected); char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsUTF16_3Byte +- (void)testCopyStringContentsUTF16_3Byte { - NSString* string = @"ঠ"; - const char* expected = [string UTF8String]; + NSString *string = @"ঠ"; + const char *expected = [string UTF8String]; int expectedLength = (int)strlen(expected); char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsUTF16_4Byte +- (void)testCopyStringContentsUTF16_4Byte { - NSString* string = @"𐅐"; - const char* expected = [string UTF8String]; + NSString *string = @"𐅐"; + const char *expected = [string UTF8String]; int expectedLength = (int)strlen(expected); char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsMutable +- (void)testCopyStringContentsMutable { - NSMutableString* string = [NSMutableString stringWithFormat:@"%@", @"test"]; - const char* expected = [string UTF8String]; + NSMutableString *string = [NSMutableString stringWithFormat:@"%@", @"test"]; + const char *expected = [string UTF8String]; int expectedLength = (int)string.length; char actual[100]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsMutableLong +- (void)testCopyStringContentsMutableLong { - NSMutableString* string = [NSMutableString string]; - for(int i = 0; i < 1000; i++) - { + NSMutableString *string = [NSMutableString string]; + for (int i = 0; i < 1000; i++) { [string appendString:@"1"]; } - const char* expected = [string UTF8String]; + const char *expected = [string UTF8String]; int expectedLength = (int)string.length; char actual[2000]; - int copied = ksobjc_copyStringContents((__bridge void*)string, actual, sizeof(actual)); + int copied = ksobjc_copyStringContents((__bridge void *)string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testCopyStringContentsCFString +- (void)testCopyStringContentsCFString { - for(NSUInteger i = 0; i < g_test_strings.count; i++) - { - const char* expected = [g_test_strings[i] UTF8String]; + for (NSUInteger i = 0; i < g_test_strings.count; i++) { + const char *expected = [g_test_strings[i] UTF8String]; int expectedLength = (int)strlen(expected); - CFStringRef string = CFStringCreateWithBytes(NULL, (uint8_t*)expected, (CFIndex)expectedLength, kCFStringEncodingUTF8, FALSE); + CFStringRef string = + CFStringCreateWithBytes(NULL, (uint8_t *)expected, (CFIndex)expectedLength, kCFStringEncodingUTF8, FALSE); char actual[100]; int copied = ksobjc_copyStringContents(string, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); @@ -463,213 +477,212 @@ - (void) testCopyStringContentsCFString } } -- (void) testStringDescription +- (void)testStringDescription { - for(NSUInteger i = 0; i < g_test_strings.count; i++) - { - NSString* string = g_test_strings[i]; - void* stringPtr = (__bridge void*)string; - NSString* expectedClassName = [NSString stringWithCString:class_getName([string class]) encoding:NSUTF8StringEncoding]; - NSString* expectedTheRest = [NSString stringWithFormat:@"\"%@\"", string]; + for (NSUInteger i = 0; i < g_test_strings.count; i++) { + NSString *string = g_test_strings[i]; + void *stringPtr = (__bridge void *)string; + NSString *expectedClassName = [NSString stringWithCString:class_getName([string class]) + encoding:NSUTF8StringEncoding]; + NSString *expectedTheRest = [NSString stringWithFormat:@"\"%@\"", string]; char buffer[100]; int copied = ksobjc_getDescription(stringPtr, buffer, sizeof(buffer)); XCTAssertTrue(copied > 0, @""); - NSString* description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - NSArray* components = [self componentsOfComplexDescription:description]; - NSString* className = [components objectAtIndex:0]; - NSString* theRest = [components objectAtIndex:1]; + NSString *description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; + NSArray *components = [self componentsOfComplexDescription:description]; + NSString *className = [components objectAtIndex:0]; + NSString *theRest = [components objectAtIndex:1]; XCTAssertEqualObjects(className, expectedClassName, @""); XCTAssertEqualObjects(theRest, expectedTheRest, @""); } } -- (void) testURLIsValid +- (void)testURLIsValid { - NSURL* URL = [NSURL URLWithString:@"http://www.google.com"]; - void* URLPtr = (__bridge void*)URL; + NSURL *URL = [NSURL URLWithString:@"http://www.google.com"]; + void *URLPtr = (__bridge void *)URL; bool valid = ksobjc_isValidObject(URLPtr); XCTAssertTrue(valid, @""); } -- (void) testCopyURLContents +- (void)testCopyURLContents { - NSURL* URL = [NSURL URLWithString:@"http://www.google.com"]; - NSString* string = [URL absoluteString]; - const char* expected = [string UTF8String]; + NSURL *URL = [NSURL URLWithString:@"http://www.google.com"]; + NSString *string = [URL absoluteString]; + const char *expected = [string UTF8String]; int expectedLength = (int)string.length; char actual[100]; - int copied = ksobjc_copyURLContents((__bridge void*)URL, actual, sizeof(actual)); + int copied = ksobjc_copyURLContents((__bridge void *)URL, actual, sizeof(actual)); XCTAssertEqual(copied, expectedLength, @""); int result = strcmp(actual, expected); XCTAssertTrue(result == 0, @"String %s did not equal %s", actual, expected); } -- (void) testURLDescription +- (void)testURLDescription { - NSURL* URL = [NSURL URLWithString:@"http://www.google.com"]; - void* URLPtr = (__bridge void*)URL; - NSString* expectedClassName = [NSString stringWithCString:class_getName([URL class]) encoding:NSUTF8StringEncoding]; - NSString* expectedTheRest = @"\"http://www.google.com\""; + NSURL *URL = [NSURL URLWithString:@"http://www.google.com"]; + void *URLPtr = (__bridge void *)URL; + NSString *expectedClassName = [NSString stringWithCString:class_getName([URL class]) encoding:NSUTF8StringEncoding]; + NSString *expectedTheRest = @"\"http://www.google.com\""; char buffer[100]; int copied = ksobjc_getDescription(URLPtr, buffer, sizeof(buffer)); XCTAssertTrue(copied > 0, @""); - NSString* description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - NSArray* components = [self componentsOfComplexDescription:description]; - NSString* className = [components objectAtIndex:0]; - NSString* theRest = [components objectAtIndex:1]; + NSString *description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; + NSArray *components = [self componentsOfComplexDescription:description]; + NSString *className = [components objectAtIndex:0]; + NSString *theRest = [components objectAtIndex:1]; XCTAssertEqualObjects(className, expectedClassName, @""); XCTAssertEqualObjects(theRest, expectedTheRest, @""); } -- (void) testDateIsValid +- (void)testDateIsValid { - NSDate* date = [NSDate dateWithTimeIntervalSinceReferenceDate:10.0]; - void* datePtr = (__bridge void*)date; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:10.0]; + void *datePtr = (__bridge void *)date; bool valid = ksobjc_isValidObject(datePtr); XCTAssertTrue(valid, @""); } -- (void) testGetDateContents +- (void)testGetDateContents { - NSDate* date = [NSDate dateWithTimeIntervalSinceReferenceDate:10.0]; - void* datePtr = (__bridge void*)date; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:10.0]; + void *datePtr = (__bridge void *)date; NSTimeInterval expected = [date timeIntervalSinceReferenceDate]; NSTimeInterval actual = ksobjc_dateContents(datePtr); XCTAssertEqual(actual, expected, @""); } -- (void) testDateDescription +- (void)testDateDescription { - NSDate* date = [NSDate dateWithTimeIntervalSinceReferenceDate:10.0]; - void* datePtr = (__bridge void*)date; - NSString* expectedClassName = @"NSDate"; - NSString* expectedTheRest = @"10.000000"; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:10.0]; + void *datePtr = (__bridge void *)date; + NSString *expectedClassName = @"NSDate"; + NSString *expectedTheRest = @"10.000000"; char buffer[100]; int copied = ksobjc_getDescription(datePtr, buffer, sizeof(buffer)); XCTAssertTrue(copied > 0, @""); - NSString* description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - NSArray* components = [self componentsOfComplexDescription:description]; - NSString* className = [components objectAtIndex:0]; - NSString* theRest = [components objectAtIndex:1]; + NSString *description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; + NSArray *components = [self componentsOfComplexDescription:description]; + NSString *className = [components objectAtIndex:0]; + NSString *theRest = [components objectAtIndex:1]; XCTAssert([className hasSuffix:expectedClassName]); XCTAssertEqualObjects(theRest, expectedTheRest, @""); } -- (void) testNumberIsValid +- (void)testNumberIsValid { - NSNumber* number = [NSNumber numberWithInt:10]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithInt:10]; + void *numberPtr = (__bridge void *)number; bool valid = ksobjc_isValidObject(numberPtr); XCTAssertTrue(valid, @""); } -- (void) testNumberIsFloat +- (void)testNumberIsFloat { - NSNumber* number = [NSNumber numberWithDouble:0.1]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithDouble:0.1]; + void *numberPtr = (__bridge void *)number; bool isFloat = ksobjc_numberIsFloat(numberPtr); XCTAssertTrue(isFloat, ""); } -- (void) testNumberIsFloat2 +- (void)testNumberIsFloat2 { - NSNumber* number = [NSNumber numberWithDouble:1]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithDouble:1]; + void *numberPtr = (__bridge void *)number; bool isFloat = ksobjc_numberIsFloat(numberPtr); XCTAssertTrue(isFloat, ""); } -- (void) testNumberIsInt +- (void)testNumberIsInt { - NSNumber* number = [NSNumber numberWithInt:1]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithInt:1]; + void *numberPtr = (__bridge void *)number; bool isFloat = ksobjc_numberIsFloat(numberPtr); XCTAssertFalse(isFloat, ""); } -- (void) testFloatNumber +- (void)testFloatNumber { Float64 expected = 0.1; - NSNumber* number = [NSNumber numberWithDouble:expected]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithDouble:expected]; + void *numberPtr = (__bridge void *)number; Float64 actual = ksobjc_numberAsFloat(numberPtr); XCTAssertEqual(expected, actual, ""); } -- (void) testFloatNumberWhole +- (void)testFloatNumberWhole { Float64 expected = 1.0; - NSNumber* number = [NSNumber numberWithDouble:expected]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithDouble:expected]; + void *numberPtr = (__bridge void *)number; Float64 actual = ksobjc_numberAsFloat(numberPtr); XCTAssertEqual(expected, actual, ""); } -- (void) testFloatNumberFromInt +- (void)testFloatNumberFromInt { Float64 expected = 1.0; - NSNumber* number = [NSNumber numberWithInt:(int)expected]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithInt:(int)expected]; + void *numberPtr = (__bridge void *)number; Float64 actual = ksobjc_numberAsFloat(numberPtr); XCTAssertEqual(expected, actual, ""); } -- (void) testIntNumber +- (void)testIntNumber { int64_t expected = 55; - NSNumber* number = [NSNumber numberWithLongLong:expected]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithLongLong:expected]; + void *numberPtr = (__bridge void *)number; int64_t actual = ksobjc_numberAsInteger(numberPtr); XCTAssertEqual(expected, actual, ""); } -- (void) testLargeIntNumber +- (void)testLargeIntNumber { int64_t expected = 0x7fffffffffffffff; - NSNumber* number = [NSNumber numberWithLongLong:expected]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithLongLong:expected]; + void *numberPtr = (__bridge void *)number; int64_t actual = ksobjc_numberAsInteger(numberPtr); XCTAssertEqual(expected, actual, ""); } -- (void) testIntNumberFromFloat +- (void)testIntNumberFromFloat { int64_t expected = 55; - NSNumber* number = [NSNumber numberWithDouble:expected]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithDouble:expected]; + void *numberPtr = (__bridge void *)number; int64_t actual = ksobjc_numberAsInteger(numberPtr); XCTAssertEqual(expected, actual, ""); } -- (void) testIntNumberFromFloatTruncated +- (void)testIntNumberFromFloatTruncated { int64_t expected = 55; - NSNumber* number = [NSNumber numberWithDouble:55.8]; - void* numberPtr = (__bridge void*)number; + NSNumber *number = [NSNumber numberWithDouble:55.8]; + void *numberPtr = (__bridge void *)number; int64_t actual = ksobjc_numberAsInteger(numberPtr); XCTAssertEqual(expected, actual, ""); } -- (void) testArrayIsValid +- (void)testArrayIsValid { - NSArray* array = [NSArray array]; - void* arrayPtr = (__bridge void*)array; + NSArray *array = [NSArray array]; + void *arrayPtr = (__bridge void *)array; bool valid = ksobjc_isValidObject(arrayPtr); XCTAssertTrue(valid, @""); } -- (void) testMutableArrayIsValid +- (void)testMutableArrayIsValid { - NSMutableArray* array = [NSMutableArray array]; - void* arrayPtr = (__bridge void*)array; + NSMutableArray *array = [NSMutableArray array]; + void *arrayPtr = (__bridge void *)array; bool valid = ksobjc_isValidObject(arrayPtr); XCTAssertTrue(valid, @""); } -- (void) testCFArrayIsValid +- (void)testCFArrayIsValid { - const void* values[4] = - { + const void *values[4] = { @"1", @"2", @"3", @@ -681,7 +694,7 @@ - (void) testCFArrayIsValid CFRelease(arrayPtr); } -- (void) testEmptyCFMutableArrayIsValid +- (void)testEmptyCFMutableArrayIsValid { CFMutableArrayRef arrayPtr = CFArrayCreateMutable(NULL, 4, NULL); bool valid = ksobjc_isValidObject(arrayPtr); @@ -689,99 +702,101 @@ - (void) testEmptyCFMutableArrayIsValid CFRelease(arrayPtr); } -- (void) testCFMutableArrayIsValid +- (void)testCFMutableArrayIsValid { CFMutableArrayRef arrayPtr = CFArrayCreateMutable(NULL, 4, NULL); id value = @"blah"; - CFArrayAppendValue(arrayPtr, (__bridge void*)value); + CFArrayAppendValue(arrayPtr, (__bridge void *)value); bool valid = ksobjc_isValidObject(arrayPtr); XCTAssertTrue(valid, @""); CFRelease(arrayPtr); } -- (void) testCopyArrayContentsEmpty +- (void)testCopyArrayContentsEmpty { - NSArray* array = [NSArray array]; - void* arrayPtr = (__bridge void*)array; + NSArray *array = [NSArray array]; + void *arrayPtr = (__bridge void *)array; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); } -- (void) testArrayCountEmpty +- (void)testArrayCountEmpty { - NSArray* array = [NSArray array]; - void* arrayPtr = (__bridge void*)array; + NSArray *array = [NSArray array]; + void *arrayPtr = (__bridge void *)array; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, 0, @""); } -- (void) testArrayDescriptionEmpty +- (void)testArrayDescriptionEmpty { - NSArray* array = [NSArray array]; - void* arrayPtr = (__bridge void*)array; - NSString* expectedClassName = [NSString stringWithCString:class_getName([array class]) encoding:NSUTF8StringEncoding]; - NSString* expectedTheRest = @"[]"; + NSArray *array = [NSArray array]; + void *arrayPtr = (__bridge void *)array; + NSString *expectedClassName = [NSString stringWithCString:class_getName([array class]) + encoding:NSUTF8StringEncoding]; + NSString *expectedTheRest = @"[]"; char buffer[100]; int copied = ksobjc_getDescription(arrayPtr, buffer, sizeof(buffer)); XCTAssertTrue(copied > 0, @""); - NSString* description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - NSArray* components = [self componentsOfComplexDescription:description]; - NSString* className = [components objectAtIndex:0]; - NSString* theRest = [components objectAtIndex:1]; + NSString *description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; + NSArray *components = [self componentsOfComplexDescription:description]; + NSString *className = [components objectAtIndex:0]; + NSString *theRest = [components objectAtIndex:1]; XCTAssertEqualObjects(className, expectedClassName, @""); XCTAssertEqualObjects(theRest, expectedTheRest, @""); } -- (void) testArrayDescription +- (void)testArrayDescription { - NSArray* array = [NSArray arrayWithObjects:@"test", nil]; // __NSSingleObjectArrayI - void* arrayPtr = (__bridge void*)array; - NSString* expectedClassName = [NSString stringWithCString:class_getName([array class]) encoding:NSUTF8StringEncoding]; - NSString* expectedTheRest = @"\"test\""; + NSArray *array = [NSArray arrayWithObjects:@"test", nil]; // __NSSingleObjectArrayI + void *arrayPtr = (__bridge void *)array; + NSString *expectedClassName = [NSString stringWithCString:class_getName([array class]) + encoding:NSUTF8StringEncoding]; + NSString *expectedTheRest = @"\"test\""; char buffer[100]; int copied = ksobjc_getDescription(arrayPtr, buffer, sizeof(buffer)); XCTAssertTrue(copied > 0, @""); - NSString* description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - NSArray* components = [self componentsOfComplexDescription:description]; - NSString* className = [components objectAtIndex:0]; - NSString* theRest = [components objectAtIndex:1]; + NSString *description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; + NSArray *components = [self componentsOfComplexDescription:description]; + NSString *className = [components objectAtIndex:0]; + NSString *theRest = [components objectAtIndex:1]; XCTAssertEqualObjects(className, expectedClassName, @""); - + // Remove bounding [ and ] - theRest = [theRest substringWithRange:NSMakeRange(1, [theRest length]-2)]; + theRest = [theRest substringWithRange:NSMakeRange(1, [theRest length] - 2)]; components = [self componentsOfComplexDescription:theRest]; className = [components objectAtIndex:0]; theRest = [components objectAtIndex:1]; - expectedClassName = [NSString stringWithCString:class_getName([expectedTheRest class]) encoding:NSUTF8StringEncoding]; + expectedClassName = [NSString stringWithCString:class_getName([expectedTheRest class]) + encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(className, expectedClassName, @""); XCTAssertEqualObjects(theRest, expectedTheRest, @""); } -- (void) testCopyArrayContentsImmutable +- (void)testCopyArrayContentsImmutable { - NSArray* array = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil]; // __NSArrayI - void* arrayPtr = (__bridge void*)array; + NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil]; // __NSArrayI + void *arrayPtr = (__bridge void *)array; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); uintptr_t contents[10]; int copied = ksobjc_arrayContents(arrayPtr, contents, sizeof(contents)); XCTAssertEqual(copied, count, @""); - for(int i = 0; i < count; i++) - { - bool isValid = ksobjc_objectType((void*)contents[i]) == KSObjCTypeObject; + for (int i = 0; i < count; i++) { + bool isValid = ksobjc_objectType((void *)contents[i]) == KSObjCTypeObject; XCTAssertTrue(isValid, @"Object %d is not an object", i); - isValid = ksobjc_isValidObject((void*)contents[i]); + isValid = ksobjc_isValidObject((void *)contents[i]); XCTAssertTrue(isValid, @"Object %d is invalid", i); } } -- (void) testCopyArrayContentsImmutableEmpty +- (void)testCopyArrayContentsImmutableEmpty { - NSArray* array = [NSArray array]; - void* arrayPtr = (__bridge void*)array; + NSArray *array = [NSArray array]; + void *arrayPtr = (__bridge void *)array; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); @@ -790,10 +805,10 @@ - (void) testCopyArrayContentsImmutableEmpty XCTAssertEqual(copied, expectedCount, @""); } -- (void) testCopyArrayContentsMutable +- (void)testCopyArrayContentsMutable { - NSMutableArray* array = [NSMutableArray arrayWithObjects:@"1", @"2", @"3", @"4", nil]; // __NSArrayM - void* arrayPtr = (__bridge void*)array; + NSMutableArray *array = [NSMutableArray arrayWithObjects:@"1", @"2", @"3", @"4", nil]; // __NSArrayM + void *arrayPtr = (__bridge void *)array; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); @@ -803,14 +818,16 @@ - (void) testCopyArrayContentsMutable XCTAssertEqual(copied, expectedCopied, @""); } -- (void) testCopyArrayContentsCopyOfMutable +- (void)testCopyArrayContentsCopyOfMutable { NSMutableArray *array = [NSMutableArray array]; int size = 100; - for (NSUInteger i = 0; i < size; i++) { [array addObject:@(i)]; } + for (NSUInteger i = 0; i < size; i++) { + [array addObject:@(i)]; + } - NSArray *copy = array.copy; // __NSFrozenArrayM - void* arrayPtr = (__bridge void*)copy; + NSArray *copy = array.copy; // __NSFrozenArrayM + void *arrayPtr = (__bridge void *)copy; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); @@ -820,10 +837,10 @@ - (void) testCopyArrayContentsCopyOfMutable XCTAssertEqual(copied, expectedCopied, @""); } -- (void) testCopyArrayContentsMutableEmpty +- (void)testCopyArrayContentsMutableEmpty { - NSMutableArray* array = [NSMutableArray array]; - void* arrayPtr = (__bridge void*)array; + NSMutableArray *array = [NSMutableArray array]; + void *arrayPtr = (__bridge void *)array; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); @@ -832,37 +849,35 @@ - (void) testCopyArrayContentsMutableEmpty XCTAssertEqual(copied, expectedCount, @""); } -- (void) testCopyArrayContentsCFArray +- (void)testCopyArrayContentsCFArray { - const void* values[4] = - { + const void *values[4] = { @"1", @"2", @"3", @"4", }; CFArrayRef arrayPtr = CFArrayCreate(NULL, values, 4, NULL); - NSArray* array = (__bridge NSArray*)arrayPtr; + NSArray *array = (__bridge NSArray *)arrayPtr; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); uintptr_t contents[10]; int copied = ksobjc_arrayContents(arrayPtr, contents, sizeof(contents)); XCTAssertEqual(copied, count, @""); - for(int i = 0; i < count; i++) - { - bool isValid = ksobjc_objectType((void*)contents[i]) == KSObjCTypeObject; + for (int i = 0; i < count; i++) { + bool isValid = ksobjc_objectType((void *)contents[i]) == KSObjCTypeObject; XCTAssertTrue(isValid, @"Object %d is not an object", i); - isValid = ksobjc_isValidObject((void*)contents[i]); + isValid = ksobjc_isValidObject((void *)contents[i]); XCTAssertTrue(isValid, @"Object %d is invalid", i); } CFRelease(arrayPtr); } -- (void) testCopyArrayContentsCFArrayEmpty +- (void)testCopyArrayContentsCFArrayEmpty { CFArrayRef arrayPtr = CFArrayCreate(NULL, NULL, 0, NULL); - NSArray* array = (__bridge NSArray*)arrayPtr; + NSArray *array = (__bridge NSArray *)arrayPtr; int expectedCount = (int)array.count; int count = ksobjc_arrayCount(arrayPtr); XCTAssertEqual(count, expectedCount, @""); @@ -872,52 +887,53 @@ - (void) testCopyArrayContentsCFArrayEmpty CFRelease(arrayPtr); } -- (void) testUntrackedClassIsValid +- (void)testUntrackedClassIsValid { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; bool isValid = ksobjc_objectType(classPtr) == KSObjCTypeClass; XCTAssertTrue(isValid, @"Not a class"); } -- (void) testUntrackedClassDescription +- (void)testUntrackedClassDescription { - SomeObjCClass* instance = [[SomeObjCClass alloc] init]; - void* instancePtr = (__bridge void*)instance; - NSString* expectedClassName = [NSString stringWithCString:class_getName([instance class]) encoding:NSUTF8StringEncoding]; + SomeObjCClass *instance = [[SomeObjCClass alloc] init]; + void *instancePtr = (__bridge void *)instance; + NSString *expectedClassName = [NSString stringWithCString:class_getName([instance class]) + encoding:NSUTF8StringEncoding]; char buffer[100]; int copied = ksobjc_getDescription(instancePtr, buffer, sizeof(buffer)); XCTAssertTrue(copied > 0, @""); - NSString* description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - NSArray* components = [self componentsOfBasicDescription:description]; - NSString* className = [components objectAtIndex:0]; + NSString *description = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; + NSArray *components = [self componentsOfBasicDescription:description]; + NSString *className = [components objectAtIndex:0]; XCTAssertEqualObjects(className, expectedClassName, @""); } -- (void) testSuperclass +- (void)testSuperclass { - void* classPtr = (__bridge void*)[SomeObjCClass class]; - const void* expected = (__bridge void*)[NSObject class]; - const void* superclass = ksobjc_superClass(classPtr); + void *classPtr = (__bridge void *)[SomeObjCClass class]; + const void *expected = (__bridge void *)[NSObject class]; + const void *superclass = ksobjc_superClass(classPtr); XCTAssertEqual(superclass, expected, @""); } -- (void) testNSObjectIsRootClass +- (void)testNSObjectIsRootClass { - void* classPtr = (__bridge void*)[NSObject class]; + void *classPtr = (__bridge void *)[NSObject class]; bool isRootClass = ksobjc_isRootClass(classPtr); XCTAssertTrue(isRootClass, @""); } -- (void) testNotRootClass +- (void)testNotRootClass { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; bool isRootClass = ksobjc_isRootClass(classPtr); XCTAssertFalse(isRootClass, @""); } -- (void) testIsClassNamed +- (void)testIsClassNamed { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; bool isClassNamed = ksobjc_isClassNamed(classPtr, "SomeObjCClass"); XCTAssertTrue(isClassNamed, @""); isClassNamed = ksobjc_isClassNamed(classPtr, "NSObject"); @@ -926,9 +942,9 @@ - (void) testIsClassNamed XCTAssertFalse(isClassNamed, @""); } -- (void) testIsKindOfClass +- (void)testIsKindOfClass { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; bool isKindOfClass = ksobjc_isKindOfClass(classPtr, "NSObject"); XCTAssertTrue(isKindOfClass, @""); isKindOfClass = ksobjc_isKindOfClass(classPtr, "NSDate"); @@ -937,33 +953,33 @@ - (void) testIsKindOfClass XCTAssertFalse(isKindOfClass, @""); } -- (void) testBaseClass +- (void)testBaseClass { - const void* classPtr = (__bridge void*)[SomeSubclass class]; - const void* expected = (__bridge void*)[SomeObjCClass class]; - const void* baseClass = ksobjc_baseClass(classPtr); + const void *classPtr = (__bridge void *)[SomeSubclass class]; + const void *expected = (__bridge void *)[SomeObjCClass class]; + const void *baseClass = ksobjc_baseClass(classPtr); XCTAssertEqual(baseClass, expected, @""); } -- (void) testIvarCount +- (void)testIvarCount { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; int ivarCount = ksobjc_ivarCount(classPtr); XCTAssertEqual(ivarCount, 2, @""); } -- (void) testIvarList +- (void)testIvarList { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; KSObjCIvar ivars[10]; - int ivarCount = ksobjc_ivarList(classPtr, ivars, sizeof(ivars)/sizeof(*ivars)); - const char* expectedIvar1Name = "someIvar"; - const char* expectedIvar1Type = "i"; - const char* expectedIvar2Name = "anotherIvar"; - const char* expectedIvar2Type = "@"; - + int ivarCount = ksobjc_ivarList(classPtr, ivars, sizeof(ivars) / sizeof(*ivars)); + const char *expectedIvar1Name = "someIvar"; + const char *expectedIvar1Type = "i"; + const char *expectedIvar2Name = "anotherIvar"; + const char *expectedIvar2Type = "@"; + int compare; - + XCTAssertEqual(ivarCount, 2, @""); compare = strcmp(ivars[0].name, expectedIvar1Name); XCTAssertEqual(compare, 0, @""); @@ -975,16 +991,16 @@ - (void) testIvarList XCTAssertEqual(compare, 0, @""); } -- (void) testIvarListTruncated +- (void)testIvarListTruncated { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; KSObjCIvar ivars[1]; - int ivarCount = ksobjc_ivarList(classPtr, ivars, sizeof(ivars)/sizeof(*ivars)); - const char* expectedIvar1Name = "someIvar"; - const char* expectedIvar1Type = "i"; - + int ivarCount = ksobjc_ivarList(classPtr, ivars, sizeof(ivars) / sizeof(*ivars)); + const char *expectedIvar1Name = "someIvar"; + const char *expectedIvar1Type = "i"; + int compare; - + XCTAssertEqual(ivarCount, 1, @""); compare = strcmp(ivars[0].name, expectedIvar1Name); XCTAssertEqual(compare, 0, @""); @@ -992,30 +1008,30 @@ - (void) testIvarListTruncated XCTAssertEqual(compare, 0, @""); } -- (void) testIvarListNull +- (void)testIvarListNull { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; int ivarCount = ksobjc_ivarList(classPtr, NULL, 10); XCTAssertEqual(ivarCount, 0, @""); } -- (void) testIvarNamed +- (void)testIvarNamed { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; KSObjCIvar ivar; bool found = ksobjc_ivarNamed(classPtr, "someIvar", &ivar); XCTAssertTrue(found, @""); - const char* expectedIvarName = "someIvar"; - const char* expectedIvarType = "i"; + const char *expectedIvarName = "someIvar"; + const char *expectedIvarType = "i"; int compare = strcmp(ivar.name, expectedIvarName); XCTAssertEqual(compare, 0, @""); compare = strcmp(ivar.type, expectedIvarType); XCTAssertEqual(compare, 0, @""); } -- (void) testIvarNamedNotFound +- (void)testIvarNamedNotFound { - void* classPtr = (__bridge void*)[SomeObjCClass class]; + void *classPtr = (__bridge void *)[SomeObjCClass class]; KSObjCIvar ivar; bool found = ksobjc_ivarNamed(classPtr, "blahblahh", &ivar); XCTAssertFalse(found, @""); @@ -1024,31 +1040,31 @@ - (void) testIvarNamedNotFound XCTAssertFalse(found, @""); } -- (void) testIvarValue +- (void)testIvarValue { int expectedValue = 100; - SomeObjCClass* object = [[SomeObjCClass alloc] init]; + SomeObjCClass *object = [[SomeObjCClass alloc] init]; object.someIvar = expectedValue; - void* objectPtr = (__bridge void*)object; + void *objectPtr = (__bridge void *)object; int value = 0; bool success = ksobjc_ivarValue(objectPtr, 0, &value); XCTAssertTrue(success, @""); XCTAssertEqual(value, expectedValue, @""); } -- (void) testIvarValueOutOfRange +- (void)testIvarValueOutOfRange { - SomeObjCClass* object = [[SomeObjCClass alloc] init]; - void* objectPtr = (__bridge void*)object; + SomeObjCClass *object = [[SomeObjCClass alloc] init]; + void *objectPtr = (__bridge void *)object; int value = 0; bool success = ksobjc_ivarValue(objectPtr, 100, &value); XCTAssertFalse(success, @""); } -- (void) testUnknownObjectIsValid +- (void)testUnknownObjectIsValid { - SomeObjCClass* object = [[SomeObjCClass alloc] init]; - void* objectPtr = (__bridge void*)object; + SomeObjCClass *object = [[SomeObjCClass alloc] init]; + void *objectPtr = (__bridge void *)object; bool success = ksobjc_isValidObject(objectPtr); XCTAssertTrue(success, @""); } diff --git a/Tests/KSCrashRecordingCoreTests/KSSignalInfo_Tests.m b/Tests/KSCrashRecordingCoreTests/KSSignalInfo_Tests.m index 6865a9ea9..dad04f644 100644 --- a/Tests/KSCrashRecordingCoreTests/KSSignalInfo_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSSignalInfo_Tests.m @@ -24,63 +24,61 @@ // THE SOFTWARE. // - #import #import "KSSignalInfo.h" - -@interface KSSignalInfo_Tests : XCTestCase @end - +@interface KSSignalInfo_Tests : XCTestCase +@end @implementation KSSignalInfo_Tests -- (void) testSignalName +- (void)testSignalName { - NSString* expected = @"SIGBUS"; - NSString* actual = [NSString stringWithCString:kssignal_signalName(SIGBUS) encoding:NSUTF8StringEncoding]; + NSString *expected = @"SIGBUS"; + NSString *actual = [NSString stringWithCString:kssignal_signalName(SIGBUS) encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected, @""); } -- (void) testHighSignalName +- (void)testHighSignalName { - const char* result = kssignal_signalName(90); + const char *result = kssignal_signalName(90); XCTAssertTrue(result == NULL, @""); } -- (void) testNegativeSignalName +- (void)testNegativeSignalName { - const char* result = kssignal_signalName(-1); + const char *result = kssignal_signalName(-1); XCTAssertTrue(result == NULL, @""); } -- (void) testSignalCodeName +- (void)testSignalCodeName { - NSString* expected = @"BUS_ADRERR"; - NSString* actual = [NSString stringWithCString:kssignal_signalCodeName(SIGBUS, BUS_ADRERR) + NSString *expected = @"BUS_ADRERR"; + NSString *actual = [NSString stringWithCString:kssignal_signalCodeName(SIGBUS, BUS_ADRERR) encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected, @""); } -- (void) testHighSignalCodeName +- (void)testHighSignalCodeName { - const char* result = kssignal_signalCodeName(SIGBUS, 90); + const char *result = kssignal_signalCodeName(SIGBUS, 90); XCTAssertTrue(result == NULL, @""); } -- (void) testNegativeSignalCodeName +- (void)testNegativeSignalCodeName { - const char* result = kssignal_signalCodeName(SIGBUS, -1); + const char *result = kssignal_signalCodeName(SIGBUS, -1); XCTAssertTrue(result == NULL, @""); } -- (void) testFatalSignals +- (void)testFatalSignals { - const int* fatalSignals = kssignal_fatalSignals(); + const int *fatalSignals = kssignal_fatalSignals(); XCTAssertTrue(fatalSignals != NULL, @""); } -- (void) testNumFatalSignals +- (void)testNumFatalSignals { int numSignals = kssignal_numFatalSignals(); XCTAssertTrue(numSignals > 0, @""); diff --git a/Tests/KSCrashRecordingCoreTests/KSString_Tests.m b/Tests/KSCrashRecordingCoreTests/KSString_Tests.m index 57930ddf4..c7005e248 100644 --- a/Tests/KSCrashRecordingCoreTests/KSString_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSString_Tests.m @@ -24,20 +24,18 @@ // THE SOFTWARE. // - #import #import "KSString.h" - -@interface KSString_Tests : XCTestCase @end - +@interface KSString_Tests : XCTestCase +@end @implementation KSString_Tests -- (void) testExtractHexValue +- (void)testExtractHexValue { - const char* string = "Some string with 0x12345678 and such"; + const char *string = "Some string with 0x12345678 and such"; uint64_t expected = 0x12345678; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); @@ -45,9 +43,9 @@ - (void) testExtractHexValue XCTAssertEqual(result, expected, @""); } -- (void) testExtractHexValue2 +- (void)testExtractHexValue2 { - const char* string = "Some string with 0x1 and such"; + const char *string = "Some string with 0x1 and such"; uint64_t expected = 0x1; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); @@ -55,9 +53,9 @@ - (void) testExtractHexValue2 XCTAssertEqual(result, expected, @""); } -- (void) testExtractHexValue3 +- (void)testExtractHexValue3 { - const char* string = "Some string with 0x1234567890123456 and such"; + const char *string = "Some string with 0x1234567890123456 and such"; uint64_t expected = 0x1234567890123456; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); @@ -65,9 +63,9 @@ - (void) testExtractHexValue3 XCTAssertEqual(result, expected, @""); } -- (void) testExtractHexValueBeginning +- (void)testExtractHexValueBeginning { - const char* string = "0x12345678 Some string"; + const char *string = "0x12345678 Some string"; uint64_t expected = 0x12345678; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); @@ -75,9 +73,9 @@ - (void) testExtractHexValueBeginning XCTAssertEqual(result, expected, @""); } -- (void) testExtractHexValueEnd +- (void)testExtractHexValueEnd { - const char* string = "Some string with 0x12345678"; + const char *string = "Some string with 0x12345678"; uint64_t expected = 0x12345678; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); @@ -85,96 +83,96 @@ - (void) testExtractHexValueEnd XCTAssertEqual(result, expected, @""); } -- (void) testExtractHexValueEmpty +- (void)testExtractHexValueEmpty { - const char* string = ""; + const char *string = ""; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); XCTAssertFalse(success, @""); } -- (void) testExtractHexValueInvalid +- (void)testExtractHexValueInvalid { - const char* string = "Some string with 0xoo and such"; + const char *string = "Some string with 0xoo and such"; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); XCTAssertFalse(success, @""); } -- (void) testExtractHexValueInvalid2 +- (void)testExtractHexValueInvalid2 { - const char* string = "Some string with 0xoo"; + const char *string = "Some string with 0xoo"; uint64_t result = 0; bool success = ksstring_extractHexValue(string, (int)strlen(string), &result); XCTAssertFalse(success, @""); } -- (void) testIsNullTerminatedUTF8String +- (void)testIsNullTerminatedUTF8String { - const char* string = "A string"; + const char *string = "A string"; bool success = ksstring_isNullTerminatedUTF8String(string, 2, 100); XCTAssertTrue(success, @""); } -- (void) testIsNullTerminatedUTF8String2 +- (void)testIsNullTerminatedUTF8String2 { - const char* string = "テスト"; + const char *string = "テスト"; bool success = ksstring_isNullTerminatedUTF8String(string, 2, 100); XCTAssertTrue(success, @""); } -- (void) testIsNullTerminatedUTF8String3 +- (void)testIsNullTerminatedUTF8String3 { - const char* string = "aŸঠ𐅐 and so on"; + const char *string = "aŸঠ𐅐 and so on"; bool success = ksstring_isNullTerminatedUTF8String(string, 2, 100); XCTAssertTrue(success, @""); } -- (void) testIsNullTerminatedUTF8StringTooShort +- (void)testIsNullTerminatedUTF8StringTooShort { - const char* string = "A string"; + const char *string = "A string"; bool success = ksstring_isNullTerminatedUTF8String(string, 10, 100); XCTAssertFalse(success, @""); } -- (void) testIsNullTerminatedUTF8StringTooLong +- (void)testIsNullTerminatedUTF8StringTooLong { - const char* string = "A string"; + const char *string = "A string"; bool success = ksstring_isNullTerminatedUTF8String(string, 2, 5); XCTAssertFalse(success, @""); } -- (void) testIsNullTerminatedUTF8StringInvalid +- (void)testIsNullTerminatedUTF8StringInvalid { - const char* string = "A string\xf8"; + const char *string = "A string\xf8"; bool success = ksstring_isNullTerminatedUTF8String(string, 2, 100); XCTAssertFalse(success, @""); } -- (void) testIsNullTerminatedUTF8StringInvalid2 +- (void)testIsNullTerminatedUTF8StringInvalid2 { - const char* string = "A string\xc1zzz"; + const char *string = "A string\xc1zzz"; bool success = ksstring_isNullTerminatedUTF8String(string, 2, 100); XCTAssertFalse(success, @""); } -- (void) testIsNullTerminatedUTF8StringInvalid3 +- (void)testIsNullTerminatedUTF8StringInvalid3 { - const char* string = "\xc0"; + const char *string = "\xc0"; bool success = ksstring_isNullTerminatedUTF8String(string, 1, 1); XCTAssertFalse(success, @""); } -- (void) testIsNullTerminatedUTF8StringInvalid4 +- (void)testIsNullTerminatedUTF8StringInvalid4 { - const char* string = "blah \x80"; + const char *string = "blah \x80"; bool success = ksstring_isNullTerminatedUTF8String(string, 1, 100); XCTAssertFalse(success, @""); } -- (void) testIsNullTerminatedUTF8StringInvalid5 +- (void)testIsNullTerminatedUTF8StringInvalid5 { - const char* string = "\x01\x02\x03"; + const char *string = "\x01\x02\x03"; bool success = ksstring_isNullTerminatedUTF8String(string, 2, 100); XCTAssertFalse(success, @""); } diff --git a/Tests/KSCrashRecordingCoreTests/KSSysCtl_Tests.m b/Tests/KSCrashRecordingCoreTests/KSSysCtl_Tests.m index 902639973..4472fe7da 100644 --- a/Tests/KSCrashRecordingCoreTests/KSSysCtl_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSSysCtl_Tests.m @@ -24,177 +24,175 @@ // THE SOFTWARE. // - #import #import "KSSysCtl.h" - -@interface KSSysCtl_Tests : XCTestCase @end - +@interface KSSysCtl_Tests : XCTestCase +@end @implementation KSSysCtl_Tests -- (void) testSysCtlInt32 +- (void)testSysCtlInt32 { int32_t result = kssysctl_int32(CTL_KERN, KERN_POSIX1); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlInt32Invalid +- (void)testSysCtlInt32Invalid { int32_t result = kssysctl_int32(CTL_KERN, 1000000); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlInt32ForName +- (void)testSysCtlInt32ForName { int32_t result = kssysctl_int32ForName("kern.posix1version"); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlInt32ForNameInvalid +- (void)testSysCtlInt32ForNameInvalid { int32_t result = kssysctl_int32ForName("kernblah.posix1version"); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlInt64 +- (void)testSysCtlInt64 { int64_t result = kssysctl_int64(CTL_KERN, KERN_USRSTACK64); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlInt64Invalid +- (void)testSysCtlInt64Invalid { int64_t result = kssysctl_int64(CTL_KERN, 1000000); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlInt64ForName +- (void)testSysCtlInt64ForName { int64_t result = kssysctl_int64ForName("kern.usrstack64"); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlInt64ForNameInvalid +- (void)testSysCtlInt64ForNameInvalid { int64_t result = kssysctl_int64ForName("kernblah.usrstack64"); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlUInt32 +- (void)testSysCtlUInt32 { uint32_t result = kssysctl_uint32(CTL_KERN, KERN_POSIX1); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlUInt32Invalid +- (void)testSysCtlUInt32Invalid { uint32_t result = kssysctl_uint32(CTL_KERN, 1000000); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlUInt32ForName +- (void)testSysCtlUInt32ForName { uint32_t result = kssysctl_uint32ForName("kern.posix1version"); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlUInt32ForNameInvalid +- (void)testSysCtlUInt32ForNameInvalid { uint32_t result = kssysctl_uint32ForName("kernblah.posix1version"); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlUInt64 +- (void)testSysCtlUInt64 { uint64_t result = kssysctl_uint64(CTL_KERN, KERN_USRSTACK64); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlUInt64Invalid +- (void)testSysCtlUInt64Invalid { uint64_t result = kssysctl_uint64(CTL_KERN, 1000000); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlUInt64ForName +- (void)testSysCtlUInt64ForName { uint64_t result = kssysctl_uint64ForName("kern.usrstack64"); XCTAssertTrue(result > 0, @""); } -- (void) testSysCtlUInt64ForNameInvalid +- (void)testSysCtlUInt64ForNameInvalid { uint64_t result = kssysctl_uint64ForName("kernblah.usrstack64"); XCTAssertTrue(result == 0, @""); } -- (void) testSysCtlString +- (void)testSysCtlString { - char buff[100] = {0}; + char buff[100] = { 0 }; bool success = kssysctl_string(CTL_KERN, KERN_OSTYPE, buff, sizeof(buff)); XCTAssertTrue(success, @""); XCTAssertTrue(buff[0] != 0, @""); } -- (void) testSysCtlStringInvalid +- (void)testSysCtlStringInvalid { - char buff[100] = {0}; + char buff[100] = { 0 }; bool success = kssysctl_string(CTL_KERN, 1000000, buff, sizeof(buff)); XCTAssertFalse(success, @""); XCTAssertTrue(buff[0] == 0, @""); } -- (void) testSysCtlStringForName +- (void)testSysCtlStringForName { - char buff[100] = {0}; + char buff[100] = { 0 }; bool success = kssysctl_stringForName("kern.ostype", buff, sizeof(buff)); XCTAssertTrue(success, @""); XCTAssertTrue(buff[0] != 0, @""); } -- (void) testSysCtlStringForNameInvalid +- (void)testSysCtlStringForNameInvalid { - char buff[100] = {0}; + char buff[100] = { 0 }; bool success = kssysctl_stringForName("kernblah.ostype", buff, sizeof(buff)); XCTAssertFalse(success, @""); XCTAssertTrue(buff[0] == 0, @""); } -- (void) testSysCtlDate +- (void)testSysCtlDate { struct timeval value = kssysctl_timeval(CTL_KERN, KERN_BOOTTIME); XCTAssertTrue(value.tv_sec > 0, @""); } -- (void) testSysCtlDateInvalid +- (void)testSysCtlDateInvalid { struct timeval value = kssysctl_timeval(CTL_KERN, 1000000); XCTAssertTrue(value.tv_sec == 0, @""); } -- (void) testSysCtlDateForName +- (void)testSysCtlDateForName { struct timeval value = kssysctl_timevalForName("kern.boottime"); XCTAssertTrue(value.tv_sec > 0, @""); } -- (void) testSysCtlDateForNameInvalid +- (void)testSysCtlDateForNameInvalid { struct timeval value = kssysctl_timevalForName("kernblah.boottime"); XCTAssertTrue(value.tv_sec == 0, @""); } -- (void) testGetProcessInfo +- (void)testGetProcessInfo { int pid = getpid(); - struct kinfo_proc procInfo = {{{{0}}}}; + struct kinfo_proc procInfo = { { { { 0 } } } }; bool success = kssysctl_getProcessInfo(pid, &procInfo); XCTAssertTrue(success, @""); - NSString* processName = [NSString stringWithCString:procInfo.kp_proc.p_comm encoding:NSUTF8StringEncoding]; - NSString* expected = @"xctest"; + NSString *processName = [NSString stringWithCString:procInfo.kp_proc.p_comm encoding:NSUTF8StringEncoding]; + NSString *expected = @"xctest"; XCTAssertEqualObjects(processName, expected, @""); } @@ -207,23 +205,22 @@ - (void) testGetProcessInfo // XCTAssertFalse(success, @""); //} -- (void) testGetMacAddress +- (void)testGetMacAddress { - unsigned char macAddress[6] = {0}; - bool success = kssysctl_getMacAddress("en0", (char*)macAddress); + unsigned char macAddress[6] = { 0 }; + bool success = kssysctl_getMacAddress("en0", (char *)macAddress); XCTAssertTrue(success, @""); unsigned int result = 0; - for(unsigned i = 0; i < sizeof(macAddress); i++) - { + for (unsigned i = 0; i < sizeof(macAddress); i++) { result |= macAddress[i]; } XCTAssertTrue(result != 0, @""); } -- (void) testGetMacAddressInvalid +- (void)testGetMacAddressInvalid { - unsigned char macAddress[6] = {0}; - bool success = kssysctl_getMacAddress("blah blah", (char*)macAddress); + unsigned char macAddress[6] = { 0 }; + bool success = kssysctl_getMacAddress("blah blah", (char *)macAddress); XCTAssertFalse(success, @""); } diff --git a/Tests/KSCrashRecordingCoreTests/KSThread_Tests.m b/Tests/KSCrashRecordingCoreTests/KSThread_Tests.m index 1c1aa4cea..a4a65ae35 100644 --- a/Tests/KSCrashRecordingCoreTests/KSThread_Tests.m +++ b/Tests/KSCrashRecordingCoreTests/KSThread_Tests.m @@ -24,18 +24,17 @@ // THE SOFTWARE. // - #import #import "KSThread.h" #import "TestThread.h" - -@interface KSThread_Tests : XCTestCase @end +@interface KSThread_Tests : XCTestCase +@end @implementation KSThread_Tests -- (void) testGetQueueName +- (void)testGetQueueName { kern_return_t kr; const task_t thisTask = mach_task_self(); @@ -47,18 +46,15 @@ - (void) testGetQueueName bool success = false; char buffer[100]; - for(mach_msg_type_number_t i = 0; i < numThreads; i++) - { + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { thread_t thread = threads[i]; - if(ksthread_getQueueName(thread, buffer, sizeof(buffer))) - { + if (ksthread_getQueueName(thread, buffer, sizeof(buffer))) { success = true; break; } } - for(mach_msg_type_number_t i = 0; i < numThreads; i++) - { + for (mach_msg_type_number_t i = 0; i < numThreads; i++) { mach_port_deallocate(thisTask, threads[i]); } vm_deallocate(thisTask, (vm_address_t)threads, sizeof(thread_t) * numThreads); diff --git a/Tests/KSCrashRecordingTests/KSCrashCachedData_Tests.m b/Tests/KSCrashRecordingTests/KSCrashCachedData_Tests.m index 3529e1490..fc3b6c9fa 100644 --- a/Tests/KSCrashRecordingTests/KSCrashCachedData_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashCachedData_Tests.m @@ -22,22 +22,20 @@ // THE SOFTWARE. // - #import #import "KSCrashCachedData.h" #import "TestThread.h" - -@interface KSCrashCachedData_Tests : XCTestCase @end - +@interface KSCrashCachedData_Tests : XCTestCase +@end @implementation KSCrashCachedData_Tests -- (void) testGetThreadName +- (void)testGetThreadName { - NSString* expectedName = @"This is a test thread"; - TestThread* thread = [TestThread new]; + NSString *expectedName = @"This is a test thread"; + TestThread *thread = [TestThread new]; thread.name = expectedName; [thread start]; [NSThread sleepForTimeInterval:0.1]; @@ -45,9 +43,9 @@ - (void) testGetThreadName [NSThread sleepForTimeInterval:0.1]; [thread cancel]; ksccd_freeze(); - const char* cName = ksccd_getThreadName(thread.thread); + const char *cName = ksccd_getThreadName(thread.thread); XCTAssertTrue(cName != NULL); - NSString* name = [NSString stringWithUTF8String:cName]; + NSString *name = [NSString stringWithUTF8String:cName]; XCTAssertEqualObjects(name, expectedName); ksccd_unfreeze(); } diff --git a/Tests/KSCrashRecordingTests/KSCrashConfiguration_Tests.m b/Tests/KSCrashRecordingTests/KSCrashConfiguration_Tests.m index 2cd7f445d..37fc185d3 100644 --- a/Tests/KSCrashRecordingTests/KSCrashConfiguration_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashConfiguration_Tests.m @@ -1,6 +1,6 @@ // // KSCrashConfiguration_Tests.m -// +// // Created by Gleb Linnik on 13.06.2024. // // Copyright (c) 2012 Karl Stenerud. All rights reserved. @@ -25,8 +25,8 @@ // #import -#import "KSCrashConfiguration.h" #import "KSCrashConfiguration+Private.h" +#import "KSCrashConfiguration.h" @interface KSCrashConfigurationTests : XCTestCase @end @@ -56,11 +56,11 @@ - (void)testToCConfiguration { KSCrashConfiguration *config = [[KSCrashConfiguration alloc] init]; config.monitors = KSCrashMonitorTypeDebuggerSafe; - config.userInfoJSON = @{@"key": @"value"}; + config.userInfoJSON = @{ @"key" : @"value" }; config.deadlockWatchdogInterval = 5.0; config.enableQueueNameSearch = YES; config.enableMemoryIntrospection = YES; - config.doNotIntrospectClasses = @[@"ClassA", @"ClassB"]; + config.doNotIntrospectClasses = @[ @"ClassA", @"ClassB" ]; config.addConsoleLogToReport = YES; config.printPreviousLogOnStartup = YES; config.maxReportCount = 10; @@ -83,8 +83,7 @@ - (void)testToCConfiguration XCTAssertTrue(cConfig.enableSwapCxaThrow); // Free memory allocated for C string array - for (int i = 0; i < cConfig.doNotIntrospectClasses.length; i++) - { + for (int i = 0; i < cConfig.doNotIntrospectClasses.length; i++) { free((void *)cConfig.doNotIntrospectClasses.strings[i]); } free(cConfig.doNotIntrospectClasses.strings); @@ -95,11 +94,11 @@ - (void)testCopyWithZone { KSCrashConfiguration *config = [[KSCrashConfiguration alloc] init]; config.monitors = KSCrashMonitorTypeDebuggerSafe; - config.userInfoJSON = @{@"key": @"value"}; + config.userInfoJSON = @{ @"key" : @"value" }; config.deadlockWatchdogInterval = 5.0; config.enableQueueNameSearch = YES; config.enableMemoryIntrospection = YES; - config.doNotIntrospectClasses = @[@"ClassA", @"ClassB"]; + config.doNotIntrospectClasses = @[ @"ClassA", @"ClassB" ]; config.addConsoleLogToReport = YES; config.printPreviousLogOnStartup = YES; config.maxReportCount = 10; @@ -108,11 +107,11 @@ - (void)testCopyWithZone KSCrashConfiguration *copy = [config copy]; XCTAssertEqual(copy.monitors, KSCrashMonitorTypeDebuggerSafe); - XCTAssertEqualObjects(copy.userInfoJSON, @{@"key": @"value"}); + XCTAssertEqualObjects(copy.userInfoJSON, @{ @"key" : @"value" }); XCTAssertEqual(copy.deadlockWatchdogInterval, 5.0); XCTAssertTrue(copy.enableQueueNameSearch); XCTAssertTrue(copy.enableMemoryIntrospection); - XCTAssertEqualObjects(copy.doNotIntrospectClasses, (@[@"ClassA", @"ClassB"])); + XCTAssertEqualObjects(copy.doNotIntrospectClasses, (@[ @"ClassA", @"ClassB" ])); XCTAssertTrue(copy.addConsoleLogToReport); XCTAssertTrue(copy.printPreviousLogOnStartup); XCTAssertEqual(copy.maxReportCount, 10); @@ -155,7 +154,7 @@ - (void)testLargeDataForJSONConversion - (void)testSpecialCharactersInStrings { KSCrashConfiguration *config = [[KSCrashConfiguration alloc] init]; - config.userInfoJSON = @{@"key": @"value with special characters: @#$%^&*()"}; + config.userInfoJSON = @{ @"key" : @"value with special characters: @#$%^&*()" }; KSCrashCConfiguration cConfig = [config toCConfiguration]; XCTAssertTrue(cConfig.userInfoJSON != NULL); diff --git a/Tests/KSCrashRecordingTests/KSCrashDoctor_Tests.m b/Tests/KSCrashRecordingTests/KSCrashDoctor_Tests.m index c2133fac5..9fcd7d721 100644 --- a/Tests/KSCrashRecordingTests/KSCrashDoctor_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashDoctor_Tests.m @@ -3,7 +3,8 @@ #import "KSCrashDoctor.h" #import "KSTestModuleConfig.h" -@interface KSCrashDoctor_Tests : XCTestCase @end +@interface KSCrashDoctor_Tests : XCTestCase +@end @implementation KSCrashDoctor_Tests @@ -14,14 +15,14 @@ @implementation KSCrashDoctor_Tests return [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; } -- (void) testGracefulTermination +- (void)testGracefulTermination { id report = [self _crashReportAsJSON:@"sigterm"]; NSString *diagnostic = [[[KSCrashDoctor alloc] init] diagnoseCrash:report]; XCTAssertEqual(diagnostic, @"The OS request the app be gracefully terminated."); } -- (void) testOOM +- (void)testOOM { id report = [self _crashReportAsJSON:@"oom"]; NSString *diagnostic = [[[KSCrashDoctor alloc] init] diagnoseCrash:report]; diff --git a/Tests/KSCrashRecordingTests/KSCrashMonitor_AppState_Tests.m b/Tests/KSCrashRecordingTests/KSCrashMonitor_AppState_Tests.m index 016308d2d..d44a0b9d1 100644 --- a/Tests/KSCrashRecordingTests/KSCrashMonitor_AppState_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashMonitor_AppState_Tests.m @@ -24,27 +24,25 @@ // THE SOFTWARE. // - #import "FileBasedTestCase.h" #import "XCTestCase+KSCrash.h" #import "KSCrashMonitor_AppState.h" - -@interface KSCrashMonitor_AppState_Tests : FileBasedTestCase @end - +@interface KSCrashMonitor_AppState_Tests : FileBasedTestCase +@end @implementation KSCrashMonitor_AppState_Tests -- (void) initializeCrashState +- (void)initializeCrashState { - NSString* stateFile = [self.tempPath stringByAppendingPathComponent:@"state.json"]; + NSString *stateFile = [self.tempPath stringByAppendingPathComponent:@"state.json"]; kscrashstate_initialize([stateFile cStringUsingEncoding:NSUTF8StringEncoding]); kscm_appstate_getAPI()->setEnabled(false); kscm_appstate_getAPI()->setEnabled(true); } -- (void) testInitRelaunch +- (void)testInitRelaunch { [self initializeCrashState]; KSCrash_AppState context = *kscrashstate_currentState(); @@ -83,7 +81,7 @@ - (void) testInitRelaunch XCTAssertFalse(context.crashedLastLaunch, @""); } -- (void) testInitCrash +- (void)testInitCrash { [self initializeCrashState]; KSCrash_AppState context = *kscrashstate_currentState(); @@ -94,26 +92,17 @@ - (void) testInitCrash kscrashstate_notifyAppCrash(); KSCrash_AppState checkpointC = *kscrashstate_currentState(); - XCTAssertTrue(checkpointC.applicationIsInForeground == - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpointC.applicationIsActive == - checkpoint0.applicationIsActive, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLaunch == - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpointC.applicationIsInForeground == checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpointC.applicationIsActive == checkpoint0.applicationIsActive, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpointC.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLaunch == checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); @@ -137,11 +126,11 @@ - (void) testInitCrash XCTAssertTrue(context.crashedLastLaunch, @""); } -- (void) testActRelaunch +- (void)testActRelaunch { [self initializeCrashState]; KSCrash_AppState context = *kscrashstate_currentState(); - + KSCrash_AppState checkpoint0 = *kscrashstate_currentState(); usleep(1); @@ -149,27 +138,18 @@ - (void) testActRelaunch KSCrash_AppState checkpoint1 = *kscrashstate_currentState(); - XCTAssertTrue(checkpoint1.applicationIsInForeground == - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpoint1.applicationIsActive != - checkpoint0.applicationIsActive, @""); + XCTAssertTrue(checkpoint1.applicationIsInForeground == checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpoint1.applicationIsActive != checkpoint0.applicationIsActive, @""); XCTAssertTrue(checkpoint1.applicationIsActive, @""); - XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash == - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpoint1.activeDurationSinceLaunch == - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch == - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash == checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash == checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpoint1.activeDurationSinceLaunch == checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertFalse(checkpoint1.crashedThisLaunch, @""); XCTAssertFalse(checkpoint1.crashedLastLaunch, @""); @@ -177,7 +157,7 @@ - (void) testActRelaunch usleep(1); [self initializeCrashState]; context = *kscrashstate_currentState(); - + XCTAssertTrue(context.applicationIsInForeground, @""); XCTAssertFalse(context.applicationIsActive, @""); @@ -194,7 +174,7 @@ - (void) testActRelaunch XCTAssertFalse(context.crashedLastLaunch, @""); } -- (void) testActCrash +- (void)testActCrash { [self initializeCrashState]; usleep(1); @@ -205,26 +185,17 @@ - (void) testActCrash kscrashstate_notifyAppCrash(); KSCrash_AppState checkpointC = *kscrashstate_currentState(); - XCTAssertTrue(checkpointC.applicationIsInForeground == - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpointC.applicationIsActive == - checkpoint0.applicationIsActive, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLastCrash > - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLaunch > - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpointC.applicationIsInForeground == checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpointC.applicationIsActive == checkpoint0.applicationIsActive, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLastCrash > checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpointC.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLaunch > checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); @@ -248,7 +219,7 @@ - (void) testActCrash XCTAssertTrue(context.crashedLastLaunch, @""); } -- (void) testActDeactRelaunch +- (void)testActDeactRelaunch { [self initializeCrashState]; usleep(1); @@ -259,27 +230,18 @@ - (void) testActDeactRelaunch kscrashstate_notifyAppActive(false); KSCrash_AppState checkpoint1 = *kscrashstate_currentState(); - XCTAssertTrue(checkpoint1.applicationIsInForeground == - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpoint1.applicationIsActive != - checkpoint0.applicationIsActive, @""); + XCTAssertTrue(checkpoint1.applicationIsInForeground == checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpoint1.applicationIsActive != checkpoint0.applicationIsActive, @""); XCTAssertFalse(checkpoint1.applicationIsActive, @""); - XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash > - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpoint1.activeDurationSinceLaunch > - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch == - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash > checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash == checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpoint1.activeDurationSinceLaunch > checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertFalse(checkpoint1.crashedThisLaunch, @""); XCTAssertFalse(checkpoint1.crashedLastLaunch, @""); @@ -305,7 +267,7 @@ - (void) testActDeactRelaunch XCTAssertFalse(checkpointR.crashedLastLaunch, @""); } -- (void) testActDeactCrash +- (void)testActDeactCrash { [self initializeCrashState]; KSCrash_AppState context = *kscrashstate_currentState(); @@ -319,26 +281,17 @@ - (void) testActDeactCrash kscrashstate_notifyAppCrash(); KSCrash_AppState checkpointC = *kscrashstate_currentState(); - XCTAssertTrue(checkpointC.applicationIsInForeground == - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpointC.applicationIsActive == - checkpoint0.applicationIsActive, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLaunch == - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpointC.applicationIsInForeground == checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpointC.applicationIsActive == checkpoint0.applicationIsActive, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpointC.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLaunch == checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); @@ -362,7 +315,7 @@ - (void) testActDeactCrash XCTAssertTrue(context.crashedLastLaunch, @""); } -- (void) testActDeactBGRelaunch +- (void)testActDeactBGRelaunch { [self initializeCrashState]; usleep(1); @@ -375,27 +328,18 @@ - (void) testActDeactBGRelaunch kscrashstate_notifyAppInForeground(false); KSCrash_AppState checkpoint1 = *kscrashstate_currentState(); - XCTAssertTrue(checkpoint1.applicationIsInForeground != - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpoint1.applicationIsActive == - checkpoint0.applicationIsActive, @""); + XCTAssertTrue(checkpoint1.applicationIsInForeground != checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpoint1.applicationIsActive == checkpoint0.applicationIsActive, @""); XCTAssertFalse(checkpoint1.applicationIsInForeground, @""); - XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash == - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpoint1.activeDurationSinceLaunch == - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch == - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash == checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash == checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpoint1.activeDurationSinceLaunch == checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertFalse(checkpoint1.crashedThisLaunch, @""); XCTAssertFalse(checkpoint1.crashedLastLaunch, @""); @@ -420,7 +364,7 @@ - (void) testActDeactBGRelaunch XCTAssertFalse(checkpointR.crashedLastLaunch, @""); } -- (void) testActDeactBGTerminate +- (void)testActDeactBGTerminate { [self initializeCrashState]; usleep(1); @@ -440,8 +384,7 @@ - (void) testActDeactBGTerminate XCTAssertTrue(checkpointR.applicationIsInForeground, @""); XCTAssertFalse(checkpointR.applicationIsActive, @""); - XCTAssertTrue(checkpointR.backgroundDurationSinceLastCrash > - checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointR.backgroundDurationSinceLastCrash > checkpoint0.backgroundDurationSinceLastCrash, @""); XCTAssertEqual(checkpointR.launchesSinceLastCrash, 2, @""); XCTAssertEqual(checkpointR.sessionsSinceLastCrash, 2, @""); @@ -453,7 +396,7 @@ - (void) testActDeactBGTerminate XCTAssertFalse(checkpointR.crashedLastLaunch, @""); } -- (void) testActDeactBGCrash +- (void)testActDeactBGCrash { [self initializeCrashState]; KSCrash_AppState context = *kscrashstate_currentState(); @@ -469,26 +412,17 @@ - (void) testActDeactBGCrash kscrashstate_notifyAppCrash(); KSCrash_AppState checkpointC = *kscrashstate_currentState(); - XCTAssertTrue(checkpointC.applicationIsInForeground == - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpointC.applicationIsActive == - checkpoint0.applicationIsActive, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash > - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLaunch == - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch > - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpointC.applicationIsInForeground == checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpointC.applicationIsActive == checkpoint0.applicationIsActive, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash > checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpointC.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLaunch == checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch > checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); @@ -512,7 +446,7 @@ - (void) testActDeactBGCrash XCTAssertTrue(context.crashedLastLaunch, @""); } -- (void) testActDeactBGFGRelaunch +- (void)testActDeactBGFGRelaunch { [self initializeCrashState]; usleep(1); @@ -528,27 +462,18 @@ - (void) testActDeactBGFGRelaunch kscrashstate_notifyAppInForeground(true); KSCrash_AppState checkpoint1 = *kscrashstate_currentState(); - XCTAssertTrue(checkpoint1.applicationIsInForeground != - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpoint1.applicationIsActive == - checkpoint0.applicationIsActive, @""); + XCTAssertTrue(checkpoint1.applicationIsInForeground != checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpoint1.applicationIsActive == checkpoint0.applicationIsActive, @""); XCTAssertTrue(checkpoint1.applicationIsInForeground, @""); - XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash == - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash > - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash + 1, @""); - - XCTAssertTrue(checkpoint1.activeDurationSinceLaunch == - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch > - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpoint1.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch + 1, @""); + XCTAssertTrue(checkpoint1.activeDurationSinceLastCrash == checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLastCrash > checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash + 1, @""); + + XCTAssertTrue(checkpoint1.activeDurationSinceLaunch == checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.backgroundDurationSinceLaunch > checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpoint1.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch + 1, @""); XCTAssertFalse(checkpoint1.crashedThisLaunch, @""); XCTAssertFalse(checkpoint1.crashedLastLaunch, @""); @@ -574,7 +499,7 @@ - (void) testActDeactBGFGRelaunch XCTAssertFalse(checkpointR.crashedLastLaunch, @""); } -- (void) testActDeactBGFGCrash +- (void)testActDeactBGFGCrash { [self initializeCrashState]; KSCrash_AppState context = *kscrashstate_currentState(); @@ -592,26 +517,17 @@ - (void) testActDeactBGFGCrash kscrashstate_notifyAppCrash(); KSCrash_AppState checkpointC = *kscrashstate_currentState(); - XCTAssertTrue(checkpointC.applicationIsInForeground == - checkpoint0.applicationIsInForeground, @""); - XCTAssertTrue(checkpointC.applicationIsActive == - checkpoint0.applicationIsActive, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == - checkpoint0.activeDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == - checkpoint0.backgroundDurationSinceLastCrash, @""); - XCTAssertTrue(checkpointC.launchesSinceLastCrash == - checkpoint0.launchesSinceLastCrash, @""); - XCTAssertTrue(checkpointC.sessionsSinceLastCrash == - checkpoint0.sessionsSinceLastCrash, @""); - - XCTAssertTrue(checkpointC.activeDurationSinceLaunch == - checkpoint0.activeDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == - checkpoint0.backgroundDurationSinceLaunch, @""); - XCTAssertTrue(checkpointC.sessionsSinceLaunch == - checkpoint0.sessionsSinceLaunch, @""); + XCTAssertTrue(checkpointC.applicationIsInForeground == checkpoint0.applicationIsInForeground, @""); + XCTAssertTrue(checkpointC.applicationIsActive == checkpoint0.applicationIsActive, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLastCrash == checkpoint0.activeDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLastCrash == checkpoint0.backgroundDurationSinceLastCrash, @""); + XCTAssertTrue(checkpointC.launchesSinceLastCrash == checkpoint0.launchesSinceLastCrash, @""); + XCTAssertTrue(checkpointC.sessionsSinceLastCrash == checkpoint0.sessionsSinceLastCrash, @""); + + XCTAssertTrue(checkpointC.activeDurationSinceLaunch == checkpoint0.activeDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.backgroundDurationSinceLaunch == checkpoint0.backgroundDurationSinceLaunch, @""); + XCTAssertTrue(checkpointC.sessionsSinceLaunch == checkpoint0.sessionsSinceLaunch, @""); XCTAssertTrue(checkpointC.crashedThisLaunch, @""); XCTAssertFalse(checkpointC.crashedLastLaunch, @""); diff --git a/Tests/KSCrashRecordingTests/KSCrashMonitor_Deadlock_Tests.m b/Tests/KSCrashRecordingTests/KSCrashMonitor_Deadlock_Tests.m index 3f80baf0f..194d6b62a 100644 --- a/Tests/KSCrashRecordingTests/KSCrashMonitor_Deadlock_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashMonitor_Deadlock_Tests.m @@ -24,21 +24,19 @@ // THE SOFTWARE. // - #import #import "KSCrashMonitorContext.h" #import "KSCrashMonitor_Deadlock.h" - -@interface KSCrashMonitor_Deadlock_Tests : XCTestCase @end - +@interface KSCrashMonitor_Deadlock_Tests : XCTestCase +@end @implementation KSCrashMonitor_Deadlock_Tests -- (void) testInstallAndRemove +- (void)testInstallAndRemove { - KSCrashMonitorAPI* api = kscm_deadlock_getAPI(); + KSCrashMonitorAPI *api = kscm_deadlock_getAPI(); kscm_setDeadlockHandlerWatchdogInterval(10); api->setEnabled(true); XCTAssertTrue(api->isEnabled()); @@ -47,10 +45,10 @@ - (void) testInstallAndRemove XCTAssertFalse(api->isEnabled()); } -- (void) testDoubleInstallAndRemove +- (void)testDoubleInstallAndRemove { - KSCrashMonitorAPI* api = kscm_deadlock_getAPI(); - + KSCrashMonitorAPI *api = kscm_deadlock_getAPI(); + api->setEnabled(true); XCTAssertTrue(api->isEnabled()); api->setEnabled(true); diff --git a/Tests/KSCrashRecordingTests/KSCrashMonitor_Memory_Tests.m b/Tests/KSCrashRecordingTests/KSCrashMonitor_Memory_Tests.m index cbc2b327e..b8e79eeb2 100644 --- a/Tests/KSCrashRecordingTests/KSCrashMonitor_Memory_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashMonitor_Memory_Tests.m @@ -21,33 +21,33 @@ // THE SOFTWARE. // - #import -#import "KSSystemCapabilities.h" +#import "KSCrashAppMemory+Private.h" +#import "KSCrashAppStateTracker.h" #import "KSCrashMonitorContext.h" #import "KSCrashMonitor_Memory.h" #import "KSCrashReportStore.h" -#import "KSCrashAppStateTracker.h" -#import "KSCrashAppMemory+Private.h" +#import "KSSystemCapabilities.h" -@interface KSCrashMonitor_Memory_Tests : XCTestCase @end +@interface KSCrashMonitor_Memory_Tests : XCTestCase +@end @implementation KSCrashMonitor_Memory_Tests - (void)setUp { [super setUp]; - + // reset defaults ksmemory_set_nonfatal_report_level(KSCrash_Memory_NonFatalReportLevelNone); ksmemory_set_fatal_reports_enabled(true); setenv("ActivePrewarm", "0", 1); } -- (void) testInstallAndRemove +- (void)testInstallAndRemove { - KSCrashMonitorAPI* api = kscm_memory_getAPI(); + KSCrashMonitorAPI *api = kscm_memory_getAPI(); api->setEnabled(true); XCTAssertTrue(api->isEnabled()); [NSThread sleepForTimeInterval:0.1]; @@ -55,31 +55,29 @@ - (void) testInstallAndRemove XCTAssertFalse(api->isEnabled()); } -- (void) testDoubleInstallAndRemove +- (void)testDoubleInstallAndRemove { - KSCrashMonitorAPI* api = kscm_memory_getAPI(); - + KSCrashMonitorAPI *api = kscm_memory_getAPI(); + api->setEnabled(true); XCTAssertTrue(api->isEnabled()); api->setEnabled(true); XCTAssertTrue(api->isEnabled()); - + api->setEnabled(false); XCTAssertFalse(api->isEnabled()); api->setEnabled(false); XCTAssertFalse(api->isEnabled()); } -- (void) testInstallation +- (void)testInstallation { (void)KSCrash.sharedInstance; - - __KSCrashAppMemorySetProvider(^KSCrashAppMemory * _Nonnull{ - return [[KSCrashAppMemory alloc] initWithFootprint:100 - remaining:0 - pressure:KSCrashAppMemoryStateNormal]; + + __KSCrashAppMemorySetProvider(^KSCrashAppMemory *_Nonnull { + return [[KSCrashAppMemory alloc] initWithFootprint:100 remaining:0 pressure:KSCrashAppMemoryStateNormal]; }); - + // Generate a unique identifier NSString *uniqueIdentifier = [[NSUUID UUID] UUIDString]; @@ -97,17 +95,16 @@ - (void) testInstallation NSFileManager *mngr = [NSFileManager new]; [mngr removeItemAtURL:memoryURL error:nil]; [mngr removeItemAtURL:breadcrumbURL error:nil]; - - + // init KSCrashCConfiguration config = KSCrashCConfiguration_Default(); config.monitors = KSCrashMonitorTypeMemoryTermination; kscrash_install("test", installURL.path.UTF8String, config); - + // init memory API - KSCrashMonitorAPI* api = kscm_memory_getAPI(); + KSCrashMonitorAPI *api = kscm_memory_getAPI(); XCTAssertTrue(api->isEnabled()); - + // validate we didn't OOM bool userPerceptible = false; BOOL oomed = ksmemory_previous_session_was_terminated_due_to_memory(&userPerceptible); @@ -119,7 +116,7 @@ - (void) testInstallation [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidFinishLaunchingNotification object:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidBecomeActiveNotification object:nil]; #endif - + // disable // FIXME: The call to `kscrash_setMonitoring(KSCrashMonitorTypeNone)` is temporarily commented out // because the public API is not fully formed yet. Currently using `kscm_disableAllMonitors()` @@ -141,7 +138,7 @@ - (void) testInstallation // notify the system is enabled api->notifyPostSystemEnable(); - + // check oom oomed = ksmemory_previous_session_was_terminated_due_to_memory(&userPerceptible); XCTAssertTrue(oomed); @@ -149,7 +146,7 @@ - (void) testInstallation // check the last report, it should be the OOM report NSMutableArray *reports = [NSMutableArray array]; - int64_t reportIDs[10] = {0}; + int64_t reportIDs[10] = { 0 }; kscrash_getReportIDs(reportIDs, 10); for (int index = 0; index < 10; index++) { int64_t reportID = reportIDs[index]; @@ -164,43 +161,57 @@ - (void) testInstallation } } XCTAssert(reports.count > 0); - + NSUInteger oomReports = 0; for (NSDictionary *report in reports) { - - if (![report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_Type] isEqualToString:KSCrashExcType_MemoryTermination]) { + if (![report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_Type] + isEqualToString:KSCrashExcType_MemoryTermination]) { continue; } - + oomReports++; - - XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryLevel], @"terminal"); - XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryPressure], @"normal"); - XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryFootprint], @(100)); + + XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryLevel], + @"terminal"); + XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryPressure], + @"normal"); + XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryFootprint], + @(100)); XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryRemaining], @(0)); XCTAssertEqualObjects(report[KSCrashField_System][KSCrashField_AppMemory][KSCrashField_MemoryLimit], @(100)); - - XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryLevel], @"terminal"); - XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryPressure], @"normal"); - XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryFootprint], @(100)); - XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryRemaining], @(0)); - XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryLimit], @(100)); - - XCTAssertEqualObjects(report [KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_Signal][KSCrashField_Signal], @(SIGKILL)); - XCTAssertEqualObjects(report [KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_Signal][KSCrashField_Name], @"SIGKILL"); - + + XCTAssertEqualObjects( + report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryLevel], + @"terminal"); + XCTAssertEqualObjects( + report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryPressure], + @"normal"); + XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination] + [KSCrashField_MemoryFootprint], + @(100)); + XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination] + [KSCrashField_MemoryRemaining], + @(0)); + XCTAssertEqualObjects( + report[KSCrashField_Crash][KSCrashField_Error][KSCrashField_MemoryTermination][KSCrashField_MemoryLimit], + @(100)); + + XCTAssertEqualObjects( + report[KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_Signal][KSCrashField_Signal], @(SIGKILL)); + XCTAssertEqualObjects(report[KSCrashField_Crash][KSCrashField_Error][KSCrashExcType_Signal][KSCrashField_Name], + @"SIGKILL"); } - + XCTAssert(oomReports > 0); } -- (void) testTransitionState +- (void)testTransitionState { XCTAssertFalse(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateStartupPrewarm)); XCTAssertFalse(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateBackground)); XCTAssertFalse(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateTerminating)); XCTAssertFalse(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateExiting)); - + XCTAssertTrue(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateStartup)); XCTAssertTrue(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateLaunching)); XCTAssertTrue(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateForegrounding)); @@ -208,26 +219,29 @@ - (void) testTransitionState XCTAssertTrue(ksapp_transitionStateIsUserPerceptible(KSCrashAppTransitionStateDeactivating)); } -static KSCrashAppMemory *Memory(uint64_t footprint) { - return [[KSCrashAppMemory alloc] initWithFootprint:footprint remaining:100-footprint pressure:KSCrashAppMemoryStateNormal]; +static KSCrashAppMemory *Memory(uint64_t footprint) +{ + return [[KSCrashAppMemory alloc] initWithFootprint:footprint + remaining:100 - footprint + pressure:KSCrashAppMemoryStateNormal]; } -- (void) testAppMemory +- (void)testAppMemory { XCTAssertEqual(Memory(0).level, KSCrashAppMemoryStateNormal); XCTAssertEqual(Memory(25).level, KSCrashAppMemoryStateWarn); XCTAssertEqual(Memory(50).level, KSCrashAppMemoryStateUrgent); XCTAssertEqual(Memory(75).level, KSCrashAppMemoryStateCritical); XCTAssertEqual(Memory(95).level, KSCrashAppMemoryStateTerminal); - + XCTAssertEqual(Memory(0).isOutOfMemory, NO); XCTAssertEqual(Memory(25).isOutOfMemory, NO); XCTAssertEqual(Memory(50).isOutOfMemory, NO); XCTAssertEqual(Memory(75).isOutOfMemory, YES); XCTAssertEqual(Memory(95).isOutOfMemory, YES); - + KSCrashAppMemory *memory = Memory(50); - + XCTAssertEqual(memory.footprint, 50); XCTAssertEqual(memory.remaining, 50); XCTAssertEqual(memory.limit, 100); @@ -238,41 +252,41 @@ - (void)testAppStateTrackerNoPrewarm NSNotificationCenter *center = NSNotificationCenter.defaultCenter; setenv("ActivePrewarm", "0", 1); __block KSCrashAppTransitionState state; - + KSCrashAppStateTracker *tracker = [KSCrashAppStateTracker new]; [tracker addObserverWithBlock:^(KSCrashAppTransitionState transitionState) { state = transitionState; }]; - + XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateStartup); - + [tracker start]; - + #if KSCRASH_HAS_UIAPPLICATION [center postNotificationName:UIApplicationDidFinishLaunchingNotification object:nil]; XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateLaunching); XCTAssertEqual(tracker.transitionState, state); - + [center postNotificationName:UIApplicationWillEnterForegroundNotification object:nil]; XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateForegrounding); XCTAssertEqual(tracker.transitionState, state); - + [center postNotificationName:UIApplicationDidBecomeActiveNotification object:nil]; XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateActive); XCTAssertEqual(tracker.transitionState, state); - + [center postNotificationName:UIApplicationWillResignActiveNotification object:nil]; XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateDeactivating); XCTAssertEqual(tracker.transitionState, state); - + [center postNotificationName:UIApplicationDidEnterBackgroundNotification object:nil]; XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateBackground); XCTAssertEqual(tracker.transitionState, state); - + [center postNotificationName:UIApplicationDidFinishLaunchingNotification object:nil]; XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateLaunching); XCTAssertEqual(tracker.transitionState, state); - + [center postNotificationName:UIApplicationWillTerminateNotification object:nil]; XCTAssertEqual(tracker.transitionState, KSCrashAppTransitionStateTerminating); XCTAssertEqual(tracker.transitionState, state); @@ -282,13 +296,13 @@ - (void)testAppStateTrackerNoPrewarm #endif } -- (void) testNonFatalReportLevel +- (void)testNonFatalReportLevel { XCTAssertEqual(ksmemory_get_nonfatal_report_level(), KSCrash_Memory_NonFatalReportLevelNone); - + ksmemory_set_nonfatal_report_level(12); XCTAssertEqual(ksmemory_get_nonfatal_report_level(), 12); - + ksmemory_set_nonfatal_report_level(KSCrashAppMemoryStateUrgent); XCTAssertEqual(ksmemory_get_nonfatal_report_level(), KSCrashAppMemoryStateUrgent); } diff --git a/Tests/KSCrashRecordingTests/KSCrashMonitor_NSException_Tests.m b/Tests/KSCrashRecordingTests/KSCrashMonitor_NSException_Tests.m index c4495ded0..12a4f86a1 100644 --- a/Tests/KSCrashRecordingTests/KSCrashMonitor_NSException_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashMonitor_NSException_Tests.m @@ -24,21 +24,19 @@ // THE SOFTWARE. // - #import #import "KSCrashMonitorContext.h" #import "KSCrashMonitor_NSException.h" - -@interface KSCrashMonitor_NSException_Tests : XCTestCase @end - +@interface KSCrashMonitor_NSException_Tests : XCTestCase +@end @implementation KSCrashMonitor_NSException_Tests -- (void) testInstallAndRemove +- (void)testInstallAndRemove { - KSCrashMonitorAPI* api = kscm_nsexception_getAPI(); + KSCrashMonitorAPI *api = kscm_nsexception_getAPI(); api->setEnabled(true); XCTAssertTrue(api->isEnabled()); [NSThread sleepForTimeInterval:0.1]; @@ -46,15 +44,15 @@ - (void) testInstallAndRemove XCTAssertFalse(api->isEnabled()); } -- (void) testDoubleInstallAndRemove +- (void)testDoubleInstallAndRemove { - KSCrashMonitorAPI* api = kscm_nsexception_getAPI(); - + KSCrashMonitorAPI *api = kscm_nsexception_getAPI(); + api->setEnabled(true); XCTAssertTrue(api->isEnabled()); api->setEnabled(true); XCTAssertTrue(api->isEnabled()); - + api->setEnabled(false); XCTAssertFalse(api->isEnabled()); api->setEnabled(false); diff --git a/Tests/KSCrashRecordingTests/KSCrashMonitor_Signal_Tests.m b/Tests/KSCrashRecordingTests/KSCrashMonitor_Signal_Tests.m index 61452834b..636afad3f 100644 --- a/Tests/KSCrashRecordingTests/KSCrashMonitor_Signal_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashMonitor_Signal_Tests.m @@ -24,23 +24,22 @@ // THE SOFTWARE. // - #import -#import "KSSystemCapabilities.h" #import "KSCrashMonitorContext.h" #import "KSCrashMonitor_Signal.h" +#import "KSSystemCapabilities.h" -@interface KSCrashMonitor_Signal_Tests : XCTestCase @end - +@interface KSCrashMonitor_Signal_Tests : XCTestCase +@end @implementation KSCrashMonitor_Signal_Tests #if KSCRASH_HAS_SIGNAL -- (void) testInstallAndRemove +- (void)testInstallAndRemove { - KSCrashMonitorAPI* api = kscm_signal_getAPI(); + KSCrashMonitorAPI *api = kscm_signal_getAPI(); api->setEnabled(true); XCTAssertTrue(api->isEnabled()); [NSThread sleepForTimeInterval:0.1]; @@ -48,15 +47,15 @@ - (void) testInstallAndRemove XCTAssertFalse(api->isEnabled()); } -- (void) testDoubleInstallAndRemove +- (void)testDoubleInstallAndRemove { - KSCrashMonitorAPI* api = kscm_signal_getAPI(); - + KSCrashMonitorAPI *api = kscm_signal_getAPI(); + api->setEnabled(true); XCTAssertTrue(api->isEnabled()); api->setEnabled(true); XCTAssertTrue(api->isEnabled()); - + api->setEnabled(false); XCTAssertFalse(api->isEnabled()); api->setEnabled(false); @@ -65,9 +64,9 @@ - (void) testDoubleInstallAndRemove #else -- (void) testNoImplementation +- (void)testNoImplementation { - KSCrashMonitorAPI* api = kscm_signal_getAPI(); + KSCrashMonitorAPI *api = kscm_signal_getAPI(); XCTAssertTrue(api == NULL); } diff --git a/Tests/KSCrashRecordingTests/KSCrashReportFixer_Tests.m b/Tests/KSCrashRecordingTests/KSCrashReportFixer_Tests.m index 25e208243..ddd05565c 100644 --- a/Tests/KSCrashRecordingTests/KSCrashReportFixer_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashReportFixer_Tests.m @@ -16,31 +16,34 @@ @interface KSCrashReportFixer_Tests : XCTestCase @implementation KSCrashReportFixer_Tests -- (void)setUp { +- (void)setUp +{ [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. } -- (void)tearDown { +- (void)tearDown +{ // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testLoadCrash { - NSBundle* bundle = KS_TEST_MODULE_BUNDLE; - NSString* rawPath = [bundle pathForResource:@"raw" ofType:@"json"]; - NSData* rawData = [NSData dataWithContentsOfFile:rawPath]; - char* fixedBytes = kscrf_fixupCrashReport(rawData.bytes); -// NSLog(@"%@", [[NSString alloc] initWithData:[NSData dataWithBytes:fixedBytes length:strlen(fixedBytes)] encoding:NSUTF8StringEncoding]); - NSData* fixedData = [NSData dataWithBytesNoCopy:fixedBytes length:strlen(fixedBytes)]; - NSError* error = nil; + NSBundle *bundle = KS_TEST_MODULE_BUNDLE; + NSString *rawPath = [bundle pathForResource:@"raw" ofType:@"json"]; + NSData *rawData = [NSData dataWithContentsOfFile:rawPath]; + char *fixedBytes = kscrf_fixupCrashReport(rawData.bytes); + // NSLog(@"%@", [[NSString alloc] initWithData:[NSData dataWithBytes:fixedBytes length:strlen(fixedBytes)] + // encoding:NSUTF8StringEncoding]); + NSData *fixedData = [NSData dataWithBytesNoCopy:fixedBytes length:strlen(fixedBytes)]; + NSError *error = nil; id fixedObjects = [NSJSONSerialization JSONObjectWithData:fixedData options:0 error:&error]; XCTAssertNil(error); XCTAssertNotNil(fixedObjects); - NSString* processedPath = [bundle pathForResource:@"processed" ofType:@"json"]; - NSData* processedData = [NSData dataWithContentsOfFile:processedPath]; + NSString *processedPath = [bundle pathForResource:@"processed" ofType:@"json"]; + NSData *processedData = [NSData dataWithContentsOfFile:processedPath]; id processedObjects = [NSJSONSerialization JSONObjectWithData:processedData options:0 error:&error]; XCTAssertNil(error); XCTAssertNotNil(processedObjects); diff --git a/Tests/KSCrashRecordingTests/KSCrashReportStore_Tests.m b/Tests/KSCrashRecordingTests/KSCrashReportStore_Tests.m index 4bbb5dc88..59f124629 100644 --- a/Tests/KSCrashRecordingTests/KSCrashReportStore_Tests.m +++ b/Tests/KSCrashRecordingTests/KSCrashReportStore_Tests.m @@ -24,7 +24,6 @@ // THE SOFTWARE. // - #import "FileBasedTestCase.h" #import "XCTestCase+KSCrash.h" @@ -32,15 +31,13 @@ #include - #define REPORT_PREFIX @"CrashReport-KSCrashTest" - @interface KSCrashReportStore_Tests : FileBasedTestCase -@property(nonatomic,readwrite,retain) NSString* appName; -@property(nonatomic,readwrite,retain) NSString* reportStorePath; -@property(atomic,readwrite,assign) int64_t reportCounter; +@property(nonatomic, readwrite, retain) NSString *appName; +@property(nonatomic, readwrite, retain) NSString *reportStorePath; +@property(atomic, readwrite, assign) int64_t reportCounter; @end @@ -50,126 +47,120 @@ @implementation KSCrashReportStore_Tests @synthesize reportStorePath = _reportStorePath; @synthesize reportCounter = _reportCounter; -- (int64_t) getReportIDFromPath:(NSString*) path +- (int64_t)getReportIDFromPath:(NSString *)path { - const char* filename = path.lastPathComponent.UTF8String; + const char *filename = path.lastPathComponent.UTF8String; char scanFormat[100]; sprintf(scanFormat, "%s-report-%%" PRIx64 ".json", self.appName.UTF8String); - + int64_t reportID = 0; sscanf(filename, scanFormat, &reportID); return reportID; } -- (void) setUp +- (void)setUp { [super setUp]; self.appName = @"myapp"; } -- (void) prepareReportStoreWithPathEnd:(NSString*) pathEnd +- (void)prepareReportStoreWithPathEnd:(NSString *)pathEnd { self.reportStorePath = [self.tempPath stringByAppendingPathComponent:pathEnd]; kscrs_initialize(self.appName.UTF8String, self.tempPath.UTF8String, self.reportStorePath.UTF8String); } -- (NSArray*) getReportIDs +- (NSArray *)getReportIDs { int reportCount = kscrs_getReportCount(); int64_t rawReportIDs[reportCount]; reportCount = kscrs_getReportIDs(rawReportIDs, reportCount); - NSMutableArray* reportIDs = [NSMutableArray new]; - for(int i = 0; i < reportCount; i++) - { + NSMutableArray *reportIDs = [NSMutableArray new]; + for (int i = 0; i < reportCount; i++) { [reportIDs addObject:@(rawReportIDs[i])]; } return reportIDs; } -- (int64_t) writeCrashReportWithStringContents:(NSString*) contents +- (int64_t)writeCrashReportWithStringContents:(NSString *)contents { - NSData* crashData = [contents dataUsingEncoding:NSUTF8StringEncoding]; + NSData *crashData = [contents dataUsingEncoding:NSUTF8StringEncoding]; char crashReportPath[KSCRS_MAX_PATH_LENGTH]; kscrs_getNextCrashReport(crashReportPath); [crashData writeToFile:[NSString stringWithUTF8String:crashReportPath] atomically:YES]; return [self getReportIDFromPath:[NSString stringWithUTF8String:crashReportPath]]; } -- (int64_t) writeUserReportWithStringContents:(NSString*) contents +- (int64_t)writeUserReportWithStringContents:(NSString *)contents { - NSData* data = [contents dataUsingEncoding:NSUTF8StringEncoding]; + NSData *data = [contents dataUsingEncoding:NSUTF8StringEncoding]; return kscrs_addUserReport(data.bytes, (int)data.length); } -- (void) loadReportID:(int64_t) reportID - reportString:(NSString* __autoreleasing *) reportString +- (void)loadReportID:(int64_t)reportID reportString:(NSString *__autoreleasing *)reportString { - char* reportBytes = kscrs_readReport(reportID); - - if(reportBytes == NULL) - { + char *reportBytes = kscrs_readReport(reportID); + + if (reportBytes == NULL) { reportString = nil; - } - else - { - *reportString = [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:reportBytes length:strlen(reportBytes)] encoding:NSUTF8StringEncoding]; + } else { + *reportString = [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:reportBytes + length:strlen(reportBytes)] + encoding:NSUTF8StringEncoding]; } } -- (void) expectHasReportCount:(int) reportCount +- (void)expectHasReportCount:(int)reportCount { XCTAssertEqual(kscrs_getReportCount(), reportCount); } -- (void) expectReports:(NSArray*) reportIDs - areStrings:(NSArray*) reportStrings +- (void)expectReports:(NSArray *)reportIDs areStrings:(NSArray *)reportStrings { - for(NSUInteger i = 0; i < reportIDs.count; i++) - { + for (NSUInteger i = 0; i < reportIDs.count; i++) { int64_t reportID = [reportIDs[i] longLongValue]; - NSString* reportString = reportStrings[i]; - NSString* loadedReportString; + NSString *reportString = reportStrings[i]; + NSString *loadedReportString; [self loadReportID:reportID reportString:&loadedReportString]; XCTAssertEqualObjects(loadedReportString, reportString); } } -- (void) testReportStorePathExists +- (void)testReportStorePathExists { [self prepareReportStoreWithPathEnd:@"somereports/blah/2/x"]; XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:self.reportStorePath]); } -- (void) testCrashReportCount1 +- (void)testCrashReportCount1 { [self prepareReportStoreWithPathEnd:@"testCrashReportCount1"]; - NSString* reportContents = @"Testing"; + NSString *reportContents = @"Testing"; [self writeCrashReportWithStringContents:reportContents]; [self expectHasReportCount:1]; } - -- (void) testStoresLoadsOneCrashReport +- (void)testStoresLoadsOneCrashReport { [self prepareReportStoreWithPathEnd:@"testStoresLoadsOneCrashReport"]; - NSString* reportContents = @"Testing"; + NSString *reportContents = @"Testing"; int64_t reportID = [self writeCrashReportWithStringContents:reportContents]; - [self expectReports:@[@(reportID)] areStrings:@[reportContents]]; + [self expectReports:@[ @(reportID) ] areStrings:@[ reportContents ]]; } -- (void) testStoresLoadsOneUserReport +- (void)testStoresLoadsOneUserReport { [self prepareReportStoreWithPathEnd:@"testStoresLoadsOneUserReport"]; - NSString* reportContents = @"Testing"; + NSString *reportContents = @"Testing"; int64_t reportID = [self writeUserReportWithStringContents:reportContents]; - [self expectReports:@[@(reportID)] areStrings:@[reportContents]]; + [self expectReports:@[ @(reportID) ] areStrings:@[ reportContents ]]; } -- (void) testStoresLoadsMultipleReports +- (void)testStoresLoadsMultipleReports { [self prepareReportStoreWithPathEnd:@"testStoresLoadsMultipleReports"]; - NSMutableArray* reportIDs = [NSMutableArray new]; - NSArray* reportContents = @[@"report1", @"report2", @"report3", @"report4"]; + NSMutableArray *reportIDs = [NSMutableArray new]; + NSArray *reportContents = @[ @"report1", @"report2", @"report3", @"report4" ]; [reportIDs addObject:@([self writeCrashReportWithStringContents:reportContents[0]])]; [reportIDs addObject:@([self writeUserReportWithStringContents:reportContents[1]])]; [reportIDs addObject:@([self writeUserReportWithStringContents:reportContents[2]])]; @@ -178,7 +169,7 @@ - (void) testStoresLoadsMultipleReports [self expectReports:reportIDs areStrings:reportContents]; } -- (void) testDeleteAllReports +- (void)testDeleteAllReports { [self prepareReportStoreWithPathEnd:@"testDeleteAllReports"]; [self writeCrashReportWithStringContents:@"1"]; @@ -190,7 +181,7 @@ - (void) testDeleteAllReports [self expectHasReportCount:0]; } -- (void) testPruneReports +- (void)testPruneReports { int reportStorePrunesTo = 7; kscrs_setMaxReportCount(reportStorePrunesTo); @@ -207,17 +198,17 @@ - (void) testPruneReports // Calls kscrs_initialize() again, which prunes the reports. [self prepareReportStoreWithPathEnd:@"testDeleteAllReports"]; [self expectHasReportCount:reportStorePrunesTo]; - NSArray* reportIDs = [self getReportIDs]; + NSArray *reportIDs = [self getReportIDs]; XCTAssertFalse([reportIDs containsObject:@(prunedReportID)]); } -- (void) testStoresLoadsWithUnicodeAppName +- (void)testStoresLoadsWithUnicodeAppName { self.appName = @"ЙогуртЙод"; [self prepareReportStoreWithPathEnd:@"testStoresLoadsWithUnicodeAppName"]; - NSString* reportContents = @"Testing"; + NSString *reportContents = @"Testing"; int64_t reportID = [self writeCrashReportWithStringContents:reportContents]; - [self expectReports:@[@(reportID)] areStrings:@[reportContents]]; + [self expectReports:@[ @(reportID) ] areStrings:@[ reportContents ]]; } @end diff --git a/Tests/KSCrashRecordingTests/KSTestModuleConfig.h b/Tests/KSCrashRecordingTests/KSTestModuleConfig.h index 353041e1f..25d0b56af 100644 --- a/Tests/KSCrashRecordingTests/KSTestModuleConfig.h +++ b/Tests/KSCrashRecordingTests/KSTestModuleConfig.h @@ -1,6 +1,6 @@ // // KSTestModuleConfig.h -// +// // // Created by Alexander Cohen on 5/9/24. // @@ -18,4 +18,4 @@ #endif #endif -#endif // KSTestModuleConfig_h +#endif // KSTestModuleConfig_h diff --git a/Tests/KSCrashReportingCoreTests/Container+DeepSearch_Tests.m b/Tests/KSCrashReportingCoreTests/Container+DeepSearch_Tests.m index cb770e465..c3eff4fa2 100644 --- a/Tests/KSCrashReportingCoreTests/Container+DeepSearch_Tests.m +++ b/Tests/KSCrashReportingCoreTests/Container+DeepSearch_Tests.m @@ -24,221 +24,180 @@ // THE SOFTWARE. // - #import #import "Container+DeepSearch.h" - -@interface Container_DeepSearch_Tests : XCTestCase @end +@interface Container_DeepSearch_Tests : XCTestCase +@end @implementation Container_DeepSearch_Tests -- (void) testDeepSearchDictionary +- (void)testDeepSearchDictionary { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"key3", - nil], @"key2", - nil], @"key1", - nil]; + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:expected, + @"key3", nil], + @"key2", nil], + @"key1", nil]; id deepKey = [NSArray arrayWithObjects:@"key1", @"key2", @"key3", nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchDictionaryPath +- (void)testDeepSearchDictionaryPath { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"key3", - nil], @"key2", - nil], @"key1", - nil]; + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:expected, + @"key3", nil], + @"key2", nil], + @"key1", nil]; id actual = [container objectForKeyPath:@"key1/key2/key3"]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchDictionaryPathAbs +- (void)testDeepSearchDictionaryPathAbs { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"key3", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:expected, + @"key3", nil], + @"key2", nil], + @"key1", nil]; + id actual = [container objectForKeyPath:@"/key1/key2/key3"]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchDictionary2 +- (void)testDeepSearchDictionary2 { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"3", - nil], @"2", - nil], @"1", - nil]; + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:expected, @"3", + nil], + @"2", nil], + @"1", nil]; id deepKey = [NSArray arrayWithObjects:@"1", @"2", @"3", nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchDictionary2Path +- (void)testDeepSearchDictionary2Path { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"3", - nil], @"2", - nil], @"1", - nil]; + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:expected, @"3", + nil], + @"2", nil], + @"1", nil]; id actual = [container objectForKeyPath:@"1/2/3"]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchArray +- (void)testDeepSearchArray { id expected = @"Object"; - id container = [NSArray arrayWithObjects: - [NSArray arrayWithObjects: - @"blah", - [NSArray arrayWithObjects: - @"blah2", - expected, - nil], - nil], - nil]; - - id deepKey = [NSArray arrayWithObjects: - [NSNumber numberWithInt:0], - [NSNumber numberWithInt:1], - [NSNumber numberWithInt:1], - nil]; + id container = [NSArray + arrayWithObjects:[NSArray arrayWithObjects:@"blah", [NSArray arrayWithObjects:@"blah2", expected, nil], nil], + nil]; + + id deepKey = [NSArray + arrayWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:1], [NSNumber numberWithInt:1], nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchArrayString +- (void)testDeepSearchArrayString { id expected = @"Object"; - id container = [NSArray arrayWithObjects: - [NSArray arrayWithObjects: - @"blah", - [NSArray arrayWithObjects: - @"blah2", - expected, - nil], - nil], - nil]; + id container = [NSArray + arrayWithObjects:[NSArray arrayWithObjects:@"blah", [NSArray arrayWithObjects:@"blah2", expected, nil], nil], + nil]; id deepKey = [NSArray arrayWithObjects:@"0", @"1", @"1", nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchArrayString2 +- (void)testDeepSearchArrayString2 { - id container = [NSArray arrayWithObjects: - [NSArray arrayWithObjects: - @"blah", - [NSArray arrayWithObjects: - @"blah2", - nil], - nil], - nil]; + id container = [NSArray + arrayWithObjects:[NSArray arrayWithObjects:@"blah", [NSArray arrayWithObjects:@"blah2", nil], nil], nil]; id deepKey = [NSArray arrayWithObjects:@"0", @"1", @"key", nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertNil(actual, @""); } -- (void) testDeepSearchArrayEmptyString +- (void)testDeepSearchArrayEmptyString { id expected = @"Object"; - id container = [NSArray arrayWithObjects: - [NSArray arrayWithObjects: - @"blah", - [NSArray arrayWithObjects: - expected, - @"blah2", - nil], - nil], - nil]; - + id container = [NSArray + arrayWithObjects:[NSArray arrayWithObjects:@"blah", [NSArray arrayWithObjects:expected, @"blah2", nil], nil], + nil]; + id deepKey = [NSArray arrayWithObjects:@"0", @"1", @"", nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchArrayPath +- (void)testDeepSearchArrayPath { id expected = @"Object"; - id container = [NSArray arrayWithObjects: - [NSArray arrayWithObjects: - @"blah", - [NSArray arrayWithObjects: - @"blah2", - expected, - nil], - nil], - nil]; + id container = [NSArray + arrayWithObjects:[NSArray arrayWithObjects:@"blah", [NSArray arrayWithObjects:@"blah2", expected, nil], nil], + nil]; id actual = [container objectForKeyPath:@"0/1/1"]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchMixed +- (void)testDeepSearchMixed { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObjects: - @"blah", - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"key3", - nil], - nil], @"key1", - nil]; - - id deepKey = [NSArray arrayWithObjects: - @"key1", - [NSNumber numberWithInt:1], - @"key3", nil]; + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"blah", + [NSDictionary + dictionaryWithObjectsAndKeys:expected, @"key3", nil], + nil], + @"key1", nil]; + + id deepKey = [NSArray arrayWithObjects:@"key1", [NSNumber numberWithInt:1], @"key3", nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchMixedPath +- (void)testDeepSearchMixedPath { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObjects: - @"blah", - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"key3", - nil], - nil], @"key1", - nil]; + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"blah", + [NSDictionary + dictionaryWithObjectsAndKeys:expected, @"key3", nil], + nil], + @"key1", nil]; id actual = [container objectForKeyPath:@"key1/1/key3"]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testDeepSearchNotFound +- (void)testDeepSearchNotFound { id container = [NSDictionary dictionary]; id deepKey = [NSArray arrayWithObjects:@"key1", nil]; @@ -246,7 +205,7 @@ - (void) testDeepSearchNotFound XCTAssertNil(actual, @""); } -- (void) testDeepSearchNotFoundArray +- (void)testDeepSearchNotFoundArray { id container = [NSArray array]; id deepKey = [NSArray arrayWithObjects:@"key1", nil]; @@ -254,256 +213,234 @@ - (void) testDeepSearchNotFoundArray XCTAssertNil(actual, @""); } -- (void) testDeepSearchNonContainerObject +- (void)testDeepSearchNonContainerObject { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObjects: - @"blah", - [NSDictionary dictionaryWithObjectsAndKeys: - expected, @"key3", - nil], - nil], @"key1", - nil]; - - id deepKey = [NSArray arrayWithObjects: - @"key1", - [NSNumber numberWithInt:1], - @"key3", - @"key4", nil]; + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"blah", + [NSDictionary + dictionaryWithObjectsAndKeys:expected, @"key3", nil], + nil], + @"key1", nil]; + + id deepKey = [NSArray arrayWithObjects:@"key1", [NSNumber numberWithInt:1], @"key3", @"key4", nil]; id actual = [container objectForDeepKey:deepKey]; XCTAssertNil(actual, @""); } -- (void) testSetObjectForDeepKeyDict +- (void)testSetObjectForDeepKeyDict { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"someKey", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableDictionary + dictionaryWithObjectsAndKeys:@"someObject", + @"someKey", nil], + @"key2", nil], + @"key1", nil]; + id deepKey = [NSArray arrayWithObjects:@"key1", @"key2", @"key3", nil]; [container setObject:expected forDeepKey:deepKey]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testSetObjectForDeepKeyDictSimple +- (void)testSetObjectForDeepKeyDictSimple { id expected = @"Object"; - id container = [NSMutableDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"someKey", - nil]; - + id container = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"someObject", @"someKey", nil]; + id deepKey = [NSArray arrayWithObjects:@"key1", nil]; [container setObject:expected forDeepKey:deepKey]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testSetObjectForDeepKeyDictEmptyKey +- (void)testSetObjectForDeepKeyDictEmptyKey { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"someKey", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableDictionary + dictionaryWithObjectsAndKeys:@"someObject", + @"someKey", nil], + @"key2", nil], + @"key1", nil]; + id deepKey = [NSArray array]; XCTAssertThrows([container setObject:expected forDeepKey:deepKey], @""); } -- (void) testSetObjectForDeepKeyArray +- (void)testSetObjectForDeepKeyArray { id expected = @"Object"; - id container = [NSArray arrayWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableArray arrayWithObjects: - @"someObject", - nil], @"key2", - nil], - nil]; - + id container = + [NSArray arrayWithObjects:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableArray arrayWithObjects:@"someObject", nil], + @"key2", nil], + nil]; + id deepKey = [NSArray arrayWithObjects:@"0", @"key2", @"0", nil]; [container setObject:expected forDeepKey:deepKey]; id actual = [container objectForDeepKey:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testSetObjectForKeyPathArray +- (void)testSetObjectForKeyPathArray { id expected = @"Object"; - id container = [NSArray arrayWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableArray arrayWithObjects: - @"someObject", - nil], @"key2", - nil], - nil]; - + id container = + [NSArray arrayWithObjects:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableArray arrayWithObjects:@"someObject", nil], + @"key2", nil], + nil]; + id deepKey = @"0/key2/0"; [container setObject:expected forKeyPath:deepKey]; id actual = [container objectForKeyPath:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testSetObjectForDeepKeyInvalidContainer +- (void)testSetObjectForDeepKeyInvalidContainer { id expected = @"Object"; id container = [NSDate date]; - + id deepKey = [NSArray arrayWithObjects:@"key1", @"key2", @"0", nil]; XCTAssertThrows([container setObject:expected forDeepKey:deepKey], @""); } -- (void) testSetObjectForDeepKeyImmutableArray +- (void)testSetObjectForDeepKeyImmutableArray { id expected = @"Object"; - id container = [NSArray arrayWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObjects: - @"someObject", - nil], @"key2", - nil], - nil]; - + id container = [NSArray + arrayWithObjects:[NSDictionary + dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"someObject", nil], @"key2", nil], + nil]; + id deepKey = [NSArray arrayWithObjects:@"0", @"key2", @"0", nil]; XCTAssertThrows([container setObject:expected forDeepKey:deepKey], @""); } -- (void) testSetObjectForDeepKeyImmutableDict +- (void)testSetObjectForDeepKeyImmutableDict { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"someKey", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:@"someObject", + @"someKey", nil], + @"key2", nil], + @"key1", nil]; + id deepKey = [NSArray arrayWithObjects:@"key1", @"key2", [NSDate date], nil]; XCTAssertThrows([container setObject:expected forDeepKey:deepKey], @""); } -- (void) testSetObjectForKeyPathDict +- (void)testSetObjectForKeyPathDict { id expected = @"Object"; - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"someKey", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableDictionary + dictionaryWithObjectsAndKeys:@"someObject", + @"someKey", nil], + @"key2", nil], + @"key1", nil]; + id deepKey = @"key1/key2/key3"; [container setObject:expected forKeyPath:deepKey]; id actual = [container objectForKeyPath:deepKey]; XCTAssertEqualObjects(expected, actual, @""); } -- (void) testRemoveObjectForDeepKeyDict +- (void)testRemoveObjectForDeepKeyDict { - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"key3", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableDictionary + dictionaryWithObjectsAndKeys:@"someObject", + @"key3", nil], + @"key2", nil], + @"key1", nil]; + id deepKey = [NSArray arrayWithObjects:@"key1", @"key2", @"key3", nil]; [container removeObjectForDeepKey:deepKey]; id actual = [container objectForDeepKey:deepKey]; XCTAssertNil(actual, @""); } -- (void) testRemoveObjectForKeyPathDict +- (void)testRemoveObjectForKeyPathDict { - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"key3", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableDictionary + dictionaryWithObjectsAndKeys:@"someObject", + @"key3", nil], + @"key2", nil], + @"key1", nil]; + id deepKey = @"key1/key2/key3"; [container removeObjectForKeyPath:deepKey]; id actual = [container objectForKeyPath:deepKey]; XCTAssertNil(actual, @""); } -- (void) testRemoveObjectForDeepKeyArray +- (void)testRemoveObjectForDeepKeyArray { - id container = [NSArray arrayWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableArray arrayWithObjects: - @"someObject", - nil], @"key2", - nil], - nil]; - + id container = + [NSArray arrayWithObjects:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableArray arrayWithObjects:@"someObject", nil], + @"key2", nil], + nil]; + id deepKey = [NSArray arrayWithObjects:@"0", @"key2", @"0", nil]; [container removeObjectForDeepKey:deepKey]; XCTAssertThrows([container objectForDeepKey:deepKey], @""); } -- (void) testRemoveObjectForKeyPathArray +- (void)testRemoveObjectForKeyPathArray { - id container = [NSArray arrayWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSMutableArray arrayWithObjects: - @"someObject", - nil], @"key2", - nil], - nil]; - + id container = + [NSArray arrayWithObjects:[NSDictionary + dictionaryWithObjectsAndKeys:[NSMutableArray arrayWithObjects:@"someObject", nil], + @"key2", nil], + nil]; + id deepKey = @"0/key2/0"; [container removeObjectForKeyPath:deepKey]; XCTAssertThrows([container objectForKeyPath:deepKey], @""); } -- (void) testRemoveObjectForDeepKeyInvalidContainer +- (void)testRemoveObjectForDeepKeyInvalidContainer { id container = [NSDate date]; - + id deepKey = [NSArray arrayWithObjects:@"key1", @"key2", @"0", nil]; XCTAssertThrows([container removeObjectForDeepKey:deepKey], @""); } -- (void) testRemoveObjectForDeepKeyImmutableArray +- (void)testRemoveObjectForDeepKeyImmutableArray { - id container = [NSArray arrayWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSArray arrayWithObjects: - @"someObject", - nil], @"key2", - nil], - nil]; - + id container = [NSArray + arrayWithObjects:[NSDictionary + dictionaryWithObjectsAndKeys:[NSArray arrayWithObjects:@"someObject", nil], @"key2", nil], + nil]; + id deepKey = [NSArray arrayWithObjects:@"0", @"key2", @"0", nil]; XCTAssertThrows([container removeObjectForDeepKey:deepKey], @""); } -- (void) testRemoveObjectForDeepKeyImmutableDict +- (void)testRemoveObjectForDeepKeyImmutableDict { - id container = [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSDictionary dictionaryWithObjectsAndKeys: - @"someObject", @"someKey", - nil], @"key2", - nil], @"key1", - nil]; - + id container = [NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:[NSDictionary + dictionaryWithObjectsAndKeys:@"someObject", + @"someKey", nil], + @"key2", nil], + @"key1", nil]; + id deepKey = [NSArray arrayWithObjects:@"key1", @"key2", [NSDate date], nil]; XCTAssertThrows([container removeObjectForDeepKey:deepKey], @""); } diff --git a/Tests/KSCrashReportingCoreTests/KSCString_Tests.m b/Tests/KSCrashReportingCoreTests/KSCString_Tests.m index 161cbb9c7..d50f8f98e 100644 --- a/Tests/KSCrashReportingCoreTests/KSCString_Tests.m +++ b/Tests/KSCrashReportingCoreTests/KSCString_Tests.m @@ -24,52 +24,50 @@ // THE SOFTWARE. // - #import #import "KSCString.h" - -@interface KSCString_Tests : XCTestCase @end - +@interface KSCString_Tests : XCTestCase +@end @implementation KSCString_Tests -- (void) testNSString +- (void)testNSString { - NSString* expected = @"Expected"; - KSCString* actual = [KSCString stringWithString:expected]; + NSString *expected = @"Expected"; + KSCString *actual = [KSCString stringWithString:expected]; BOOL matches = strcmp([expected cStringUsingEncoding:NSUTF8StringEncoding], actual.bytes) == 0; XCTAssertTrue(matches, @""); XCTAssertEqual(actual.length, expected.length, @""); } -- (void) testCString +- (void)testCString { - const char* expected = "Expected"; + const char *expected = "Expected"; NSUInteger expectedLength = strlen(expected); - KSCString* actual = [KSCString stringWithCString:expected]; + KSCString *actual = [KSCString stringWithCString:expected]; BOOL matches = strcmp(expected, actual.bytes) == 0; XCTAssertTrue(matches, @""); XCTAssertEqual(actual.length, expectedLength, @""); } -- (void) testNSData +- (void)testNSData { - const char* expected = "Expected"; + const char *expected = "Expected"; NSUInteger expectedLength = strlen(expected); - NSData* source = [NSData dataWithBytes:expected length:expectedLength]; - KSCString* actual = [KSCString stringWithData:source]; + NSData *source = [NSData dataWithBytes:expected length:expectedLength]; + KSCString *actual = [KSCString stringWithData:source]; BOOL matches = strcmp(expected, actual.bytes) == 0; XCTAssertTrue(matches, @""); XCTAssertEqual(actual.length, expectedLength, @""); } -- (void) testData +- (void)testData { - const char* expected = "Expected"; + const char *expected = "Expected"; NSUInteger expectedLength = strlen(expected); - KSCString* actual = [KSCString stringWithData:expected length:expectedLength]; + KSCString *actual = [KSCString stringWithData:expected length:expectedLength]; BOOL matches = strcmp(expected, actual.bytes) == 0; XCTAssertTrue(matches, @""); XCTAssertEqual(actual.length, expectedLength, @""); diff --git a/Tests/KSCrashReportingCoreTests/NSData+Gzip_Tests.m b/Tests/KSCrashReportingCoreTests/NSData+Gzip_Tests.m index 701939aa8..83a63d80e 100644 --- a/Tests/KSCrashReportingCoreTests/NSData+Gzip_Tests.m +++ b/Tests/KSCrashReportingCoreTests/NSData+Gzip_Tests.m @@ -24,31 +24,28 @@ // THE SOFTWARE. // - #import #import "NSData+KSGZip.h" - -@interface NSData_Gzip_Tests : XCTestCase @end - +@interface NSData_Gzip_Tests : XCTestCase +@end @implementation NSData_Gzip_Tests -- (void) testCompressDecompress +- (void)testCompressDecompress { NSUInteger numBytes = 1000000; - NSMutableData* data = [NSMutableData dataWithCapacity:numBytes]; - for(NSUInteger i = 0; i < numBytes; i++) - { + NSMutableData *data = [NSMutableData dataWithCapacity:numBytes]; + for (NSUInteger i = 0; i < numBytes; i++) { unsigned char byte = (unsigned char)i; [data appendBytes:&byte length:1]; } - NSError* error = nil; - NSData* original = [NSData dataWithData:data]; - NSData* compressed = [original gzippedWithCompressionLevel:-1 error:&error]; + NSError *error = nil; + NSData *original = [NSData dataWithData:data]; + NSData *compressed = [original gzippedWithCompressionLevel:-1 error:&error]; XCTAssertNil(error, @""); - NSData* uncompressed = [compressed gunzippedWithError:&error]; + NSData *uncompressed = [compressed gunzippedWithError:&error]; XCTAssertNil(error, @""); XCTAssertEqualObjects(uncompressed, original, @""); @@ -56,43 +53,42 @@ - (void) testCompressDecompress XCTAssertTrue([compressed length] < [uncompressed length], @""); } -- (void) testCompressDecompressEmpty +- (void)testCompressDecompressEmpty { - NSError* error = nil; - NSData* original = [NSData data]; - NSData* compressed = [original gzippedWithCompressionLevel:-1 error:&error]; + NSError *error = nil; + NSData *original = [NSData data]; + NSData *compressed = [original gzippedWithCompressionLevel:-1 error:&error]; XCTAssertNil(error, @""); - NSData* uncompressed = [compressed gunzippedWithError:&error]; + NSData *uncompressed = [compressed gunzippedWithError:&error]; XCTAssertNil(error, @""); XCTAssertEqualObjects(uncompressed, original, @""); XCTAssertEqualObjects(compressed, original, @""); } -- (void) testCompressDecompressNilError +- (void)testCompressDecompressNilError { NSUInteger numBytes = 1000; - NSMutableData* data = [NSMutableData dataWithCapacity:numBytes]; - for(NSUInteger i = 0; i < numBytes; i++) - { + NSMutableData *data = [NSMutableData dataWithCapacity:numBytes]; + for (NSUInteger i = 0; i < numBytes; i++) { unsigned char byte = (unsigned char)i; [data appendBytes:&byte length:1]; } - NSData* original = [NSData dataWithData:data]; - NSData* compressed = [original gzippedWithCompressionLevel:-1 error:nil]; - NSData* uncompressed = [compressed gunzippedWithError:nil]; + NSData *original = [NSData dataWithData:data]; + NSData *compressed = [original gzippedWithCompressionLevel:-1 error:nil]; + NSData *uncompressed = [compressed gunzippedWithError:nil]; XCTAssertEqualObjects(uncompressed, original, @""); XCTAssertFalse([compressed isEqualToData:uncompressed], @""); XCTAssertTrue([compressed length] < [uncompressed length], @""); } -- (void) testCompressDecompressEmptyNilError +- (void)testCompressDecompressEmptyNilError { - NSData* original = [NSData data]; - NSData* compressed = [original gzippedWithCompressionLevel:-1 error:nil]; - NSData* uncompressed = [compressed gunzippedWithError:nil]; + NSData *original = [NSData data]; + NSData *compressed = [original gzippedWithCompressionLevel:-1 error:nil]; + NSData *uncompressed = [compressed gunzippedWithError:nil]; XCTAssertEqualObjects(uncompressed, original, @""); XCTAssertEqualObjects(compressed, original, @""); diff --git a/Tests/KSCrashReportingCoreTests/NSMutableData+AppendUTF8_Tests.m b/Tests/KSCrashReportingCoreTests/NSMutableData+AppendUTF8_Tests.m index b31a37862..a5da222b2 100644 --- a/Tests/KSCrashReportingCoreTests/NSMutableData+AppendUTF8_Tests.m +++ b/Tests/KSCrashReportingCoreTests/NSMutableData+AppendUTF8_Tests.m @@ -24,33 +24,31 @@ // THE SOFTWARE. // - #import #import "NSMutableData+AppendUTF8.h" - -@interface NSMutableData_AppendUTF8_Tests : XCTestCase @end - +@interface NSMutableData_AppendUTF8_Tests : XCTestCase +@end @implementation NSMutableData_AppendUTF8_Tests -- (void) testAppendUTF8String +- (void)testAppendUTF8String { - NSString* expected = @"testテスト"; - NSMutableData* data = [NSMutableData data]; + NSString *expected = @"testテスト"; + NSMutableData *data = [NSMutableData data]; [data appendUTF8String:expected]; - NSString* actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSString *actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected, @""); } -- (void) testAppendUTF8Format +- (void)testAppendUTF8Format { - NSString* expected = @"Testing 1 2.0 3"; - NSMutableData* data = [NSMutableData data]; + NSString *expected = @"Testing 1 2.0 3"; + NSMutableData *data = [NSMutableData data]; [data appendUTF8Format:@"Testing %d %.1f %@", 1, 2.0, @"3"]; - NSString* actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSString *actual = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; XCTAssertEqualObjects(actual, expected, @""); }