Why does my program get EXC_BAD_ACCESS in _class_isInitialized () during objc_msgSend ()?

The final update . It turns out that fixing this problem is depressing. Go to the .xcodeproj directory inside your project and delete the <username>.mode1v3 and <username>.pbxuser . This fixed it. Boo, Xcode.


I will start by saying this is not your usual save / release error. This has just begun to happen in the development branch of my code, the error is missing from the main branch, and I am having problems finding any differences in the source indicating the answer. So I just get to the gory stuff.

I have a view controller class. It has several properties that reference a couple of other controllers. Each of them is loaded through the getter receiver as needed, for example:

 - (NotesViewController *)notesViewController { if (notesViewController == nil) { notesViewController = [[NotesViewController alloc] initWithNibName:@"NotesViewController" bundle:nil]; } return notesViewController; } 

When you later call [self notesViewController] , all this is good. This one, however, just stops working:

 - (DateFieldController *)dateFieldController { NSLog(@"made it into the method at least ..."); if (dateFieldController == nil) { NSLog(@"nib loader, don't let us down..."); dateFieldController = [[DateFieldController alloc] initWithNibName:@"DateFieldController" bundle:nil]; } return dateFieldController; } 

When this method is called in the same way as other accessors, it explodes, apparently, during the loading of the knife, but, possibly, before it:

 2010-07-08 11:44:58.029 MyApp[24404:207] made it into the method at least ... 2010-07-08 11:44:58.030 MyApp[24404:207] nib loader, don't let us down... Program received signal: "EXC_BAD_ACCESS". (gdb) bt #0 0x028bb0ca in _class_isInitialized () #1 0x028b9eca in _class_initialize () #2 0x028bf1f6 in prepareForMethodLookup () #3 0x028b86c9 in lookUpMethod () #4 0x028b8836 in _class_lookupMethodAndLoadCache () #5 0x028c6ad3 in objc_msgSend () #6 0x00007bb3 in -[EntryViewController controllerForFieldType:] (self=0x7942d70, _cmd=0x190c20, type=0x79844b0) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/Classes/EntryViewController.m:481 #7 0x00007e07 in -[EntryViewController selectTypesControllerDidSelect:] (self=0x7942d70, _cmd=0x190bb4, type=0x79844b0) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/Classes/EntryViewController.m:527 #8 0x0000d2ad in -[TypesViewController tableView:didSelectRowAtIndexPath:] (self=0x5d2aac0, _cmd=0x1eac458, aTableView=0x6056000, indexPath=0x781c780) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/Classes/TypesViewController.m:81 #9 0x0059e718 in -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] () #10 0x00594ffe in -[UITableView _userSelectRowAtIndexPath:] () #11 0x002abcea in __NSFireDelayedPerform () #12 0x0274cd43 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ () #13 0x0274e384 in __CFRunLoopDoTimer () #14 0x026aad09 in __CFRunLoopRun () #15 0x026aa280 in CFRunLoopRunSpecific () #16 0x026aa1a1 in CFRunLoopRunInMode () #17 0x02fd02c8 in GSEventRunModal () #18 0x02fd038d in GSEventRun () #19 0x0053ab58 in UIApplicationMain () #20 0x00001e24 in main (argc=1, argv=0xbffff050) at /Users/wgray/Documents/Sources/iPhone/MyApp-iphone/main.m:14 (gdb) 

Something unpleasant seems to be happening in the Simulator SDK when starting the knife loading method. In fact, perhaps earlier. Overloading the thread loading initializer with a small NSLog action in the DateFieldController , we suspiciously see nowhere:

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { NSLog(@"come on, you..."); if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { NSLog(@"rock on!"); } return self; } 

Suffice it to say that none of these NSLog instructions are executed.

So what is going on? Why does it annoy me at runtime? (Switching the call from self.dateFieldController to [self dateFieldController] does not fix the error - and remember that this code is exactly the same as on my main branch, where it does not fail).

