Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ilasm produces wrong SequencePoints when a method references several Documents #102198

Closed
yjaradin opened this issue May 14, 2024 · 1 comment · Fixed by #102199
Closed

ilasm produces wrong SequencePoints when a method references several Documents #102198

yjaradin opened this issue May 14, 2024 · 1 comment · Fixed by #102199

Comments

@yjaradin
Copy link
Contributor

Description

When a method contains .line directives referring to several documents, ilasm ignores all but the last specified document.
This in turn impacts tools (such as Visual Studio) that will, for example, show the wrong file (and therefore an irrelevant line) when stepping through the built code.

Reproduction Steps

After having built the tests, run the following program.

using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

//Adapt the following two lines to suit your platform/configuration/folders.
var dotnetRuntimeRepo = "C:\\repositories\\dotnet\\runtime";
var pepath = $"{dotnetRuntimeRepo}\\artifacts\\tests\\coreclr\\windows.x64.Debug\\ilasm\\PortablePdb\\IlasmPortablePdbTests\\TestFiles\\TestDocuments1_win.dll";
//compiled from <dotnetRuntimeRepo>\src\tests\ilasm\PortablePdb\TestFiles\TestDocuments1_win.il
var pereader = new PEReader(File.OpenRead(pepath));
pereader.TryOpenAssociatedPortablePdb(pepath, s => File.OpenRead(s), out var pdbreader, out var pdbpath);
if (pdbreader == null) return;
var reader = pdbreader.GetMetadataReader();
foreach (var mdi in reader.MethodDebugInformation)
{
    if (mdi.IsNil) continue;
    foreach (var sp in reader.GetMethodDebugInformation(mdi).GetSequencePoints())
    {
        var d = sp.Document;
        if (d.IsNil) continue;
        Console.WriteLine(reader.GetString(reader.GetDocument(d).Name));
    }
}

For reference, here is TestsDocuments1_win.il:

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

.assembly extern System.Runtime
{
}

.assembly TestDocuments
{
}

.class public auto ansi beforefieldinit TestDocumentsType
       extends [System.Runtime]System.Object
{
    .method public hidebysig instance void Foo() cil managed
    {
    .line 1,1 : 9,10 'C:\\tmp\\non_existent_source1.cs'
        nop
    .line 2,2 : 9,10 'C:\\tmp\\non_existent_source2.cs'
        ret
    }
}

Expected behavior

The following output is expected (on Windows, on other platforms the paths will be different but the important digit would be the same):

C:\tmp\non_existent_source1.cs
C:\tmp\non_existent_source2.cs

Actual behavior

The following output is produced (again, on Windows with slight changes to the paths but not the digits on other platforms):

C:\tmp\non_existent_source2.cs
C:\tmp\non_existent_source2.cs

Regression?

This is a functional regression compared to .NET Framework although it used a different (non-portable) PDB file format.

Known Workarounds

Using .NET Framework where practical.

Configuration

Observed on:

.NET 6 -> .NET 9 (preview 3)
Windows 10 x64, Windows 11 x64

Not specific to that configuration

Other information

The issue is in the method

HRESULT PortablePdbWriter::DefineSequencePoints(Method* method)
which doesn't deal with an initial document (L208) and only provides a unique document (L314, notice that it uses currSeqPoint outside the loop).

I have a fix and a test for this issue that will be in an upcoming PR.

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 14, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label May 14, 2024
yjaradin added a commit to yjaradin/dotnet-runtime that referenced this issue May 14, 2024
Make sure the SequencePoints produced in the PDB
reference the documents indicated on the .line directive.

Fix dotnet#102198
@jkotas jkotas added area-ILTools-coreclr and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 14, 2024
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

noahfalk pushed a commit that referenced this issue May 27, 2024
* ilasm support for methods with multiple documents

Make sure the SequencePoints produced in the PDB
reference the documents indicated on the .line directive.

Fix #102198

* Clean up ilasm PortablePdb tests

---------

Co-authored-by: Ivan Povazan <[email protected]>
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label May 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants