Bug 5090 - The CGColorSpace.CreateDeviceRGB () causes a crash
Summary: The CGColorSpace.CreateDeviceRGB () causes a crash
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 4.x
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2012-05-15 10:05 UTC by Paul Sinnema
Modified: 2013-12-05 18:36 UTC (History)
3 users (show)

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:

Description Paul Sinnema 2012-05-15 10:05:26 UTC

The problem with this crash is that it does not happen immediately but after a while in a routine that is not related to the CGColorSpace.CreateDeviceRGB () method.

I've debugged this deeply and thoroughly and have to come to this conclusion. The CGColorSpace.CreateDeviceRGB () method is used in the ZXing library implementation for MonoTouch. In the Bitmap class in the constructor it used as shown below. When I comment out all the code for the 'using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB ())' the App no longer crashes. This for me leads to the conclusion that there must be some interference in this method.

Paul Sinnema

		public Bitmap (UIImage image)
			UIImage backingImage = image;
			IntPtr rawData;
			using (CGImage imageRef = backingImage.CGImage)
				width = imageRef.Width;
				height = imageRef.Height;
				using (CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB ())
					int size = height * width * 4;
					rawData = ReallocBuffer(size);
					using (CGContext context = new CGBitmapContext (rawData, width, height, 8, 4 * width, colorSpace, CGImageAlphaInfo.PremultipliedLast))
						context.DrawImage (new RectangleF (0.0f, 0.0f, (float)width, (float)height), imageRef);
						pixelData = new byte[size];
						Marshal.Copy (rawData, pixelData, 0, pixelData.Length);
Comment 1 Sebastien Pouliot 2012-05-15 10:46:03 UTC
Please attach:
* a sample solution that shows the issue;
* a crash log;
* the version numbers of MonoTouch (MD...) that you're using;

> the App no longer crashes.

CGBitmapContext is more likely to be misused since it relies on manually managed memory (e.g. ReallocBuffer) that must be handled (e.g. in the finalizer).

You might want to try keeping the `CGColorSpace.CreateDeviceRGB` but commenting what's inside the using block to see if it crash or not.
Comment 2 Paul Sinnema 2012-05-15 11:04:30 UTC
Hi Sebastien,

I have already done that. Just using the CreateDeviceRGB() and nothing in the body of the using, crashes the App.

My latest try was to create the ColorSpace only once (which is something the method itself also does) but to no relieve, which was to be expected.

Comment 3 Paul Sinnema 2012-05-15 11:08:05 UTC
	Mono 2.10.9 (tarball Mon May  7 20:25:51 EDT 2012)
	GTK 2.24.10
	GTK# (
	Package version: 210090011
Apple Developer Tools:
	 Xcode 4.2.1 (834)
	 Build 4D502
Monotouch: 5.2.11

A sample solution would take a lot of time to create since it is inside an App that uses a library class which in turn uses a ZXing library class. You would need the complete ZXing.MonoTouch implementation.

If you insist I could look what I can do.
Comment 4 Paul Sinnema 2012-05-15 11:11:48 UTC

