在 Windows 容器(Docker 管理)中运行 Visual Studio 远程调试器

17

我尝试在 Windows Server 2016 TP4 上的 Windows Container 中运行 Visual Studio远程调试器。由于它在容器内部运行,因此没有用户界面。

我尝试通过以下方式运行远程调试器:

 .\msvsmon.exe /nostatus /silent /nosecuritywarn /nofirewallwarn /noclrwarn /port 4020

我正在以管理员用户(nt authority\system)执行上述操作。 这在主机计算机上运行良好,但在容器内部无法运行。Windows事件日志显示以下错误事件。

Msvsmon was unable to start a server named "`6D2D071453C5:4020`". 
The following error occurred: The parameter is incorrect. 

完整的事件日志:

Get-EventLog -LogName Application -EntryType Error | format-list

Index              : 1718
EntryType          : Error
InstanceId         : 3221226473
Message            : The description for Event ID '-1073740823' in Source 'Visual Studio Remote Debugger' cannot be found.  The local computer may not have the necessary registry information or message DLL
                     files to display the message, or you may not have permission to access them.  The following information is part of the event:'Msvsmon was unable to start a server named
                     '6D2D071453C5:4020'. The following error occurred: The parameter is incorrect.

                     View Msvsmon's help for more information.'
Category           : (0)
CategoryNumber     : 0
ReplacementStrings : {Msvsmon was unable to start a server named '6D2D071453C5:4020'. The following error occurred: The parameter is incorrect.

                     View Msvsmon's help for more information.}
Source             : Visual Studio Remote Debugger
TimeGenerated      : 05.04.2016 9:47:19 AM
TimeWritten        : 05.04.2016 9:47:19 AM
UserName           : NT AUTHORITY\SYSTEM

我注意到容器的主机名存在一个问题,但这可以修复:

6D2D071453C5是我的Windows容器(由docker管理)的容器ID

PS C:> docker ps -a
CONTAINER ID        IMAGE               COMMAND                   CREATED             STATUS                    PORTS               NAMES
6d2d071453c5        d9d15fbca6d7        "cmd /S /C 'C:\\myprg-"   6 days ago          Up 3 days                                     derrin

通常,在Docker中,这个容器ID也将是容器内/内部的主机名

所以,当我运行docker inspect 6d2d071453c5时,在输出中会得到以下内容:

"Config": {
    "Hostname": "6d2d071453c5",
    "Domainname": "",

但是,在容器内部,我在命令行中键入"hostname",并获得以下输出:

PS C:> hostname
test2016
这是目前仅限于Windows Server 2016 TP4 / Windows Containers的一个特定错误。 主机名不应该是test2016(容器主机名称,我的实际物理Win2016服务器的名称),而应该是容器ID(6d2d071453c5)。 至少,这将是我期望的行为,并且当我在Windows上运行需要VM的任何其他容器,例如Ubuntu容器时,情况也是如此。我刚刚重新检查了一下。

尽管如此,为了绕过此问题,我调整了主机文件,添加了:

172.16.0.2        6d2d071453c5

现在我至少可以ping通自己的主机名。

PS C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x64> ping 6D2D071453C5

Pinging 6d2d071453c5 [172.16.0.2] with 32 bytes of data:
Reply from 172.16.0.2: bytes=32 time<1ms TTL=128
Reply from 172.16.0.2: bytes=32 time<1ms TTL=128

然而,远程调试器仍未启动,并且仍然显示:

Msvsmon was unable to start a server named "`6D2D071453C5:4020`". 
The following error occurred: The parameter is incorrect.

根据附带的帮助文件列出的所有参数和选项,我看不出任何参数有什么问题。相同的命令在容器主机上可以正常工作,但在容器内部却不能。

有人成功地让远程调试器在容器内部运行吗?

======= 更新 ======

如下建议,我尝试了主机名参数。现在事件日志中不再出现任何错误,但是我也没有看到任何东西在4020端口上监听。

在 C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x64 目录下在容器内执行:

> hostname
WIN-DE6U4068NAF

> ".\msvsmon.exe /nostatus /silent /nosecuritywarn /nofirewallwarn /noclrwarn /port 4020 /hostname WIN-DE6U4068NAF"
.\msvsmon.exe /nostatus /silent /nosecuritywarn /nofirewallwarn /noclrwarn /port 4020 /hostname WIN-DE6U4068NAF

> netstat -ab | find "4020"

>

已添加有关主机名的 Docker 问题:https://github.com/docker/docker/issues/21762 - Mathias Conradt
主机名问题似乎是Server 2016 TP4中已知的Windows容器问题,请参见https://github.com/docker/docker/issues/21762#issuecomment-205904128。然而,我的原始问题仍然存在。 - Mathias Conradt
主机名问题在Server 2016 TP5中已解决,但仍无法使远程调试器正常工作。 - Mathias Conradt
我知道这是一个旧帖子,但我看到你的docker ps -a中没有端口...我认为你的调试器找不到具有端口的docker容器,因为你没有在Dockerfile中设置EXPOSE 4020。 - Gabbax0r
4个回答

2
要进行调试,您需要将远程工具安装到镜像中,像平常一样运行容器,然后使用docker exec启动远程调试器。
以下是命令行: docker exec -it <container id/name> "C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe" /nostatus /silent /noauth /anyuser /nosecuritywarn 我在博客文章中有更多细节。是的,在本地开发机上关闭身份验证确实存在一定风险(无论多小),但这至少可以让您了解如何操作。您始终可以调整命令行选项以使其按照您想要的方式工作。

2

好的,显而易见的是,从您的帖子中,命令

".\msvsmon.exe /nostatus /silent /nosecuritywarn /nofirewallwarn /noclrwarn /port 4020 /hostname WIN-DE6U4068NAF"

只会在powershell中打印相同的字符串。它并不实际启动调试器。回显输出显示了这一点。(我可能读得太多了)

因此,/nofirewallwarn 只会抑制被防火墙阻止的警告(YMMV),并不能真正通过防火墙。您是否首先使用 /prepcomputer 运行它?

您是否尝试过使用 /anyuser 来绕过身份验证并允许仅 TCP 工作?

msvsmon 是否实际绑定到正确的网络接口?有时,绑定到环回适配器意味着它只能在本地到达。当您运行 netstat 时,它是否显示在所有接口上侦听(0.0.0.0)?

你尝试过使用/service选项将其作为服务运行吗?可能还有一些需要注意的地方。在实际应用中,我通常很难让它正常工作。

谢谢你的回答。我现在没有这个环境了,所以暂时无法再测试它了。项目已经过时了。我想我也运行过没有冒号 " 的版本,但不确定,因为我在主机上运行它进行测试时就是这样运行的(请参见我的第一条命令)。你能在你的容器内部运行调试器吗?因为你提到“我通常很难让它在现场工作”。 - Mathias Conradt
我尝试在Windows Server无头模式下通过VPN(TAP)使其工作,以下是我尝试过的一些方法。 - Asti
抱歉,Mathias。我刚刚注意到原始帖子的日期。 - Asti
没问题。顺便说一下:我认为Windows容器和Windows Server headless仍然是不同的东西,有不同的问题/行为。虽然不确定。我发现并报告了几个与此帖子无关的问题,这些问题是容器特定的,而不是Windows特定的。如果我再次设置容器,我会尝试您的想法。如果开启此帖子悬赏的@Sedate Alien可以确认这是一个解决方案,请让我知道。 - Mathias Conradt
如果您和Alien先生无法使其正常工作,而且由于您具有shell访问权限,我可以建议使用cordbg吗?假设您已经准备好了符号文件,您可以(稍微有点痛苦地)设置断点并获取控制台输出。 - Asti

2
我发现这个序列可行:
PS C:\> start-service msvsmon150
PS C:\Program Files\Microsoft Visual Studio 15.0\Common7\IDE\Remote Debugger\x64> .\msvsmon  /noauth /anyuser /silent

在运行在Windows 10托管的Windows容器中,start-Service命令会出现无法启动服务的错误。然而,在输入第二个命令后,端口将显示为在netstat -ab中被阻止,并且Visual Studio 2017可以嗅探调试器单元。


1

您是否尝试使用msvsmon /hostname选项进行“硬编码”主机名?

根据msvsmon文档: "/hostname hostname_value"指示远程调试器使用指定的主机名值或IP地址值在网络上侦听。在具有多个网络卡或多个分配的DNS主机名的计算机上,可以使用此选项来限制允许远程调试的内容。例如,服务器可能具有面向互联网的地址和内部地址。通过使用“/hostname private_ip_address”,将无法通过面向互联网的地址进行远程调试。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接