dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.84k stars 4.62k forks source link

Debugging not working with self-contained single file .NET6 assemblies #84428

Closed Pyrdacor closed 3 weeks ago

Pyrdacor commented 1 year ago

Description

When I publish a .NET assembly with the following command, there are no debug symbols available in VS2022. And trying to load the PDB manually leads to "image mismatch" errors or "can't find matching debug symbols".

This is the publish command:

dotnet publish -c Debug ./path/to/project.csproj -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -r win-x64 --nologo --self-contained -o ./path/to/output

However if I set self-contained to false, it just works: --self-contained=false.

The problem occurs regardless if the debug symbols are embedded or stored as a PDB file.

I hope this is the right place. I know VS2022 is the one which can't load the debug symbols but I am pretty sure it's about the debug symbol creation/connection and not the loading. But I might be wrong.

Others seem to have the same problems. Look here: https://stackoverflow.com/questions/64897623/no-symbols-when-attaching-to-net-core-program-single-file/73796666#73796666.

Configuration

dsplaisted commented 1 year ago

@agocke Can you have someone take a look at this and triage it?

agocke commented 1 year ago

@Pyrdacor there's some extra requirements for debugging single file in net6.0. Did you try the instructions at https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli#attach-a-debugger

Otherwise, could you try this in .net 7 and see if you get the same result? There are some changes to debugger tooling so that .NET 7 should have a better experience.

forReason commented 1 year ago

same issue here in .net 7

from0toTheSummit commented 1 year ago

confirm. the problem with self contained single file.

ghost commented 1 year ago

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

Issue Details
### Description When I publish a .NET assembly with the following command, there are no debug symbols available in VS2022. And trying to load the PDB manually leads to "image mismatch" errors or "can't find matching debug symbols". This is the publish command: `dotnet publish -c Debug ./path/to/project.csproj -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -r win-x64 --nologo --self-contained -o ./path/to/output` However if I set self-contained to false, it just works: `--self-contained=false`. The problem occurs regardless if the debug symbols are embedded or stored as a PDB file. I hope this is the right place. I know VS2022 is the one which can't load the debug symbols but I am pretty sure it's about the debug symbol creation/connection and not the loading. But I might be wrong. Others seem to have the same problems. Look here: https://stackoverflow.com/questions/64897623/no-symbols-when-attaching-to-net-core-program-single-file/73796666#73796666. ### Configuration - dotnet 6 (but seems to be a problem since netcore already) - tested on Win7 x64 but I guess the OS doesn't matter here - x64 in this case - Debug config of course
Author: Pyrdacor
Assignees: -
Labels: `area-Diagnostics-coreclr`
Milestone: -
ghost commented 1 year ago

Tagging subscribers to this area: @agocke, @vitek-karas, @vsadov See info in area-owners.md if you want to be subscribed.

Issue Details
### Description When I publish a .NET assembly with the following command, there are no debug symbols available in VS2022. And trying to load the PDB manually leads to "image mismatch" errors or "can't find matching debug symbols". This is the publish command: `dotnet publish -c Debug ./path/to/project.csproj -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -r win-x64 --nologo --self-contained -o ./path/to/output` However if I set self-contained to false, it just works: `--self-contained=false`. The problem occurs regardless if the debug symbols are embedded or stored as a PDB file. I hope this is the right place. I know VS2022 is the one which can't load the debug symbols but I am pretty sure it's about the debug symbol creation/connection and not the loading. But I might be wrong. Others seem to have the same problems. Look here: https://stackoverflow.com/questions/64897623/no-symbols-when-attaching-to-net-core-program-single-file/73796666#73796666. ### Configuration - dotnet 6 (but seems to be a problem since netcore already) - tested on Win7 x64 but I guess the OS doesn't matter here - x64 in this case - Debug config of course
Author: Pyrdacor
Assignees: -
Labels: `area-Diagnostics-coreclr`, `area-Single-File`, `untriaged`
Milestone: -
agocke commented 1 year ago

@VSadov I assume this is the new Windows API problems showing up

from0toTheSummit commented 1 year ago

no. it is not new. there are a lot of topics for 1-2 years

agocke commented 1 year ago

@from0toTheSummit As detailed in the old docs, single file was not debuggable in initial releases. VS has been updated to support it, but we've recently seen problems due to our usage of a new API in Windows for memory mapping that is now starting to roll-out and disrupt the VS work.

Kurpanik commented 5 months ago

Problem still exists. Our workaround for now: Use PublishSingleFile=true only when in Release configuration

<PublishSingleFile Condition="'$(Configuration)' == 'Release'">true</PublishSingleFile>

agocke commented 5 months ago

@tommcdon Could someone from diagnostics take a look? My understanding is that current VS should be working.

BDisp commented 1 month ago

This issue still happens with .NET8. I want to know why it is failing as single file, I can attach to the debugger but no PDB are loaded.

tommcdon commented 3 weeks ago

This scenario is working for me. @Pyrdacor @BDisp please confirm that the correct debug engine is being used in VS/VS Code

For example:

  1. dotnet new console
  2. dotnet publish -c Debug -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -r win-x64 --nologo --self-contained
  3. devenv /debugexe bin\Debug\net9.0\win-x64\publish\foo2.exe
  4. Right click on the project (foo2) and pick the Managed (.NET Core, .NET 5+) debug engine: image
  5. Set a breakpoint in the app and F5, observe that the breakpoint is hit: image

Note that the contents of the output window should show that we are loading binaries from the temp directory as this is a self-extracting zip file scenario

'foo2.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Users\tommcdon\AppData\Local\Temp\.net\foo2\cesQfxpuDvEYg7B9P3ifk6DBLAJVJWc=\System.Private.CoreLib.dll'. Symbol loading disabled by Include/Exclude setting.
'foo2.exe' (CoreCLR: clrhost): Loaded 'C:\Users\tommcdon\AppData\Local\Temp\.net\foo2\cesQfxpuDvEYg7B9P3ifk6DBLAJVJWc=\foo2.dll'. Symbols loaded.
'foo2.exe' (CoreCLR: clrhost): Loaded 'C:\Users\tommcdon\AppData\Local\Temp\.net\foo2\cesQfxpuDvEYg7B9P3ifk6DBLAJVJWc=\System.Runtime.dll'. Symbol loading disabled by Include/Exclude setting.
'foo2.exe' (CoreCLR: clrhost): Loaded 'C:\Users\tommcdon\AppData\Local\Temp\.net\foo2\cesQfxpuDvEYg7B9P3ifk6DBLAJVJWc=\System.Console.dll'. Symbol loading disabled by Include/Exclude setting.

If symbols are not being loaded for app code, then ensure that the app hasn't been rebuilt since debugging. The PDB will be in the publish directory, but the module will be in temp. From the Modules window in VS: image

dotnet-policy-service[bot] commented 3 weeks ago

This issue has been marked needs-author-action and may be missing some important information.

BDisp commented 3 weeks ago

@tommcdon I really appreciated your help. I didn't know we could prepare a pre debug from running an executable. I was using the System.Diagnostics.Debugger.IsAttached but that isn't working on native Aot. It seems that publishing from the VS2022 using a publish profile doesn't have the same behavior as like using the dotnet publish command line, including the path which is different. I had to use the command line to achieve your explanation, thanks. And for debugging the same way in WSL using linux-64, it's also possible?

But that didn't work for me. I've VS2022 Version 17.10.5 and I've to right click the project pick the Properties and then pick the Managed (.NET Core, .NET 5+) debug engine. I can't see the Program.cs file to set a breakpoint. I click on Start to run it but I couldn't set a breakpoint. The only way I could manage the debug it was put at start of the Program.cs file the instruction Console.Read();. After I click on Start the console is waiting for input but still the Program.cs file doesn't open. I had to click on pause for the Program.cs file show up.

The Modules window is only enabled after the executable is running and that way it's possible to load some external sources after decompile. But how to set a breakpoint before start running?

tommcdon commented 3 weeks ago

I was using the System.Diagnostics.Debugger.IsAttached but that isn't working on native Aot.

Do you mean System.Diagnostics.Debugger.IsAttached does not return true if a native debugger is attached to the app, or that you were not able to use the Managed (.NET Core, .NET 5+) debug engine with Native AOT? Note that Native AOT publish is off by default in VS and is only enabled if clicking the "Enable native AOT publish" option when creating the project:

image

When the publish for NativeAOT checkbox is set, the csproj will have the following line in it:

<PublishAot>true</PublishAot>

To use managed debugging on a published app, that line would need to be removed.

It seems that publishing from the VS2022 using a publish profile doesn't have the same behavior as like using the dotnet publish command line, including the path which is different.

It's possible to configure VS publishing to produce a single-file app:

image

Drag and drop the EXE into VS to create a VS EXE project: image

Configure the Debugger engine for Managed (.NET Core, .NET 5+) image

Then hit F10 to start the program with the instruction pointer in the first line in the program:

image

And for debugging the same way in WSL using linux-64, it's also possible?

Yes:

The only way I could manage the debug it was put at start of the Program.cs file the instruction Console.Read();. After I click on Start the console is waiting for input but still the Program.cs file doesn't open. I had to click on pause for the Program.cs file show up.

One way is to use File->Open and navigate to the proper C# file and open it, then set a breakpoint at the desired location.
Another other way is to simply start the program with F10 (step) instead of F5 (go). F10 will start the program in the first line of the program.
And yet another way is to set a function breakpoint to stop in the desired function, automatically loading the sources for it. For example:

using System;

public class Foo
{
    public static void Main()
    {
        Console.WriteLine("Hello, World!");
    }
}

image

image

It sounds like the original problem reported in this issue is resolved, so I will go ahead and close this issue.

Hope this helps!!

BDisp commented 3 weeks ago

Do you mean System.Diagnostics.Debugger.IsAttached does not return true if a native debugger is attached to the app, or that you were not able to use the Managed (.NET Core, .NET 5+) debug engine with Native AOT?

I meant System.Diagnostics.Debugger.IsAttached does not return true if a native debugger is attached to the app.

Thank you very much for your excellent explanation.

BDisp commented 3 weeks ago

When the publish for NativeAOT checkbox is set, the csproj will have the following line in it:

<PublishAot>true</PublishAot>

To use managed debugging on a published app, that line would need to be removed.

The problem here is some functionality doesn't work with a NativeAOT published executable and I need to debug to identify them and using another alternatives, such as source generators. What the alternative to I could use to debug it?

tommcdon commented 3 weeks ago

The problem here is some functionality doesn't work with a NativeAOT published executable and I need to debug to identify them and using another alternatives, such as source generators. What the alternative to I could use to debug it?

You can use native AOT publish debug configuration:

image

Then similar to .NET core singlefile, drag the EXE into VS to create a VS project, then use the Native debug engine to debug (which I believe will be the default for this app type):

image

You should find that symbols load for the EXE and that you can set breakpoints in the program, view locals, and observe the callstack:

image

Note that the debug experience won't be the same as .NET Core because the app has been compiled to native code, so things like C# expression evaluation and async stepping won't work. Please see https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/diagnostics#native-debugging for more information.

Hope this helps!

BDisp commented 3 weeks ago

Then hit F10 to start the program with the instruction pointer in the first line in the program:

When I hit F10 the app run and ends without give any chance to set a breakpoint. I also open the C# file in the EXE project and set the breakpoint in the first line in the program but the debugger don't stop on it. It's due I have the Microsoft Visual Studio Community 2022 (64-bit) - Current - Version 17.10.5?

tommcdon commented 3 weeks ago

Then hit F10 to start the program with the instruction pointer in the first line in the program:

When I hit F10 the app run and ends without give any chance to set a breakpoint. I also open the C# file in the EXE project and set the breakpoint in the first line in the program but the debugger don't stop on it. It's due I have the Microsoft Visual Studio Community 2022 (64-bit) - Current - Version 17.10.5?

It should work with VS Community with no issues. Please try disabling Just My Code under Debug->Options.

Hope this helps!

BDisp commented 3 weeks ago

It should work with VS Community with no issues. Please try disabling Just My Code under Debug->Options.

Hope this helps!

Disabled Just My Code it's working now as expect. Sorry and thank you very much for your great help and time.