Skip to content

[clr-interp] Line number off-by-one for non-leaf interpreter frames in debugger stack traces #127277

@kotlarmilos

Description

@kotlarmilos

Summary

In debugger stack walks of interpreter frames, non-leaf frames map to the IL offset of the instruction after the call, producing a source line one statement past the call site. Leaf frames are correct. JIT frames are not affected.

Affected tests:

  • StackWalking.BigStackTest
  • StackWalking.Stacktrace
  • StackWalking.DbgBreakThreads

Root cause

The stack walker returns the raw interpreter IP, which for non-leaf frames points at the instruction after the call. IP-to-IL mapping on the consumer side does a half-open [nativeStartOffset, nativeEndOffset) range lookup against the OffsetMapping the interpreter emits.

On the ICorDebug / DI path, rsstackwalk.cpp only subtracts STACKWALK_CONTROLPC_ADJUST_OFFSET for justAfterILThrow. For regular non-leaf frames the raw native offset is passed to SequencePoints::MapNativeOffsetToIL, so nothing compensates for the return-address IP.

The JIT does not hit this because it emits boundaries only at statement/sequence-point starts; the ranges are coarse enough that the return-address IP stays inside the call-statement's native range.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions