Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
194 views
in Technique[技术] by (71.8m points)

.net - Detecting what the target object is when NullReferenceException is thrown

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?

--edit

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

Try
  ' // 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...