9
votes

Why would a stack trace show "line 0", but only for one frame in the stack trace?

eg.

...
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at My.LibraryA.Some.Method():line 16
at My.LibraryB.Some.OtherMethod():line 0
at My.LibraryB.Some.Method():line 22
at My.LibraryA.Some.Method():line 10

Background:

I have an application that is failing with an exception, and is logging a stack trace to its log file. When the applciation was built, all assemblies were compiled with full debug info (Project Properties -> Build -> Advanced -> Debug Info -> Full), and so PDB files were generated. To help me diagnose where the error is coming from, I dropped the PDB files into the application's bin directory, and reproduced the exception. All line numbers for each stack frame look correct, with the exception of one which displays "line 0" as its source.

1
Was it compiled with optimizations turned on? (Remember, optimizations on/off and debug info on/off are orthogonal switches.) If so then the jitter might choose to do inlining or other optimizations that can make it hard to work out where the original code was.Eric Lippert
@Eric: yes it was. Is there any way of getting the actual line number of out?adrianbanks
Sure. Compile it with optimizations turned off.Eric Lippert
Note also that the jitter is allowed to optimize away call stack frames if it can do tail recursion. An important fact that many people seem to not appreciate: the call stack does not tell you where the call came from. It tells you where control is going to next. Usually you can figure out where the call came from by knowing where it is going next, but if the jitter can figure out where control is going next without preserving information about where the call came from, it is allowed to do so.Eric Lippert

1 Answers

5
votes

This was indeed down the the inlining of them method as Eric suggested.

I managed to reproduce the original error locally, but only when compiling in a release build. As I had the PDBs, I could step through the code and find the problem.