Despite the increasing popularity of Wine thanks to efforts such as Valve’s Proton, the process of porting new Windows applications to Wine remains daunting for many developers. Although specific tooling is available for remotely testing applications on SteamOS devices, there is currently no generalised solution for easily testing Windows applications under Wine on a single machine. The process of manually setting up a debugging environment can be complex, and requires a familiarity with Linux that many Windows developers may not have.
To address this gap and help lower the barrier to entry for Windows developers who want to test their applications under Wine using familiar tools, we have created an open source Visual Studio extension that reduces it all to a single click. The extension uses WSL2 and Linux containers to provide a Wine environment that is automatically configured for use with the Visual Studio debugger.
Contents
- Quick Start
- First Run
- Setting Options
- How does it work?
- Getting the code
- What if something goes wrong
Quick Start
-
Install Docker Desktop and switch to Linux containers
-
Download the extension and install it by double clicking
-
Open any native or managed project in Visual Studio
-
Set some breakpoints in your application
-
Press the new
Start Wine Debugging button in the toolbar -
A terminal window will open and the container image will download
-
Your application will be installed into the container and run
-
Debugging commences!
First Run
Apart from the container image pull, the first run will copy the Wine source code out of the container, if you are debugging a native application. Take note of the temporary directory as Visual Studio will ask you to locate it when you try to step into Wine code. Subsequent runs will look a lot like this:
Setting Options
You may be wondering how to set command line arguments for your application, or other options. Go to Debug → Options and a pane will appear. Under Debugging → Wine Containers press Wine Containers and configuration dialog will appear.
| Arguments | The arguments to be passed to the application |
|---|---|
| Pull Container | Set this to false if you’ve made local changes to the container, otherwise it will be pulled (default) |
| Stop At Beginning | Set this to true if you’d like your native application to stop at the beginning of execution, otherwise execution continues to the first breakpoint (default) |
| WINEDEBUG | The environment variable to control Wine debug channels |
How does it work?
There’s a lot packed into that one action. Of course we require a container to run your application in and it needs to contain Wine. We use a custom patched version that is built from the source code in the Epic Games WineResources repository. The patches provide a number of enhancements that improve the experience of using Wine inside a container, particularly around tracking and reporting memory usage. We then index the Wine binaries and symbol files so they can be exposed via a web server to Visual Studio. The extension takes care of setting that up for you. This means you can debug your application and the parts of Wine you’re interacting with, at the same time.
When the container is run we automatically specify the environment variables and port forwarding required to run GUI applications. We copy across your application and any DLLs it requires to run. For managed applications, we also copy across the .NET runtime it requires. Finally we copy across the Remote Debugging tools from your Visual Studio installation and ensure the debugging monitor is running on a port that has been forwarded.
When you’re done debugging and your application stops running, we output the exit code and wait for a keypress before closing the terminal window.
Getting the code
The source code for the Visual Studio extension itself, all of the accompanying tooling, and the container images is available on GitHub: https://github.com/TensorWorks/WineDebugging
What if something goes wrong
When there’s a problem, most of the time you can just kill the container called “winedebug”. Otherwise, inspect the terminal window for issues if available. If not, look in the Output → Debug pane for error messages.
Although we have tested the extension with a variety of workloads, there’s always something new to learn when it comes to Wine. If you’re looking to port a particularly complex Windows workflow to Wine then we’d love to hear from you.