0

I've solved the problem (explanation below) but I'm trying to figure out why the stack trace is giving me the wrong line.

Overview: This is a Repeater control that allows a professor to mark an exam, one question at a time while still being able to view an entire exam.

Basic Idea (pseudo.aspx):

<asp:repeater>
    <ItemTemplate>
    <fields/>
    <textbox id="grade">
    <asp:LinkButton ID="UpdateButton" runat="server" Text="Update" OnClick="OnUpdate" />
    </ItemTemplate>
</asp:repeater>

The user is supposed to enter a grade, and the question mark is updated in the database in the OnClick event, and the entire page is databound again.

Code:

protected void OnUpdate(object sender, EventArgs e)
{  // I broke this down line by line trying to trace the error. 
   LinkButton button = (LinkButton)sender; //Object Not set exception here!!! 
   object o = button.Parent;
   RepeaterItem item = o as RepeaterItem;
   int StudentID = int.Parse((item.FindControl("StudentKeyLabel1") as HiddenField).Value);
   string ExamID = (item.FindControl("ExamIDLabel1") as HiddenField).Value.Trim();
   int QuestionID = int.Parse((item.FindControl("QuestionIDLabel1") as HiddenField).Value);
   int Grade;
   try
   {
       Grade = int.Parse((item.FindControl("GradeTextBox") as TextBox).Text);
       // Update DB
   }
   catch (FormatException)
   { // Message to user - bad or missing grade }
   //Custom Databind
}

I had changed the fields in the .aspx from labels to hidden fields in the aspx, but forgot to change them in the .aspx.cs file -- This was the actual cause of the error.

However, the stack trace (customerrors="Off") showed the Object reference not set to type Object as occurring at this line:

LinkButton button = (LinkButton)sender; //Object Not set error here!!!

but the actual error was several lines below.

My oversight took a long time to fix because of this. You can see that I broke down the retrieval of the RepeaterItem line by line, and put a throw new Exception(xxx.GetType().ToString() to check for reference validity after each line trying to figure it out. The funny thing is, that the original error didn't appear when there was a manual throw lower down.

Why was the stack trace showing the exception as coming from the wrong spot in the code?

Chris Cudmore
  • 29,793
  • 12
  • 57
  • 94
  • 1
    Similar (not sure if duplicate)? https://stackoverflow.com/questions/37072185/wrong-line-numbers-in-stack-trace – gunr2171 Nov 26 '18 at 21:25
  • 1
    In a pinch, you can use [#line](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-line) preprocessor directive to force exceptions to log line numbers the way you want. – Brian Nov 27 '18 at 14:00

1 Answers1

4

There are a great many reasons why the line number in the stack trace can be wrong. Here are just a few:

  • You edited the code after you compiled the program. Now the source code line numbers and the running code do not match.
  • You're running an optimized version of the program. Optimizations can cause line numbers to be reported incorrectly.
  • You've modified the compiled code with an IL injecting tool, and now the generated code does not match the debugging information. This can cause line numbers to be reported wrong.

Basically, there are three things: the source code, the generated IL code, and the PDB that contains debugging information describing the relationship between the source and IL. If any of those for any reason do not match each other, then they do not match each other, and so you can observe them not matching each other.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • The thing is, if I put a debugging "throw new Exception(xxx.GetType().ToString()" above the line where the actual error was, the line number was reported correctly. 1 and 3 definitely don't apply, and as I was still in early development, I hadn't yet turned on optimizations. – Chris Cudmore Nov 27 '18 at 13:50