UIImageView crash when trying to set the frame - ios4

First here's my crash log:
Thread 0 Crashed:
0 libSystem.B.dylib 0x35176264 __kill + 8
1 libSystem.B.dylib 0x35176254 kill + 4
2 libSystem.B.dylib 0x35176246 raise + 10
3 libSystem.B.dylib 0x3518ad02 abort + 50
4 libstdc++.6.dylib 0x31432a20 __gnu_cxx::__verbose_terminate_handler() + 376
5 libobjc.A.dylib 0x31a97594 _objc_terminate + 104
6 libstdc++.6.dylib 0x31430df2 _cxxabiv1::_terminate(void (*)()) + 46
7 libstdc++.6.dylib 0x31430e46 std::terminate() + 10
8 libstdc++.6.dylib 0x31430f16 __cxa_throw + 78
9 libobjc.A.dylib 0x31a964c4 objc_exception_throw + 64
10 CoreFoundation 0x361857c2 +[NSException raise:format:arguments:] + 62
11 CoreFoundation 0x361857fc +[NSException raise:format:] + 28
12 QuartzCore 0x3148b222 CALayerSetPosition(CALayer*, CA::Vec2 const&, bool) + 134
13 QuartzCore 0x3148b190 -[CALayer setPosition:] + 32
14 QuartzCore 0x3148b0dc -[CALayer setFrame:] + 384
15 UIKit 0x35d15aba -[UIView(Geometry) setFrame:] + 182
16 UIKit 0x35d15928 -[UIImageView setFrame:] + 96
I have copied a part from the crash log. After line 16 there are my classes, which I cannot present here. In MyClass and MyMethod I change the frame of an imageView. My problem is that I cannot reproduce this bug and I want to reproduce it. What causes this log? I tried to release the imageView before I call the setFrame:, but it doesn't produce this error.
Any ideas how to get it? Or why this error happens some times?

I recognize this problem from one of my own projects. Usually when setFrame: crashes it's because your trying to set a NaN (Not a number). I don't know if you've dealt with NaN before, but if you haven't drop a comment and I'll provide information on how to deal with it.
EDIT: Had some time and thought I might give you an example.
So here's a code example to explain why the bug is hard to reproduce and how to fix it. I don't know what your code looks like, but your problem sounds similar enough to make me believe that you've done the same mistake as I did.
Consider the following code:
- (void)layoutSubviews {
CGRect imageFrame;
switch (self.state) {
case 0:
imageFrame = CGRectMake(0, 0, 100, 100);
case 1:
imageFrame = CGRectMake(10, 10, 50, 50);
}
self.imageView.frame = imageFrame;
}
Consider that self.state is 2, then imageFrame will never be initialized and will contain whatever was on that memory location, possibly NaN. The reason why this is hard to reproduce is that the crash will only occur when there is NaN on that memory location.
In my example the error is very easy to spot and it's likely that it's not as easy to spot in your code. If you can't find it yourself, feel free to post your code and I'll take a look at it. If you have any questions, don't hesitate to leave a comment.

Related

Spritekit iOS app main thread freeze with no apparent error or deadlock

I have a question from France for you so I hope my english won't be too bad.
This is my very first question to the community and first of all I'd like to thank you all of you for all the useful tips and answers I already read here for few months and helped me a lot for my very first iOS app.
I'm very new to the iOS dev world so I hope my questions won't be too basic.
Here it comes :
I have a Spritekit game running "pretty" well with no identified issue at this time except that in some very rare case the app freeze and never "recover". It's a kind of breakout game so I have balls and bricks and I use the Apple physicworld and physicbodies of Spritekit. Let's say that one run every 500 the main thread freeze. At first I investigated for deadlocks because I use a bit of multithreading (GCD). But nothing seems wrong on this side. In order to simplify the investigation for the community I did the following changes : no GCD at all in my code. Nothing in the update method of the scene. Everything is now running in the main scene. I would be happy to post some code but not sure what could be relevant since I have no GCD and update code anymore.
Only the main thread seems buged.
Below is the btrace of the main thread hoping it can help. The trace is always the same each time it freezes.
* thread #1: tid = 0x519fe, 0x00000001941224d0 libsystem_m.dylib`__sincosf_stret, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
* frame #0: 0x00000001941224d0 libsystem_m.dylib`__sincosf_stret
frame #1: 0x000000018f2b864c PhysicsKit`b2SeparationFunction::Evaluate(int, int, float) const + 112
frame #2: 0x000000018f2b79d0 PhysicsKit`b2TimeOfImpact(b2TOIOutput*, b2TOIInput const*) + 928
frame #3: 0x000000018f2bfac0 PhysicsKit`b2World::SolveTOI(b2TimeStep const&) + 1144
frame #4: 0x000000018f2c0318 PhysicsKit`b2World::Step(float, int, int) + 280
frame #5: 0x000000018f2af248 PhysicsKit`-[PKPhysicsWorld stepWithTime:velocityIterations:positionIterations:] + 260
frame #6: 0x000000018a38ce08 SpriteKit`-[SKScene _update:] + 616
frame #7: 0x000000018a39ffc8 SpriteKit`-[SKView(Private) _update:] + 260
frame #8: 0x000000018a39dab0 SpriteKit`-[SKView renderCallback:] + 876
frame #9: 0x000000018a39b794 SpriteKit`__29-[SKView setUpRenderCallback]_block_invoke + 76
frame #10: 0x000000018a3baa90 SpriteKit`-[SKDisplayLink _callbackForNextFrame:] + 288
frame #11: 0x00000001002ffc80 libglInterpose.dylib`-[DYDisplayLinkInterposer forwardDisplayLinkCallback:] + 172
frame #12: 0x000000018a114cbc QuartzCore`CA::Display::DisplayLinkItem::dispatch() + 36
frame #13: 0x000000018a114ac8 QuartzCore`CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 300
frame #14: 0x000000018840fe74 IOKit`IODispatchCalloutFromCFMessage + 364
frame #15: 0x00000001874c08e0 CoreFoundation`__CFMachPortPerform + 192
frame #16: 0x00000001874cee90 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56
frame #17: 0x00000001874cedf0 CoreFoundation`__CFRunLoopDoSource1 + 444
frame #18: 0x00000001874cd014 CoreFoundation`__CFRunLoopRun + 1620
frame #19: 0x000000018740dc20 CoreFoundation`CFRunLoopRunSpecific + 452
frame #20: 0x000000018d0f5c0c GraphicsServices`GSEventRunModal + 168
frame #21: 0x000000018a53efdc UIKit`UIApplicationMain + 1156
frame #22: 0x0000000100117308 MyGameName`main(argc=1, argv=0x000000016fd37bf0) + 116 at main.m:16
frame #23: 0x000000019400baa0 libdyld.dylib`start + 4
Thank you very much for your time and if you need more info or code sample do not hesitate to ask me.
Have a great weekend,
Gradlon

can't get wxHaskell to work from ghci on Mac

