Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,9 @@ static Vertex CreateLineNumbersBlob(NativeWriter writer, StackTraceDocumentsNode

foreach (NativeSequencePoint sequencePoint in debugInfoNode.GetNativeSequencePoints())
{
if (currentLineNumber == sequencePoint.LineNumber && currentDocument == sequencePoint.FileName)
continue;

// Make sure a zero native offset delta is not possible because we use it below
// to indicate an update to the current document.
if (currentDocument != null && currentNativeOffset == sequencePoint.NativeOffset)
continue;

Debug.Assert(currentDocument == null || currentNativeOffset != sequencePoint.NativeOffset);
if (currentDocument != sequencePoint.FileName)
{
// We start with currentDocument == null, so the reader knows the first byte of the output
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,9 @@ public IEnumerable<NativeSequencePoint> GetNativeSequencePoints()
if (_debugLocInfos == null)
yield break;

var sequencePoints = new (string Document, int LineNumber, bool IsBackedSequencePoint)[_debugLocInfos.Length * 4 /* chosen empirically */];
var sequencePoints = new (string Document, int LineNumber)[_debugLocInfos.Length * 4 /* chosen empirically */];
try
{
int maxOffset = 0;
foreach (var sequencePoint in _debugInfo.GetSequencePoints())
{
int offset = sequencePoint.Offset;
Expand All @@ -272,16 +271,15 @@ public IEnumerable<NativeSequencePoint> GetNativeSequencePoints()
int newLength = Math.Max(2 * sequencePoints.Length, sequencePoint.Offset + 1);
Array.Resize(ref sequencePoints, newLength);
}
sequencePoints[offset] = (sequencePoint.Document, sequencePoint.LineNumber, true);
maxOffset = Math.Max(maxOffset, offset);
sequencePoints[offset] = (sequencePoint.Document, sequencePoint.LineNumber);
}

// Propagate last known document/line number forward to enable correct mapping when IL offsets decrease at higher native offsets
for (int i = 1; i <= maxOffset; i++)
for (int i = 1; i < sequencePoints.Length; i++)
{
if (sequencePoints[i].Document == null && sequencePoints[i - 1].Document != null)
{
sequencePoints[i] = (sequencePoints[i - 1].Document, sequencePoints[i - 1].LineNumber, false);
sequencePoints[i] = (sequencePoints[i - 1].Document, sequencePoints[i - 1].LineNumber);
}
}
}
Expand All @@ -294,28 +292,26 @@ public IEnumerable<NativeSequencePoint> GetNativeSequencePoints()
}

int previousNativeOffset = -1;
int previousIlOffset = -1;
string previousDocument = null;
int previousLineNumber = -1;
// OffsetMapping is sorted in order of increasing native offset (but not necessarily by IL offset)
foreach (var nativeMapping in _debugLocInfos)
{
if (nativeMapping.NativeOffset == previousNativeOffset)
Copy link
Member

@jkotas jkotas Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (nativeMapping.ILOffset < sequencePoints.Length) condition below looks suspect to me. Should we map IL offsets that are higher than sequencePoints.Length to the last non-backed sequencePoint?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like sequencePoints.Length was chosen to try to minimize the chances of this, but yes I think this would be a good failure behavior.

continue;

if (nativeMapping.ILOffset < sequencePoints.Length)
var sequencePoint = sequencePoints[Math.Min(nativeMapping.ILOffset, sequencePoints.Length - 1)];
// Emit sequence point if its line number or document differ from the previous one.
// See WalkILOffsetsCallback in src/coreclr/vm/debugdebugger.cpp for more details.
if (sequencePoint.Document != null && (sequencePoint.Document != previousDocument || sequencePoint.LineNumber != previousLineNumber))
{
var sequencePoint = sequencePoints[nativeMapping.ILOffset];
// Emit sequence point if we have it from _debugInfo or if ILOffset decreases.
// This handles the case of IL offsets decreasing at higher native offsets.
// See WalkILOffsetsCallback in src/coreclr/vm/debugdebugger.cpp for more details.
if ((sequencePoint.IsBackedSequencePoint || nativeMapping.ILOffset < previousIlOffset) &&
sequencePoint.Document != null)
{
yield return new NativeSequencePoint(
nativeMapping.NativeOffset,
sequencePoint.Document,
sequencePoint.LineNumber);
previousNativeOffset = nativeMapping.NativeOffset;
previousIlOffset = nativeMapping.ILOffset;
}
yield return new NativeSequencePoint(
nativeMapping.NativeOffset,
sequencePoint.Document,
sequencePoint.LineNumber);
previousNativeOffset = nativeMapping.NativeOffset;
previousDocument = sequencePoint.Document;
previousLineNumber = sequencePoint.LineNumber;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,9 @@ private void setBoundaries(CORINFO_METHOD_STRUCT_* ftn, uint cMap, OffsetMapping
case (int)MappingTypes.NO_MAPPING:
continue;
}
// Ignore these; see WalkILOffsetsCallback in src/coreclr/vm/debugdebugger.cpp.
if (nativeToILInfo->source == SourceTypes.CALL_INSTRUCTION)
continue;

debugLocInfos.Add(new DebugLocInfo((int)nativeToILInfo->nativeOffset, ilOffset));
}
Expand Down
Loading