Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
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
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.
The CGDataProvider(byte buffer, int offset, int count) constructor does not hold onto a reference to buffer. Thus, buffer can be garbage collected before the data provider is used to construct an image. The CGDataProvider instance should hold a reference to buffer so that it can be used safely and the Monotouch garbage collector doesn't free the memory prematurely.
There is a reference kept to `buffer` when you use:
public CGDataProvider (byte  buffer, int offset, int count)
so the GC should not collect it unless the `CGDataProvider` instance is disposed.
a. Can you provide a test case that shows your issue ?
b. Also include all your version informations*
* The easiest way to get exact version information is to use the "Xamarin Studio" menu, "About Xamarin Studio" item, "Show Details" button and copy/paste the version informations (you can use the "Copy Information" button).
After further debugging, retaining an instance doesn't seem to fix the problem.
The problem only reproduces using the SGen garbage collector.
As far as I can tell, if the array is recently allocated, it resides in generation 0. If a collection occurs before the CGDataProvider is used, the array is copied in memory to generation 1, and the native CGDataProvider ends up referencing garbage memory because it doesn't know that the memory has moved.
Looking at the source code for CGDataProvider, it doesn't seem like there is any code that prevents the array from moving (or copies the data) when a garbage collection occurs.
I don't have a good small test case that I can attach at this time. It is a bit difficult to reproduce the issue.
=== Xamarin Studio ===
Version 5.1 (build 479)
Installation UUID: a0248109-ee04-4fb3-bea3-55b92bef282e
Mono 3.4.0 ((no/954ed3c)
GTK+ 2.24.23 (Raleigh theme)
Package version: 304000214
=== Xamarin.Android ===
=== Apple Developer Tools ===
Xcode 5.1.1 (5085)
=== Xamarin.iOS ===
Version: 126.96.36.199 (Indie Edition)
Build date: 2014-06-18 02:37:27-0400
=== Xamarin.Mac ===
=== Build Information ===
Release ID: 501000479
Git revision: e5a428cec75d4cc7e6e3ccd8192a3660d013e7dc
Build date: 2014-06-26 09:28:17-04
Xamarin addins: 190d93e026e17280e75a3680ef38f2630b9228d3
=== Operating System ===
Mac OS X 10.9.3
Darwin Peters-MacBook-Pro.local 13.2.0 Darwin Kernel Version 13.2.0
Thu Apr 17 23:03:13 PDT 2014
You're right. The existing `fixed` statement only pin the memory for the duration of the call (p/invoke).
OTOH that pointer can be used later (by native code) and the corresponding managed memory could have moved (when sgen is used). That will need a `GCHandle.Alloc(buffer, GCHandleType.Pinned);`
Fixed in master / c16c3a72107ac5be9c1da73cc44cb6ff5657d9c7
I have checked this issue on following:
Mac OS X 10.9.3
Xamarin Studio: 5.3 (build 413)
Mono 3.8.0 ((no/9ffca33)
Release ID: 503000413
Git revision: 0b0a22314801b920383045d46a578c716f55e481
Build date: 2014-08-06 04:53:22-04
Xamarin addins: 57e379e6a9454a1c0d97aa3f770e7ae7cc16c522
I have checked the definition of "CGDataProvider" class in assembly browser and observed that the "this.gch=GCHandle.Alloc(buffer, GCHandleType.Pinned);" statement is added to the "CGDataProvider (byte buffer, int offset, int count)". Now "CGDataProvider" hold reference to the buffer.
This issue has been fixed. Hence closing this issue.