diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 51fc79f9d1..4c46371d50 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -187,10 +187,10 @@ Extension releases on the marketplace are done from the prerelease and release b ### Snap main -> prerelease The snap is done via the "Branch snap" github action. To run the snap from main -> prerelease, run the action via "Run workflow" and choose main as the base branch. -![branch snap action](./docs/main_snap.png) +![branch snap action](./docs/images/main_snap.png) This will generate two PRs that must be merged. One merging the main branch into prerelease, and the other bumps the version in main. -![generated prs](./docs/generated_prs.png) +![generated prs](./docs/images/generated_prs.png) ### Snap prerelease -> release To snap from prerelease to release, run the same action but use **prerelease** as the workflow branch. This will generate a single PR merging from prerelease to release. @@ -199,6 +199,6 @@ To snap from prerelease to release, run the same action but use **prerelease** a The marketplace release is managed by an internal AzDo pipeline. On the pipeline page, hit run pipeline. This will bring up the pipeline parameters to fill out: 1. The branch will **always** be main, no matter if release a build from prerelease or release. 2. Uncheck the "test" option. -3. In "Resources", choose "dotnet-vscode-csharp [officialBuildCI]", then check only the build that should be released, and then confirm with "Use selected run". Based on the selected build, it will automatically determine if it is prerelease or release. ![release pipeline image](./docs/release_pipeline.png) -4. The pipeline parameters should then look something like the following image. Hit "Run". ![release pipeline parameters image](./docs/release_pipeline_params.png) +3. In "Resources", choose "dotnet-vscode-csharp [officialBuildCI]", then check only the build that should be released, and then confirm with "Use selected run". Based on the selected build, it will automatically determine if it is prerelease or release. ![release pipeline image](./docs/images/release_pipeline.png) +4. The pipeline parameters should then look something like the following image. Hit "Run". ![release pipeline parameters image](./docs/images/release_pipeline_params.png) 5. After a bit, the pipeline will request approval from an authorized approver before it actually uploads to the marketplace. Hit approve and it will continue. diff --git a/SUPPORT.md b/SUPPORT.md index 43fd31a6d9..13dac4a04e 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -13,7 +13,7 @@ For help and questions about using this project, please see the [README](https:/ ### How to file an issue We highly recommend using the C# extension's built-in command, `CSharp: Report an issue` (`csharp.reportIssue`) to create a pre-filled issue template. This will include helpful details such as local dotnet installations, installed extensions, and other information. -![csharp.reportIssue command](./docs/report_issue.png) +![csharp.reportIssue command](./docs/images/report_issue.png) #### Collecting General Logs @@ -22,8 +22,8 @@ The template has a section to include the `C#` output window logs. These logs ar 1. **Set the Log Level to Trace**: - Open the `C#` output window (`View` -> `Output`). - Set the log level to `Trace`. - - ![c# output window showing trace option](./docs/csharp_trace.png) + + ![c# output window showing trace option](./docs/images/csharp_trace.png) 2. **Reproduce the Issue**: - Perform the actions that reproduce the issue. @@ -57,8 +57,8 @@ For issues with Razor, the Razor Log output window can contain useful informatio 1. **Set the Log Level to Trace**: - Open the `Razor Logs` output window (`View` -> `Output`). - Set the log level to `Trace`. - - ![razor log output window showing trace option](./docs/razor_logs.png) + + ![razor log output window showing trace option](./docs/images/razor_logs.png) 2. **Reproduce the Issue**: - Perform the actions that reproduce the issue. @@ -81,7 +81,7 @@ Missing language features are often caused by a failure to load the project(s) o - This information is displayed in the bottom-right corner of the VSCode window in the language status section. - You can pin this item using the pin icon to keep it visible at all times. - ![language status bar showing file active project context](./docs/language_status.png) + ![language status bar showing file active project context](./docs/images/language_status.png) 3. **Verify the Solution Explorer (C# Dev Kit)**: - If you are using C# Dev Kit, check the Solution Explorer to ensure the project is displayed with the expected references. @@ -100,12 +100,12 @@ If you encounter issues with document classification (e.g., incorrect syntax hig 3. Click on the word or section with incorrect colorization to display the token and scope information. - Take a screenshot of the output and include it in your issue report. - ![Inspect Tokens and Scopes Output](./docs/inspect_tokens.png) + ![Inspect Tokens and Scopes Output](./docs/images/inspect_tokens.png) ### Diagnostics problems For issues with diagnostics, please provide values of the background analysis scope options, `dotnet.backgroundAnalysis.analyzerDiagnosticsScope` and `dotnet.backgroundAnalysis.compilerDiagnosticsScope` -![background analysis settings](./docs/background_analysis.png) +![background analysis settings](./docs/images/background_analysis.png) #### Language server crashing @@ -124,12 +124,12 @@ When investigating performance issues, we may request a performance trace of the The C# extension has a built in command, `csharp.recordLanguageServerTrace` to help with trace collection. This command will install `dotnet-trace` as a global tool and invoke it against the language server. 1. Invoke the record language server trace command -![alt text](docs/recordTraceCommand.png) +![alt text](docs/images/recordTraceCommand.png) 2. Select the folder to save the trace. 3. Accept the default trace arguments, or change them if requested -![alt text](docs/recordTraceArgs.png) +![alt text](docs/images/recordTraceArgs.png) 4. A new terminal window will open to run the trace collection. While the trace is running, reproduce the peformance issue. When done, hit or in the trace window to stop the trace -![alt text](docs/recordTraceTerminal.png) +![alt text](docs/images/recordTraceTerminal.png) 5. Share the trace. Note that the trace may contain PII, so generally we will provide an email or other confidential way to share the trace with us. ## Microsoft Support Policy diff --git a/debugger.md b/debugger.md index 37016974a7..04f7f982f5 100644 --- a/debugger.md +++ b/debugger.md @@ -65,7 +65,7 @@ Your project is now all set. Set a breakpoint or two where you want to stop, cli If your code was built on a different computer from where you would like to run in there are a few things to keep in mind -- * **Source Maps**: Unless your local source code is at exactly the same path as where the code was originally built you will need to add a [sourceFileMap](https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md#source-file-map) to launch.json. -* **Portable PDBs**: If the code was built on Windows, it might have been built using Windows PDBs instead of portable PDBs, but the C# extension only supports portable PDBs. See the [portable PDB documentation](https://github.com/dotnet/vscode-csharp/wiki/Portable-PDBs#how-to-generate-portable-pdbs) for more information. +* **Portable PDBs**: If the code was built on Windows, it might have been built using Windows PDBs instead of portable PDBs, but the C# extension only supports portable PDBs. See the [portable PDB documentation](./docs/debugger/Portable-PDBs.md#how-to-generate-portable-pdbs) for more information. * **Debug vs. Release**: It is much easier to debug code which has been compiled in the `Debug` configuration. So unless the issue you are looking at only reproduces with optimizations, it is much better to use Debug bits. If you do need to debug optimized code, you will need to disable [justMyCode](https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md#just-my-code) in launch.json. #### [Configurating launch.json for C# Debugging](debugger-launchjson.md) @@ -76,7 +76,7 @@ See the [official documentation](https://code.visualstudio.com/docs/csharp/debug #### Remote Debugging -The debugger supports remotely launching or attaching to processes. See [Attaching to remote processes](https://github.com/dotnet/vscode-csharp/wiki/Attaching-to-remote-processes) in the wiki for more information. +The debugger supports remotely launching or attaching to processes. See [Attaching to remote processes](./docs/debugger/Attaching-to-remote-processes.md) in the wiki for more information. #### Exception Settings diff --git a/docs/How-to-run-and-debug-unit-tests.md b/docs/How-to-run-and-debug-unit-tests.md new file mode 100644 index 0000000000..d944db52f0 --- /dev/null +++ b/docs/How-to-run-and-debug-unit-tests.md @@ -0,0 +1,23 @@ +The C# extension currently supports running and debugging a unit test via CodeLens annotations on test methods. Just click the 'run test' or 'debug test' links: + +![CodeLens](./images/unit-test-codelens.png) + +### Notes + +* Because `dotnet test` will run the test code in a child process, it isn't possible to configure a "unit test debugging" configuration in launch.json +* There currently isn't a VS Code command to run the current test, though there is an [issue for this in the backlog](https://github.com/dotnet/vscode-csharp/issues/421). +* You can tweak [debugging options](../debugger-launchjson.md) for unit tests by opening your VS Code settings file (ex: File->Preferences->Settings on Windows), and configuring the `"csharp.unitTestDebuggingOptions"` setting. See example below. +* If your unit tests are targeting .NET Framework instead of .NET Core, see [Desktop .NET Framework](./debugger/Desktop-.NET-Framework.md) for more information. + +Example User Settings file with unit test debugging options: + +```json +{ + "window.zoomLevel": 0, + "csharp.unitTestDebuggingOptions": { + "sourceFileMap": { + "c:\\example\\folder\\where\\library\\was\\built": "/folder/where/my/library/is/now" + } + } +} +``` diff --git a/docs/Installing-without-Internet-connectivity.md b/docs/Installing-without-Internet-connectivity.md new file mode 100644 index 0000000000..fea4e30040 --- /dev/null +++ b/docs/Installing-without-Internet-connectivity.md @@ -0,0 +1,10 @@ +Some environments may not have access to the Internet and thus the marketplace to download extensions or dependencies dynamically. To install the C# language extension and dependencies without Internet access, the following is required: + +> NOTE: It is important that if extensions offer platform-specific versions, that you ensure you are downloading/installing the matching platform pieces. Failure to do so could put your VS Code environment in a non-functional state. + +* Download and install the required ASP.NET Core 9.0.8 runtime from https://dot.net/downloads +* Download the following VS Code extensions **for your specific platform**: + * [.NET Install Tool](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.vscode-dotnet-runtime) + * [C# language extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) + * Optional extensions such as the [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit), [MAUI](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-maui), or [IntelliCode for C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.vscodeintellicode-csharp) +* Follow the documentation to [**Install from VSIX**](https://code.visualstudio.com/docs/editor/extension-marketplace#_install-from-a-vsix) in VS Code with the downloaded extension files diff --git a/docs/Reporting-Issues.md b/docs/Reporting-Issues.md new file mode 100644 index 0000000000..770b0759c2 --- /dev/null +++ b/docs/Reporting-Issues.md @@ -0,0 +1,15 @@ +The extension supports the command that populates the necessary information from the user's system into a new github issue and opens the preview in the user's default browser to preview and submit. + +#### Report issue on GitHub +* In VSCode, navigate to the View --> Command Palette menu or press Ctrl+Shift+P. +* Select the option : `CSharp: Report an issue`. This will open the github repository issues page with a new issue with all the necessary system information. +* Fill in all the fields like "Expected Behavior", "Actual Behavior", "Steps to Reproduce". +* Paste the "C#" log (if any) and hit "Submit" + + ##### OmniSharp and C# log + * In VSCode, navigate to View-->Output or press Ctrl+Shift+U + * In the output pane on the right, you should see an "OmniSharp log" in the drop-down + * Paste the output from here to the "OmniSharp log" section + + ![OmniSharp log](./images/omnisharp_log.png) + * The C# log can also be found in the same window. diff --git a/docs/Troubleshooting-'The-.NET-Core-SDK-cannot-be-located.'-errors.md b/docs/Troubleshooting-'The-.NET-Core-SDK-cannot-be-located.'-errors.md new file mode 100644 index 0000000000..481e1ae35a --- /dev/null +++ b/docs/Troubleshooting-'The-.NET-Core-SDK-cannot-be-located.'-errors.md @@ -0,0 +1,85 @@ +## Introduction + +This page contains more information about the error: + +> The .NET Core SDK cannot be located. .NET Core debugging will not be enabled. Make sure the .NET Core SDK is installed and is on the path. + +What this error means is that this extension ran the command `dotnet` and `dotnet` was **NOT** found on the `PATH` within the extension's process. + +If you don't have the .NET Core SDK installed, fixing this error is usually simple enough: visit https://dot.net/core-sdk-vscode to download and install the .NET Core SDK. + +If you do have the .NET Core SDK installed, then this means that the directory containing `dotnet` (Linux and macOS) or `dotnet.exe` (Windows) is not on your `PATH`, at least in this extension's process. The rest of this page will provide advice on understanding why. + +## Known issues + +Before we get to a list of troubleshooting steps, lets first enumerate a few known reasons why this error happens: + +1. If you very recently installed the .NET SDK -- + * If you had Visual Studio Code open at the time you installed the .NET SDK, and you haven't restarted it, you should do so. + * On Windows, on some machines, environment variable changes don't immediately take effect. Restart your computer to see if that resolves this problem. +2. If the .NET SDK was installed through Linux Snap - see [Linux Snap instructions](#linux-snap-instructions) + +## General troubleshooting steps on Linux/Mac + +The first step in troubleshooting this problem is to see if this problem also happens is a terminal/shell. After you have launched a terminal or shell, type in `which dotnet`. + +If `which dotnet` produces a PATH, then the .NET SDK was able to successfully modify the PATH, but VS Code isn't picking it up. VS Code attempts to scrape the environment by launching the default shell under the covers. But this process can be fragile. You can attempt to work around this by starting VS Code from your Terminal. Alternatively, you can attempt to debug VS Code to understand what is going wrong -- at this time at least, the function to debug is [`getUnixShellEnvironment`](https://github.com/microsoft/vscode/blob/ab10e26096a5494b68bc709a405a0dddeb227e0b/src/vs/code/node/shellEnv.ts#L13). Lastly, you could manually add a symbolic link from within a directory which is on the PATH in all processes to wherever `dotnet` is installed (see below for instructions). + +If `which dotnet` produces no output, then this means the .NET SDK wasn't able to modify the `PATH` or add a symbolic link, or the .NET SDK for your platform doesn't do so. You can fix this by either adding a symbolic link yourself (example: `sudo ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet` where `/usr/share/dotnet/dotnet` should be replaced with wherever the .NET SDK installer for your platform was installed to), or by modifying your `PATH` manually (example: modify ~/.bashrc add add something like `export PATH=$PATH:/new/directory/here`). + +## General troubleshooting steps on Windows + +First, as mentioned above, if you installed the .NET SDK since you last rebooted Windows, you might start by just rebooting to see if that fixes things. + +Otherwise, you can start troubleshooting this problem is to see if this problem also happens is a command prompt: + +* Start a command prompt: + * Hit `WinKey+R` to bring up the Windows run dialog + * Type in `cmd.exe` +* When the command prompt starts, type in `where.exe dotnet`. + +If the result of running `where.exe` is that a path to dotnet.exe is printed (example: `C:\Program Files\dotnet\dotnet.exe`) then the .NET SDK has successfully added itself to the Windows Path. There are no known reasons why PATH wouldn't be propagated to the VS Code process. You could try starting VS Code from the command prompt to see if that helps. + +If the result of running `where.exe` is a message like `INFO: Could not find files for the given pattern(s).` then the .NET SDK wasn't able to add itself to the PATH. You could try uninstalling and reinstalling the .NET SDK. You could also try examining the default path with the following steps: + +* Bring up System Properties: + * Windows 10 - On the Start Menu, search for 'This PC' and bring up properties + * Before - On the Start Menu, search for 'My Computer' and bring up properties +* Go to the Advanced settings +* Click the button for 'Environment Variables' +* Find 'Path' in either the user or system list +* See if the dotnet.exe directory (example: `C:\Program Files\dotnet`) is in the list. If not you could add it. +* If it is in the list, you could see if maybe another directory has added it self incorrectly (example: added an opening quote without a trailing quote), or if the set of environment variables has grown very large -- there is a limit of 32,767 total characters. + +### Note about 64-bit installs of the .NET SDK + +In 64-bit environments the .NET SDK will fail to be discovered if the 32-bit dotnet path comes before the 64-bit dotnet path in the Environment PATH variable. Try removing the 32-bit path entirely from your PATH variable and relaunch VS Code to see if your issue is resolved. + +## Special instructions + +#### Linux Snap instructions + +The Linux Snap packages for the .NET Core SDK, by default, will not create the `dotnet` link. To do so, run `sudo snap alias dotnet-sdk.dotnet dotnet`. More information about this can be found in [the .NET Core SDK release notes](https://github.com/dotnet/core/blob/master/release-notes/3.1/3.1.0/3.1.0-install-instructions.md#install-using-snap). + +Note that, as of the time of this writing, there are also other incompatibilities between this extension and the .NET Core SDK Snap package beyond the `dotnet` PATH issue. This incompatibility may result in: + +> Some projects have trouble loading. Please review the output for more details. +> It was not possible to find any installed .NET Core SDKs +> Did you mean to run .NET Core SDK commands? Install a .NET Core SDK from: +> https://aka.ms/dotnet-download + +More information about this problem can be found in [dotnet/cli#12110](https://github.com/dotnet/cli/issues/12110). + +Another possible workaround is to add the following to `~/.omnisharp/omnisharp.json`. + +```json +{ + "MSBuild": { + "UseLegacySdkResolver": true + } +} +``` + +Instead, you also may create a symbolic link to your dotnet install like so: + +`ln -s /snap/dotnet-sdk/current/dotnet /usr/local/bin/dotnet` diff --git a/docs/debugger/.NET-Core-debugging-feature-list.md b/docs/debugger/.NET-Core-debugging-feature-list.md new file mode 100644 index 0000000000..3e8495d616 --- /dev/null +++ b/docs/debugger/.NET-Core-debugging-feature-list.md @@ -0,0 +1,25 @@ +The following table describes the feature list for .NET Core debugging using VS Code C# extension / VS For Mac / [Visual Studio](https://github.com/microsoft/MIEngine/wiki/Offroad-Debugging-of-.NET-Core-on-Linux---OSX-from-Visual-Studio) on non-Windows platforms with availability information: + +| Feature | Description | Visual Studio Code | Visual Studio For Mac | Visual Studio | Availability | +| --------- | ----------- | :----------------: | :-------------------: | :-----------: | ------------- | +| Breakpoints | Adding / removing breakpoints | :white_check_mark: | :white_check_mark: | :white_check_mark: | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.2.2 / VS For Mac Preview | +| Execution control | Step through code (including async stepping), pause, continue | :white_check_mark: | :white_check_mark: | :white_check_mark: | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.2.2 / VS For Mac Preview| +| Launch / Attach | Includes launching, attaching to, detaching from and terminating the target app | :white_check_mark: | :white_check_mark: | :white_check_mark: | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.2.2 / VS For Mac Preview| +| EE | This is the ability to view variables, custom expressions in locals / watch windows | :white_check_mark: | :white_check_mark: | :white_check_mark: | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.2.2 / VS For Mac Preview| +| Just my code | This is the ability to hide external code during debugging | :white_check_mark: | :white_check_mark: | :white_check_mark: | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.2.2 / VS For Mac Preview| +| Conditional breakpoints | This is the ability to stop on a breakpoint when the given condition is satisfied | :white_check_mark: | :white_check_mark: | :white_check_mark: | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.3.0 / VS For Mac Preview| +| Debugging Razor views | This is the ability to debug embedded code in cshtml files | :white_check_mark: | :white_check_mark: | N/A | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.3.0 | +| Edit variable values | This is the ability to update the value of a variable inside locals / watch windows | :white_check_mark: | :white_check_mark: | :white_check_mark: | VS2015.3 + [MIEngine](https://github.com/Microsoft/MIEngine/wiki/Building-the-MIEngine) / C# ext 1.3.0 / VS For Mac Preview| +| Set Next Statement | This is the ability to change the current instruction pointer to another line during debugging | [Work Item](https://github.com/Microsoft/vscode-debugadapter-node/issues/28) | [Work Item](https://github.com/Microsoft/vscode-debugadapter-node/issues/28) | [Work Item](https://github.com/Microsoft/vscode-debugadapter-node/issues/28) | | +| Tracepoints | This is the ability to print custom expressions when a breakpoint is hit | N/A | | | | +| Symbol search information | Showing the path to the pdb being loaded for a particular module | | | | | +| Symbol Server | This is the ability to specify a remote server to pull down pdbs for code being debugged | [Work Item](https://github.com/dotnet/roslyn/issues/6881) | [Work Item](https://github.com/dotnet/roslyn/issues/6881) | [Work Item](https://github.com/dotnet/roslyn/issues/6881) | +| Source Server | This is the ability to pull down sources from a remote server for code being debugged | [Work Item](https://github.com/dotnet/roslyn/issues/5397) [Work Item](https://github.com/dotnet/roslyn/issues/4119)| [Work Item](https://github.com/dotnet/roslyn/issues/5397) [Work Item](https://github.com/dotnet/roslyn/issues/4119) | [Work Item](https://github.com/dotnet/roslyn/issues/5397) [Work Item](https://github.com/dotnet/roslyn/issues/4119) | | +| Manual symbol loading | This is the ability to locate and load symbols for a module anytime during a debug session | | | | | +| Function bps | This is the ability to stop the debugger at the start of a given function | [Work Item](https://github.com/dotnet/vscode-csharp/issues/295)| [Work Item](https://github.com/dotnet/vscode-csharp/issues/295) | [Work Item](https://github.com/dotnet/vscode-csharp/issues/295) | +| Hit count bps | This is the ability to stop the debugger after a breakpoint is hit given number of times | [Work Item](https://github.com/dotnet/vscode-csharp/issues/895)| [Work Item](https://github.com/dotnet/vscode-csharp/issues/895) | [Work Item](https://github.com/dotnet/vscode-csharp/issues/895) | +| Edit and Continue | This is the ability to make code changes during a debugging session without having to restart a new session | [Work Item](https://github.com/dotnet/roslyn/issues/1952) | [Work Item](https://github.com/dotnet/roslyn/issues/1952) | [Work Item](https://github.com/dotnet/roslyn/issues/1952) | +| Dump debugging | This is the ability to debug crash dumps | | | | | +| Return values | This is the ability to see the values a function returns as the user is stepping through the code | | | | | +| Visualizers | This is the ability to invoke a custom UI for visualizing a value in the locals / watch windows | | | | | +| Step Into Specific | This is the ability to select a particular function to step into when the current instruction pointer is on a line that contains multiple functions to be called | | | | diff --git a/docs/debugger/Attaching-to-remote-processes.md b/docs/debugger/Attaching-to-remote-processes.md new file mode 100644 index 0000000000..301eb54a7f --- /dev/null +++ b/docs/debugger/Attaching-to-remote-processes.md @@ -0,0 +1,201 @@ +The C# extension supports attaching to processes running on remote machines/containers. It does so in a flexible way that only requires a transport program (example: `ssh`, `docker exec`, `kubectl exec`, etc) which can prove a remote unix-like shell to the target system. + +Note that while this page gives instructions for attach, it is also to launch a remote process. See the [[Remote Debugging On Linux-Arm]] page for examples. + +### Setting up SSH + +In this section, we will walk through the steps for configuring SSH. If you are using Docker or some other transport, you can skip this. + +#### Visual Studio Code (client) machine setup + +There is no way to pop up credential UI with VS Code, so we need a scriptable way to authenticate. One option is to provide the password on the command line, but obviously there are some security concerns with passing an unencrypted password around so much. A more secure option is to use SSH keys. To do this, open a bash prompt and run the following commands (note: if you are on Windows you can find better instructions [here](https://github.com/Microsoft/MIEngine/wiki/Offroad-Debugging-of-.NET-Core-on-Linux---OSX-from-Visual-Studio#ssh)). Since you want to store your key file without a password, make sure to keep it in a secure location. + +``` +mkdir ~/.ssh +chmod 700 ~/.ssh +ssh-keygen -t rsa +``` + +#### Target machine (server) setup + +If you don't already have SSH installed on your server. The first step is obviously to install it. For example, on Ubuntu you can do that by running: `sudo apt-get install openssh-server`. + +After SSH is installed, you want to add the public key generated in the last step (id_rsa.pub) to the list of keys in ~/.ssh/authorized_keys file on your server. If your computer has the ssh-copy-id command, the easy way is to run `ssh-copy-id ExampleAccount@ExampleTargetComputer`. Alternatively, you can copy the id_rsa.pub file to the server and then run `cat id_rsa.pub >> ~/.ssh/authorized_keys`. + +#### Test your connection + +Now that your client and server are configured, it is time to verify your connection works. To do this, open a terminal and type something like: + +``` +ssh ExampleAccount@ExampleTargetComputer echo "Hello World" +``` + +(Where ExampleAccount and ExampleTargetComputer should be replaced with appropriate values) + +### Installing VSDBG on the server + +As the last server setup step, we need to download VSDBG (the .NET Core command line debugger) onto the server. The easiest way to do this is by running the following command. Replace '~/vsdbg' with wherever you want VSDBG installed to. + +`curl -sSL https://aka.ms/getvsdbgsh | /bin/sh /dev/stdin -v latest -l ~/vsdbg` + +##### Using wget +If you are on a system that uses wget instead of curl, here is the wget equivalent: + +`wget https://aka.ms/getvsdbgsh -O - 2>/dev/null | /bin/sh /dev/stdin -v latest -l ~/vsdbg` + +##### Using PowerShell +If you want to download vsdbg on Windows and then copy it to your Linux/Mac computer/container, you can use the .ps1 script with this one-liner. Other supported `RuntimeID` values are `linux-musl-x64`, `linux-arm` and `osx`. + +`powershell -NoProfile -ExecutionPolicy RemoteSigned -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -useb 'https://aka.ms/getvsdbgps1'))) -Version latest -RuntimeID linux-x64 -InstallPath c:\vsdbg\linux-x64"` + +### Configuring SSH attach with launch.json + +Now that we have our target machine ready to go, its time to configure your project. Open up .vscode/launch.json in VS Code, and add a new configuration to the end similar to the following: + +```json + { + "name": ".NET Core SSH Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickRemoteProcess}", + "pipeTransport": { + "pipeProgram": "ssh", + "pipeArgs": [ "-T", "ExampleAccount@ExampleTargetComputer" ], + "debuggerPath": "~/vsdbg/vsdbg", + "pipeCwd": "${workspaceRoot}", + "quoteArgs": true + }, + "sourceFileMap": { + "/home/ExampleAccount/ExampleProject": "${workspaceRoot}" + } + } +``` + +Here is what these options do: +* `processId`: 'command:pickRemoteProcess' instructs Visual Studio code to bring up UI to select the process to attach to. You can also replace this with the process id of the process you would like to debug if for some reason you don't like the selection UI. +* `pipeTransport.pipeProgram`: This an the executable which should be launched to provide a connection to the target computer. In this example we are using SSH, so this is the path to ssh client command. +* `pipeTransport.pipeArgs`: This is any arguments to pass to the pipe program. For the SSH client library we need to provide the computer to connect to. To use SSH, replace ExampleAccount/ExampleTargetComputer with appropriate values. Note that you can use the value `${debuggerCommand}` if you need to place the command line of the debugger program someplace other than the end of this command line. +* `pipeTransport.debuggerPath`: This is the path to where VSDBG is running on the target computer. +* `sourceFileMap`: To debug programs built on computers other than the Visual Studio code computer, Visual Studio code needs to be hold how to map file paths. So, for example, if you are debugging 'ExampleProject' which was built in your home directory on the Linux server, and now you have the same code open in Visual Studio code, this rule tells the debugger to change any file paths that it sees in '/home/ExampleAccount/ExampleProject' and replace it with the open directory. +* `quoteArgs`: Should arguments that contain characters that need to be quoted (example: spaces) be quoted? Defaults to 'true'. If set to false, the debugger command will no longer be automatically quoted. + +Once this is all setup, then switch to the debug tab in VS Code, open the configuration drop down and select your new configuration ('.NET Core Remote Attach'). You may need to restart VS Code to have your new configuration show up in the list. + +![Debug launch configuration](../images/debug-launch-configurations-remote-attach.png) + +Once the configuration is selected. Press the play button (F5) to bring up the process selection UI and start debugging. + +### Building and deploying the application and PDBs + +Last, to be able to debug obviously the application must somehow be runnable on the target box. For this you can either build the application on the target server, or build the application somewhere else and then deploy it (see [.NET Core documentation](https://docs.microsoft.com/en-us/dotnet/articles/core/deploying/index) for more information). + +There are two special concerns in this area when it comes to debugging: + +1. Debug vs. Release Configuration: If you are going to be debugging, the experience is going to be much better if the debug configuration of your application is running instead of the release configuration. If this isn't possible, one can debug release code. To do this, disable [justMyCode](../../debugger.md#just-my-code) in launch.json. +2. PDB files: In order for VSDBG to be able to be able to map executable code back to its source code (or vice versa) VSDBG needs to have PDB files. If you are already building your application on the target server, this is taken care of for you. If you are building it somewhere else, you need to make sure to copy the PDB files next to their associated dll or set the DebugType to 'embedded' so that the PDB data is kept inside of the compiled dll. + +### Configuring Docker attach with launch.json + +If you are using Docker instead of SSH, here is what your launch.json might look like: + +```json + { + "name": ".NET Core Docker Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickRemoteProcess}", + "pipeTransport": { + "pipeProgram": "docker", + "pipeArgs": [ "exec", "-i", "my_container_name" ], + "debuggerPath": "/root/vsdbg/vsdbg", + "pipeCwd": "${workspaceRoot}", + "quoteArgs": false + }, + "sourceFileMap": { + "/home/ExampleAccount/ExampleProject": "${workspaceRoot}" + } + } +``` + +Here are additional notes about what these options are doing (see the SSH instructions for more information): +* `processId`: Just like for SSH, 'command:pickRemoteProcess' instructs Visual Studio code to bring up UI to select the process to attach to. This requires your container to have `ps`. If it doesn't, you can install it (on most distros using the 'procps' package), or you change this to a process id if you know what you want to debug. Alpine based containers do have ps, but the default version doesn't handle the required arguments, so you will need to install procps, with something like: RUN apk --no-cache add procps. +* `pipeTransport.pipeArgs`: Docker requires the name of the container to execute in, so make sure to replace `my_container_name` what what you really want. +* `pipeTransport.debuggerPath`: This is the path to where VSDBG is running on the target container. You can either change your container's build instructions to always include a version of vsdbg, or you can shell into the container before you start debugging to download it (example: `docker exec -it my_container_name /bin/sh`). See [Installing VSDBG on the server](#installing-vsdbg-on-the-server) for more information. +* `sourceFileMap`: To debug programs built on computers other than the Visual Studio code computer, Visual Studio code needs to be hold how to map file paths. So, for example, if you are debugging 'ExampleProject' which was built in your home directory on the Linux server, and now you have the same code open in Visual Studio code, this rule tells the debugger to change any file paths that it sees in '/home/ExampleAccount/ExampleProject' and replace it with the open directory. +* `quoteArgs`: The Docker CLI does NOT expect the command line for vsdbg to be quoted, so set this to `false`. + +## Troubleshooting + +### Enable Logging + +#### Visual Studio +From View -> Other Windows -> Command Window, type ```DebugAdapterHost.Logging /On /OutputWindow to have logs appear in the Output Window. + +#### VsCode +Logging can be enabled by adding the following to your launch.json configuration: +```javascript +"logging": { + "engineLogging": true +} +``` + +### Known Errors + +### Pipe program exited unexpectedly + +If remote debugging is failing with an error message such as: + + "The pipe program '' exited unexpectedly with code 1." + +Then there are a few possibilities as to what is going on: +* Something may be incorrectly configured with the transport. Read more of the log to try and understand what this could be. Also try re-running your transport command to test your connection -- copy your pipeProgram/args to a terminal and have your pipe program execute something like `echo Hello World` to see if it working. +* If the target process is running in a Docker container, this could indicate that the container shutdown. For example because the additional memory used by the debugger caused the container to hit its memory limit. +* This could also indicate that vsdbg running in the container is crashing or being aborted. You can confirm or deny this by modifying the transport command line to run a script that would run vsdbg and then output vsdbg's exit code. For some transports, you may also be able to do this by just modifying `pipeArgs`, for example, add an arg of: `"${debuggerCommand}; echo \"vsdbg exited with code: $?\""` + +If vsdbg is crashing or being aborted a few additional troubleshooting steps: + +#### 1: Check for libicu compatibility + +See the [Testing libicu compatibility on Linux](./Testing-libicu-compatibility-on-Linux.md) page for more information. + +#### 2: Save a coredump of a possible vsdbg crash + +Another possible reason for the transport aborting is that vsdbg is crashing. To see if this is the problem and investigate why if it is, you can follow these steps. + +First, on the target computer, set /proc/sys/kernel/core_pattern is set to something valid. For example: + +``` +mkdir ~/crash_reports +cd ~/crash_reports +cp /proc/sys/kernel/core_pattern core_pattern.bak +sudo sh -c 'echo "$(pwd)/%e-%p.cor" > /proc/sys/kernel/core_pattern' +``` +More information on core_pattern can be found on [kernel.org](http://www.kernel.org/doc/Documentation/sysctl/kernel.txt). + +After core_pattern is configured, you then want to change your launch.json configuration to set `ulimit -c unlimited` before starting vsdbg. This can be done by adding `"ulimit -c unlimited && ${debuggerCommand}"` as another argument in `pipeArgs` in your launch.json file. + +Example: +``` + "pipeArgs": [ "-T", "ExampleAccount@ExampleTargetComputer", "ulimit -c unlimited && ${debuggerCommand}" ], +``` + +If all goes well this should result in a coredump being written to ~/crash_reports. You can then take a look at the coredump yourself using gdb, or share it with the debugger team. + +#### Developer Mode not Enabled on macOS +If the process failed to attach and there is a similar event to the following: +```javascript +{ + "event":"output", + "body": { + "category":"telemetry", + "output":"VS/Diagnostics/Debugger/vsdbg/AttachFailed", + "data":{ + "VS.Diagnostics.Debugger.vsdbg.OSFamily":"Darwin", + "VS.Diagnostics.Debugger.vsdbg.ErrorCode":-2147024809 +} +``` + +and if you are on VsCode, you should see the stderr message: +``` vmmap[6174]: [fatal] unable to ask for permission to examine process; run tool using sudo, or without redirecting stdin and stderr. ``` + +Most likely that Developer Mode is not enabled on your mac machine. You can enable it by typing ```sudo DevToolsSecurity --enable``` diff --git a/docs/debugger/Debugging-Sandboxed-Processes-on-OSX.md b/docs/debugger/Debugging-Sandboxed-Processes-on-OSX.md new file mode 100644 index 0000000000..b772707d63 --- /dev/null +++ b/docs/debugger/Debugging-Sandboxed-Processes-on-OSX.md @@ -0,0 +1,14 @@ +The debugger has basic support for attaching to processes that load CoreCLR in a sandbox. Note that this workflow is subject to change in the future. + +To tell the debugger that your application is loaded in a sandbox, you need to drop a .json file next to your application's executable. It should have the same name as your application with an added `.coreclr-debug-config.json`. The content of this file is as follows: + +```json +{ + "applicationGroupId" : "" +} +``` + +Notes: +1. This will work in both Visual Studio and VS Code +2. Comments are NOT supported +3. The file must be UTF-8 encoded. A BOM is allowed but not required. \ No newline at end of file diff --git a/docs/debugger/Debugging-into-the-.NET-Runtime-itself.md b/docs/debugger/Debugging-into-the-.NET-Runtime-itself.md new file mode 100644 index 0000000000..f864981e5c --- /dev/null +++ b/docs/debugger/Debugging-into-the-.NET-Runtime-itself.md @@ -0,0 +1,70 @@ +## About this page + +This page provides instructions on debugging into the .NET Runtime and likely any other Open-Source .NET Libraries provided by Microsoft that your application is using. The end of this page also provides instructions for debugging into other external libraries from nuget.org. + +## C# Debugger settings in VS Code + +In VS Code, C# debugger options can be configured as a VS Code setting (File->Preferences->Setting) or, if you have a launch.json file, as properties of your active launch configuration in your launch.json file. This page will explain how to set these settings through launch.json, but they are also configurable as a setting. For more information see the [official documentation for debugger settings](https://code.visualstudio.com/docs/csharp/debugger-settings). + +If you are not currently debugging using a launch.json file, but would like to in order to follow along with this tutorial, you can generate a launch.json by running ".NET: Generate Assets for build and debug" from the VS Code command pallet. + +### Enable debugging into the .NET Runtime + +In order to debug into the .NET Runtime, you need to configure the following settings -- + +```json + "justMyCode": false, + "symbolOptions": { + "searchMicrosoftSymbolServer": true + }, + "suppressJITOptimizations": true, + "env": { + "COMPlus_ReadyToRun": "0" + } +``` + +**Note:** if you already have an `env` property in your launch.json, move the `COMPlus_*` environment variables to that block rather than creating a second `env` property. + +When you start debugging, symbols should now download from the internet, and if you stop in .NET Runtime code, or click on a stack frame, the debugger should automatically download sources. + +After you have debugged and downloaded all the symbols you need, comment out the `"searchMicrosoftSymbolServer": true` so that the debugger doesn't always go to the internet and search for symbols for any dlls which don't have symbols on the Microsoft symbol server. + +### Explanation about what the options are doing + +> `"justMyCode": false,` + +Just My Code is a feature that makes it easier to find problems in your code by ignoring code that is optimized or you don't have symbols for. See [here](https://code.visualstudio.com/docs/csharp/debugger-settings#_just-my-code) for a full explanation. + +> `"searchMicrosoftSymbolServer": true` + +This adds the Microsoft Symbol Server (`https://msdl.microsoft.com/download/symbols`) to the end of the symbol search path. So if a module loads, and the debugger cannot find symbols for it any of the other places, it will then search the Microsoft Symbol Server. + +> `"suppressJITOptimizations": true` + +This option disables optimizations when .NET assemblies load. See [here](https://code.visualstudio.com/docs/csharp/debugger-settings#_suppress-jit-optimizations) for a full explanation. + +> `"COMPlus_ReadyToRun": "0"` + +This environment variables tells the .NET Runtime that it should ignore the ahead-of-time compiled native code that is in many .NET Runtime assemblies, and it should instead compile these assemblies to native code just-in-time. This is important because `"suppressJITOptimizations": true` doesn't affect assemblies that have already been compiled to native code. So the two options work together to make it so that the .NET Runtime runs without optimizations. + +## Debugging into other open-source nuget packages + +If you would like to debug into other open-source nuget packages, such as Newtonsoft.Json, you can also enable `searchNuGetOrgSymbolServer`. Example: + +```jsonc + "justMyCode": false, + "symbolOptions": { + "searchNuGetOrgSymbolServer": true, + "searchMicrosoftSymbolServer": true + }, + "suppressJITOptimizations": true, + // NOTE: Remove unless debugging into the .NET Runtime + "env": { + "COMPlus_ReadyToRun": "0" + } +``` + +A few notes: +1. Not every library on nuget.org will have their .pdb files indexed. If you find that the debugger cannot find a pdb file for an open-source library you are using, please encourage the open-source library to upload their PDBs ([see here for instructions](https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg)). +2. Most libraries on nuget.org are **not** ahead-of-time compiled, so if you are only trying to debug into this library and not the .NET Runtime itself, you can likely omit the `env` section from above. Using an optimized .NET Runtime will significantly improve performance in some cases. +3. Only Microsoft provided libraries will have their .pdb files on the Microsoft symbol server, so you can omit `searchMicrosoftSymbolServer` if you are only interested in an OSS library. diff --git a/docs/debugger/Debugging-x64-processes-on-an-arm64-computer.md b/docs/debugger/Debugging-x64-processes-on-an-arm64-computer.md new file mode 100644 index 0000000000..c018d675c3 --- /dev/null +++ b/docs/debugger/Debugging-x64-processes-on-an-arm64-computer.md @@ -0,0 +1,32 @@ +### Introduction + +On both ARM64 Windows and ARM64 macOS, it is possible to run .NET code in an x64 process. This page provides instructions on how to do so. + +### Steps + +1. Install the ARM64 version of the .NET SDK so that the Language Service can be fully functional +2. Obtain an x64 version of the .NET Runtime for the target process to run on top of. This can either be installed as the shared framework (see [downloads](https://dotnet.microsoft.com/en-us/download/dotnet)), or you could change build tasks to publish the target app as a self-contained application (see [documentation](https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-self-contained)). +3. Install the C# Extension, and optionally, the C# Dev Kit +4. Open a folder containing code you would like to debug. +5. If you don't already have a launch.json, generate one by opening the VS Code command pallet (press F1) and run ".NET: Generate Assets for Build and Debug" +5. Open your .vscode/launch.json file +6. You should see the path to your project's dll file in `program`. Move that to the first element of the args array. +Change program to be the path to the x64 dotnet executable (example: /usr/local/share/dotnet/x64/dotnet). If your project is hosted in some sort of other executable, you could also use that. +7. Add `"targetArchitecture": "x86_64"` + +Example launch.json configuration: +```jsonc + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "cwd": "${workspaceFolder}", + "program": "/usr/local/share/dotnet/x64/dotnet", + "args": "${workspaceFolder}/bin/Debug/net8.0/ExampleProject.dll", + "targetArchitecture": "x86_64" + } +``` \ No newline at end of file diff --git a/docs/debugger/Desktop-.NET-Framework.md b/docs/debugger/Desktop-.NET-Framework.md new file mode 100644 index 0000000000..c492c19e85 --- /dev/null +++ b/docs/debugger/Desktop-.NET-Framework.md @@ -0,0 +1,52 @@ +The C# extension supports limited full .NET framework debugging. It can only debug 64-bit applications with [portable PDBs](./Portable-PDBs.md). + +To enable the Desktop CLR debugger, change the configuration type in launch.json to be "clr" instead of "coreclr" and program should be pointing at the exe (**NOT** a .dll). + +For unit tests, this can be done thusly: +1. File->Preferences->Settings +2. Open "CSharp: Unit Test Debugging Options" +3. Set the 'type' to 'clr' (see settings.json example below) +4. NOTE: For MSTest projects, also see [Forcing MSTest projects to use a 64-bit worker](./Desktop-.NET-Framework.md#forcing-mstest-projects-to-use-a-64-bit-worker) section. + +## launch.json example + +``` +{ + ... + "type": "clr", + "program": "path\\to\\program.exe", + ... +} +``` + +More information about debugging desktop .NET Framework can be found here, https://stackoverflow.com/questions/47707095. + + +## settings.json example + +``` +{ + ... + "csharp.unitTestDebuggingOptions": { + "type": "clr" + } +} +``` + +## Forcing MSTest projects to use a 64-bit worker + +Some versions of MSTest will use an x86 worker process to run tests, which is not supported by the debugger. This can result in error messages like: `Unable to start program '\\testhost.net472.x86.exe'. Unknown Error: 0x80131c30` or `Unable to start program '\\testhost.net472.x86.exe'. The .NET debugger can only debug x64 processes.`. + +To fix this: +1. Create a '.runsettings' file such as the following +2. Add/modify a 'settings.json' file in the root of the workspace that points at the .runsettings file: `"omnisharp.testRunSettings": "C:\\My-workspace-root-here\\UseX64Worker.runsettings"` + +#### Example .runsettings file +```xml + + + + x64 + + +``` diff --git a/docs/debugger/Diagnosting-'Debug-adapter-process-has-terminated-unexpectedly'.md b/docs/debugger/Diagnosting-'Debug-adapter-process-has-terminated-unexpectedly'.md new file mode 100644 index 0000000000..647452b23e --- /dev/null +++ b/docs/debugger/Diagnosting-'Debug-adapter-process-has-terminated-unexpectedly'.md @@ -0,0 +1,74 @@ +If Visual Studio code displays "Debug adapter process has terminated unexpectedly", and the debug console doesn't have information about why, this generally means that the debugger process (vsdbg-ui) crashed. Here is some information you can provide us to diagnose what went wrong. + +### Common +On all OSs, it can be useful to have [logging enabled](Enabling-C#-debugger-logging.md), and to provide the last bit of the event log. + +### macOS + +1. Open 'Console' from the Application->Utilities +2. Go to 'User Reports', and find the vsdbg-ui crash (see screen shot below). +3. Copy paste the 'Exception Type', 'Exception Codes' and 'Exception Note' section into the GitHub issue. +4. Also look at the 'Crashed Thread', then find the call stack for that thread, and send that too (see example below). + +![macOS console screen shot](../images/OSXConsoleUtility.png) + +``` +Thread 9 Crashed: +0 libsystem_c.dylib 0x00007fffbbc43b52 strlen + 18 +1 libc++.1.dylib 0x00007fffba7e0b27 std::__1::basic_string, std::__1::allocator >::assign(char const*) + 21 +2 libvsdbg.dylib 0x0000000103fab41f VsCode::LaunchOptions::Deserialize(rapidjson::GenericValue, rapidjson::MemoryPoolAllocator > const&, VsCode::LaunchOptions&, std::__1::basic_string, std::__1::allocator >&) + 1999 +3 libvsdbg.dylib 0x0000000103f70fe0 VsCode::CVsCodeProtocol::HandleLaunchRequest(rapidjson::GenericDocument, rapidjson::MemoryPoolAllocator, rapidjson::CrtAllocator> const&, std::__1::basic_string, std::__1::allocator >&, unsigned int&, bool&) + 288 +4 libvsdbg.dylib 0x0000000103f6e6a0 VsCode::CVsCodeProtocol::HandleRequest(char const*) + 1648 +5 libvsdbg.dylib 0x0000000103f62e7c std::__1::__function::__func)::$_1, std::__1::allocator)::$_1>, int ()>::operator()() + 28 +6 libvsdbg.dylib 0x0000000103f629f8 VsCode::CommandQueue::CommandLoop() + 360 +7 libvsdbg.dylib 0x0000000103f6cfc7 CVsCodeMainLoop::Run() + 103 +8 libvsdbg.dylib 0x0000000103f10b41 RunMainLoop + 17 +9 ??? 0x000000011038d5a3 0 + 4567127459 +10 ??? 0x000000011038128e 0 + 4567077518 +11 ??? 0x000000010fee99c6 0 + 4562262470 +12 ??? 0x000000010fe99e71 0 + 4561935985 +13 ??? 0x000000010fee9fc7 0 + 4562264007 +14 ??? 0x000000010fee9ce8 0 + 4562263272 +15 ??? 0x000000010feffd25 0 + 4562353445 +16 libcoreclr.dylib 0x00000001017c99a1 CallDescrWorkerInternal + 124 +17 libcoreclr.dylib 0x00000001016b5b43 MethodDescCallSite::CallTargetWorker(unsigned long const*, unsigned long*, int) + 707 +18 libcoreclr.dylib 0x00000001016d1025 QueueUserWorkItemManagedCallback(void*) + 165 +19 libcoreclr.dylib 0x000000010167515a ManagedThreadBase_DispatchOuter(ManagedThreadCallState*) + 378 +20 libcoreclr.dylib 0x0000000101675803 ManagedThreadBase::ThreadPool(ADID, void (*)(void*), void*) + 51 +21 libcoreclr.dylib 0x0000000101669d4c ManagedPerAppDomainTPCount::DispatchWorkItem(bool*, bool*) + 268 +22 libcoreclr.dylib 0x0000000101694b00 ThreadpoolMgr::WorkerThreadStart(void*) + 992 +23 libcoreclr.dylib 0x00000001014ede48 CorUnix::CPalThread::ThreadEntry(void*) + 328 +24 libsystem_pthread.dylib 0x00007fffbbe269af _pthread_body + 180 +25 libsystem_pthread.dylib 0x00007fffbbe268fb _pthread_start + 286 +26 libsystem_pthread.dylib 0x00007fffbbe26101 thread_start + 13 +``` + +### Windows + +#### Gathering details using PowerShell +1. Open a powershell prompt +2. Run `Get-EventLog -LogName Application -Source 'Windows Error Reporting' -after (get-date).AddDays(-1) | Where Message –match 'P1:\s+(vsdbg-ui.exe|vsdbg.exe)' | Format-List | clip` +3. Paste the results into the bug + +#### Gathering details by hand +1. Open Event Viewer +2. Go to Windows Logs->Application +3. Find an event with a Source of 'Application Error' or 'Windows Error Reporting' for the crash +4. Copy/paste the event details. Something like the following. + +``` +Faulting application name: vsdbg-ui.exe, version: 1.1.0.1179, time stamp: 0x58224b03 +Faulting module name: vsdbg.DLL, version: 15.1.10517.0, time stamp: 0x591cc77d +Exception code: 0xc0000005 +Fault offset: 0x00000000002e3d3a +Faulting process id: 0x2dd8 +Faulting application start time: 0x01d2cf58f1e7031e +Faulting application path: C:\Users\greggm\.vscode\extensions\ms-dotnettools.csharp-1.21.18\.debugger\vsdbg-ui.exe +Faulting module path: C:\Users\greggm\.vscode\extensions\ms-dotnettools.csharp-1.21.18\.debugger\vsdbg.DLL +Report Id: 694807aa-44e0-42d3-8129-437f457a5efd +Faulting package full name: +Faulting package-relative application ID: +``` + +### Linux +TBD diff --git a/docs/debugger/Enabling-C#-debugger-logging.md b/docs/debugger/Enabling-C#-debugger-logging.md new file mode 100644 index 0000000000..f962bedc4d --- /dev/null +++ b/docs/debugger/Enabling-C#-debugger-logging.md @@ -0,0 +1,63 @@ +Here is how to enable additional logging for the VS Code C# debugger to help troubleshoot problems. + +## VS Code Settings + +The C# debugger exposes several logging setting via a [Visual Studio Code Setting](https://code.visualstudio.com/docs/getstarted/settings). To modify them: +1. Open up the VS Code settings editor (File->Preferences->Settings). +2. Enter 'diagnosticsLog' into the search bar +3. Navigate to 'Extensions->C#->Debugger' using the settings tree +4. Enable the required setting. The most commonly used logging setting is 'Protocol Messages'. + +When this is enabled, logging will be sent to the VS Code Debug Console where you can copy/paste the relevant sections. + +## Using launch.json +If you have VS Code configured using a launch.json file with `"type": "coreclr"` or `"type": "clr"`, then you can configure logging using launch configuration properties. Here is an example of the new sections to add to launch.json: + +```json + "configurations": [ + { + "type": "coreclr", + "...": "...", + "logging": { + "diagnosticsLog": { + "protocolMessages": true + } + } + }, + { "...": "..." } + ] +``` + +Just like when configured via a VS Code Setting, when this is enabled, logging will be sent to the VS Code Debug Console where you can copy/paste the relevant sections. + +## Full Method +If you are dealing with a problem that happens either very early on during debugger startup, or a problem where the debugger is crashing, it can be helpful to run the debugger (vsdbg-ui) in the console. + +To do this: + +1. Open up a terminal (command prompt) window +2. Change to the directory of the debugger. (NOTE: if you are using VS Code Insiders, change `.vscode` to `.vscode-insiders`) + * **Linux**: `cd ~/.vscode/extensions/ms-dotnettools.csharp--/.debugger` + * **macOS**: `cd ~/.vscode/extensions/ms-dotnettools.csharp--/.debugger/` + * **Windows**: `cd /d C:\Users\\.vscode\extensions\ms-dotnettools.csharp--\.debugger\` +3. Run vsdbg-ui: `./vsdbg-ui --server --consoleLogging` +4. Go back to VS Code and open your `.vscode\launch.json` file. +5. Go to the section for of launch.json for your current launch configuration and add: `"debugServer": 4711` +6. Debug as normal +7. When the problem happens, look at what is printed into the terminal. + +Example launch.json configuration: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "debugServer": 4711, + "name": ".NET Core Launch (console)", + "...": "...", + }, + { "...": "..." } + ] +} +``` diff --git a/docs/debugger/ExampleCode/tasks.json b/docs/debugger/ExampleCode/tasks.json new file mode 100644 index 0000000000..08226435c2 --- /dev/null +++ b/docs/debugger/ExampleCode/tasks.json @@ -0,0 +1,19 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/docs/debugger/Microsoft-.NET-Core-Debugger-licensing-and-Microsoft-Visual-Studio-Code.md b/docs/debugger/Microsoft-.NET-Core-Debugger-licensing-and-Microsoft-Visual-Studio-Code.md new file mode 100644 index 0000000000..4e0a6886d7 --- /dev/null +++ b/docs/debugger/Microsoft-.NET-Core-Debugger-licensing-and-Microsoft-Visual-Studio-Code.md @@ -0,0 +1,13 @@ +This Wiki page contains information for the following error: + +> .NET Debugging is supported only in Microsoft versions of VS Code. See https://aka.ms/VSCode-DotNet-DbgLicense for more information. + +## What does this error mean? + +The C# extension for Visual Studio Code includes the Microsoft .NET Core Debugger (vsdbg). Unlike VS Code, and most other parts of the .NET Core ecosystem, vsdbg is not an open source product but rather is a proprietary part of Visual Studio. It is licensed to work only with IDEs from Microsoft -- Visual Studio Code, Visual Studio, or Visual Studio for Mac. Visual Studio Code has an official version distributed by Microsoft but it is also an open source project, so anyone can build and distribute their own version. The C# extension itself along with the C# and Razor language services will work correctly with a VS Code distribution based on the OSS project. However, the debugger is only licensed to work with the Microsoft-distributed version of Visual Studio Code. + +## How to resolve the issue + +If you installed the OSS version of VS Code, you can uninstall it and reinstall the Microsoft version from [https://code.visualstudio.com/download](https://code.visualstudio.com/download). + +If you believe you have the Microsoft version installed and you are still seeing this problem, you can [open an issue](https://github.com/dotnet/vscode-csharp/issues) in this repo. diff --git a/docs/debugger/Portable-PDBs.md b/docs/debugger/Portable-PDBs.md new file mode 100644 index 0000000000..0d39b77582 --- /dev/null +++ b/docs/debugger/Portable-PDBs.md @@ -0,0 +1,21 @@ +## Summary +.NET Core introduces a new symbol file (PDB) format - portable PDBs. Unlike traditional PDBs which are Windows-only, portable PDBs can be created and read on all platforms. The new .NET debugger for Visual Studio Code only supports this new portable format. Portable PDBs can be generated both from [C# VS projects (.csproj)](#csproj) and [project.json projects](#net-cli-projects-projectjson), and they can be used regardless of what version of .NET the project targets. + +More information about portable PDBs can be found on the [.NET team's GitHub page](https://github.com/dotnet/core/blob/master/Documentation/diagnostics/portable_pdb.md). + +## How to Generate Portable PDBs +### .csproj +With .NET Core "SDK"-style .csproj's, Portable PDBs are already enabled by default. + +For older .csproj files such as portable class libraries (PCLs) or the default in full .NET Framework applications, portable PDBs can be explicitly enabled by modifying the 'DebugType' property in the .csproj file to – + + portable + +**NOTE**: For legacy reasons, the C# compiler option (and hence the name of the msbuild/project.json flags) to generate Windows PDBs is 'full'. However, this should NOT imply that Windows-only PDBs have more information than Portable PDBs. + +### project.json projects +If you still have legacy project.json-based projects, the following option can be used to force the use of portable PDBs. This is not necessary when building on OSX/Linux, but is on Windows -- + + "buildOptions": { + "debugType": "portable" + }, diff --git a/docs/debugger/Remote-Debugging-On-Linux-Arm.md b/docs/debugger/Remote-Debugging-On-Linux-Arm.md new file mode 100644 index 0000000000..55f6cbb058 --- /dev/null +++ b/docs/debugger/Remote-Debugging-On-Linux-Arm.md @@ -0,0 +1,163 @@ +The extension supports remote debugging netcoreapp 2.1 or newer on `linux-arm`. The extension has been tested against **`Raspbian 8 and 9`**. Please let us know if you run into issues with other distributions. + +As of netcoreapp 3.0, `linux-arm64` is also supported. When following these instructions for arm64, be sure to replace `linux-arm` with `linux-arm64`. + +If you run into any problems, please file an [issue](https://github.com/dotnet/vscode-csharp) and note in the text that this is related to `linux-arm`. + +Choose **one** of the following deployment methods: + +* [Framework Dependent Deployment](#framework-dependent-deployment): Compile the application locally. Deploy the binary to `linux-arm`. **Requires the .NET Core Runtime to be installed on `linux-arm`.** + +* [Self Contained Deployment](#self-contained-deployment): Compile and publish the application locally. Deploy the standalone application to `linux-arm`. + +# Prerequisites + +## Install .NET Core 2.1 (or newer) SDK locally (IDE computer) +See [microsoft.com](https://www.microsoft.com/net/learn/get-started-with-dotnet-tutorial) for links to the SDK and instructions. + +## Install the debugger for `linux-arm` (target computer) +* Install the [native dependencies of .NET Core](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x). On Raspbian, this should only mean installing Curl and unzip if it they aren't already installed (`sudo apt-get install curl`). +* Run the following command on `linux-arm` *(installs to ~/vsdbg)*: +``` +curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -r linux-arm -v latest -l ~/vsdbg +``` + +# Framework-Dependent Deployment +Framework-dependent deployments are when the application is deployed without a copy of .NET Core itself, so the application depends on the shared .NET Core Framework being installed. See [docs.microsoft.com](https://docs.microsoft.com/en-us/dotnet/core/deploying/) for more information. + +## Install prerequisites +* [General prerequisites](#prerequisites) +* On the target computer, install a `linux-arm` build of the .NET Core runtime. As of this editing the latest 2.1 version can be found at https://dotnetcli.blob.core.windows.net/dotnet/Runtime/2.1.3/dotnet-runtime-2.1.3-linux-arm.tar.gz. See the [arm docker file](https://github.com/dotnet/dotnet-docker/blob/master/2.1/runtime/stretch-slim/arm32v7/Dockerfile) to find the latest version number. + + *Example (installs to ~/dotnet):* + ``` + mkdir ~/dotnet & curl -sSL https://dotnetcli.blob.core.windows.net/dotnet/Runtime/2.1.3/dotnet-runtime-2.1.3-linux-arm.tar.gz | + tar xvzf /dev/stdin -C ~/dotnet + ``` + +## Create a new console project +On the IDE computer: +* Run `dotnet new console -n MyConsoleApp`. This will create a new netcoreapp console application called `MyConsoleApp`. + +## Build and Deploy +On the IDE computer: +* In your application's root folder, run `dotnet publish` +* Copy all the files under `bin/Debug/netcoreapp2.1/publish` to your `linux-arm` device (replace '2.1' with whatever framework you are targeting). + * To test run your application, on `linux-arm`, run the entrypoint `MyConsoleApp.dll` with `dotnet`. + ```bash + $ ~/dotnet/dotnet MyConsoleApp.dll + ``` + +## Remotely debug your application +Reference the sample `launch.json` below. +* The `"program"` field is set to the `dotnet` executable and the first `"args"` item is the application `.dll` relative to the current working directory (`"cwd"`) on `linux-arm`. +* Update the fields under `"pipeArgs"` to include the IP address of the `linux-arm` device and the ssh keyfile. +* The `"debuggerPath"` points to the location where you installed the debugger to on `linux-arm`. + +### Sample `launch.json` - macOS and Linux +```json + { + "name": ".NET Core Remote Launch - Framework Dependent (console)", + "type": "coreclr", + "request": "launch", + "program": "~/dotnet/dotnet", + "args": [ + "./MyConsoleApp.dll" + ], + "cwd": "~/MyConsoleApp", + "stopAtEntry": false, + "console": "internalConsole", + "pipeTransport": { + "pipeCwd": "${workspaceRoot}", + "pipeProgram": "/usr/bin/ssh", + "pipeArgs": [ + "-T", "-i", "mysshkeyfile", + "pi@10.10.10.10" + ], + "debuggerPath": "~/vsdbg/vsdbg" + } + } +``` + +### Sample `launch.json` - Windows + +This launch.json requires that [PuTTY](http://www.putty.org/) is installed. You must convert your ssh keyfile to a format that PuTTY understands with puttygen. See [How to convert SSH keypairs generated using PuttyGen(Windows) into key-pairs used by ssh-agent and KeyChain(Linux)](https://stackoverflow.com/questions/2224066/how-to-convert-ssh-keypairs-generated-using-puttygenwindows-into-key-pairs-use) for tips. + +``` json + { + "name": ".NET Core Remote Launch - Framework Dependent (console)", + "type": "coreclr", + "request": "launch", + "program": "~/dotnet/dotnet", + "args": ["./dotnetapp.dll"], + "cwd": "~/dotnet-core-app", + "stopAtEntry": false, + "console": "internalConsole", + "pipeTransport": { + "pipeCwd": "${workspaceRoot}", + "pipeProgram": "c:\\Program Files\\PuTTY\\plink.exe", + "pipeArgs": [ + "-i", + "mysshkeyfile.ppk", + "pi@10.10.10.10" + ], + "debuggerPath": "~/vsdbg/vsdbg" + } + } +``` + +It is likely that other tools than PuTTY can be used. They have not been tested. + +We are researching if WSL (ssh) can be used to avoid needing to install PuTTY (or similar tool). + +# Self-Contained Deployment +Self-contained deployments are when all of an applications' dependencies are carried with the deployment. So the only thing that must be installed on the target computer is the [native dependencies of .NET Core](https://docs.microsoft.com/en-us/dotnet/core/linux-prerequisites?tabs=netcore2x). See [docs.microsoft.com](https://docs.microsoft.com/en-us/dotnet/core/deploying/) for more information. + +## Install prerequisites +* [General prerequisites](#prerequisites) + +## Create a new console project +On the IDE computer: +* Run `dotnet new console -n MyConsoleApp`. This will create a new netcoreapp console application called `MyConsoleApp`. + +## Build and Deploy +On the IDE computer: +* Run `dotnet publish -r linux-arm` +* Copy all the files under `bin/Debug/netcoreapp2.1/linux-arm/publish/` to `linux-arm` (replace '2.1' with whatever framework you are targeting). +* Test your application by running the standalone executable `MyConsoleApp`. + ```bash + $ ./MyConsoleApp + ``` + +## Remotely debug your standalone application executable +Reference the sample `launch.json` below. +* The `"program"` field is the standalone executable relative to the current working directory (`"cwd"`) on `linux-arm`. +* Update the fields under `"pipeArgs"` to include the IP address of the `linux-arm` device and the ssh keyfile. +* The `"debuggerPath"` points to the location where you installed the debugger to on `linux-arm`. + +### Sample `launch.json` -- macOS and Linux +```json + { + "name": ".NET Core Remote Launch - Standalone Application (console)", + "type": "coreclr", + "request": "launch", + "program": "MyConsoleApp", + "args": [], + "cwd": "~/MyConsoleApp", + "stopAtEntry": false, + "console": "internalConsole", + "pipeTransport": { + "pipeCwd": "${workspaceRoot}", + "pipeProgram": "/usr/bin/ssh", + "pipeArgs": [ + "-T", "-i", "mysshkeyfile", + "pi@10.10.10.10" + ], + "debuggerPath": "~/vsdbg/vsdbg" + } + } +``` + +### Sample `launch.json` - Windows + +See Framework Dependent sample above for the appropriate `pipeTransport` section for Windows. diff --git a/docs/debugger/Testing-libicu-compatibility-on-Linux.md b/docs/debugger/Testing-libicu-compatibility-on-Linux.md new file mode 100644 index 0000000000..ebd0f31fba --- /dev/null +++ b/docs/debugger/Testing-libicu-compatibility-on-Linux.md @@ -0,0 +1,33 @@ +## Background +On Linux, .NET Core depends on libicu for data about locales and international settings. There is a special [Globalization Invariant Mode](https://github.com/dotnet/corefx/blob/master/Documentation/architecture/globalization-invariant-mode.md) that can be enabled to remove this dependency, but Invariant Mode isn't enabled by default. When Invariant Mode is NOT enabled, and when a compatible libicu cannot be found, the process running .NET Core (probably the debugger if you are reading this article) will abruptly exit. + +To enable invariant mode, add the following environment variable: `export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1`. + +This page provides information to verify that the libicu installed on your system is compatible with .NET Core. + +## Testing + +1. Run: `dotnet new console -f net5.0 -o CultureInfoTest` to create a new console app +2. `cd CultureInfoTest` +3. Replace Program.cs with the below code +4. `dotnet run` + +New program.cs: +```C# +using System; + +namespace CultureInfoTest +{ + class Program + { + static void Main(string[] args) + { + // Test if we can successfully create a culture info + new System.Globalization.CultureInfo("en-US"); + + Console.WriteLine("Test successful."); + } + } +} +``` + diff --git a/docs/debugger/Troubleshoot-Breakpoints.md b/docs/debugger/Troubleshoot-Breakpoints.md new file mode 100644 index 0000000000..f41b4f2288 --- /dev/null +++ b/docs/debugger/Troubleshoot-Breakpoints.md @@ -0,0 +1,44 @@ +## Breakpoint Warnings + +When debugging, a breakpoint has two possible visual states: a solid red circle and a hollow grey circle. If the debugger is able to successfully set a breakpoint in the target process, it will stay a solid red circle. If the breakpoint is a hollow circle a warning has occurred when trying to set the breakpoint. To see the warning, hover over the breakpoint in the debug view: + +![Breakpoints Window](../images/breakpoints-window.png) + +The following two sections describe prominent warnings and how to fix them. + +NOTE: If you have an app that exits immediately so that you cannot read the message in time, you can add a call to `System.Threading.Thread.Sleep(-1);` in your Main method. + +### "No Symbols have been loaded for this document" + +Look at the 'Debug Console' and check if there is a line indicating that your module loaded (example: `Loaded 'C:\MyProject\bin\Debug\netcoreapp2.2\MyProject.dll'. Symbols loaded.`) + +If the line exists, did symbols load? + +* If symbols are not loaded: + * Did the debugger provide additional information in the log lines around this? + * If the dll is being loaded from a different directory from where it was originally built, you may need to add an additional directory through the symbol search path -- in your launch.json file, add a "symbolsOptions/searchPaths" section ([documentation](../../debugger-launchjson.md#symbol-options)). +* If symbols are loaded, the PDB does not contain information about your source files. These are a few possible causes: + * If your source files were recently added, confirm that an up-to-date version of the module is being loaded. + * The PDB file is partially corrupted. Delete the file and perform a clean build of the module to try to resolve the issue. +* If your module is not loaded: + * Confirm that your code is actually running. For example, add a new logging line. + * Confirm that the debugger is attached to your process. You can do this by adding a call to `System.Diagnostics.Debugger.IsAttached` and logging the result. If you are attaching, you might also want to call something like `Console.WriteLine("MyProgram is running in process {0}.", Environment.ProcessId)` to list the process id and compare that to the process you are trying to debug. + +### "… the current source code is different from the version built into..." + +If a source file has changed and the source no longer matches the code you are debugging, the debugger will not set breakpoints in the code by default. Normally, this problem happens when a source file is changed, but the source code wasn’t rebuilt. To fix this issue, rebuild the project. If the build system thinks the project is already up-to-date even though it isn’t, you can force the project system to rebuild either by saving the source file again or by cleaning the project’s build output before building. + +In rare scenarios, you may want to debug without having matching source code. Debugging without matching source code can lead to a confusing debugging experience, so make sure that this is how you want to proceed. To disable these safety checks, edit your launch.json file, and add `"requireExactSource": false`. + +## The breakpoint was successfully set (no warning), but didn’t hit + +This section provides information to troubleshoot issues when the debugger isn’t displaying any warnings – the breakpoint is a solid red circle while actively debugging, yet the breakpoint isn’t being hit. + +Here are a few things to check: +1. If your code runs in more than one process or more than one computer, make sure that you are debugging the right process or computer. +2. Confirm that your code is running. To test that your code is running, add a call to `System.Diagnostics.Debugger.Break` to the line of code where you are trying to set the breakpoint and then rebuild your project. +3. If you are debugging optimized code, make sure the function where your breakpoint is set isn’t being inlined into another function. The `Debugger.Break` test described in the previous check can work to test this issue as well. + +## I deleted a breakpoint, but I continue to hit it when I start debugging again + +If you deleted a breakpoint while debugging, you may hit the breakpoint again the next time you start debugging. To stop hitting this breakpoint, make sure all the instances of the breakpoint are removed from the **Breakpoints** window. diff --git a/docs/debugger/Troubleshoot-loading-the-.NET-Debug-Services.md b/docs/debugger/Troubleshoot-loading-the-.NET-Debug-Services.md new file mode 100644 index 0000000000..09abadffc7 --- /dev/null +++ b/docs/debugger/Troubleshoot-loading-the-.NET-Debug-Services.md @@ -0,0 +1,104 @@ +## Overview + +This page provides instructions for troubleshooting the error "Failed to load the .NET Debugging Services" when using the VS Code C# Extension. + +## Background + +The C# Extension's debugger depends on the .NET Debugging services, which is a pair of native dynamic libraries which ship as part of the .NET Runtime --[lib]mscordbi. and [lib]mscordaccore.. These files must be in the folder of the .NET Runtime that is running in the process being debugged (example: '/usr/share/dotnet/shared/Microsoft.NETCore.App/6.0.424'). This error indicates that one or both of these native libraries couldn't be loaded into the debugger's process. + +There are three reasons that we have seen this happen: +1. [.NET Debugging Services library file is missing](#error-cause-1-net-debugging-services-library-file-is-missing) +2. [Missing dependencies or other load failures](#error-cause-2-missing-dependencies) +3. [Mismatched processor architecture (macOS only)](#error-cause-3-mismatched-processor-architecture-macos-only) + +### Error cause 1: .NET Debugging Services library file is missing + +This error cause is if either of the .NET Debugging services native dynamic libraries ([lib]mscordbi. and [lib]mscordaccore.) don't exist. The most likely reasons for this would be if the target process has its own copy of the .NET Runtime, and that copy doesn't have these libraries. Note that if the target process is using the 'SingleFile' publishing (`dotnet publish ... -p:PublishSingleFile=true`) this will always happen -- debugging single file is not supported. + +You can test for this condition by adding the following code to the start of your project and running your project using "Run->Run Without Debugging". + +```C# + string coreLibPath = typeof(object).Assembly.Location; + if (string.IsNullOrEmpty(coreLibPath) || !System.IO.Path.IsPathFullyQualified(coreLibPath)) + { + Console.WriteLine("CoreLib is not in a rooted path ('{0}')", coreLibPath); + } + else + { + string? dotnetRuntimeDirectory = System.IO.Path.GetDirectoryName(coreLibPath); + if (dotnetRuntimeDirectory is null) + { + Console.WriteLine(".NET Runtime directory is null"); + } + else + { + string? nativeLibraryPrefix = null, nativeLibraryExtension = null; + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) + { + nativeLibraryPrefix = string.Empty; + nativeLibraryExtension = ".dll"; + } + else if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux)) + { + nativeLibraryPrefix = "lib"; + nativeLibraryExtension = ".so"; + } + else if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)) + { + nativeLibraryPrefix = "lib"; + nativeLibraryExtension = ".so"; + } + else + { + Console.WriteLine("Unsupported OS"); + } + + if (nativeLibraryPrefix is not null) + { + string dbiPath = System.IO.Path.Combine(dotnetRuntimeDirectory, nativeLibraryPrefix + "mscordbi" + nativeLibraryExtension); + string dacPath = System.IO.Path.Combine(dotnetRuntimeDirectory, nativeLibraryPrefix + "mscordaccore" + nativeLibraryExtension); + if (!System.IO.File.Exists(dbiPath)) + { + Console.WriteLine("DBI not found at '{0}'", dbiPath); + } + else if (!System.IO.File.Exists(dacPath)) + { + Console.WriteLine("DAC not found at '{0}'", dacPath); + } + else + { + Console.WriteLine(".NET Debugging Services libries were found"); + } + } + } + } +``` + +### Error cause 2: Missing dependencies + +Another reason for this error is if the dynamic loader fails to load one of these native libraries. Exact troubleshooting steps will vary by platform, but here are the Linux troubleshooting steps as an example. + +First open a terminal and execute these steps: +``` +# Step 1: go to the '.debugger' directory of the C# extension. +# 'XXX' should be replaced with the actual version number. +cd ~/.vscode/extensions/ms-dotnettools.csharp-XXX.XXX.XXX-linux-x64/.debugger + +# Step 2: export the 'LD_DEBUG' environment variable, which enables tracing +export LD_DEBUG=all + +# Step 3, start the debugger as a server +./vsdbg-ui --server 2> ~/vsdbg-ui.log +``` + +Step 4: Go back to VS Code and configure the debugger to connect to vsdbg-ui in server mode: +* If you aren't using a launch.json file to debug, generate a launch.json file using the '.NET: Generate Assets for Build and Debug' command from the VS Code command palette (View->Command Palette). +* Open the launch.json file, find the active configuration, and add `"debugServer": 4711`. + +Step 5: Start debugging. You should hopefully see debugging still fail with the same error, and now you have a large log file (~/vsdbg-ui.log in this example) of all the dynamic loader activity. You can then either try and understand the file yourself, or find the relevant section (search for 'mscordbi' for a good starting point) and share that log with the C# Extension debugger team. + + +### Error cause 3: Mismatched processor architecture (macOS only) + +On ARM64 macOS, this error can be caused if the processor architecture of the debugger is different from the processor architecture of the target process. See [Debugging x64 processes on an arm64 computer +](Debugging-x64-processes-on-an-arm64-computer) for more information. \ No newline at end of file diff --git a/docs/debugger/Windows-Subsystem-for-Linux.md b/docs/debugger/Windows-Subsystem-for-Linux.md new file mode 100644 index 0000000000..8ff4ae45ba --- /dev/null +++ b/docs/debugger/Windows-Subsystem-for-Linux.md @@ -0,0 +1,111 @@ +With the Windows 10 Creators Update (Windows version 10.0.15063), you can use Visual Studio Code to debug .NET core applications on [Windows Subsystem for Linux (WSL)](https://msdn.microsoft.com/en-us/commandline/wsl/about). + +This page will walk you through the steps required to debug a .NET core application on WSL. + +## Prerequisites +* Windows 10 Creators Update or newer with [Windows Subsystem for Linux](https://msdn.microsoft.com/en-us/commandline/wsl/install_guide) and Bash installed. +* .NET Core on WSL +* Visual Studio Code +* Microsoft C# extension for VSCode. + +Go to [.NET Core SDK Linux install instructions](https://dotnet.microsoft.com/learn/dotnet/hello-world-tutorial/install?initial-os=linux) for steps to install the .NET Core SDK into WSL. Change the 'Linux Distribution' drop down to the version you have installed. + +## Install the debugger +You can download a copy of the debugger with: + +``` +sudo apt-get install unzip +curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg +``` + +This will download and install the debugger at `~/vsdbg/vsdbg`. This will be used later as the `debuggerPath`. + +## Configuring debugging + +VS Code uses json files to configure how your application is debugged (both for launch and attach) as well as built. There are two files that we need to configure -- +* \/.vscode/launch.json: This provides an array of different configurations you can use to launch your application. There is a drop down in the Debug view for selecting which configuration is active. +* \/.vscode/tasks.json: This provides an array of different tasks, like building your application, that you can execute. Debug configurations can link to one of these tasks through the `preLaunchTask` property. + +The rest of this page will provide examples of how launch.json and tasks.json should be configured to support WSL. + +## Sample launch.json configuration for launch + +```json + { + "name": ".NET Core WSL Launch", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "publish", + "program": "/mnt/c/temp/dotnetapps/wslApp/bin/publish/wslApp.dll", + "args": [], + "cwd": "/mnt/c/temp/dotnetapps/wslApp", + "stopAtEntry": false, + "console": "internalConsole", + "pipeTransport": { + "pipeCwd": "${workspaceRoot}", + "pipeProgram": "bash.exe", + "pipeArgs": [ "-c" ], + "debuggerPath": "~/vsdbg/vsdbg" + } + } +``` + +## Sample 'publish' task for tasks.json (needed for launching) + +```json +{ + "version": "2.0.0", + "tasks": [ + ..., + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/wslApp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary", + "-o", + "${workspaceFolder}/bin/publish" + ] + } + ] +} +``` + +The sample application shown here was created in the Windows path `C:\temp\dotnetapps\wslApp`. WSL by default allows windows paths to be accessible through `/mnt//`, so the path above is accessible as `/mnt/c/temp/dotnetapps/wslApp` from WSL. + +Notes: +1. `preLaunchTask` executes ```dotnet publish```, which builds the project on Windows. Since coreclr is cross-platform, the binary can be executed on WSL without any extra work. +2. `pipeProgram` is set to bash.exe. +3. `debuggerPath` points to vsdbg, the coreclr debugger. +4. This will not support programs that want to read from the console. + +## Sample launch.json configuration for attach + +```json + { + "name": ".NET Core WSL Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickRemoteProcess}", + "pipeTransport": { + "pipeCwd": "${workspaceRoot}", + "pipeProgram": "bash.exe", + "pipeArgs": [ "-c" ], + "debuggerPath": "~/vsdbg/vsdbg", + "quoteArgs": true + } + } +``` +Notes: +1. `"processId": "${command:pickRemoteProcess}"` lists the processes running on WSL using the pipe program. +2. `quoteArgs` will quote any arguments and debugger commands with spaces if set to `true`. +3. Use `sourceFileMap` to map sources if they are available in a different location than where they were built. If you build your project in Linux, make sure to add a map from the /mnt drive letters. Example: `"sourceFileMap": { "/mnt/c/": "c:\\" }` +4. File and paths are case sensitive in Linux. + +## Also see +[Configuring C# Launch.json](../../debugger-launchjson.md) + +[C++ debugging in WSL with VSCode C++ Extensions.](https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Debugger/gdb/Windows%20Subsystem%20for%20Linux.md) diff --git a/docs/images/Exception-Settings.png b/docs/images/Exception-Settings.png new file mode 100644 index 0000000000..ab409d50e1 Binary files /dev/null and b/docs/images/Exception-Settings.png differ diff --git a/docs/images/OSXConsoleUtility.png b/docs/images/OSXConsoleUtility.png new file mode 100644 index 0000000000..e0c2acd5f2 Binary files /dev/null and b/docs/images/OSXConsoleUtility.png differ diff --git a/docs/background_analysis.png b/docs/images/background_analysis.png similarity index 100% rename from docs/background_analysis.png rename to docs/images/background_analysis.png diff --git a/docs/images/breakpoints-window.png b/docs/images/breakpoints-window.png new file mode 100644 index 0000000000..e8de753504 Binary files /dev/null and b/docs/images/breakpoints-window.png differ diff --git a/docs/crash_dump.png b/docs/images/crash_dump.png similarity index 100% rename from docs/crash_dump.png rename to docs/images/crash_dump.png diff --git a/docs/csharp_trace.png b/docs/images/csharp_trace.png similarity index 100% rename from docs/csharp_trace.png rename to docs/images/csharp_trace.png diff --git a/docs/images/debug-launch-configurations-remote-attach.png b/docs/images/debug-launch-configurations-remote-attach.png new file mode 100644 index 0000000000..7923a30d6f Binary files /dev/null and b/docs/images/debug-launch-configurations-remote-attach.png differ diff --git a/docs/images/debug-launch-configurations.png b/docs/images/debug-launch-configurations.png new file mode 100644 index 0000000000..2034e70ba5 Binary files /dev/null and b/docs/images/debug-launch-configurations.png differ diff --git a/docs/images/debugging_debugicon.png b/docs/images/debugging_debugicon.png new file mode 100644 index 0000000000..8ee3ed059a Binary files /dev/null and b/docs/images/debugging_debugicon.png differ diff --git a/docs/generated_prs.png b/docs/images/generated_prs.png similarity index 100% rename from docs/generated_prs.png rename to docs/images/generated_prs.png diff --git a/docs/images/info-bar-add-required-assets.png b/docs/images/info-bar-add-required-assets.png new file mode 100644 index 0000000000..596af576c5 Binary files /dev/null and b/docs/images/info-bar-add-required-assets.png differ diff --git a/docs/inspect_tokens.png b/docs/images/inspect_tokens.png similarity index 100% rename from docs/inspect_tokens.png rename to docs/images/inspect_tokens.png diff --git a/docs/language_status.png b/docs/images/language_status.png similarity index 100% rename from docs/language_status.png rename to docs/images/language_status.png diff --git a/docs/main_snap.png b/docs/images/main_snap.png similarity index 100% rename from docs/main_snap.png rename to docs/images/main_snap.png diff --git a/docs/images/omnisharp_log.png b/docs/images/omnisharp_log.png new file mode 100644 index 0000000000..2e96b6f1c6 Binary files /dev/null and b/docs/images/omnisharp_log.png differ diff --git a/docs/razor_logs.png b/docs/images/razor_logs.png similarity index 100% rename from docs/razor_logs.png rename to docs/images/razor_logs.png diff --git a/docs/recordTraceArgs.png b/docs/images/recordTraceArgs.png similarity index 100% rename from docs/recordTraceArgs.png rename to docs/images/recordTraceArgs.png diff --git a/docs/recordTraceCommand.png b/docs/images/recordTraceCommand.png similarity index 100% rename from docs/recordTraceCommand.png rename to docs/images/recordTraceCommand.png diff --git a/docs/recordTraceTerminal.png b/docs/images/recordTraceTerminal.png similarity index 100% rename from docs/recordTraceTerminal.png rename to docs/images/recordTraceTerminal.png diff --git a/docs/release_pipeline.png b/docs/images/release_pipeline.png similarity index 100% rename from docs/release_pipeline.png rename to docs/images/release_pipeline.png diff --git a/docs/release_pipeline_params.png b/docs/images/release_pipeline_params.png similarity index 100% rename from docs/release_pipeline_params.png rename to docs/images/release_pipeline_params.png diff --git a/docs/report_issue.png b/docs/images/report_issue.png similarity index 100% rename from docs/report_issue.png rename to docs/images/report_issue.png diff --git a/docs/images/unit-test-codelens.png b/docs/images/unit-test-codelens.png new file mode 100644 index 0000000000..cd7e2f6e8e Binary files /dev/null and b/docs/images/unit-test-codelens.png differ diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 0000000000..0588b2c983 --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,26 @@ +**Documentation** + +* [Change log](../CHANGELOG.md) +* [Contributor guide](../CONTRIBUTING.md) +* [How to get support](../SUPPORT.md) +* [Installing without internet connectivity](./Installing-without-Internet-connectivity.md) +* [How to run and debug unit tests](./How-to-run-and-debug-unit-tests.md) +* [Troubleshooting: 'The .NET Core SDK cannot be located.' errors](./Troubleshooting-'The-.NET-Core-SDK-cannot-be-located.'-errors.md) + +**Debugger** + +* [Overview](../debugger.md) +* [launch.json Help](../debugger-launchjson.md) +* [Feature List](./debugger/.NET-Core-debugging-feature-list.md) +* [Enable Logging](./debugger/Enabling-C%23-debugger-logging.md) +* [Portable PDBs](./debugger/Portable-PDBs.md) +* [Troubleshoot Breakpoints](./debugger/Troubleshoot-Breakpoints.md) +* [Attaching to remote processes](./debugger/Attaching-to-remote-processes.md) +* [Remote Debugging On Linux-Arm](./debugger/Remote-Debugging-On-Linux-Arm.md) +* [Windows Subsystem for Linux](./debugger/Windows-Subsystem-for-Linux.md) +* [Diagnosting 'Debug adapter process has terminated unexpectedly'](./debugger/Diagnosting-'Debug-adapter-process-has-terminated-unexpectedly'.md) +* [Testing libicu compatibility on Linux](./debugger/Testing-libicu-compatibility-on-Linux.md) +* [Debugging into the .NET Runtime itself](./debugger/Debugging-into-the-.NET-Runtime-itself.md) +* [Debugging x64 processes on an arm64 computer](./debugger/Debugging-x64-processes-on-an-arm64-computer.md) +* [Debugging sandboxed processes on MacOS](./debugger/Debugging-Sandboxed-Processes-on-OSX.md) +* [Troubleshoot loading the .NET debug services](./debugger/Troubleshoot-loading-the-.NET-Debug-Services.md)