Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullReferenceException with no stack trace when hooking SetConsoleCtrlHandler

Tags:

c#

console

hook

Using code to hook the console close event from this thread, I sometimes get a NullReferenceException with no stacktrace (most of the times I don't). It happens in both release and debug and "break when an exception is thrown" doesn't help (it breaks, but the stack trace is still empty). I never get this exception when I exit my application normally (which is hitting enter and thus releasing a Console.ReadLine). The Application event log has 2 entries:

Application: MyApp.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.NullReferenceException Stack:

And:

Faulting application name: Gateway.exe, version: 1.0.0.0, time stamp: 0x4e284101 Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000 Exception code: 0xc0000005 Fault offset: 0x004d41ce Faulting process id: 0xf00 Faulting application start time: 0x01cc47b827e19a6e Faulting application path: C:\dev\MyApp.exe Faulting module path: unknown Report Id: 689c1caa-b3ab-11e0-ba1b-00247e777f12

Google has revealed some bugs and issues with SetConsoleCtrlHandler, so I'm wondering if this is a lost battle.

like image 247
Ohad Schneider Avatar asked Jul 21 '11 22:07

Ohad Schneider


People also ask

Can a stack trace be null?

Yes. If you create a new Exception() and don't throw it, every property except Data and Message will be null.

Why am I getting a NullReferenceException?

This error is caused when an object is trying to be used by a script but does not refer to an instance of an object. To fix this example we can acquire a reference to an instance of the script using GameObject.

How do you handle NullReferenceException?

You can eliminate the exception by declaring the number of elements in the array before initializing it, as the following example does. For more information on declaring and initializing arrays, see Arrays and Arrays. You get a null return value from a method, and then call a method on the returned type.

What does system NullReferenceException mean?

The NullReferenceException is designed as a valid runtime condition that can be thrown and caught in normal program flow. It indicates that you are trying to access member fields, or function types, on an object reference that points to null. That means the reference to an Object which is not initialized.


1 Answers

The most typical issue with code like that is not keeping a reference to the delegate instance. The one you pass as the first argument to SetConsoleCtrlHandler(). The garbage collector cannot see references held to a delegate object by unmanaged code. So this will, eventually, bomb when the garbage collector runs:

 SetConsoleCtrlHandler(Handler, true);

which is the exact same thing as

 SetConsoleCtrlHandler(new EventHandler(Handler), true);

assuming you used the types in the linked code. The author of that code carefully avoided this issue by making _handler a static variable. As opposed to the temporary delegate instance that is created by the previous two lines of code. Storing it in a static variable ensures it stays referenced for the life of the program. The Right Thing to do in this particular case since you are actually interested in the events until the program ends.

like image 102
Hans Passant Avatar answered Nov 19 '22 22:11

Hans Passant