microsoft / DockerTools

Tools For Docker, including Visual Studio Provisioning and Publishing
Other
175 stars 26 forks source link

How can the platform be specified for the correct remote debug tools to be copied? #354

Closed Metritutus closed 2 months ago

Metritutus commented 2 years ago

I have a project that builds for x86, whose files are then copied to a docker container. By default, when building the container Visual Studio will copy the x64 msvsmon files to the C:\remote_debugger folder, not the ones the project was building for (in this case x86).

As far as I can tell, the msvsmon files come from the onecoremsvsmon folder in the current user directory, which appears to get created during the ResolveOneCoreMsVsMonPath step, from somewhere within Microsoft.Docker.BuildTasks.dll.

Is there any way to get it to copy the correct remote debugger? What am I missing?

dbreshears commented 2 years ago

I don't believe there is an x86 version of onecoremsvsmon. The x64 version of this debugger should work with x86 applications as the debugger architecture should match the Container OS and not the application.

Can you elaborate on the scenario a bit more?

I am not able to find x86 versions of Windows Server beyond Windows 2008 R2 so I assume the container OS is 64-bit? Is that not the case? What is your base image? Are you able to CTRL-F5 the application or run the application successfully in the container without debugging?

Metritutus commented 2 years ago

I don't believe there is an x86 version of onecoremsvsmon. The x64 version of this debugger should work with x86 applications as the debugger architecture should match the Container OS and not the application.

Can you elaborate on the scenario a bit more?

I am not able to find x86 versions of Windows Server beyond Windows 2008 R2 so I assume the container OS is 64-bit? Is that not the case? What is your base image? Are you able to CTRL-F5 the application or run the application successfully in the container without debugging?

The container is Windows Server Core (specifically mcr.microsoft.com/windows/servercore:ltsc2022), and the OS can run both x86 and x64 applications. Manually running the x86 application via the container CLI works fine. The issue is debugging when using the remote debugger copied across by the build process.

When attempting to start the project with debugging from Visual Studio with Docker (not using a docker-compose project), it attempts to attach the debugger and fails almost immediately with no error dialog is shown, and the only debug output is this:

'dotnet.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.4\System.Private.CoreLib.dll'. 
The program '[1992] dotnet.exe' has exited with code 3762504530 (0xe0434352).

When running with a simple docker-compose project, it doesn't seem to get to the point of attempting to attach the debugger (so there's no debug output), but an error dialog is shown with more useful information:

Unable to start program '<REDACTED>'

The 64-bit version of the Visual Studio Remote Debugger (MSVSMON.EXE) cannot be used to debug 32-bit processes or 32-bit dumps. Please use the 32-bit version instead.

I did find this, which may shed some light on the situation (quoted from the linked page):

The VS remote debuggers (on their own) are only able to debug a process of matching architecture. So an x64 msvsmon can only debug an x64 process, and similarly for an x86 msvsmon. However, if both the x86 and x64 msvsmons are present, the x64 msvsmon can be used to debug an x86 process because it will launch the x86 version of msvsmon.

So if you are copying msvsmon over from a VS installation, copying the entire Remote Debugger folder instead of just a specific architecture and then running the x64 version should allow you to remote debug either type of process.

I'm not sure if this functionality of msvsmon is documented anywhere (if it is, I have been unable to find it).

dbreshears commented 2 years ago

@Metritutus

Thank you for the information on how x64 falls back to x86. I guess from below I validated that behavior. Certainly a valid bug here in our tooling that assumes x64 only but I am trying to find a workaround for now.

I assumed there was no x86 version of onecoremsvsmon but that was incorrect. It appears it is only installed as part of the UWP workload in VS setup. I installed that workload and then replicated by hand the %userprofile%\onecoremsvsmon\x86 folder, copying in the CoreClr and target\lib folder like we do for x64. I tried with both x64 and x86 folders (fallback) as well as just an x86 after changing the entrypoint in to point to the x86 version. In all cases I keep getting a 3221225781 exit code which looks like it is a missing DLL issue?

I'll need to reach out to the debugger team and see if we can figure out why that version is not able run and what we might be missing.

dbreshears commented 2 years ago

Actually, I just noticed I hadn't updated my Dockerfile to use ltsc2022 from the default VS scaffolds. With that ltsc2022 base image I am able to run the x86 version of msvsmon in the container after replicating the folder structure that we copy too. now hit the issue of not having the x86 version of dotnet installed, which assume you have installed in yours.

Metritutus commented 2 years ago

Actually, I just noticed I hadn't updated my Dockerfile to use ltsc2022 from the default VS scaffolds. With that ltsc2022 base image I am able to run the x86 version of msvsmon in the container after replicating the folder structure that we copy too. now hit the issue of not having the x86 version of dotnet installed, which assume you have installed in yours.

That's correct. The Hosting Bundle installer (found here) is used, which is installs both x86 and x64 versions of .NET.

PMJMendes commented 1 year ago

I've run into this exact same problem, but I'm using the following images:

mcr.microsoft.com/dotnet/runtime:7.0

mcr.microsoft.com/dotnet/sdk:7.0

Visual Studio 2022 simply exits debug mode with no error message or console output.

NCarlsonMSFT commented 1 year ago

I took another look at this and now have a much simpler work-around. Once you have a ServerCore image that supports the x86 runtime you can update your project for x86 by adding the Project Properties:

    <DockerDebuggeeProgram>c:\Program Files (x86)\dotnet\dotnet.exe</DockerDebuggeeProgram>
    <ContainerVsDbgPath>$(DevEnvDir)\Remote Debugger</ContainerVsDbgPath>

DockerDebuggeeProgram is needed to start the x86 dotnet runtime, ContainerVsDbgPath is needed to use the full remote debugger instead of onecoremsvsmon (that's only needed for Nano). I've now made a sample for this with a commit of going from x64 to x86: Target x86

PMJMendes commented 1 year ago

Edit: Never mind. I swapped the images for ltsc2019 instead, and everything works like a charm! Thank you kindly for the example repo.

Original comment:

This looks like it should work, but I've run into a few problems.

First, the images in the example don't run on my Win10Pro machine. I had to use images mcr.microsoft.com/windows:10.0.19042.1889 AS installer and mcr.microsoft.com/dotnet/runtime:7.0.12 AS base

Second, the final container exits immediately with no logs, and then Visual Studio says the container has no IP address.

Also, as an aside, this build process seems to leave the installer image dangling.

dbreshears commented 2 months ago

Closing issue as there is a a workaround. This has a high regression risk and we have no plans to address.