FWIW, I create a 64-bit version of Xcode 3.2.3, compile for Simulator 4.0, Debug, i386 arch (in the new version of Mac Book Pro running OS X 10.6.3), for the purpose of deployment, the project settings are set to "iPhone OS 3.0 "(up this 3.1.3 also cannot be fixed).

Update: as requested, implementation of controllerForFieldType: ::

 - (id)controllerForFieldType:(Type *)type { id controller = nil; if ([type.mode isEqualToString:@"note"]) { controller = self.notesViewController; } else if ([type.mode isEqualToString:@"date"]) { NSLog(@"going for it, attempting to load dateFieldController from accessor..."); controller = self.dateFieldController; } else { controller = self.fieldViewController; } return controller; } 

I left this before because I don’t think it is particularly relevant, the problem seems to occur later on the stack, in the actual getter method of DateFieldController .

Update II: in @zneak suggesting, I turned on the Run β†’ Enable Guard Malloc option and looked at the script again. The results are basically the same, but the internal backtrace at runtime is different. It would seem that something is wrong with the class or NIB, which prevents its decryption:

 2010-07-08 12:26:26.180 Strip[24961:207] made it into the method at least ... 2010-07-08 12:26:26.289 Strip[24961:207] nib loader, don't let us down... Program received signal: "EXC_BAD_ACCESS". Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.) (gdb) bt #0 0x028cd41f in attachMethodLists () #1 0x028cdf77 in realizeClass () #2 0x028cedad in _class_getNonMetaClass () #3 0x028c8eb0 in _class_initialize () #4 0x028ce1f6 in prepareForMethodLookup () #5 0x028c76c9 in lookUpMethod () #6 0x028c7836 in _class_lookupMethodAndLoadCache () #7 0x028d5ad3 in objc_msgSend () #8 0x00007b81 in -[EntryViewController controllerForFieldType:] (self=0x38cfaf30, _cmd=0x190c8f, type=0x3cacbfe0) at /Users/wgray/Documents/Sources/iPhone/strip-iphone/Classes/EntryViewController.m:482 ...snip... #22 0x00001de4 in main (argc=1, argv=0xbfffefec) at /Users/wgray/Documents/Sources/iPhone/strip-iphone/main.m:14 (gdb) 

Update III: in which the plot thickens. In the @ohorob comment in the comments, I added env arg OBJC_PRINT_INITIALIZE_METHODS = YES and found that each initialization of each class in the application looks good, except for the one discussed here. Each of them looks like this on the console output:

 objc[26750]: INITIALIZE: calling +[UIPinchGestureRecognizer initialize] objc[26750]: INITIALIZE: finished +[UIPinchGestureRecognizer initialize] objc[26750]: INITIALIZE: UIPinchGestureRecognizer is fully +initialized 

When I launch the application and select the row of the table that causes the explosion, we just see the output of the nslog console before the failure and the failure itself. I would like to think that this means that we could rule out incorrect initialization, but I lack an expert at runtime.

I did a thorough audit of the code differences between the main branch and the dev branch and did not find anything that indicated that I had already stepped on the pointer, but I continue to think that, most likely, I think this is happening.

+4
source share
2 answers

The fact that the problem continues to move makes me suspect that something is stomping in the internal data structures of the inner class. The first thing I suspected would be too smart classes. You do not have classes that play games with isa? See XMPPMessage.m for an example. I am not asking if these class controller classes play with isa; I mean, any class in the system, as it does the wrong thing, can lead to it stomping in memory in amazing ways.

Next, I'll try to use class_copyMethodList () and see if this works before calling + alloc. If so, then your class table has definitely been corrupted.

+1
source

During the initialization of the class, something insecure happens.

Try setting the environment variable OBJC_PRINT_INITIALIZE_METHODS to YES and start the application. This can give us a clue. Or not. (Set the environment variable in the Xcode executable inspector - see docs ).

Do you have +initialize methods? (in any class - maybe one of your classes tickles the initialization of something that doesn’t seem to be related to the failure)

+2
source

Source: https://habr.com/ru/post/1315101/


All Articles