-
Notifications
You must be signed in to change notification settings - Fork 51
Tips for debugging extensions
This page contains tips for better debugging of Concord extensions in particular, and, to some degree at least, Visual Studio all up.
Extensions will load into an msvsmon.exe process if either: (1) they are configured to load into a worker process -or- (2) they are monitor components (components with a component level less than 100,000) and the target process is 64-bit.
The best way to debug these:
- Install the Microsoft Child Process Debugging Power Tool into Visual Studio using the Extension Manager.
- Configure your startup project (example: vsix.csproj) to use either native-only or native+managed (interop) debugging. If your startup project is already a VC project (.vcxproj), this is the default. If your startup project is a C# project, see below.
- Open 'Debug->Other Debug Targets->Child Process Debugging Settings' to configure the child process debugger.
- Check the checkbox to 'Enable Child Process Debugging'
- Set the '<All other processes>' action to 'Do not debug'
- Click the blank row in the process list, and add an entry for msvsmon.exe
- Set the 'Debugger Type' value to what is appropriate for your extension (example: 'Managed (v4.6, v4.5, v4.0)' if your extension is implemented in managed code). You may want to enable 'Managed + Native' debugging to prevent msvsmon from timing out.
- Hit F5 to start debugging
If you debug the devenv.exe process with a native debugger and either don't debug msvsmon.exe, or you debug msvsmon.exe with a non-native debugger, and if you sit in break state for more than three minutes msvsmon will timeout and abort. You can work around this problem be either:
- In child process debug settings, enable 'Managed + Native' debugging for msvsmon.exe instead of managed-only debugging
-or-
- If you are in break state for msvsmon, but you are only attaching to devenv.exe for use by the child process debugger than you can work around this problem by going to Tools->Options->Debugging->General, uncheck 'Break all processes when one process breaks'. This will keep the debugger from breaking into the devenv.exe process when the debugger is stopped for managed debugging msvsmon.exe.
If you have a .csproj as your startup project it is still sometimes useful to launch Visual Studio with native debugging enabled. There are three ways to do this:
Right click on your startup project and bring up project properties. Then switch to the 'Debug' tab and check the 'Enable native code debugging' checkbox. This setting is probably the best option as long as the performance of Visual Studio is acceptable in this mode. Note that if you find things are running too slow, two things that might help in addition to the other options here:
- Review your Just My Code settings
- If your target VS is doing something very intensive (example: loading a large .vcxproj) consider if there are ways to avoid this such as opening the build executable an an exe project instead of the real project.
- Right click on the startup project and unload it
- Right click again and edit it
- Inside a
<PropertyGroup>
add:
<!-- Enable native-only debugging -->
<DebugEngines>{3B476D35-A401-11D2-AAD4-00C04F990171}</DebugEngines>
- Right click on your project and reload it + set it as the startup project
This approach is best as long as you don't need to debug any managed code running in devenv.exe, and you aren't frequently wanting to switch back and forth between managed-only and native-only debugging.
- Add a new C++ console app to your solution. Call it something like 'NativeDebugDevenv'.
- Right click on your new project, and go to Build Dependencies->Project Dependencies, and make your new project dependent on your current startup project (ex: vsix.csproj). This will make it so your real project will build as part of F5.
- Right click on the project again and open project properties. Go to the 'Debugging' tab, and make these changes:
- Change 'Command' to
$(DevEnvDir)devenv.exe
- Change 'Command arguments' to
/rootsuffix Exp
- Change 'Working directory' to
$(DevEnvDir)
- Change 'Command' to
- Make this new project your startup project.
Now you can quickly toggle between managed-only debugging and native-only debugging just by switching your startup project.
If your are managed debugging, there are two Tools->Options->Debugging->General settings that can have a pretty significant impact on debugging experience:
- Enable Just My Code
- Suppress JIT optimizations on module load (Managed only)
For best performance, you want to leave these in the default state -- Just My Code (JMC) checked, suppress JIT optimizations unchecked. This will also break, by default, if your code raises an exceptions to Visual Studio. This isn't always what you want -- sometimes your extension is probably supposed to throw an exception. But it is usually a good default and you can configure the specific exception types that you don't want to stop on, such as maybe 'NotImplementedException' to stop breaking when the exception is 'User Unhandled'.
If your are investigating a failure that is happening in some other part of Visual Studio it can be useful to temporarily change both of these -- uncheck JMC and check suppress JIT optimizations. Now the output window will show you all the exceptions raised, and you can configure the debugger to break on ones that you think might be causing your problem.
If you haven't already looked at method logs you might want to do so. For some problems, like understanding why your component isn't getting called, logs are better than debugging.
Concord Documentation:
- Overview
- Visual Studio 2022 support
- Concord Architecture
- Getting troubleshooting logs
- Tips for debugging extensions
- Component Discovery and Configuration
- Component Levels
- Navigating the Concord API
- Obtaining the Concord API headers, libraries, etc
- Concord Threading Model
- Data Container API
- Creating and Closing Objects
- Expression Evaluators (EEs)
- .NET language EEs
- Native language EEs
- Installing Extensions
- Cross Platform and VS Code scenarios:
- Implementing components in native code:
- Worker Process Remoting
Samples: