Wine Developer's Guide/VS Remote Debugging
Using Visual Studio Remote Debugging with Wine
Microsoft Visual Studio supports debugging an application that runs on a separate machine via network. With a few tricks this also works for applications running on Wine. This can be useful if you have the source code of an application you want to get running on Wine and are familiar with Microsoft Visual Studio.
This article assumes familiarity with Visual Studio and msvsmon. If you are unfamiliar with them the official Microsoft documentation is a good starting point: https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019
It is highly recommended to get familiar with msvsmon by using it to remote debug between two Windows machines before trying it on Wine.
At this point remote debugging has only been tested with "native" C++ applications. It may or may not work with .NET applications.
Wine Specific Issues
The following problems need manual workaround/awareness at this point:
- ) Native webservices.dll is needed
A small wine hack is needed
- ) Some msvsmon plugin DLLs don't work and have to be disabled
- ) Authentication doesn't work - run the debugger with auth disabled
Visual Studio will fail if it sees a stack trace that points into Unix code. ntdll avoids this by setting up syscall frames, but this is not in place for all mixed Unix/PE DLLs yet.
Wine Specific Setup
1) Download msvsmon from https://visualstudio.microsoft.com/downloads/#remote-tools-for-visual-studio-2019 . This link might send you to the generic Visual Studio download page if Microsoft thinks you prefer a non-english language. In this case you can find the remote tools towards the bottom of the page in the "Tools for Visual Studio" dropdown field. You can also scroll all the way to the bottom, set the page to English with a menu on the left side, and open the above link again.
2) Install the downloaded program in your Wine prefix
3) Delete or rename C:\Program Files\Common Files\Files/Microsoft Shared/VS7Debug and C:\Program Files (x86)\Common Files\Files/Microsoft Shared/VS7Debug to remove some plugins that cause failure later. (Your C:\ drive is probably in ~/.wine/drive_c/)
4) Copy C:\windows\system32\webservices.dll and C:\windows\syswow64\webservices.dll from a Windows 10 installation to the equivalent place in Wine. Depending on your Win10 version you may also need some extra api-*-*.dll files if step 6 complains about missing DLLs.
5) Go to C:\Program Files\Microsoft Visual Studio 16.0\Common7\IDE/Remote Debugger\x64
6) Run WINEDLLOVERRIDES=webservices=n wine msvsmon.exe /noclrwarn /nowowwarn /nofirewallwarn /anyuser /noauth /nosecuritywarn . The switches disable authentication and shut up some warnings. You can also disable authentication in the GUI options alternatively, but beware that the options don't stick and have to be set again every time you run msvsmon.
7) At this point you should be able to connect from Visual Studio on your Windows machine. Note that you have to select "Remote Debugger (no authentication)" as the debug target. The default remote debugger target will refuse to connect to msvsmon that is run in /noauth mode.
8) You can either try to deploy + run your Visual Studio project (follow Microsoft's instructions on how to set this up) or try to attach to a running Wine process. To attach to a process, use Debug->Attach to Process in the Visual Studio menu, select "Remote (No Authentication)" as connection type and either type in the IP address of your Wine machine or use the search button to find it.
Wine DLL debug symbols
Loading debug symbols for Wine PE DLLs and showing Wine's source code Visual Studio's debug view is possible, but the process is not very convenient yet.
mingw-clang can generate .pdb debug symbols. To do so set CROSSDEBUG=pdb CROSSCC=clang when running Wine's configure:
./configure CROSSDEBUG=pdb CROSSCC=clang <other args>
Then build Wine as usual with make. This has been tested with clang version 12.0.1, newer versions should work, older ones may or may not. Do this for both the 64 and 32 bit Wine build.
Then, make the Wine source code and build output available to your Windows machine - ideally via a network share. When inspecting a stack frame inside Wine's DLLs, Visual Studio will tell you that it cannot find the matching .pdb file. You can add the build path of the DLL to the search path and tell Visual Studio to re-search. Next it will ask you for the path to the corresponding .c file. Here (for me) it works to point to the top level Wine source directory.
Note that ntdll syscall thunks (lines with -syscall in dlls/ntdll/ntdll.spec) and assembly functions don't have corresponding entries inside the .pdb file. The best you can see here is the disassembly of the syscall thunk or assembler implementation. You will likely encounter this at the top stack frame whenever the thread is in a waiting state.
If you need to debug the Unix side of ntdll you'll probably need Unix tools (i.e., gdb, lldb). Visual Studio has support for kernel mode debugging, but the Unix side of Wine is not a Windows kernel, so it is unlikely that we can make it work.