[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);