Skip to content

Support for cross platform .NET scenarios

Gregg Miskelly edited this page Jun 6, 2023 · 15 revisions

Scenario

In addition to supporting .NET and Native debugging in Visual Studio on Microsoft Windows, Concord also powers .NET debugging in various cross-platform scenarios:

  • Local and remote debugging in Visual Studio Code on all platforms from the C# Extension.
  • Remote Linux debugging from Visual Studio -- Docker Linux launch, WSL launch, SSH or Docker attach, etc
  • Local and remote CoreCLR (.NET Core/.NET 5+) debugging in Visual Studio for Mac

In all these cases, the way debugging works is to run on the same computer as the target process in a standalone debugger process -- either vsdbg or vsdbg-ui. This standalone process will communicate to the client IDE over the Debug Adapter Protocol, though this is largely all abstracted away from a Concord component. Unlike in Visual Studio scenarios, there is no msvsmon.exe process. Instead the vsdbg/vsdbg-ui process will always match the bitness of the target.

This page provides information on how to support these scenarios in your Concord extension.

Making an extension work for these scenarios

Here are the required steps to make a Concord extension work in these scenarios:

  1. Compile for .NET Core / Linux -- this may go without saying, but if your extension is targeting the full .NET Framework then it isn't going to run on Linux/Mac. The easiest option here is to convert your project file to a .NET Core style 'sdk' project, and target .NET Standard 2.0. This should allow your extension to run in both recent versions of Visual Studio, and in these cross-platform scenarios. Alternatively, you can compile twice to target multiple frameworks if there are .NET Core features that you want to take advantage of which are not part of .NET Standard. Note that vsdbg/vsdbg-ui has its own copy of .NET Core which excludes assemblies that we don't use (ex: ASP.NET Core). If your extension depends on one of these, please contact the debugger team about potentially adding it. If your extension is written in C++: this scenario isn't tested, but theoretically you could use clang with msvc extensions enabled along with some subset of CoreCLR PAL headers definitions to make this work.
  2. If you have a .pkgdef to register a language GUID under AD7Metrics, you need to author a .vsdbg-config.json (see more info below)
  3. Deploy your .dll+.vsdconfig+.vsdbg-config.json (if you have one) to the target system. For Visual Studio Code support, probably the best option would be to package this as part of a Visual Studio Code extension. At least currently, there is no support for automatic deployment for remote debugging from any of the IDEs. So you likely want to provide some sort of gzip along with instructions to your customers.
  4. Register your extension with vsdbg/vsdbg-ui. On startup, vsdbg/vsdbg-ui will scan for .link files under $HOME/.dotnet/vsdbg-extensions to discover installed extensions. See below for more information.
  5. VS Code only: A VS Code extension needs to be registered with VS Code to indicate breakpoints are supported in your language. Here is an example of doing so with the C# extension: breakpoint registration, language registration. As a stop gap measure, you can also configure VS Code to allow breakpoints in all files by setting the debug.allowBreakpointsEverywhere preference.
  6. Visual Studio only: Visual Studio needs a way to map from source file names to language so that the 'Language' column in the call stack window will be correct. To do this, follow the example in the Iris sample.

.vsdbg-config.json files

As stated above, .vsdbg-config.json files are a replacement for various configuration registry keys that are used in full Visual Studio. Currently they are just used to register a language. You should drop this file next to your .vsdconfig. Comments are not supported.

Note that Portable PDBs don't currently support vendor ids -- the Microsoft value of "{994b45c4-e6e9-11d2-903f-00c04fa302a1}" is always used. So you will want to register that value even if you also register your own vendor id.

Example:

{
  "$schema": "https://aka.ms/vs/vsdbg-config-schema",
  "languages": [
    {
      "languageId": "{f40a557a-5e53-4479-9b83-7a2a450c1615}",
      "vendorId": "{994b45c4-e6e9-11d2-903f-00c04fa302a1}",
      "name": "Example Language Name"
    }
  ]
}

.link files

As indicated above, vsdbg/vsdbg-ui will use .link files to find installed extensions. The way this works is that your extension's installer should write a single-line UTF-8 text file to $HOME/.dotnet/vsdbg-extensions/<Your-Company-and-Extension-Name>.link (where $HOME is replaced with %USERPROFILE% on Windows). The content of this file is the full path to the directory where your extension is installed (the directory containing your .vsdconfig file(s)). Blank lines, and lines that start with a '#' are ignored.

Example:

/home/<installing-user's-alias-here>/.vscode/extensions/<example-vscode-extension-name-here>-1.0.2/.debugger

Debugging your extension

See Iris/xplat-package/README.md for instructions.

Troubleshooting extension loading

If your extension doesn't seem to be loading, here are a few troubleshooting steps:

1: Check if vsdbg/vsdbg-ui indicates your extension is being loaded. At startup, it will print what extensions are being loaded as the first line after the vsdbg legal notice in the Debug pane of the Output Window (Visual Studio) or Debug Console (Visual Studio Code). It will also print a notice if there was a problem loading your extension (ex: the .link file is wrong). Example:

-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
Loading extensions from '/mnt/c/dd/ConcordExtensibilitySamples/Iris/xplat-package/bin/Debug/linux-x64'.
Loaded '/usr/share/dotnet/shared/Microsoft.NETCore.App/5.0.0/System.Private.CoreLib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

2: Check in the modules window to see if your extension really is loaded or not.

3: Disable Just My Code in your debugger attached to vsdbg/vsdbg-ui, and check for any exceptions.

Clone this wiki locally