无法从 Visual Studio 在某些计算机上调试远程 docker:VsDbgRemoteUnixLauncher 仅支持远程 Unix 计算机

Can't debug remote docker on some machines from Visual Studio: VsDbgRemoteUnixLauncher only supports remote Unix machines

提问人:Coder14 提问时间:10/27/2023 最后编辑:Coder14 更新时间:11/22/2023 访问量:81

问:

我有一个 .NET 7 应用程序在 Ubuntu 机器上的 Linux docker 容器中运行。我无法将 Visual Studio(在 Windows 11 上)附加到我的应用程序。我可以连接到其他 Ubuntu 机器上 Docker 中的其他 .NET 应用程序。

我收到此错误: 无法启动调试适配器“coreclr”。 VsDbgRemoteUnixLauncher 仅支持远程 Unix 计算机!

附加到进程向导可以看到容器,也可以看到这些容器中的进程,因此 ssh 连接似乎没有问题。

我没有在网上找到任何关于这个错误的信息。

额外信息:运行以下命令后,调试适配器主机日志的输出:DebugAdapterHost.Logging /On /OutputWindow

 1> DebugAdapterHost version: 17.6.10530.1 commit:a8b80a80533cc2b91039497e292d6997b60501a6
 1> ERROR: Failed to launch debug adapter!

DebugAdapterLaunchException: Failed to launch debug adapter.  Additional information may be available in the output window.

Failure Location: LaunchingProcess
Inner Exception: 
    InvalidOperationException: VsDbgRemoteUnixLauncher only supports remote Unix machines!

Microsoft.VisualStudio.Debugger.VsDbg.Integration.AdapterLauncher.VsDbgRemoteUnixLauncher.Microsoft.VisualStudio.Debugger.DebugAdapterHost.Interfaces.IAdapterLauncher.LaunchAdapter(IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop)
Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost.AdapterHosting.DebugAdapterProcessConnection..ctor(ConfigurationWrapper configuration, IDiagnosticLogger log, IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop, IAdapterLauncher launcher)
Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost.AdapterHosting.DebugAdapterHostFactory.CreateDebugAdapterHost(ConfigurationWrapper configuration, IDiagnosticLogger log, ExtensibilityManager extensibilityManager, IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop, Boolean registerStandardHandlers, DebugProtocolOptions options, Action`1 syncRequestErrorHandler)

 1> ERROR: Unexpected error

DebugAdapterLaunchException: Failed to launch debug adapter.  Additional information may be available in the output window.

Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost.AdapterHosting.DebugAdapterHostFactory.CreateDebugAdapterHost(ConfigurationWrapper configuration, IDiagnosticLogger log, ExtensibilityManager extensibilityManager, IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop, Boolean registerStandardHandlers, DebugProtocolOptions options, Action`1 syncRequestErrorHandler)
Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost.AdapterHosting.DebugAdapterHostFactory.CreateDebugAdapterHost(DebuggedProcess process, IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop)
Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost.Engine.Implementation.DebuggedProcess.StartDebugAdapter(IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop)

Failure Location: LaunchingProcess
Inner Exception: 
    InvalidOperationException: VsDbgRemoteUnixLauncher only supports remote Unix machines!

