Skip to content

Instantly share code, notes, and snippets.

@swillits
Last active May 17, 2021 14:29
Show Gist options
  • Select an option

  • Save swillits/12c01638dbd7c488fd30 to your computer and use it in GitHub Desktop.

Select an option

Save swillits/12c01638dbd7c488fd30 to your computer and use it in GitHub Desktop.
//
// Crashed Thread: 0 Dispatch queue: com.apple.main-thread
//
// Exception Type: EXC_BAD_ACCESS (SIGSEGV)
// Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
//
// VM Regions Near 0:
// -->
// __TEXT 000000010d268000-000000010d26a000 [ 8K] r-x/rwx SM=COW /Users/USER/Library/Developer/Xcode/DerivedData/CrashSymbolTest-duwezzdulbkaqtffihfubuglwpki/Build/Products/Debug/CrashSymbolTest
//
// Application Specific Information:
// X identifier: seth
//
// Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
// 0 CrashSymbolTest 0x000000010d269aad -[X method] + 45 (main.m:33)
// 1 CrashSymbolTest 0x000000010d269cfd __9+[Y load]_block_invoke + 189 (main.m:60)
// 2 CrashSymbolTest 0x000000010d269dcb main + 171 (main.m:82)
// 3 libdyld.dylib 0x00007fff8be0f5fd start + 1
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
// See also: http://alastairs-place.net/blog/2013/01/10/interesting-os-x-crash-report-tidbits/
// We declare a symbol with a standard/convention name
static char *__crashreporter_info__ = 0;
// Mark the __crashreporter_info__ field as "referenced dynamically";
// This means it won’t get stripped and will be included in the resulting binary so the crash reporter can see it.
asm(".desc ___crashreporter_info__, 0x10");
@interface X : NSObject
@property (readwrite, retain) NSString * identifier;
@end
@implementation X
- (void)method
{
NSLog(@"X method");
int * x = NULL;
*x = 3;
}
@end
@interface Y : X
@end
@interface Y (HackyHacky)
- (void)aq_hacky_hacky; // Shutty shutty up the compiler
@end
@implementation Y
+ (void)load;
{
if ([self class] == [Y class]) {
class_addMethod([X class], @selector(aq_hacky_hacky), imp_implementationWithBlock(^(X * instance){
snprintf(__crashreporter_info__, 128, "X identifier: %s", instance.identifier.UTF8String);
{
IMP imp = class_getMethodImplementation([X class], @selector(aq_hacky_hacky)); // Gets the ORIGINAL method imp
imp(instance, @selector(method));
}
__crashreporter_info__[0] = 0;
}), @encode(void));
Method origMethod = class_getInstanceMethod([X class], @selector(method));
Method overrideMethod = class_getInstanceMethod([X class], @selector(aq_hacky_hacky));
method_exchangeImplementations(origMethod, overrideMethod);
}
}
@end
int main(int argc, const char * argv[])
{
__crashreporter_info__ = calloc(128, 1);
@autoreleasepool {
X * x = [[X alloc] init];
x.identifier = @"seth";
[x method];
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment