Bug 347 - Random System.MissingMethodException (among other random crashes)
Summary: Random System.MissingMethodException (among other random crashes)
Status: RESOLVED NORESPONSE
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 4.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-08-20 00:00 UTC by Andrew Young
Modified: 2011-09-12 08:58 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NORESPONSE

Description Andrew Young 2011-08-20 00:00:23 UTC
I'm getting an exception that happens at random times on the device. I'm not quite sure what is causing this. It says it can't find the constructor for MapView but when the crash occurs it happens on a view that doesn't even contain a MapView on it, although a map could have appeared on a previously popped view controller. I was not able to reproduce this in a self-contained project. It only happens on our full app. I can send the app over via a private attachment or direct email if that would help. We have previously signed an NDA so this would be no prob.

I'm also getting different sorts of random exceptions/crashes happening and this is only after I have upgraded from MT v3.2.6 to v4.1 beta so I see no reason why it should crash like this except if something in MonoTouch changed.



 [0x3f0b348c:] EXCEPTION handling: System.MissingMethodException: No constructor found for Saambaa.iPhone.Controllers.Posting.Location.MapView::.ctor(System.IntPtr)
 "<unnamed thread>" tid=0x0x3f0b348c this=0x0x1c86748 thread handle 0x103 state : not waiting owns ()
   at System.Activator.CreateInstance (System.Type,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo,object[]) <0x00378>
   at System.Activator.CreateInstance (System.Type,object[],object[]) <0x00053>
   at System.Activator.CreateInstance (System.Type,object[]) <0x0003f>
   at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (intptr,intptr) <0x0009b>
   at MonoTouch.ObjCRuntime.Runtime.GetNSObject (intptr) <0x0008f>
   at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (intptr) <0x0001b>
   at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (intptr) <0xffffffff>
   at MonoTouch.UIKit.UIApplication.Main (string[],string,string) <0x0010f>
   at MonoTouch.UIKit.UIApplication.Main (string[]) <0x00023>
   at Saambaa.iPhone.Application.Main (string[]) [0x00000] in /Users/Andrew/Projects/saambaa-iphone/Saambaa.iPhone/Main.cs:22
   at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>
 [0x3f0b348c:] EXCEPTION handling: System.Exception: Selector invoked from objective-c on a managed object that has been GC'ed
 "<unnamed thread>" tid=0x0x3f0b348c this=0x0x1c86748 thread handle 0x103 state : not waiting owns ()
   at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (intptr,intptr) <0x00128>
   at MonoTouch.ObjCRuntime.Runtime.GetNSObject (intptr) <0x0008f>
   at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (intptr) <0x0001b>
   at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (intptr) <0xffffffff>
   at MonoTouch.UIKit.UIApplication.Main (string[],string,string) <0x0010f>
   at MonoTouch.UIKit.UIApplication.Main (string[]) <0x00023>
   at Saambaa.iPhone.Application.Main (string[]) [0x00000] in /Users/Andrew/Projects/saambaa-iphone/Saambaa.iPhone/Main.cs:22
   at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>
 Unhandled Exception: System.Exception: Selector invoked from objective-c on a managed object that has been GC'ed ---> System.MissingMethodException: No constructor found for Saambaa.iPhone.Controllers.Posting.Location.MapView::.ctor(System.IntPtr)
   at System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) [0x00000] in <filename unknown>:0 
   at System.Activator.CreateInstance (System.Type type, System.Object[] args, System.Object[] activationAttributes) [0x00000] in <filename unknown>:0 
   at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in <filename unknown>:0 
   at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in <filename unknown>:0 
   --- End of inner exception stack trace ---
   at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in <filename unknown>:0 
   at MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x00000] in <filename unknown>:0 
   at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) [0x00000] in <filename unknown>:0 
   at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr)
   at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00000] in <filename unknown>:0 
   at MonoTouch.UIKit.UIApplication.Main (System.String[] args) [0x00000] in <filename unknown>:0 
   at Saambaa.iPhone.Application.Main (System.String[] args) [0x00000] in /Users/Andrew/Projects/saambaa-iphone/Saambaa.iPhone/Main.cs:22 
 [ERROR] FATAL UNHANDLED EXCEPTION: System.Exception: Selector invoked from objective-c on a managed object that has been GC'ed ---> System.MissingMethodException: No constructor found for Saambaa.iPhone.Controllers.Posting.Location.MapView::.ctor(System.IntPtr)
   at System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) [0x00000] in <filename unknown>:0 
   at System.Activator.CreateInstance (System.Type type, System.Object[] args, System.Object[] activationAttributes) [0x00000] in <filename unknown>:0 
   at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in <filename unknown>:0 
   at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in <filename unknown>:0 
   --- End of inner exception stack trace ---
   at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in <filename unknown>:0 
   at MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x00000] in <filename unknown>:0 
   at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) [0x00000] in <filename unknown>:0 
   at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr)
   at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00000] in <filename unknown>:0 
   at MonoTouch.UIKit.UIApplication.Main (System.String[] args) [0x00000] in <filename unknown>:0 
   at Saambaa.iPhone.Application.Main (System.String[] args) [0x00000] in /Users/Andrew/Projects/saambaa-iphone/Saambaa.iPhone/Main.cs:22 
 Terminating runtime due to unhandled exception
 Stacktrace:
 Native stacktrace:
 MapView: finalized
 	0   SaambaaiPhone                       0x00b5132c mono_handle_native_sigsegv + 412
 	1   SaambaaiPhone                       0x00b7cb60 sigabrt_signal_handler + 148
 	2   libsystem_c.dylib                   0x3487c72f _sigtramp + 42
 	3   libsystem_c.dylib                   0x348713bb pthread_kill + 58
 	4   libsystem_c.dylib                   0x34869bff abort + 78
 	5   SaambaaiPhone                       0x00cbb3d4 monoeg_g_logv + 248
 	6   SaambaaiPhone                       0x00cbb468 monoeg_assertion_message + 44
 	7   SaambaaiPhone                       0x00b25800 mono_thread_abort + 224
 	8   SaambaaiPhone                       0x00b4fd50 mono_handle_exception_internal + 2436
 	9   SaambaaiPhone                       0x00b509c8 mono_handle_exception + 108
 	10  SaambaaiPhone                       0x00b7a9c4 mono_arm_throw_exception + 324
 	11  SaambaaiPhone                       0x008322b4 throw_exception + 48
 	12  SaambaaiPhone                       0x000a7fb8 MonoTouch_ObjCRuntime_Runtime_GetNSObject_intptr + 144
 	13  SaambaaiPhone                       0x000a8038 MonoTouch_ObjCRuntime_Runtime_GetNSObjectWrapped_intptr + 28
 	14  SaambaaiPhone                       0x000e6334 wrapper_native_to_managed_MonoTouch_ObjCRuntime_Runtime_GetNSObjectWrapped_intptr + 64
 	15  SaambaaiPhone                       0x00cdf2a4 get_managed_object_for_ptr + 136
 	16  SaambaaiPhone                       0x00ce5174 monotouch_retain_trampoline + 192
 	17  CoreFoundation                      0x36af2cdd CFRetain + 68
 	18  CoreFoundation                      0x36af7e93 -[__NSArrayM insertObject:atIndex:] + 366
 	19  CoreFoundation                      0x36af7d1b -[__NSArrayM addObject:] + 34
 	20  Foundation                          0x34f98cf9 -[NSConcreteHashTable allObjects] + 124
 	21  MapKit                              0x3163c7fb -[MKLocationManager _reportLocationStatus:] + 26
 	22  MapKit                              0x3163dd73 -[MKLocationManager _reportLocationSuccess] + 42
 	23  MapKit                              0x3163d9cd -[MKLocationManager locationManager:didUpdateToLocation:fromLocation:] + 680
 	24  CoreLocation                        0x351d1c2d -[CLLocationManager onClientEventLocation:] + 780
 	25  CoreLocation                        0x351d1f49 -[CLLocationManager onClientEvent:supportInfo:] + 52
 	26  CoreLocation                        0x351d3d05 OnClientEventInternal + 20
 	27  CoreLocation                        0x351cb7a3 _Z22CLClientInvokeCallbackP10__CLClient13CLClientEventPK14__CFDictionary + 70
 	28  CoreLocation                        0x351cdc47 _Z32CLClientHandleDaemonDataLocationP10__CLClientPK16CLClientLocationPK14__CFDictionary + 214
 	29  CoreLocation                        0x351cdd9d _Z24CLClientHandleDaemonDataP15__CFMessagePortlPK8__CFDataPv + 296
 	30  CoreFoundation                      0x36b5d70d __CFMessagePortPerform + 248
 	31  CoreFoundation                      0x36b66a97 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
 	32  CoreFoundation                      0x36b6883f __CFRunLoopDoSource1 + 166
 	33  CoreFoundation                      0x36b6960d __CFRunLoopRun + 520
 	34  CoreFoundation                      0x36af9ec3 CFRunLoopRunSpecific + 230
 	35  CoreFoundation                      0x36af9dcb CFRunLoopRunInMode + 58
 	36  GraphicsServices                    0x362b341f GSEventRunModal + 114
 	37  GraphicsServices                    0x362b34cb GSEventRun + 62
 	38  UIKit                               0x359a3d69 -[UIApplication _run] + 404
 	39  UIKit                               0x359a1807 UIApplicationMain + 670
 	40  SaambaaiPhone                       0x000e5b30 wrapper_managed_to_native_MonoTouch_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 240
 	41  SaambaaiPhone                       0x000ab5c8 MonoTouch_UIKit_UIApplication_Main_string__ + 36
 	42  SaambaaiPhone                       0x004e58f8 Saambaa_iPhone_Application_Main_string__ + 128
 	43  SaambaaiPhone                       0x007e14a0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
 	44  SaambaaiPhone                       0x00b2a2c0 mono_jit_runtime_invoke + 2800
 	45  SaambaaiPhone                       0x00c343fc mono_runtime_invoke + 140
 	46  SaambaaiPhone                       0x00c37494 mono_runtime_exec_main + 784
 	47  SaambaaiPhone                       0x00c364c4 mono_runtime_run_main + 1048
 	48  SaambaaiPhone                       0x00b35958 mono_jit_exec + 216
 	49  SaambaaiPhone                       0x00b20880 main + 5236
 	50  SaambaaiPhone                       0x00002178 start + 40
 Debug info from gdb:
 =================================================================
 Got a SIGABRT while executing native code. This usually indicates
 a fatal error in the mono runtime or one of the native libraries 
 used by your application.
 =================================================================
Comment 1 Sebastien Pouliot 2011-08-20 10:47:37 UTC
The exception message has the answer:

[ERROR] FATAL UNHANDLED EXCEPTION: System.Exception: Selector invoked from
objective-c on a managed object that has been GC'ed

Some objective-c code (the unmanaged stack trace will give you an hint) is trying to call a managed object that was GC'ed (because there was no more managed reference on that object). Either:
* That managed object should still exists (as long as some native code might needs to call it); or
* The caller itself (or the references it has) should not exists anymore (so the call itself should never have been made)

The MissingMethodException occurs because MonoTouch tries to re-create a managed object based on the on native pointer it gets. This is useful for bindings where all state is unmanaged (e.g. creating a new managed representation of a native button).

Your Saambaa.iPhone.Controllers.Posting.Location.MapView does not have this ctor, hence to MissingMethodException. Even if it had it would not be the same instance as before, so any managed state would be lost/different.

There is some GC questions/answers on http://stackoverflow.com/questions/7113145/what-does-it-mean-if-the-garbage-collector-is-more-aggressive-in-monotouch-4 that explain some other things wrt GC

I'll keep an eye open for such cases while working on bug #325
Comment 2 Andrew Young 2011-08-20 15:18:29 UTC
Thanks for the feedback. This makes a lot of sense and that was kind of what I'm suspecting the issue is. I'm sure my MapView has already been collected before something on the unmanaged stack tried to call into it. The thing is that at the point of the crash I was done with the MapView and didn't need it anymore so I expect GC to remove it. In my code there isn't anything else outside of the MapView that would make any call to it in the background.

I have a hunch, from looking at the crash report, that this call is coming from MKLocationManager. As in, when the user location is updated it would make a call into my MapView. This could be an affect of setting mapView.ShowsUserLocation = true;. I tried setting this to false, rebuilt, re-ran, and I was not able to get it to crash. But the thing with random crashes is that its hard to verify when something is really fixed or not even if you don't get crashes.

So couple questions:

1. What could be trying to call my MapView in the background after it has been collected?
2. Does the underlying unmanaged object get deallocated when the managed object gets GC'd?
3. If ShowsUserLocation is really the problem, shouldn't it stop updating user location once it is GC'd? And shouldn't the underlying MKLocationManager be collected and dealloc as a consequence of MKMapView being GC'd?

Side note: I have done more dev on our project since bug #325 and it would probably be better for me to send separately the lastest code for this specific map issue if you need it. But my MapView class has been left unchanged while surrounding classes have changed. You'll see that MapView is nothing more than a Constructor and Destructor.
Comment 3 Sebastien Pouliot 2011-08-20 20:58:55 UTC
note: answers are out of order

2. NSObject-based objects are reference counted. In many case creating a _managed_ object will create a _native_ object. In other case a managed object can simply wrap an existing native object (it's refcount will be unknown).

To allow this to coexists with the GC _managed_ object creation will retain the _native_ object (refcount++).  When nothing holds a reference to the _managed_ object it will be finalized (by the GC) and this will release (refcount--) the _native_ object. Once that refcount reach 0 then it will be freed (on the native side, out of MonoTouch or the GC control).

Now if something else takes a reference on the _native_ object then the refcount won't be 0 (when GC'ed) and the object will still exists on the native side (even if it won't exists anymore on the managed side).


1. It's likely that your application called something with MapView. That something took a (native) reference to your MapView and is using it later (and after it was GC'ed on the managed side). Normally API are symmetric so if you 'Add'ed something then there should be a 'Remove' call available (so that the final refcount will be zero). 


3. Maybe. Sometime we can make change (inside MonoTouch) to avoid such cases - but we must ensure that we don't end up adding code that can do more harm (e.g. retain some/all objects) than good.


site note: Feel free to send me an update (unless this hides/complexify) looking at #325. I might have a bit of time to look at it tomorrow - otherwise I'll check it on Monday.
Comment 4 Andrew Young 2011-08-21 03:34:12 UTC
2. This makes it very difficult for us (developers) to truly know when an object on the native side is dealloc'd because in a sense, we're not directly in charge of the ref counts.

1. Regarding the "symmetric api", is it generally a good practice to always make sure to remove something that has been added? For example, if I add an Annotation to my MapView, should I remove the Annotation when the ViewController disappears? Or if I add a gesture recognizer to a view, should I then remove it when ViewController disappears? If so, is this documented anywhere?

I can send an update for this issue but when looking at bug #325 it is probably better to stick with what I gave you the first time. Less confusion.
Comment 5 Sebastien Pouliot 2011-08-21 10:51:11 UTC
It's not as bad as it sounds :-) Most allocations and usage is done in an hierarchical fashion, e.g. collection/items, views/elements... and both the owner and the owned are collected/freed at the same time. That's why a lot of people won't ever notice such issues.

IMO complexifying such code would not be a good practice (and more likely to add new bugs / issues). Even when objects are shared they often have the same parent (e.g. view) which means they will be collected only then the parent is collected (as it has references to both).

A common issue is when you give reference to an object to something that will outlive your (managed) object. e.g. 

    form->parent->DoSomething (form->object); 

in that case you should check the documentation for "DoSomething" to see if the objected will be "retained". e.g. "This view is retained by the receiver.". 

In the previous example you could have your own "MyDoSomething" method which would set the _managed_ object to a field (in parent) before calling 'DoSomething' on it. That would ensure that _managed_ object will leave as long as 'parent' does. Or you could, when 'form' is disposed call 'parent' with the (symmetric) call UndoSomething to ensure 'object' is not referenced anymore by 'parent'.
Comment 6 Andrew Young 2011-08-22 03:34:00 UTC
Would you mind speaking to my question about #1? More specifically, in general, is it recommended to remove something that has been added? Read the specific examples I gave in my previous comment.

In the last paragraph of your last comment, you mentioned keeping a hard reference to an object that I know I'll be calling later. But in my case I am intentionally not keeping a ref to my MapView because I want it to be collected. There happens to be something else that is calling back into the MapView after it has been collected and I don't know what that something is. From what I can tell, nothing in my code related to the MapView is running in the background. The only thing I can think of would be the map updating the user's location when the GPS detects a location change. Does this mean that the native MKMapView object is still alive?
Comment 7 Sebastien Pouliot 2011-08-22 08:43:31 UTC
> Would you mind speaking to my question about #1? 

I did, second paragraph.

>> IMO complexifying such code would not be a good practice (and more likely to
>> add new bugs / issues). Even when objects are shared they often have the same
>> parent (e.g. view) which means they will be collected only then the parent is
>> collected (as it has references to both).

There's not point in complexifying 98% of the code for something that could occur 2% (also true for 80/20). You would still need to review the API being used to detect the second, less common, cases (where a reference could be taken). Otherwise you'll only do manually what's already done automatically - without solving the cases like the one you have.

> In the last paragraph of your last comment, you mentioned keeping a hard
> reference to an object that I know I'll be calling later.

Yes, that's one way. The same paragraph also discuss a second way.

>> Or you could, when 'form' is disposed call 'parent' with the
>> (symmetric) call UndoSomething to ensure 'object' is not referenced anymore by
>> 'parent'.

> Does this mean that the native MKMapView object is still alive?

Your object, being called, is still alive on the native side (it's refcount never reached 0).

All the above is mostly theory, based on a stack trace, about why it could* occur and how such things can be fixed. There's likely* only one 'referencing' call that needs to be undone - i.e. nothing that requires a major refactoring of your application.

* it could even be a bug or something we can "take care" inside MonoTouch - I just lack the information to be more precise.
Comment 8 Sebastien Pouliot 2011-08-22 11:47:49 UTC
The discussion turned a bit on the technical side and more on the "how to debug" side than the "how to code" side. MonoTouch tries to hide such issues from the developers (which is why you should not, in general, change your code). 

Please provide us with a test case and we'll see how this can be best solved.
Comment 9 Sebastien Pouliot 2011-08-27 11:12:31 UTC
I can take a look if you send me an updated source drop (or a smaller test case).
Comment 10 Sebastien Pouliot 2011-09-05 13:47:05 UTC
Andrew, have you found your issue ? If not then I'd be pleased to help, otherwise we can close this bug report. Thanks!
Comment 11 Andrew Young 2011-09-05 15:28:37 UTC
Sorry for the delayed response with this one. I've been meaning to send a sample of our code that reproduces the crash but it doesn't seem to crash like this anymore. Perhaps something in my recent development has covered it up. I had a feeling that it had something to do with show user location on the map. We can close this and then reopen it again if it ever comes up again or if I happen to have some spare time to really try hard to reproduce it. Thanks for the followup though.
Comment 12 Sebastien Pouliot 2011-09-12 08:58:35 UTC
ok, closing for lack of test case.
please re-open, with test case, if you ever hit this again
thanks!