a nullpointer in drawing.dll?? bug??

  • Thread starter Thread starter Bartje
  • Start date Start date
B

Bartje

I'm putting my first steps in the code access security
world and to run applications with different evidence.
I've been trying to write a hostapplication to give
assemblies a certain evidence and the hostapplication
seems to work well but when I close the application, I
get the following nullpointerexception:

Unhandled Exception: System.NullReferenceException:
Object reference not set to an instance of an object.
at System.Drawing.SafeNativeMethods.IntGdipDeleteFont
(HandleRef font)
at System.Drawing.SafeNativeMethods.GdipDeleteFont
(HandleRef font)
at System.Drawing.Font.Dispose(Boolean disposing)
at System.Drawing.Font.Finalize()

The strange thing is that is only appears when i host a
application with a form. For example: I've got 2
helloworld app's. One with a form with a "hello world"
label and one that writes "hello world" in the console.
the nullpointer only appears with the first application
(and also other applications with a form).
Is there someone who can help me to fix this prob?
thx a lot
bart
 
Hi Bart,

I've been doing some research about this myself. I've come across the
following discussions of similar problems:

http://www.csharp-station.com/ShowPost.aspx?PostID=1321

http://www.dotnet247.com/247reference/msgs/31/159840.aspx

I think what you are seeing is a bug in the .NET Framework class library
and, more specifically, in System.Drawing.dll. This assembly is
basically a wrapper around GDI+, a Windows API. As a result, the
assembly has to deal with lots of handles of (i.e. pointers to)
unmanaged objects.

The bug is more specifically in the cleanup code, that is, in the code
that is responsible for cleaning up resources after use. More
specifically, the bug is in the Dispose methods and, as a result, it
also shows up during finalization. It seems that the developers of this
code forgot to clearly fix ownership of unmanaged resources: who is
responsible for cleanup up which resources?

This bug shows up in your program because you are using multiple
AppDomains, all of which use System.Drawing objects. But, when your
program ends, all of these AppDomains are unloaded, and all finalizers
of all objects in these AppDomains are executed. I think that in this
case, the same unmanaged resources are being cleaned up more than once,
which clearly is something GDI+ is not happy about. I think the
NullPointerException is really a memory access violation or invalid
instruction violation or something like that, which got converted into a
NullPointerException by the CLR.

You can work around this by having a GUI only in the host application,
and not in the hosted applications. This means either using
Console.WriteLine in the hosted apps, or using .NET Remoting for
communication between the host app and the hosted app.

For example, instead of running a "void Main()" method, you could run a
"string PerformComputation()" method in the hosted domain and pass the
resulting string back to the host application. The host application can
then show the string in its GUI.

Bart
 
I have the exact same problem! I host a IE component. This component sometimes have to load a .NET application (smart client running
in a browser). Now, as I close the main form hosting the IE component, I get the same errors (NullRefException within
Drawing.Font.Dispose() etc.)

There your solution does not work, because I did not have any control about the loaded AppDomain within the IE host control, or I'm
wrong?

How can I workaround this problem? Just ignoring these exceptions would be enough...
Please help again!

Torsten

Bart said:
Hi Bart,

I've been doing some research about this myself. I've come across the
following discussions of similar problems:

http://www.csharp-station.com/ShowPost.aspx?PostID=1321

http://www.dotnet247.com/247reference/msgs/31/159840.aspx

I think what you are seeing is a bug in the .NET Framework class
library and, more specifically, in System.Drawing.dll. This assembly
is basically a wrapper around GDI+, a Windows API. As a result, the
assembly has to deal with lots of handles of (i.e. pointers to)
unmanaged objects.

The bug is more specifically in the cleanup code, that is, in the code
that is responsible for cleaning up resources after use. More
specifically, the bug is in the Dispose methods and, as a result, it
also shows up during finalization. It seems that the developers of
this code forgot to clearly fix ownership of unmanaged resources: who
is responsible for cleanup up which resources?

This bug shows up in your program because you are using multiple
AppDomains, all of which use System.Drawing objects. But, when your
program ends, all of these AppDomains are unloaded, and all finalizers
of all objects in these AppDomains are executed. I think that in this
case, the same unmanaged resources are being cleaned up more than
once, which clearly is something GDI+ is not happy about. I think the
NullPointerException is really a memory access violation or invalid
instruction violation or something like that, which got converted
into a NullPointerException by the CLR.

You can work around this by having a GUI only in the host application,
and not in the hosted applications. This means either using
Console.WriteLine in the hosted apps, or using .NET Remoting for
communication between the host app and the hosted app.

For example, instead of running a "void Main()" method, you could run
a "string PerformComputation()" method in the hosted domain and pass
the resulting string back to the host application. The host
application can then show the string in its GUI.

Bart

--
Regards,
Torsten Rendelmann

PS: Answer/Reply always to the group!
For avoidance of spam mailings my e-mail
address is invalid!
 
Torsten,

I fear that continuing to use System.Drawing (and therefore GDI+) after
these exceptions have occurred is risky business, since, in my
hypothesis, GDI+ is in an inconsistent state at that point.

I see three remedies, in order of decreasing preference:
- Microsoft fixes the bugs in the design of the System.Drawing cleanup code
- each application (i.e. AppDomain) that uses System.Drawing runs in a
seperate OS process
- make sure all AppDomains are unloaded only when you exit the process
(and the System.Drawing objects are not otherwise disposed or finalized
beforehand). This way, the exceptions occur only during process shutdown.

Bart
 
Back
Top