4

I've been noticing that the call stack in VS always seems to be off by a line. Once I step into a function the line number for the stack frame I just left gets incremented and points to the next non-empty line. Then if I double click that frame in the Call Stack window it indeed takes me to some line after the function call that I'm actually in. I've repo'd this in empty projects in both VS2015 and VS2017 (debug builds).

In the pic below you'll notice the second stack frame indicates line 17, which is the return several lines below the Log() call where the debugger is actually stopped.

This is a trivial repro, but I'm seeing this constantly in real projects and I don't recall having this problem outside of the last few days.

Anyone have any idea what might be causing this?

enter image description here

Community
  • 1
  • 1
Adam
  • 1,122
  • 9
  • 21
  • 1
    This is expected. The value on the stack is the return address. In other words, it's the next line to execute after the call returns. – Raymond Chen Mar 22 '17 at 05:53
  • 1
    The debugger has to correct the return address on the stack to find the line with the function call. This goes wrong in the specific case of a function that takes no arguments and has no (used) return value. Use connect.microsoft.com to report this bug. Beware that it has been around for a while, goes wrong in all recent VS versions back to at least VS2013, so probably not easy to fix. Or nobody reported it yet, I don't see any existing reports. – Hans Passant Mar 22 '17 at 10:09
  • 1
    @RaymondChen Are you sure this is expected? The stack is supposed to be the current state of execution, not some mix between current and future. I've never seen this occur in other languages and find it extremely unintuitive. There appears to be further evidence for it being a bug based on the fact that the behavior changes. If I add a parameter to Log() the stack is correct. If I add a return value but don't use it the stack is incorrect. If I add a return value and use it the stack is again correct. I agree with Hans assessment, this looks an awful lot like a bug. – Adam Mar 22 '17 at 15:13
  • 1
    The stack is the *future* state. It is the continuation. The reason the problem goes away if you add a parameter to `Log()` is that there is post-call work that needs to occur when there is a parameter (cdecl args cleanup), and that post-call work can be attributed to the line that made the call. Similarly, if you add a return value, then the post-call work is to save the return value. The post-call work can be attributed to the calling line because the call to the `Log` function is not the last thing the line of code does. This is completely expected. Drop to assembly language and you'll see. – Raymond Chen Mar 22 '17 at 21:38
  • 1
    Ok, I'm starting to get it. It's the *return address* being pushed onto the stack like you said in your first statement. It took a bit to click. My mental model has been wrong for quite some time. Going off Hans comment, is VS intended to 'correct' the address shown in the Call Stack Window to map to the call site, or is intended to be a raw view of the actual stack? It gets confusing to walk up the stack during an exception/breakpoint and end up at code that hasn't been run yet. I'm not sure I've run into this behavior in the last 4 years. Certainly not in C# anyway. – Adam Mar 27 '17 at 06:17
  • 1
    Does this mean that the Call Stack is not the same as a Stack Trace? I've never seen a stack trace that didn't map to the exact lines of code that were running. That would imply that a stack trace maps back to the source line that caused the stack frame to be created as opposed to mapping to the source line of the return address. That's what I would expect the VS Call Stack window to do. – Adam Mar 27 '17 at 06:25
  • @Adam, this thread shared the differences between the Call stack and Stack Trace: http://stackoverflow.com/questions/7482591/what-is-the-difference-between-call-stack-and-stack-trace, I met one issue(Stack Trace showed the wrong line number): http://stackoverflow.com/questions/2493779/wrong-line-number-on-stack-trace which was related to the Exception or the debug/release mode(optimized). – Jack Zhai Mar 29 '17 at 09:05
  • @JackZhai-MSFT The definitions of Stack Trace in the first link simply define it as a copy of the Call Stack at a point in time. This would imply they are equivalent and that a Stack Trace would exhibit this same behavior of mapping to the source code of the return address, not the call site. The second link appears to be about an entirely different topic that happens to affect the Stack Trace. – Adam Mar 29 '17 at 18:18

0 Answers0