Native stacktrace:

	0   Winkel                              0x00714b64 mono_handle_native_sigsegv + 280
	1   Winkel                              0x006ff184 mono_sigsegv_signal_handler + 268
	2   libsystem_c.dylib                   0x3394a7ed _sigtramp + 48
	3   Winkel                              0x00020344 System_Collections_Generic_Dictionary_2_System_Runtime_Serialization_Json_TypeMapMember_bool_ContainsValue_bool + 148
	4   Winkel                              0x0003dd7c iPhone_ScanLibrary_BarcodeScanController_Stop + 140
	5   Winkel                              0x0003da8c iPhone_ScanLibrary_BarcodeScanController_HandleScanOverlayBarcodeScanned_object_ScanLibrary_ScanOverlay_ScanResultArgs + 468
	6   Winkel                              0x0003a9f4 ScanLibrary_ScanOverlay_HandleCaptureVideoDelegateBarcodeScanned_object_ScanLibrary_ScanOverlay_ScanResultArgs + 212
	7   Winkel                              0x0003bc0c ScanLibrary_ScanOverlay_CaptureVideoDelegate_DidOutputSampleBuffer_MonoTouch_AVFoundation_AVCaptureOutput_MonoTouch_CoreMedia_CMSampleBuffer_MonoTouch_AVFoundation_AVCaptureConnection + 608
	8   Winkel                              0x005eb4e0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
	9   Winkel                              0x007011a4 mono_jit_runtime_invoke + 1644
	10  Winkel                              0x007a87f8 mono_runtime_invoke + 128
	11  Winkel                              0x00822e04 monotouch_trampoline + 3196
	12  AVFoundation                        0x32c6924b __74-[AVCaptureVideoDataOutput _AVCaptureVideoDataOutput_VideoDataBecameReady]_block_invoke_0 + 226
	13  libdispatch.dylib                   0x31526c59 _dispatch_call_block_and_release + 12
	14  libdispatch.dylib                   0x31528d0f _dispatch_queue_drain + 274
	15  libdispatch.dylib                   0x31528b75 _dispatch_queue_invoke$VARIANT$mp + 40
	16  libdispatch.dylib                   0x315297e7 _dispatch_worker_thread2 + 210
	17  libsystem_c.dylib                   0x338fbdfb _pthread_wqthread + 294
	18  libsystem_c.dylib                   0x338fbcd0 start_wqthread + 8

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.
Comment 5 Paul Sinnema 2012-05-15 11:14:55 UTC
My guess is that the stack trace of no use at all. The App crashes at random places and sometimes even just hangs. My first thoughts as I started debugging this problem (which I have now tried to solve for more than 3 days all together) was that the Alloc routines that allocate memory outside the managed code was overrunning its buffer or something like that. But in the mean time (after adding a free in the Dispose()) this no long seems possible.
Comment 6 Sebastien Pouliot 2012-05-15 11:21:54 UTC
We definitively need a test case. We have a bunch of unit tests for CGColorSpace, including CreateDeviceRGB, and I know several applications using it - so there's something else that is causing (alone or in conjunction with CGColorSpace) your crash.

You can attach a large test case privately to the bug report. You can also contact support@xamarin.com to ask for an NDA agreement before sharing existing code (if this helps).

Note: crash logs and/or the content of the device console logs just prior the crash can also prove useful. Thanks for the stack trace but it's sometimes just hide what's being done, at the same time, in other threads.
Comment 7 Paul Sinnema 2012-05-15 11:23:57 UTC
You can find more information here too: http://stackoverflow.com/questions/10105102/zxing-still-has-a-memory-leak-even-after-releasing-the-global-alloc
Comment 8 Paul Sinnema 2012-05-15 11:26:35 UTC
You would need an Apple developer licence, MonoTouch will not be a problem I guess ;-) An iPhone 4 or iPad 2/3 to be able to test the App with camera. If all that is no problem I could send the complete project.
Comment 9 Sebastien Pouliot 2012-05-15 11:41:47 UTC
We got the Apple licenses and the hardware.

BTW in your SO link I do not see where the unmanaged memory you allocated gets freed ? 

Your Realloc will free before allocating a new buffer but each Bitmap will leak the last allocated buffer (which can be quite large) and will lead to out of memory conditions. The GC won't free memory allocated by Marshal where th ereference it kept by an IntPtr.
Comment 10 Paul Sinnema 2012-05-15 11:54:27 UTC
You're right. In a later version I decided against that. I now use a static buffer that stays and is reallocated when it gets too small (did not solve the problem either).
Comment 11 Paul Sinnema 2012-05-15 11:59:42 UTC
Huh, what do you mean the Realloc will leak. I think not. It is only reallocated when the size needed is bigger the the size allocated. It should not leak anything.
Comment 12 Paul Sinnema 2012-05-15 12:25:23 UTC
Can you tell me what happens with the destination of the Marshal.Copy(). Does it get freed by the GC?
Comment 13 Sebastien Pouliot 2012-05-15 12:36:13 UTC
`pixelData` is a byte[] array and, like other managed instances, it will be freed by the GC (at collection time) only when no more reference exists to it. Since it's a field this will occurs once the object instance is finalized (or earlier since IDisposable is implemented*).

* btw you should not call `GC.SuppressFinalize(this);` inside Dispose (not Collect).
Comment 14 Sebastien Pouliot 2012-05-15 12:40:12 UTC
> what do you mean the Realloc will leak.

I do not have your full source code so maybe I'm missing somehting but...

Who will free the memory you allocated with Marshal.AllocHGlobal ? e.g. if Realloc is not called (and even then it will realloc a larger amount of memory).

If the memory is not freed then what can it do but leak ? i.e. it won't ever be "free" to use by your application (or anyone else).
Comment 15 Paul Sinnema 2012-05-15 13:21:35 UTC
Oh well, that's right. I allocate it once and it never gets freed. I have taken that into account and because this App will always scan something that is not a problem as long as it does not leak cumulatively. I know its not nice.

Today I tried reimplementing the free of the buffer at dispose time and again I was confronted with 'Out of Memory' warning and a crash. Somewhere in the code memory is allocated and cumulates over time. It always is in the AllocHGlobal and FreeHGlobal combination that causes this. I find the Marshal.Copy() very suspect. This btw is the reason I created the Realloc in the first place.

I'm not using the GC.SuppressFinalize(this) so that can not be the problem either.

After another day of trail and error I'm still at a loss. The problem seems to have loosened a bit (it happens after more scans now) but it still happens. I must say that debugging such crashes is almost impossible because of lacking information from iOS.
Comment 16 Sebastien Pouliot 2012-05-15 13:27:12 UTC
still waiting for a test case / app...
Comment 17 Paul Sinnema 2012-05-16 05:49:11 UTC
Tried to attach the solution to the bug but it is too big.
Comment 18 Sebastien Pouliot 2012-05-16 07:35:30 UTC
You can try to email it to my xamarin email address or use a service like dropbox and give us the URL to download from.
Comment 20 Rolf Bjarne Kvinge [MSFT] 2012-05-17 04:31:01 UTC
I tried the app and the camera has been running for 10 minutes now and nothing else has happened. Are there any specific steps needed to reproduce the crash?
Comment 21 Paul Sinnema 2012-05-17 04:38:35 UTC
In my experience it takes about 10 to 20 scans of barcodes to cause the crash. You'll need an EAN 13 barcode and let the app scan that. This will take you to the product page, then back, back and scan again (very tedious, sorry).
Comment 22 Paul Sinnema 2012-05-17 04:42:40 UTC
What I usually do is call google.com with images and search for BARCODE EAN 13. You can scan from your monitor.
Comment 23 Rolf Bjarne Kvinge [MSFT] 2012-05-17 05:08:07 UTC
I just scanned 50 barcodes, and I didn't see any indication of any problems (on an iPad 3).

Here are a few ideas to track this down:

* Try to process the same image many times, like this in ScanOverlay.cs:

string barcode;
for (int i = 0; i < 10000; i++) {
    barcode = DecodeBarcodeFromImage (image); 

any leaks in the Bitmap ctor will definitively show up now.

* Try using autorelease pool in DidOutputSampleBuffer in ScanOverlay.cs - surrounding the entire method body in a using (var pool = new NSAutoreleasePool ()) { <method body> };

* Run Instruments - the Activity Monitor and keep an eye on your process while you're processing images. Does its memory usage grow?
Comment 24 Paul Sinnema 2012-05-17 05:15:24 UTC
That's really weird. You never get any crash at all. I'm running the App on iPhone 4 or iPad 2. Could that make a difference?
Comment 25 Rolf Bjarne Kvinge [MSFT] 2012-05-17 05:17:12 UTC
Something is obviously different, and that is one possibility. Can you try the ideas in comment #23 to see what happens? That would hopefully make things a little bit clearer.
Comment 26 Paul Sinnema 2012-05-17 05:20:04 UTC
Unfortunatly I don't have an iPad or iPhone at the moment, had to return that to the company because of other developers needing it for preparation for an event this weekend. Next week I'll have it back and I'll try your suggestions then. Thanks a lot for all the help.

Comment 27 PJ 2013-11-19 17:05:51 UTC
This bug has been in the NEEDINFO state with no changes for the last 90 days. Can we put this back into the NEW or CONFIRMED state, or are we still awaiting response?

If there is no change in the status of this bug over the next two weeks, this bug will be marked as NORESPONSE.
Comment 28 PJ 2013-12-05 18:36:18 UTC
This bug has not been changed from the NEEDINFO state since my previous comment, marking as RESOLVED NORESPONSE.

Please feel free to REOPEN this bug at any time if you are still experiencing the issue. Please add the requested information and set the bug back to the NEW (or CONFIRMED) state.