%property crashes when no parameters set
The exception is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UITextSizeCache setObject:forKeyedSubscript:]: unrecognized selector sent to instance 0x280aa2fa0'
I am unable to ever modify NSMutableDictionary or NSMutableArray as a property. Can anyone help out?
@interface CHBoardView : UIView
@property NSMutableDictionary *piece;
%hook CHBoardView
%property NSMutableDictionary *piece;
-(void) initializeBoard {
%orig;
self.piece = [[NSMutableDictionary alloc] init];
}
// Trying to modify the dict
-(void) moveForward {
self.piece[@"name"] = @"test";
}
%end
Can you post the relevant stack trace in the crash log?
Can you post the relevant stack trace in the crash log?
The stack trace is a bunch of random memory addresses (from Mac Console).
I tried attaching to the process with Xcode but I get: error:
Attach failed: "Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries when the attached failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.".
error: MachTask::TaskPortForProcessID task_for_pid failed: ::task_for_pid ( target_tport = 0x0203, pid = 39725, &task ) => err = 0x00000005 ((os/kern) failure)
error: MachTask::StartExceptionThread (): task invalid, exception thread start failed.
(Even though I can attach without issues with IDA Pro or LLDB CLI, and manually launching debugserver on the device over SSH).
Here's what lldb CLI tells me when I cause the crash (write to the dict):
Process 39693 resuming
Process 39693 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x9c422d6a0)
frame #0: 0x0000000192e56980 libobjc.A.dylib`objc_retain + 16
libobjc.A.dylib`objc_retain:
-> 0x192e56980 <+16>: ldrb w8, [x8, #0x20]
0x192e56984 <+20>: tbz w8, #0x2, 0x192e569a8 ; <+56>
0x192e56988 <+24>: mov x8, #0x200000000000
0x192e5698c <+28>: ldxr x9, [x0]
Target 0: stopped.
Does it help? Or can you help me get Xcode to attach for the full stack trace?
You should be able to use Cr4shed or Crash Reporter to get a symbolicated crash log. And if you're able to attach a debugger to the process then you should be able to type bt to get a backtrace. Either of those would work but the Cr4shed report is probably better
Thanks. Here is the Cr4shed log:
printAnalysis is the function where I add to the dictionary property, which leads to the crash. (The crash happens if the property is NSMutableDictionary, NSMutableArray, or any other object that requires manually alloc'ing. I seem to remember that it doesn't crash if the property is an int (and I try to change the int at some point)).
Date: 18/11/2020, 16:41
Process: Chess
Bundle id: com.chess.iphone
Device: iPhone 7 Plus, iOS 13.6
Bundle version: 3.9.9
Exception type: NSInvalidArgumentException
Reason: -[NSISVariableObservation setObject:forKey:]: unrecognized selector sent to instance 0x2801246a0
Culprit: chesstweaker.dylib
Call stack:
0 CoreFoundation 0x0000000193119668 0x192fef000 + 0x12a654 // __exceptionPreprocess
1 libobjc.A.dylib 0x0000000192e3bbcc 0x192e36000 + 0x5bcc // objc_exception_throw
2 CoreFoundation 0x000000019301ddd8 0x192fef000 + 0x2edd8 // -[NSOrderedSet initWithSet:copyItems:]
3 CoreFoundation 0x000000019311d7f8 0x192fef000 + 0x12e7f8 // ___forwarding___
4 CoreFoundation 0x000000019311f71c 0x192fef000 + 0x13071c // _CF_forwarding_prep_0
5 chesstweaker.dylib 0x00000001063f6bfc 0x1063f0000 + 0x6bfc // _logos_method$_ungrouped$CHBoardView$printAnalysis$output$(CHBoardView*, objc_selector*, objc_object*, CHEngineOutput*)
6 Chess 0x0000000102816b24 Chess + 3255076
7 Chess 0x0000000102672184 Chess + 1532292
8 Foundation 0x0000000193511f78 0x1933db000 + 0x136f78 // __NSThreadPerformPerform
9 CoreFoundation 0x0000000193097ad8 0x192fef000 + 0xa8ad8 // __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
10 CoreFoundation 0x0000000193097a30 0x192fef000 + 0xa8a30 // __CFRunLoopDoSource0
11 CoreFoundation 0x00000001930971b8 0x192fef000 + 0xa81b8 // __CFRunLoopDoSources0
12 CoreFoundation 0x00000001930921e8 0x192fef000 + 0xa31e8 // __CFRunLoopRun
13 CoreFoundation 0x0000000193091ba8 0x192fef000 + 0xa2ba8 // CFRunLoopRunSpecific
14 GraphicsServices 0x000000019d201344 0x19d1fe000 + 0x3344 // GSEventRunModal
15 UIKitCore 0x00000001971cd3e4 0x19679f000 + 0xa2e3e4 // UIApplicationMain
16 Chess 0x00000001025039b4 Chess + 31156
17 libdyld.dylib 0x0000000192f198f0 0x192f18000 + 0x18f0 // start
{"NSExceptionReason":"-[NSISVariableObservation setObject:forKey:]: unrecognized selector sent to instance 0x2801246a0","ProcessBundleID":"com.chess.iphone","ProcessName":"Chess","Culprit":"chesstweaker.dylib"}
Okay, can you run logos.pl Tweak.xm > Tweak.m and post the contents of Tweak.m? I think Logos is just generating some bad code
(Use a paste service like Ghostbin please)
/Users/user/theos/vendor/logos/bin/logos.pl Tweak.xm > Tweak.m
Use of uninitialized value $1 in split at /Users/user/theos/vendor/logos/bin/logos.pl line 604.
And here are lines 603 and a few more from logos.pl:
#check property attribute validity
my @attributes = split/\(?\s*,\s*\)?/, $1;
my $type = $2;
my $name = $3;
my ($assign, $retain, $copy, $nonatomic, $getter, $setter);
my $numattr = 0;
The complete sourcecode of the Tweak.xm (I rewrote the source to include the bare minimum for causing the crash):
@interface CHBoardView : UIView
@property NSMutableDictionary *piece;
@end
%hook CHBoardView
%property NSMutableDictionary *piece;
-(void) initializeChessBoard {
%orig;
self.piece = [[NSMutableDictionary alloc] init];
self.piece[@"abc"] = @"def";
}
%end
edit:
Damn, I'm dumb here. It seems you have to include the property attributes. Changing the line results in no crash:
%property (nonatomic, retain) NSMutableDictionary *piece;
The issue seems to be that you aren’t specifying any property attributes. I can’t remember if it’s an intentional design decision to avoid supporting no parameters - even if it is, of course there is still a bug here as it should show a useful error, not a cryptic parsing error.
In your case, the most reasonable value to specify would be (nonatomic, strong).
@interface CHBoardView : UIView
@property (nonatomic, strong) NSMutableDictionary *piece;
@end
%hook CHBoardView
%property (nonatomic, strong) NSMutableDictionary *piece;
…
%end
The default when no parameters are specified to @property is (atomic, assign). With ARC enabled, assign is equivalent to __unsafe_unretained, which means the compiler provides no automatic memory management at all - it’s all up to you. Hence you are reading memory that got deallocated and reused just after Logos’ generated setPiece: method returned. strong however will cause the compiler to add all the necessary memory management instructions.
Thanks, that works. I somehow figured it out the moment you posted 👍