Keep end-of-method sequence points at the end of the method #987

Open
michaelglass wants to merge 1 commit from michaelglass/fix-portable-pdb-end-sequence-point into master
michaelglass commented 2026-09-25 14:15:26 -05:00 (Migrated from github.com)

Read an F# assembly with its portable PDB, insert instructions into a method, write it back, and System.Reflection.Metadata throws on that method's sequence points:

System.BadImageFormatException: Invalid compressed integer.
   at System.Reflection.Metadata.SequencePointCollection.Enumerator.MoveNext()

(MS CodeCoverage then silently drops the method.)

Cause: F# emits a hidden sequence point at offset == code size. CodeReader.ReadSequencePoints can't bind it to an instruction, so it keeps its raw offset. After an insert it's still written at the old offset, behind the previous point, so the blob gets a negative delta.

Fix: mark a point read at offset == code size as end-of-method, and move it to the new code size before the symbol writer runs. No public API change; all three symbol writers get the right offset.

Test: PortablePdbTests.EndOfMethodSequencePointAfterInsertingInstructions builds ldc.i4.1; ldc.i4.2; add; ret with points at 0, 3 and hidden 4, inserts ldc.i4 42; pop, and checks SRM decodes the points as 6, 9, 10. Fails on master with the exception above.

Related to #840 and #853, but a different cause: sorting would put this point in the wrong place rather than at the end.

Read an F# assembly with its portable PDB, insert instructions into a method, write it back, and System.Reflection.Metadata throws on that method's sequence points: ``` System.BadImageFormatException: Invalid compressed integer. at System.Reflection.Metadata.SequencePointCollection.Enumerator.MoveNext() ``` (MS CodeCoverage then silently drops the method.) **Cause:** F# emits a hidden sequence point at offset == code size. `CodeReader.ReadSequencePoints` can't bind it to an instruction, so it keeps its raw offset. After an insert it's still written at the old offset, behind the previous point, so the blob gets a negative delta. **Fix:** mark a point read at offset == code size as end-of-method, and move it to the new code size before the symbol writer runs. No public API change; all three symbol writers get the right offset. **Test:** `PortablePdbTests.EndOfMethodSequencePointAfterInsertingInstructions` builds `ldc.i4.1; ldc.i4.2; add; ret` with points at 0, 3 and hidden 4, inserts `ldc.i4 42; pop`, and checks SRM decodes the points as `6, 9, 10`. Fails on master with the exception above. Related to #840 and #853, but a different cause: sorting would put this point in the wrong place rather than at the end.
This pull request is broken due to missing fork information.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin 'michaelglass/fix-portable-pdb-end-sequence-point:michaelglass/fix-portable-pdb-end-sequence-point'
git switch 'michaelglass/fix-portable-pdb-end-sequence-point'

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch 'master'
git merge --no-ff 'michaelglass/fix-portable-pdb-end-sequence-point'
git switch 'michaelglass/fix-portable-pdb-end-sequence-point'
git rebase 'master'
git switch 'master'
git merge --ff-only 'michaelglass/fix-portable-pdb-end-sequence-point'
git switch 'michaelglass/fix-portable-pdb-end-sequence-point'
git rebase 'master'
git switch 'master'
git merge --no-ff 'michaelglass/fix-portable-pdb-end-sequence-point'
git switch 'master'
git merge --squash 'michaelglass/fix-portable-pdb-end-sequence-point'
git switch 'master'
git merge --ff-only 'michaelglass/fix-portable-pdb-end-sequence-point'
git switch 'master'
git merge 'michaelglass/fix-portable-pdb-end-sequence-point'
git push origin 'master'
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-jbevain/cecil!987
No description provided.