I'm trying to run an example using EnableGUI function.
% ghci -framework Carbon Main.hs
*Main> enableGUI >> main
This is what I get instead of a working program:
2013-01-14 00:21:03.021 ghc[13403:1303] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /SourceCache/Foundation/Foundation-945.11/Misc.subproj/NSUndoManager.m:328
2013-01-14 00:21:03.022 ghc[13403:1303] +[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.
2013-01-14 00:21:03.024 ghc[13403:1303] (
0 CoreFoundation 0x00007fff8c8ea0a6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff867243f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8c8e9ee8 +[NSException raise:format:arguments:] + 104
3 Foundation 0x00007fff884966a2 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 189
4 Foundation 0x00007fff884fc8b7 +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 156
5 AppKit 0x00007fff8ecb832d -[NSApplication run] + 687
6 libwx_osx_cocoau_core-2.9.4.0.0.dylib 0x000000010ae64c96 _ZN14wxGUIEventLoop5DoRunEv + 40
7 libwx_baseu-2.9.4.0.0.dylib 0x000000010b37e0e5 _ZN13wxCFEventLoop3RunEv + 63
8 libwx_baseu-2.9.4.0.0.dylib 0x000000010b2e91bf _ZN16wxAppConsoleBase8MainLoopEv + 81
9 libwx_osx_cocoau_core-2.9.4.0.0.dylib 0x000000010ae1b04f _ZN5wxApp5OnRunEv + 29
10 libwx_baseu-2.9.4.0.0.dylib 0x000000010b32e8d1 _Z7wxEntryRiPPw + 102
11 libwxc.dylib 0x000000010bc8a9a4 ELJApp_InitializeC + 116
12 ??? 0x000000010beb9702 0x0 + 4494956290
)
2013-01-14 00:21:03.024 ghc[13403:1303] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /SourceCache/Foundation/Foundation-945.11/Misc.subproj/NSUndoManager.m:328
When I'm compile and macosx-app it, it works rather well, but, for obvious reasons, I really want this to work from ghci.
What can I do? Google reveals nothing about the misterious problems of NSUndoManager used with Haskell. :(
ghci -fno-ghci-sandbox
works for me on OSX 10.8 , wx 0.90.0.1
thanks to Heinrich :https://github.com/jodonoghue/wxHaskell/pull/6
wxHaskell hasn't worked within ghci for a while. Apparently C++ memory management and re-using components within ghci causes problems. You juat have to rewrite main repeatedly. :(
The faq says
GHCi cannot mix static and dynamic libraries; it will be solved in the near future in wxHaskell.

MonoTouch_Disposer.Drain Exception displaying PDF content

I'm writing an app that makes heavy use of the PDF viewer to display various documents, and every so often after browsing my document library I encounter the following exception:
OutputLayer: Ecolab.SalesPad.ContentItem FreedomAire 3 Helmet
Thread finished:
Stacktrace:
at MonoTouch.Foundation.NSObject/MonoTouch_Disposer.Drain (MonoTouch.Foundation.NSObject) <0x000eb>
at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>
at MonoTouch.UIKit.UIApplication.Main (string[],string,string) <0x0010f>
at Ecolab.SalesPad.Touch.Application.Main (string[]) [0x00000] in /Users/itrgroup/Projects/SalesPad/SalesPad.Touch/Main.cs:20
at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>
Native stacktrace:
0 SalesPadTouch 0x00b62b18 mono_handle_native_sigsegv + 456
1 SalesPadTouch 0x00b484e4 mono_sigsegv_signal_handler + 428
2 libsystem_c.dylib 0x34db7539 _sigtramp + 48
3 UIKit 0x35107b23 -[UISearchDisplayController dealloc] + 78
4 libobjc.A.dylib 0x3564b0c5 _objc_rootRelease + 36
5 SalesPadTouch 0x00489eb8 wrapper_managed_to_native_MonoTouch_ObjCRuntime_Messaging_void_objc_msgSend_intptr_intptr + 68
6 SalesPadTouch 0x0028d094 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
7 SalesPadTouch 0x00b48108 mono_jit_runtime_invoke + 2892
8 SalesPadTouch 0x00c40414 mono_runtime_invoke + 200
9 SalesPadTouch 0x00cd3944 monotouch_trampoline + 3140
10 CoreFoundation 0x33e9222b -[NSObject performSelector:withObject:] + 42
11 Foundation 0x31a01757 __NSThreadPerformPerform + 350
12 CoreFoundation 0x33f07b03 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
13 CoreFoundation 0x33f072cf __CFRunLoopDoSources0 + 214
14 CoreFoundation 0x33f06075 __CFRunLoopRun + 652
15 CoreFoundation 0x33e894dd CFRunLoopRunSpecific + 300
16 CoreFoundation 0x33e893a5 CFRunLoopRunInMode + 104
17 GraphicsServices 0x35ac9fcd GSEventRunModal + 156
18 UIKit 0x34fce743 UIApplicationMain + 1090
19 SalesPadTouch 0x00491160 wrapper_managed_to_native_MonoTouch_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 240
20 SalesPadTouch 0x00073d60 Ecolab_SalesPad_Touch_Application_Main_string__ + 152
21 SalesPadTouch 0x0028d094 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
22 SalesPadTouch 0x00b48108 mono_jit_runtime_invoke + 2892
23 SalesPadTouch 0x00c40414 mono_runtime_invoke + 200
24 SalesPadTouch 0x00c4353c mono_runtime_exec_main + 836
25 SalesPadTouch 0x00c4253c mono_runtime_run_main + 968
26 SalesPadTouch 0x00b4f1b8 mono_jit_exec + 244
27 SalesPadTouch 0x00b424fc main + 4076
28 SalesPadTouch 0x00002914 start + 52
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
It hits this on MonoTouch.Disposer_Drain every time. Sometimes after ViewDidAppear is called, sometimes before. I can't find any advice on MonoTouch.Disposer_Drain in a Google search. Has anyone run into this before? Any advice on what the cause and/or a workaround would be?
Thanks!
Scott --
There are two likely causes for this:
A (native) object is being freed too early. This can happen if there is no managed reference to the corresponding managed peer, while native code still has a pointer to it. In this case the garbage collector will free the managed peer (and the native object is freed too).
Dispose is called on an object when it's not needed (calling Dispose manually may, in some very rare cases, change the usual order the objects in a tree of objects are destroyed).
It can be quite hard to track down the cause, but there is a hint in the stack trace:
3 UIKit 0x35107b23 -[UISearchDisplayController dealloc] + 78
it's related to a UISearchDisplayController. My guess is that the UISearchDisplayController's native destructor is trying to call into an object it has a reference to (to call that object's destructor for instance), and that object has already been freed. So I would look if any objects assigned to fields of a UISearchDisplayController (that can be normal fields, event handlers, callbacks, etc.) happen to get freed early.
Once you know which object are freed early, you must ensure that the GC can see the object as long as the UISearchDisplayController is alive (one common way is to assign it to a class variable of the appropriate class).
Update
A very similar issue has been answered here: MonoTouch SIGSEGV crash using navigationcontroller and searchdisplaycontroller, it may be what you're running into.

MonoTouch instability continues: managed memory allocator crashes

Long story short: I can allocate tons of unmanaged memory, but trying to allocate the same amount (or far less) in managed memory crashes MonoTouch in GC_remap (callstack below).
Details:
I'll talk about one example of the behavior I described above. My app allocates a 2.5MB chunk of managed memory (using new byte[]) occasionally, and it often dies on my iPhone4 with the callstack pasted below (i.e. mprotect error during the allocation). I don't keep a reference to these 2.5MB blocks for longer than a single function call.
The MonoTouch guys say that 'mprotect errno 12' means you've exhausted memory on your device, but the thing is, I have lots of memory available to my app. I can allocate 0MB, 10MB, or 200MB of unmanaged memory (using Marshal.AllocHGlobal) at my app's startup, touch it every frame, and it makes zero difference in the behavior of my app or in the frequency of this mprotect error.
Some notes
GC.TotalMemory tells me that my app is sitting between 3MB and 5MB of managed memory usage all the time.
I have other places in my app where I'm allocating even-larger blocks of unmanaged memory, and it never crashes there. I have created stress tests that load 4MB of (unmanaged) texture data, hand it to GL, and draw it every frame and the app is rock solid until I start asking for large blocks of managed memory.
GC.CollectionCount barely ever changes unless I call GC.Collect myself.
The same behavior happens with MonoTouch 3.2.3 as well as MonoTouch 4.0.
The same behavior happens across all of our testing devices (iPhone 3G, 3GS, 4, iPad, iPad2).
The same behavior happens in release builds and debug builds, although it happens more frequently with debug builds.
Ways to provoke the crash
If I create a thread that loops around calling GC.Collect, then sleeping for 1ms, this makes the crash happen much sooner (i.e. practically immediately if I'm in a debug build).
Using certain .NET functionality like WebRequest will cause this crash as well. I can only assume that it's allocating big blocks of managed memory somewhere in there as well.
Ways around the crash
There are two ways to reduce the frequency of the crash or to fix it altogether:
If I PRE-allocate that 2.5MB chunk of managed memory and then just keep it around for the lifetime of the app, then there's no crash.
If I pin the 2.5MB chunk of memory prior to doing anything with it, that seems to help.
Conclusions / Questions
We have yet to achieve full stability in our app due to this issue. This crash (always inside GC_remap) happens in random allocations throughout our app (the 2.5MB example I have here is just the one that I chose to isolate and repro).
Questions:
Can I not trust the managed allocator at all?
Why is it that I can allocate 200MB of unmanaged memory, but the managed allocator dies when I'm asking for 2.5MB? (Note: It'll die when I ask for 2.5MB even when I haven't allocated the 200MB of unmanaged memory).
Why is it that the app is totally fine if I hog that 2.5MB for the lifetime of the app, but if I give it back to the system (and call GC.Collect) and ask for another 2.5MB later, the crashyness is worse! If this really is a low memory condition, shouldn't it be better to give 2.5MB back to the system than to hog it?
Can we even use MonoTouch?
My team is seriously considering abandoning MonoTouch for our product because we can't get it to be reliably stable.
We also can't get the time of day from the MonoTouch team either on stackoverflow, by filing bugs on Novell's site, or by emailing MonoTouch's support email directly. We have reduced our (managed and unmanaged) memory usage to ridiculous lows, but the app is still crashy due to this issue.
In the short term, the only workaround I've got in mind is to allocate a big chunk of memory (2-5MB) at startup, PIN it so the garbage collector never touches it, and write my own allocator to dole out parts of this memory block to my app as needed. But if this is the best solution that is possible under MonoTouch, then I'm going to want my money back as soon as I can achieve escape velocity from MonoTouch.
...
Mprotect failed at 0xaa00000 (length 3801088) with errno 12
Stacktrace:
at MyApp.GameScreen/VerifyPictureDialog.StoreBasePictureData () [0x00000] in /Users/dussault/s/MyApp/Main/Src/PhotoScreens.cs:428
at MyApp.GameScreen/VerifyPictureDialog.ApplyFilters (bool) [0x0004b] in /Users/dussault/s/MyApp/Main/Src/PhotoScreens.cs:640
at MyApp.GameScreen/VerifyPictureDialog.Simulate (single) [0x00077] in /Users/dussault/s/MyApp/Main/Src/PhotoScreens.cs:477
at MyApp.BaseWindow.Simulate (single) [0x00007] in /Users/dussault/s/MyApp/Main/Src/BaseWindow.cs:56
at MyApp.BaseWindow.Simulate (single) [0x00007] in /Users/dussault/s/MyApp/Main/Src/BaseWindow.cs:56
at MyApp.GameScreen.Simulate (single) [0x00238] in /Users/dussault/s/MyApp/Main/Src/GameScreen.cs:3114
at MyApp.BaseWindow.Simulate (single) [0x00007] in /Users/dussault/s/MyApp/Main/Src/BaseWindow.cs:56
at MyApp.WindowMgr.Simulate (single) [0x0002f] in /Users/dussault/s/MyApp/Main/Src/WindowMgr.cs:126
at MyApp.Game1.Update (Microsoft.Xna.Framework.GameTime) [0x0010f] in /Users/dussault/s/MyApp/Main/Src/Game1.cs:1194
at Microsoft.Xna.Framework.Game.DispatchUpdate (Microsoft.Xna.Framework.GameTime) [0x00000] in /Users/dussault/s/MyApp/Main/Src/XNA-Emulation/GraphicsDevice.cs:531
at MyApp_iOS.EAGLView.OnUpdateFrame () [0x00050] in /Users/dussault/s/MyApp/Main/Src/iOS/EAGLView.cs:310
at MyApp_iOS.EAGLView.SimulateAndRender () [0x0000a] in /Users/dussault/s/MyApp/Main/Src/iOS/EAGLView.cs:279
at MyApp_iOS.EAGLView.MainLoopTimerCallback () [0x00006] in /Users/dussault/s/MyApp/Main/Src/iOS/EAGLView.cs:231
at MonoTouch.Foundation.NSActionDispatcher.Apply () <0x0002b>
at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>
at MonoTouch.UIKit.UIApplication.Main (string[],string,string) <0x000cf>
at MonoTouch.UIKit.UIApplication.Main (string[]) <0x00023>
at MyApp_iOS.Application.Main (string[]) [0x00000] in /Users/dussault/s/MyApp/Main/Src/iOS/Main.cs:57
at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>
Native stacktrace:
0 MyApp_iOS 0x00af1b48 mono_handle_native_sigsegv + 412
1 MyApp_iOS 0x00b1c66c sigabrt_signal_handler + 148
2 libSystem.B.dylib 0x33bd3ddf _sigtramp + 42
3 libSystem.B.dylib 0x33bd52cb kill + 10
4 libSystem.B.dylib 0x33bd52bd raise + 16
5 libSystem.B.dylib 0x33be9d79 abort + 56
6 MyApp_iOS 0x00c74378 GC_remap + 200
7 MyApp_iOS 0x00c62c04 GC_allochblk_nth + 1536
8 MyApp_iOS 0x00c625b4 GC_allochblk + 96
9 MyApp_iOS 0x00c6bf6c GC_alloc_large + 132
10 MyApp_iOS 0x00c6c5e8 GC_generic_malloc + 324
11 MyApp_iOS 0x00c6c8c8 GC_malloc_atomic + 332
12 MyApp_iOS 0x00bd8e88 mono_object_allocate_ptrfree + 64
13 MyApp_iOS 0x00bd8ff4 mono_array_new_specific + 148
14 MyApp_iOS 0x009173f4 wrapper_managed_to_native_object___icall_wrapper_mono_array_new_specific_intptr_int + 68
15 MyApp_iOS 0x002cd880 MyApp_GameScreen_VerifyPictureDialog_ApplyFilters_bool + 628
16 MyApp_iOS 0x002cbffc MyApp_GameScreen_VerifyPictureDialog_Simulate_single + 768
17 MyApp_iOS 0x002ef9d0 MyApp_BaseWindow_Simulate_single + 280
18 MyApp_iOS 0x002ef9d0 MyApp_BaseWindow_Simulate_single + 280
19 MyApp_iOS 0x002a71fc MyApp_GameScreen_Simulate_single + 2736
20 MyApp_iOS 0x002ef9d0 MyApp_BaseWindow_Simulate_single + 280
21 MyApp_iOS 0x0038068c MyApp_WindowMgr_Simulate_single + 376
22 MyApp_iOS 0x0027f798 MyApp_Game1_Update_Microsoft_Xna_Framework_GameTime + 1992
23 MyApp_iOS 0x0039afc8 Microsoft_Xna_Framework_Game_DispatchUpdate_Microsoft_Xna_Framework_GameTime + 148
24 MyApp_iOS 0x0026ec10 MyApp_iOS_EAGLView_OnUpdateFrame + 716
25 MyApp_iOS 0x0026e8cc MyApp_iOS_EAGLView_SimulateAndRender + 196
26 MyApp_iOS 0x0026e1cc MyApp_iOS_EAGLView_MainLoopTimerCallback + 296
27 MyApp_iOS 0x009a7dfc MonoTouch_Foundation_NSActionDispatcher_Apply + 44
28 MyApp_iOS 0x00912540 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
29 MyApp_iOS 0x00acc9c4 mono_jit_runtime_invoke + 2800
30 MyApp_iOS 0x00bd3ea4 mono_runtime_invoke + 140
31 MyApp_iOS 0x00c7d214 monotouch_trampoline + 2840
32 Foundation 0x3363b469 __NSFireTimer + 136
33 CoreFoundation 0x33a770a3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
34 CoreFoundation 0x33a76b5b __CFRunLoopDoTimer + 850
35 CoreFoundation 0x33a481b5 __CFRunLoopRun + 1088
36 CoreFoundation 0x33a47c87 CFRunLoopRunSpecific + 230
37 CoreFoundation 0x33a47b8f CFRunLoopRunInMode + 58
38 GraphicsServices 0x33b0e4ab GSEventRunModal + 114
39 GraphicsServices 0x33b0e557 GSEventRun + 62
40 UIKit 0x32099329 -[UIApplication _run] + 412
41 UIKit 0x32096e93 UIApplicationMain + 670
42 MyApp_iOS 0x009d484c wrapper_managed_to_native_MonoTouch_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 240
43 MyApp_iOS 0x009b4c00 MonoTouch_UIKit_UIApplication_Main_string__ + 36
44 MyApp_iOS 0x00269694 MyApp_iOS_Application_Main_string__ + 128
45 MyApp_iOS 0x00912540 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
46 MyApp_iOS 0x00acc9c4 mono_jit_runtime_invoke + 2800
47 MyApp_iOS 0x00bd3ea4 mono_runtime_invoke + 140
48 MyApp_iOS 0x00bd6f3c mono_runtime_exec_main + 784
49 MyApp_iOS 0x00bd5f6c mono_runtime_run_main + 1048
50 MyApp_iOS 0x00ad7940 mono_jit_exec + 216
51 MyApp_iOS 0x00ac2e38 main + 3536
52 MyApp_iOS 0x000133a0 start + 52
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.
=================================================================
The Darwin kernel overcommits memory.
What this means is that if you request 200 megs of ram, you will get them, even if they are not available and as long as you do not actually consume the memory, your application will run fine.
Only when you actually write to the page will the page be allocated to your process.
A proper test would require you to allocate the memory and then fill up the used memory, this is why you probably get the impression that you can allocate 200 megs of ram even when you might not even have it.
A simple program will show you this: try allocating 500 megs, the OS will say "Yes, you got it", but there are no iPhones with this kind of memory.
A sample test case would go a long way to showing what the problem is.

Instantiating NSObject causes an out of memory crash

When running the below code, the app crashes (after ~30 seconds) with the below stacktrace. I find this very odd since I would expect the garbage collector to clean up this memory. Our application has a similar pattern and crashes with a similar stacktrace.
Commenting out the line that instantiates the NSObject member makes the app run without crash. Commenting out the line that instantiates the byte array makes the app run MUCH longer, but it still crashes.
Instruments reports a pretty well constant Live Bytes for the app and instrumenting causes the app to run much longer without crashing, but it does still crash (after ~10 minutes). The constant Live Bytes makes me feel like the garbage collector is working.
Code:
using System.Threading;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace MyExample
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main(args);
}
}
public partial class AppDelegate : UIApplicationDelegate
{
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
Thread testThread = new Thread(BreakMe);
testThread.Start();
window.MakeKeyAndVisible();
return true;
}
private void BreakMe()
{
while(true)
{
using (var arPool = new NSAutoreleasePool())
{
MyGarbage garbage = new MyGarbage();
}
}
}
private class MyGarbage
{
byte[] _Foo = new byte[100000];
NSObject _Bar = new NSObject();
}
}
}
Application Output:
Mprotect failed at 0x493c000 (length 4096) with errno 12
Stacktrace:
at (wrapper managed-to-native) System.Array.CreateInstanceImpl (System.Type,int[],int[]) <0xffffffff>
at System.Array.CreateInstance (System.Type,int[]) <0x000bc>
at System.Array.CreateInstance (System.Type,int) <0x00057>
at System.MonoCustomAttrs.GetCustomAttributes (System.Reflection.ICustomAttributeProvider,System.Type,bool) <0x000db>
at System.MonoCustomAttrs.GetCustomAttribute (System.Reflection.ICustomAttributeProvider,System.Type,bool) <0x00033>
at System.Attribute.GetCustomAttribute (System.Reflection.MemberInfo,System.Type,bool) <0x0003f>
at MonoTouch.ObjCRuntime.Class.GetHandle (System.Type) <0x00037>
at MonoTouch.Foundation.NSObject.AllocIfNeeded () <0x00063>
at MonoTouch.Foundation.NSObject..ctor (MonoTouch.Foundation.NSObjectFlag) <0x00027>
at MonoTouch.Foundation.NSAutoreleasePool..ctor () <0x00037>
at MyExample.AppDelegate.BreakMe () [0x00000] in Main.cs:30
at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0x000cb>
Native stacktrace:
0 MyExample 0x002db308 mono_handle_native_sigsegv + 404
1 MyExample 0x002fa5dc sigabrt_signal_handler + 148
2 libsystem_c.dylib 0x369c972f _sigtramp + 42
3 libsystem_c.dylib 0x369be3bb pthread_kill + 58
4 libsystem_c.dylib 0x369b6bff abort + 78
5 MyExample 0x0041e484 GC_remap + 200
6 MyExample 0x00411ee4 GC_allochblk_nth + 1536
7 MyExample 0x00411894 GC_allochblk + 96
8 MyExample 0x0041d94c GC_new_hblk + 116
9 MyExample 0x00413c3c GC_allocobj + 188
10 MyExample 0x0041859c GC_generic_malloc_inner + 352
11 MyExample 0x004187ac GC_generic_malloc + 132
12 MyExample 0x00418c60 GC_malloc + 208
13 MyExample 0x003a67dc mono_object_allocate + 64
14 MyExample 0x003a7240 mono_array_new_full + 828
15 MyExample 0x00341324 ves_icall_System_Array_CreateInstanceImpl + 896
16 MyExample 0x0012cf3c (wrapper managed-to-native) System.Array:CreateInstanceImpl (System.Type,int[],int[]) + 80
17 MyExample 0x0012d23c System.Array:CreateInstance (System.Type,int) + 88
18 MyExample 0x0018b70c System.MonoCustomAttrs:GetCustomAttributes (System.Reflection.ICustomAttributeProvider,System.Type,bool) + 220
19 MyExample 0x0018b560 System.MonoCustomAttrs:GetCustomAttribute (System.Reflection.ICustomAttributeProvider,System.Type,bool) + 52
20 MyExample 0x00131fd0 System.Attribute:GetCustomAttribute (System.Reflection.MemberInfo,System.Type,bool) + 64
21 MyExample 0x000795ec MonoTouch.ObjCRuntime.Class:GetHandle (System.Type) + 56
22 MyExample 0x00077e60 MonoTouch.Foundation.NSObject:AllocIfNeeded () + 100
23 MyExample 0x0007779c MonoTouch.Foundation.NSObject:.ctor (MonoTouch.Foundation.NSObjectFlag) + 40
24 MyExample 0x00074d10 MonoTouch.Foundation.NSAutoreleasePool:.ctor () + 56
25 MyExample 0x00002c34 MyExample.AppDelegate:BreakMe () + 164
26 MyExample 0x001f3e3c (wrapper runtime-invoke) object:runtime_invoke_dynamic (intptr,intptr,intptr,intptr) + 204
27 MyExample 0x002c4658 mono_jit_runtime_invoke + 3032
28 MyExample 0x003a34a8 mono_runtime_invoke + 140
29 MyExample 0x003a48f0 mono_runtime_delegate_invoke + 136
30 MyExample 0x003cb31c start_wrapper + 752
31 MyExample 0x003f09a0 thread_start_routine + 240
32 MyExample 0x0041f9ac GC_start_routine + 132
33 libsystem_c.dylib 0x369be311 _pthread_start + 248
34 libsystem_c.dylib 0x369bfbbc start_wqthread + 0
The true answer to this is, is suspect, the issue resolved in Why is our MonoTouch app breaking in the garbage collector? It is not out of memory which was a memory manager issue. The stack trace is very familiar to me.
You have put the allocator in a race with the garbage collector. If you make a simple change to your demo and add:
System.GC.Collect ();
In the loop, you will see it no longer crashes.
Whats happening here is you are allocating as fast as possible. When the GC runs out of memory its expanding the heap and collecting. The next few times the loop runs it runs a bit longer before having to collect again due to the expaned heap, but eventually the race is lost.
Making the minor modification I stated above allowed the test to run for 10 minutes here before I gave up.

Resources