Microsoft.VisualStudio.Debugger.VsDbg.Integration.AdapterLauncher.VsDbgRemoteUnixLauncher.Microsoft.VisualStudio.Debugger.DebugAdapterHost.Interfaces.IAdapterLauncher.LaunchAdapter(IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop)
Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost.AdapterHosting.DebugAdapterProcessConnection..ctor(ConfigurationWrapper configuration, IDiagnosticLogger log, IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop, IAdapterLauncher launcher)
Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost.AdapterHosting.DebugAdapterHostFactory.CreateDebugAdapterHost(ConfigurationWrapper configuration, IDiagnosticLogger log, ExtensibilityManager extensibilityManager, IAdapterLaunchInfo launchInfo, ITargetHostInterop targetInterop, Boolean registerStandardHandlers, DebugProtocolOptions options, Action`1 syncRequestErrorHandler)

 1> ERROR: Failed to launch debug adapter.  Additional information may be available in the output window.

VsDbgRemoteUnixLauncher only supports remote Unix machines!
docker visual-studio 调试

评论

0赞 Nathan Carlson - MSFT 11/1/2023
您的基本映像是什么?在容器中运行的结果是什么?uname
0赞 Coder14 11/6/2023
基础映像已 mcr.microsoft.com/dotnet/aspnet:7.0-alpine。容器内 uname 的结果是:Linux

答:

1赞 VonC 11/9/2023 #1

假设基础映像是,容器内部的结果是 ,这意味着容器本身应该是兼容的 Unix 环境,以便使用 Visual Studio 进行远程调试mcr.microsoft.com/dotnet/aspnet:7.0-alpineunameLinux

作为解决方法,您可以尝试在 Docker 外部运行应用程序,以隔离问题是特定于 Docker 的还是与应用程序的配置相关。

我只能找到另一个案例,它指出:

  • "通过附加到进程,使用 SSH 在 Linux 上调试 .NET Core 先决条件“:确保已遵循这些先决条件
  • 一些日志:“您可以通过转到命令窗口 () 并输入 .如果切换到 ,这将删除“输出”窗格中的其他日志。View -> Other Windows -> Command WindowDebugAdapterHost.Logging /On /OutputWindowShow output from: Debug Adapter Host Log

在 Docker 和远程调试的上下文中,防火墙也可能是一个问题。即使应用程序在 Alpine Linux 基础映像上的 Docker 容器内运行,运行 Visual Studio 的 Windows 11 计算机与远程 Ubuntu 计算机上的 Docker 容器之间的网络通信也将通过主机的网络堆栈进行,该堆栈受主机防火墙设置的约束。

┌──────────────────┐     SSH (TCP/22)    ┌──────────────────┐ Docker Port Mapping  ┌──────────────────┐
│ Windows 11       │────────────────────►│ Ubuntu Machine   │◄────────────────────►│ Docker Container │
│ Machine          │                     │                  │                      │                  │
│ ┌──────────────┐ │                     │ ┌──────────────┐ │                      │ ┌──────────────┐ │
│ │ Visual       │ │                     │ │ SSH Daemon   │ │                      │ │ .NET App     │ │
│ │ Studio       │ │                     │ │ (sshd)       │ │                      │ │              │ │
│ └──────────────┘ │                     │ └──────────────┘ │                      │ └──────────────┘ │
│                  │                     │                  │                      │ │ VsDbg        │ │
│                  │                     │                  │                      │ └──────────────┘ │
└──────────────────┘                     └──────────────────┘                      └──────────────────┘

使用 Visual Studio 远程调试 .NET 应用程序时,可能会涉及多个端口,具体取决于所使用的配置和服务。确保端口 22(或您配置的 SSH 端口)已为 Ubuntu 计算机上的传入连接打开。

sudo ufw allow 22/tcp

找出 VsDbg 正在使用的端口,并确保它处于打开状态。如果它是动态的,则可能需要设置特定端口并在启动 Docker 容器时公开它。

docker run -d -p <host-port>:<container-debug-port> myapp:tag
sudo ufw allow <host-port>/tcp

确保您的 Docker run 命令公开了必要的端口,例如,将端口 80 从容器公开到主机上的端口 8080。-p 8080:80


OP 的解决方案用于记录 Visual Studio 在 Docker 主机上执行的命令。
您可以在 Chris Binnie 撰写的 2018 年文章“在 DevOps 环境中审核 Docker 容器”中看到它。
auditd

┌──────────────────┐     SSH (TCP/22)    ┌──────────────────┐  
│ Windows 11       │────────────────────►│ Ubuntu Machine   │
│ Machine          │                     │                  │                      
│ ┌──────────────┐ │                     │ ┌──────────────┐ │                      
│ │ Visual       │ │                     │ │ SSH Daemon   │ │                      
│ │ Studio       │ │                     │ │ (sshd)       │ │                      
│ └──────────────┘ │                     │ └──────────────┘ │                      
│                  │                     │                  │                      
│                  │                     │ ┌──────────────┐ │                      
└──────────────────┘                     │ │ .docker dir  │ │                      
                                         │ │ (Ownership)  │ │                      
                                         │ └──────────────┘ │                      
                                         └──────────────────┘                      
  ┌──────────────────┐      Docker Port Mapping    |                     
  │ Docker Container │◄────────────────────────────┘                                                    
  │                  │                                                  
  │ ┌──────────────┐ │                                              
  │ │ .NET App     │ │                                                  
  │ │              │ │                                                  
  │ └──────────────┘ │                                                  
  │ │ VsDbg        │ │                                                  
  │ └──────────────┘ │                                                  
  └──────────────────┘                                                  

该问题最终与文件所有权问题有关,与 Docker 或 Visual Studio 配置没有直接关系。
该问题可追溯到 SSH 用户主目录中目录的权限问题。更改目录的所有权解决了该问题。
.docker.docker

1赞 Coder14 11/13/2023 #2

我让它工作了!我通过使用 auditd 记录 Visual Studio 在 docker 主机上执行的命令来排查此问题。通过手动执行这些命令,我获得了更多关于出错的信息。

就我而言,此命令失败:

docker exec -i myapp /bin/sh -c 'echo shell-process:$$ >> /proc/[0-9]*/cmdline; for filename in /proc/[0-9]*/cmdline 2>/dev/null; do echo -e "\nfilename:$filename\n" && cat $filename; done'

它失败了,因为用于远程调试的 SSH 用户主目录中的目录 .docker 归 root 所有。将所有者更改为正确的用户解决了我的问题。

对于任何读到这篇文章的人,都有类似但不是相同的问题:[编辑:我发现了一种更简单的调试方法,跳到底部!

安装并启动 auditd,在 /etc/audit/rules.d/audit.rules 末尾添加以下规则:

-a exit,always -F arch=b32 -S execve -k auditcmd
-a exit,always -F arch=b64 -S execve -k auditcmd

然后运行以下命令:

augenrules 
service auditd stop
service auditd start

尝试在 VS 中附加,然后执行:

ausearch -ua userYouUseForSshConnection

这将显示该用户执行的所有命令。可能最后一个会指出问题。

编辑

我找到了一种更简单的方法来调试出了什么问题。只需在尝试远程调试后立即打开一个新的 ssh 会话(使用您在 VS 中使用的相同用户)到 Docker 主机。使用向上箭头查看 VS 执行的最后一个命令。

评论

0赞 VonC 11/14/2023
抓得好,干得好。我编辑了我的答案,并添加了一些额外的评论。