[Mono-bugs] [Bug 65963][Wis] New - [PATCH] Disposing a graphics causes problems
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Tue, 14 Sep 2004 23:50:22 -0400 (EDT)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by david.mitchell@telogis.com.
http://bugzilla.ximian.com/show_bug.cgi?id=65963
--- shadow/65963 2004-09-14 23:50:22.000000000 -0400
+++ shadow/65963.tmp.4741 2004-09-14 23:50:22.000000000 -0400
@@ -0,0 +1,81 @@
+Bug#: 65963
+Product: Mono: Class Libraries
+Version: unspecified
+OS:
+OS Details:
+Status: NEW
+Resolution:
+Severity:
+Priority: Wishlist
+Component: Sys.Drawing.
+AssignedTo: mono-bugs@ximian.com
+ReportedBy: david.mitchell@telogis.com
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: [PATCH] Disposing a graphics causes problems
+
+Description of Problem:
+When you dispose a Graphics object libgdiplus frees the memory used for the
+native graphics structure. This means that if you try to get the graphics
+for an image twice, you are in trouble. Eg:
+
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+
+public class DrawTest {
+ public static void Main(string[] args) {
+ Image img = new Bitmap(300,300);
+
+ // Get the graphics once then dispose it, which frees the native
+ // obj
+ Graphics oldg1 = Graphics.FromImage(img);
+ oldg1.Dispose();
+
+ // Get the graphics again. This has an invalid native object
+ Graphics newg = Graphics.FromImage(img);
+
+ // Watch this fail
+ newg.DrawLine(Pens.Blue, 0, 0, 100, 100);
+
+ newg.Dispose();
+ }
+}
+
+This program fails with the following stack trace:
+
+Unhandled Exception: System.NullReferenceException: Object reference not
+set to an instance of an object
+in (unmanaged) (wrapper managed-to-native)
+System.Drawing.GDIPlus:GdipDrawLineI (intptr,intptr,int,int,int,int)
+in <0x00004> (wrapper managed-to-native)
+System.Drawing.GDIPlus:GdipDrawLineI (intptr,intptr,int,int,int,int)
+in <0x00042> System.Drawing.Graphics:DrawLine
+(System.Drawing.Pen,int,int,int,int)
+in <0x00097> (wrapper remoting-invoke-with-check)
+System.Drawing.Graphics:DrawLine (System.Drawing.Pen,int,int,int,int)
+in <0x00091> TestText:Main (string[])
+
+Solution to this is to set the image->graphics to NULL when the graphics is
+disposed:
+
+
+Index: graphics.c
+===================================================================
+RCS file: /mono/libgdiplus/src/graphics.c,v
+retrieving revision 1.79
+diff -u -r1.79 graphics.c
+--- graphics.c 2 Aug 2004 07:51:01 -0000 1.79
++++ graphics.c 15 Sep 2004 03:10:58 -0000
+@@ -355,6 +355,8 @@
+ if (graphics->ct)
+ cairo_destroy (graphics->ct);
+ graphics->ct = NULL;
++
++ ((GpImage*) graphics->image)->graphics = NULL;
+
+ GdipFree (graphics);