Detecting what the target object is when NullReferenceException is thrown

0 votes
asked Sep 22, 2008 by stingyjack

I'm sure we all have received the wonderfully vague "Object reference not set to instance of an Object" exception at some time or another. Identifying the object that is the problem is often a tedious task of setting breakpoints and inspecting all members in each statement.

Does anyone have any tricks to easily and efficiently identify the object that causes the exception, either via programmatical means or otherwise?


It seems I was vague like the exception =). The point is to _not have to debug the app to find the errant object. The compiler/runtime does know that the object has been allocated/declared, and that the object has not yet been instantiated. Is there a way to extract / identify those details in a caught exception

@ W. Craig Trader

Your explanation that it is a result of a design problem is probably the best answer I could get. I am fairly compulsive with defensive coding and have managed to get rid of most of these errors after fixing my habits over time. The remaining ones just tweak me to no end, and lead me to posting this question to the community.

Thanks for everyone's suggestions.

10 Answers

0 votes
answered Jan 22, 2008 by marce

Set VS to break on exceptions, then when you get your error it's usually pretty obvious what line it's on. The stack trace window will tell you how you got there. Not much else you can do apart from that.

0 votes
answered Jan 22, 2008 by pat

For reference, a similar thread:Should I catch exceptions only to log them?

Salient points is that you want to effectively capture the exception. In my experience, the goal is to make sure that the programmer checks for null references in code - however we know that in reality, we miss some. UI code should have some level of exception handling. I liked my answer to that question: My Answer. More importantly, the comment by 1800 information, who pointed out that you simply throw, and not throw ex in order to capture the entire stack trace which is how you ultimately debug these issues.

0 votes
answered Jan 25, 2008 by benjol

With regards to setting Visual Studio to catch the exception (as suggested here), DON'T FORGET to remove this option once you've fixed the problem. I've just wasted half an hour trying to work out why my application was hanging deep in some part of System.Windows.Forms....

0 votes
answered Sep 22, 2008 by ben-hoffstein

Wouldn't the stack trace give you this information?

0 votes
answered Sep 22, 2008 by kuvo

you can check the Message and InnerException properties

0 votes
answered Sep 22, 2008 by pawel-pabich

Well, you can not really identify the object as it does not exist and thus the exception you are getting.

0 votes
answered Sep 22, 2008 by oliver-mellet

There's really not much you can do besides look at the stack trace; if you're dereferencing multiple object references in the same line of code, there's no way to determine which one is null without setting a breakpoint. You could avoid this by only dereferencing one object per line, but that would result in some pretty terrible-looking code.

0 votes
answered Sep 22, 2008 by chris-marasti-georg

The line # and file are usually all you need to find the culprit. If you are the one throwing the exception, consider using an ArgumentNullException, if appropriate, or checking for nulls and throwing NullReferenceExceptions that have more details about the null field.

Edit @ your edit :)

AFAIK, you would have to examine the stack trace string to get that line # and file. Your best bet would be to get the innermost exception, and then look at the first line of its stack trace. If you want to be able to programatically parse that information to find out which field caused the null, and do something with that field's name, I fear you will be out of luck.

@W. Craig Trader

Good point. For a null value that is passed into the method, an ArgumentNullException should be thrown. For a member variable that has not yet been initialized, something like an InvalidStateException would probably be good to throw. Unfortunately, I can't find any such exception in MSDN. Roll your own?

0 votes
answered Sep 22, 2008 by craig-trader

At the point where the NRE is thrown, there is no target object -- that's the point of the exception. The most you can hope for is to trap the file and line number where the exception occurred. If you're having problems identifying which object reference is causing the problem, then you might want to rethink your coding standards, because it sounds like you're doing too much on one line of code.

A better solution to this sort of problem is Design by Contract, either through builtin language constructs, or via a library. DbC would suggest pre-checking any incoming arguments for a method for out-of-range data (ie: Null) and throwing exceptions because the method won't work with bad data.

[Edit to match question edit:]

I think the NRE description is misleading you. The problem that the CLR is having is that it was asked to dereference an object reference, when the object reference is Null. Take this example program:

public class NullPointerExample {
  public static void Main()
    Object foo;
    System.Console.WriteLine( foo.ToString() );

When you run this, it's going to throw an NRE on line 5, when it tried to evaluate the ToString() method on foo. There are no objects to debug, only an uninitialized object reference (foo). There's a class and a method, but no object.

Re: Chris Marasti-Georg's answer:

You should never throw NRE yourself -- that's a system exception with a specific meaning: the CLR (or JVM) has attempted to evaluate an object reference that wasn't initialized. If you pre-check an object reference, then either throw some sort of invalid argument exception or an application-specific exception, but not NRE, because you'll only confuse the next programmer who has to maintain your app.

0 votes
answered Sep 22, 2008 by matt-ryan

As a few answers have pointed out, tell Visual Studio to break on Throw for NullReferenceException.

How to tell VS to break when unhandled exceptions are thrown

  • Debug menu | Exceptions (or Ctrl + Alt + E)
  • Drill into Common Language Runtime Exceptions
  • Drill into System
  • Find System.NullRefernceException, and check the box to Break whenever this exception is thrown, rather than allowing it to proceed to whatever Catch blocks are in place

So now when it occurs, VS will break immediately, and the Current Statement line will be sitting on the expression that evaluated to null.

This facility is useful for all kinds of exceptions, including custom ones (can add the fully qualified type name, and VS will match it at Debug time)

The one drawback to this approach is if there is code loaded in the debugger that follows the bad practice of throwing and catching lots of the exceptions you're looking for, in which case it turns back into a haystack / needle issue (unless you can fix that code of course - then you've solved two problems :)

One other trick that may come in handy (but only in some languages) is the use of the When (or equivalent) keyword... In VB, this looks like

  ' // Do some work           '
Catch ex As Exception When CallMethodToInspectException(ex)

End Try

The trick here is that the When expression is evaluated before the callstack is unwound to the Catch block. So if you're using the debugger, you can set a breakpoint that expression, and if you look at the callstack window (Debug | Windows | Callstack), you can see and navigate to line that triggered the exception.

(You can choose to return false from the CallMethodToInspectException, so the Catch block will be ignored and the runtime will continue the search through the stack for an appropriate Catch block - which can allow for logging that doesn't affect behavior, and with less overhead than a catch and re-throw)

If you were just interested in non-interactive logging, then assuming you've got a Debug build (or to some extent as you have do deal with optimisation issues, Release build with PDBs) you could get most of the info needed to track down the bug from the Exception ToString, with the included stack-trace-with-line-number.

If however line number wasn't enough, you can get the column number too (so pretty much, the particular local or expression that is null) by extracting the StackTrace for the exception (using either the above technique, or just in the catch block itself):

int colNumber = new System.Diagnostics.StackTrace(ex, true).GetFrame(0).GetFileColumnNumber();

While I've not seen what it does for NullReference or other runtime generated exceptions, may also be interested in looking at Exception Hunter as a static analysis tool.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter