A frustrating GDI bug

In the history of bugs
feedback from users of NDepend,
there are 4 unresolved OutOfMemoryException
unhandled. They all have been reported by different users, on different version
of the product and the call stack is different for all of them. The only common
point is that their call stack all begins with: System.Drawing.Graphics.FromHdcInternal(IntPtr hdc). These bugs
have been classified as unreproductible bug so far since we cannot reproduce it
on our machines despite all our efforts and the users can’t reproduce it

For the next version of
NDepend, we are using a new library and suddenly we got once or twice a day
such OutOfMemoryException popping
from FromHdcInternal(…).  After crawling the web I found this thread
where several programmers complain for the same problem and after a lot of
ramblings an MSFT conclude by: Bottom
line: make sure you explicitly dispose *all* your Graphics objects

The problem is then if you
don’t dispose many GDI object (Font, Brush…) you might get such OutOfMemoryException. I also opened my
own thread

on this, and Hans Passant explains
that it is likely that the process is running out of GDI handles.

After reverse engineered
the library the next version of NDepend will rely on, I found indeed many undisposed
GDI objects. We are then in the process of tracking unreleased GDI objects in
our code and you know what, it reminds me the (not good) old days when I was programming with C++. Hopefully, I
found the tool .NET Memory Profiler
convenient to track undisposed objects.

Despite our efforts, we
know we won’t get all GDI objects disposed, just because some libraries we are
relying on are and will still leak. To avoid users a bad experience, we will
then add a global catch of all OutOfMemoryException
where the call stack begins with FromHdcInternal.
From a user experience perspective, very rarely some GDI drawing will miss a
detail, not clean but still acceptable. From a programmer perspective such a global catch makes me sick but do we have the choice?

I notice that OutOfMemoryException seems to be the common GDI exception for many problems. When you are tracing a small GDI object, you can get such exception as explained here. I also reported a similar exception to MS (see here) when creating a LinearGradientBrush with the 2 same points. The answer is that because of backward compatibility this can’t be changed. 

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Art Scott

    ” … The answer is that because of backward compatibility this can’t be changed. …”

    Of course that is not an answer, its an excuse.

    The good news is that there is competition, which tends towards real answers and less excuses.

    Bad news, it will take time, and someone (hello) deciding to assign the resources to it.

  • http://www.peterRitchie.com/blog Peter Ritchie

    It’s amazing how prevalent problems with two-dimensional shapes with identical top-left and bottom-right coordinates are. Although you don’t get an exception, drawing a line with a top-left coordinate the same as the bottom-right does nothing: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94779