Documentation
Topics Overview Overview Tutorial Intro Videos Agents Editor Overview Quickstart Staging & Committing Branches & Worktrees Repositories & Remotes Merge Conflicts Collaborate on GitHub Troubleshooting FAQ Get Started Terminal Basics Terminal Profiles Shell Integration Appearance Advanced Debugging Debug Configuration Tasks Testing Integrated Browser Port Forwarding Guides & Tutorials Test-Driven Development Test Web Apps with Browser Tools Overview Enterprise Policies AI Settings Extensions Telemetry Updates Overview VS Code for the Web SSH SSH Tutorial Tunnels Dev Containers WSL WSL Tutorial GitHub Codespaces VS Code Server Linux Prerequisites Tips and Tricks FAQ GitHub Copilot Setup Linux macOS Windows Raspberry Pi Network Portable Mode Additional Components Uninstall Languages & Runtimes Extension DocsOn this page there are 24 sections
Configuring C# debugging
You can configure the C# debugger in Visual Studio Code with a launch.json, launchSettings.json, or your user settings.json file.
Walkthrough: setting command-line arguments
Before we get into the details of all the possible options, let's walk through a basic scenario: setting command-line arguments to your program. These steps also work for updating other basic options like environment variables or the current working directory.
Approach 1: launchSettings.json
For C# Dev Kit, the recommended way to debug is to let C# Dev Kit automatically figure out how to debug from settings in the project file. This means that you either don't have a <workspace_root>/.vscode/launch.json file, or if you have one, you have "type": "dotnet" set for the active configuration. For command-line arguments, "figure out from the project file" means to pull the value from <Project-Directory>/Properties/launchSettings.json. The advantage of launchSettings.json is that it allows settings to be shared between Visual Studio Code, full Visual Studio, and dotnet run.
For this case, here are the steps to set the command-line arguments:
- In workspace Explorer view, navigate to the directory of the project (.csproj file) you want to launch
- If there isn't a Properties directory already, create it
- If there isn't a launchSettings.json file already, create one, you can use the below text as an example
- Change the commandLineArgs property to what you would like the command-line arguments to be
Example launchSettings.json file:
{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:59481", "sslPort": 44308 } }, "profiles": { "EnvironmentsSample": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "https://localhost:7152;http://localhost:5105", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "EnvironmentsSample-Staging": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "https://localhost:7152;http://localhost:5105", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Staging", "ASPNETCORE_DETAILEDERRORS": "1", "ASPNETCORE_SHUTDOWNTIMEOUTSECONDS": "3" } }, "EnvironmentsSample-Production": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "https://localhost:7152;http://localhost:5105", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Production" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }Profile properties
- commandLineArgs - The arguments to pass to the target being run.
- executablePath - An absolute or relative path to the executable.
- workingDirectory - Sets the working directory of the command.
- launchBrowser - Set to true if the browser should be launched.
- applicationUrl - A semi-colon delimited list of URL(s) to configure for the web server.
- sslPort - The SSL port to use for the web site.
- httpPort - The HTTP port to use for the web site.
List of configurable options
Below are common options you may want to change while debugging.
PreLaunchTask
The preLaunchTask field runs the associated taskName in tasks.json before debugging your program. You can get the default build prelaunch task by executing the command Tasks: Configure Tasks Runner from the VS Code Command Palette.
This creates a task that runs dotnet build. You can read more in the VS Code Tasks documentation.
Availability
- launch.json ✔️
- settings.json ❌
- launchSettings.json ❌
Program
The program field is set to the path of the application dll or .NET Core host executable to launch.
This property normally takes the form: "${workspaceFolder}/bin/Debug/<target-framework>/<project-name.dll>".
Example: "${workspaceFolder}/bin/Debug/netcoreapp1.1/MyProject.dll"
Where:
- <target-framework> is the framework that the debugged project is being built for. This is normally found in the project file as the 'TargetFramework' property.
- <project-name.dll> is the name of debugged project's build output dll. This is normally the same as the project file name but with a '.dll' extension.
Availability
- launch.json ✔️
- settings.json ❌
- launchSettings.json ✔️ as executablePath
Cwd
The working directory of the target process.
Availability
- launch.json ✔️
- settings.json ❌
- launchSettings.json ✔️ as workingDirectory
Args
These are the arguments that will be passed to your program.
Availability
- launch.json ✔️
- settings.json ❌
- launchSettings.json ✔️ as commandLineArgs
Stop at Entry
If you need to stop at the entry point of the target, you can optionally set stopAtEntry to be "true".
Availability
- launch.json ✔️
- settings.json ✔️ as csharp.debug.stopAtEntry
- launchSettings.json ❌
Starting a Web Browser
The default launch.json template (as of C# extension v1.20.0) for ASP.NET Core projects uses the following to configure VS Code to launch a web browser when ASP.NET starts:
"serverReadyAction": { "action": "openExternally", "pattern": "\\bNow listening on:\\s+https?://\\S", "uriFormat": "http://localhost:1234" }If you want to use the port number from the console output, but not the host name, you can also use something like this:
"serverReadyAction": { "action": "openExternally", "pattern": "\\bNow listening on:\\s+http://\\S+:([0-9]+)", "uriFormat": "http://localhost:%s/swagger/index.html" }Note You need to make sure your project has swaggerui setup to do this.
Availability
- launch.json ✔️
- settings.json ❌
- launchSettings.json ✔️ with launchBrowser and applicationUrl
Environment variables
Environment variables may be passed to your program using this schema:
"launchSettingsProfile": "ProfileNameGoesHere"Which would then, for example, use myVariableName from this example launchSettings.json file:
"launchSettingsFilePath": "${workspaceFolder}/<Relative-Path-To-Project-Directory/Properties/launchSettings.json"Restrictions:
- Only profiles with "commandName": "Project" are supported.
- Only environmentVariables, applicationUrl and commandLineArgs properties are supported
- Settings in launch.json will take precedence over settings in launchSettings.json, so for example, if args is already set to something other than an empty string/array in launch.json then the launchSettings.json content will be ignored.
Availability
- launch.json ✔️
- settings.json ❌
- launchSettings.json ❌
Source File Map
You can optionally configure how source files are opened by providing a map using this form:
"justMyCode":falseJust My Code is a set of features that makes it easier to focus on debugging your code by hiding some of the details of optimized libraries that you might be using, like the .NET Framework itself. The most important sub parts of this feature are --
- User-unhandled exceptions: automatically stop the debugger just before exceptions are about to be caught by the framework
- Just My Code stepping: when stepping, if framework code calls back to user code, automatically stop.
Availability
- launch.json ✔️
- settings.json ✔️ as csharp.debug.justMyCode
- launchSettings.json ❌
Require exact source
The debugger requires the pdb and source code to be exactly the same. To change this and disable the sources to be the same add:
"enableStepFiltering": falseAvailability
- launch.json ✔️
- settings.json ✔️ as csharp.debug.enableStepFiltering
- launchSettings.json ❌
Logging
You can optionally enable or disable messages that should be logged to the output window. The flags in the logging field are: 'exceptions', 'moduleLoad', 'programOutput', 'browserStdOut' and 'consoleUsageMessage'.
There are also advanced options under 'logging.diagnosticsLog' that are meant for diagnosing problems with the debugger.
Availability
- launch.json ✔️
- settings.json ✔️ under csharp.debug.logging
- launchSettings.json ❌
PipeTransport
If you need to have the debugger to connect to a remote computer using another executable to relay standard input and output between VS Code and the .NET Core debugger backend (vsdbg), then add the pipeTransport field following this schema:
"suppressJITOptimizations": trueHow optimizations work in .NET: If you are trying to debug code, it is easier when that code is NOT optimized. This is because when code is optimized, the compiler and runtime will make changes to the emitted CPU code so that it runs faster, but has a less direct mapping to original source code. This means that debuggers are frequently unable to tell you the value of local variables, and code stepping and breakpoints might not work as you expect.
Normally the Release build configuration creates optimized code and the Debug build configuration does not. The Optimize MSBuild property controls whether the compiler is told to optimize code.
In the .NET ecosystem, code is turned from source to CPU instructions in a two-step process: first, the C# compiler converts the text you type in to an intermediate binary form called MSIL and writes this out to .dll files. Later, the .NET Runtime converts this MSIL to CPU instructions. Both steps can optimize to some degree, but the second step performed by the .NET Runtime performs the more significant optimizations.
What does the option do: This option controls what happens when a DLL that was compiled with optimizations enabled loads inside of the target process. If this option is false (the default value), then when the .NET Runtime compiles the MSIL code into CPU code, it leaves the optimizations enabled. If the option is true, then the debugger requests that optimizations be disabled.
When should you use this option: This option should be used when you have downloaded dlls from another source, such as a nuget package, and you want to debug the code in this DLL. In order for this to work you must also find the symbol (.pdb) file for this DLL.
If you are only interested in debugging code you are building locally, it is best to leave this option false, as, in some cases, enabling this option will significantly slow down debugging. There are two reasons for this slow down --
- Optimized code runs faster. If you are turning off optimizations for lots of code the time can add up.
- If you have Just My Code enabled, the debugger will not even try and load symbols for dlls that are optimized. Finding symbols can take a long time.
Limitations of this option: There are two situations where this option will NOT work:
1: In situations where you are attaching the debugger to an already running process, this option has no effect on modules that were already loaded at the time the debugger was attached.
2: This option has no effect on dlls that have been precompiled (ngen'ed) to native code. However, you can disable usage of pre-compiled code by starting the process with the environment variable COMPlus_ReadyToRun set to 0. If you are targeting an older version of .NET Core (2.x), also set COMPlus_ZapDisable set to '1'. If you are launching under the debugger, this configuration can be set by adding this setting to launch.json:
"symbolOptions": { "searchPaths": [ "~/src/MyOtherProject/bin/debug", "https://my-companies-symbols-server" ], "searchMicrosoftSymbolServer": true, "searchNuGetOrgSymbolServer": true, "cachePath": "/symcache", "moduleFilter": { "mode": "loadAllButExcluded", "excludedModules": [ "DoNotLookForThisOne*.dll" ] } }Properties
searchPaths: Array of symbol server URLs (example: https://msdl.microsoft.com/download/symbols) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations, next to the module and the path where the .pdb was originally dropped to.
searchMicrosoftSymbolServer: If true the Microsoft Symbol server (https://msdl.microsoft.com/download/symbols) is added to the symbols search path. If unspecified, this option defaults to false.
searchNuGetOrgSymbolServer: If true the Nuget.org Symbol server (https://symbols.nuget.org/download/symbols) is added to the symbols search path. If unspecified, this option defaults to false.
cachePath": Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger defaults to %TEMP%\\SymbolCache, and on Linux and macOS the debugger defaults to ~/.dotnet/symbolcache.
moduleFilter.mode: This value is either "loadAllButExcluded" or "loadOnlyIncluded". In "loadAllButExcluded" mode, the debugger loads symbols for all modules unless the module is in the 'excludedModules' array. In "loadOnlyIncluded" mode, the debugger will not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting.
Properties for loadAllButExcluded mode
moduleFilter.excludedModules: Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported.
Properties for loadOnlyIncluded mode
moduleFilter.includedModules: Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported.
moduleFilter.includeSymbolsNextToModules: If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'.
Availability
- launch.json ✔️
- settings.json ✔️ under csharp.debug.symbolOptions
- launchSettings.json ❌
Source Link options
Source Link is a feature that makes it so that when you are debugging code that was built on another computer, such as code coming from a nuget package, the debugger can automatically bring up matching source code by downloading it from the web. To make this work, the .pdb files for the code you are debugging contains data that maps the source files in the DLL to a URL that the debugger can download from. More information about Source Link can be found at https://aka.ms/SourceLinkSpec.
The sourceLinkOptions element in launch.json allows customization of Source Link behavior by URL. It is a map from URL to Source Link options for that URL. Wildcards are supported in the URL name. Currently the only customization is if Source Link is enabled for that URL, but more options may be added in the future.
Example:
"targetArchitecture": "arm64"Availability
- launch.json ✔️
- settings.json ❌
- launchSettings.json ❌
Check for DevCert
This option controls if, on launch, the debugger should check if the computer has a self-signed HTTPS certificate used to develop web projects running on https endpoints. For this, it tries to run dotnet dev-certs https --check --trust, if no certs are found, it will prompt the user to suggest creating one. If approved by the user, the extension runs dotnet dev-certs https --trust to create a trusted self-signed certificate.
If unspecified, defaults to true when serverReadyAction is set. This option does nothing on Linux, VS Code remote, and VS Code for the Web scenarios.
You can override this behavior by setting checkForDevCert to false in your launch.json.
Example: