You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[Troubleshooting .NET COM interop](#troubleshooting-net-com-interop)
24
27
-[Links](#links)
25
28
26
29
<!-- /MarkdownTOC -->
27
30
28
-
## Quick introduction to COM
31
+
Quick introduction to COM
32
+
-------------------------
29
33
30
34
In COM, everything is about interfaces. In old times, when various compiler vendors were fighting over whose "standard" was better, the only reliable way to call C++ class methods contained in third-party libraries was to use virtual tables. As its name suggests virtual table is a table, to be precise, a table of addresses (pointers). The "virtual" adjective relates to the fact that our table's addresses point to virtual methods. If you're familiar with object programming (you plan to debug COM, so you should!), you probably thought of inheritance and abstract classes. And that's correct! The abstract class is how we implement interfaces in C++ (to be more precise [an abstract class with pure virtual methods](https://en.cppreference.com/w/cpp/language/abstract_class)). Now, COM is all about passing pointers to those various virtual tables which happen to have GUID identifiers. The most important interface (parent of all interfaces) is `IUnkown`. Every COM interface must inherit from this interface. Why? For two reasons: to manage the object lifetime and to access all the other interfaces that our object may implement (or, in other words, to find all virtual tables our object is aware of). As this interface is so important, let's have a quick look at its definition:
@@ -253,25 +258,51 @@ If comon can't decode a given parameter, you may use the **dx** command with com
253
258
254
259
Run the **!comon detach** command to stop the COM monitor. This command will remove all the comon breakpoints and debugging session data, but you can still examine COM metadata with the cometa command.
255
260
256
-
## Observing COM interactions outside WinDbg
261
+
Observing COM interactions outside WinDbg
262
+
-----------------------------------------
263
+
264
+
Sometimes we only need basic information about COM interactions, such as which objects are used and how they are launched. While WinDbg can be overkill for such scenarios, there are several simpler tools we can use to collect this additional information.
265
+
266
+
### Windows Performance Recorder (wpr.exe)
267
+
268
+
Let's begin with wpr.exe, a powerful tool that's likely already installed on your system. WPR requires profile files to configure tracing sessions. For basic COM event collection, you can use [the ComTrace.wprp profile](https://raw.githubusercontent.com/microsoft/winget-cli/refs/heads/master/tools/COMTrace/ComTrace.wprp) from [the winget-cli repository](https://github.com/microsoft/winget-cli). I've also created an enhanced profile, adding providers found in the [TSS scripts](https://learn.microsoft.com/en-us/troubleshoot/windows-client/windows-tss/introduction-to-troubleshootingscript-toolset-tss), which you can download **[here](/assets/other/WTComTrace.wprp)**. You can use those profiles either solely or in combination with other profiles, as shown in the examples below.
269
+
270
+
```shell
271
+
# Collect only COM events
272
+
wpr.exe -start .\WTComTrace.wprp -filemode
273
+
# Run COM apps ...
274
+
# Stop the trace when done
275
+
wpr -stop C:\temp\comtrace.etl
257
276
258
-
Sometimes we require only basic information about COM interactions, for example, which objects are used and how they are launched. Using WinDbg for such scenarios could be too much burden. Fortunately, it is pretty straightforward to extract this information by looking at registry and process system events. And tools that may help here are [Process Monitor](https://learn.microsoft.com/en-us/sysinternals/downloads/procmon) or [wtrace](https://github.com/lowleveldesign/wtrace).
277
+
# Collect COM events with CPU sampling
278
+
wpr.exe -start CPU -start .\WTComTrace.wprp -filemode
279
+
# Run COM apps ...
280
+
# Stop the trace when done
281
+
wpr -stop C:\temp\comtrace.etl
282
+
```
283
+
284
+
Some providers are the [legacy WPP providers](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/wpp-software-tracing), which require TMF files to read the collected events. Fortunately, the PDB file for compbase.dll contains the required TMF data and we can decode those events. To view the collected data, open the ETL file in **[Windows Performance Analyzer (WPA)](https://learn.microsoft.com/en-us/windows-hardware/test/wpt/windows-performance-analyzer)**. Remember to load symbols first (check [the Windows configuration guide](guides/configuring-windows-for-effective-troubleshooting/#configuring-debug-symbols) how to configure symbols globally in the system), then navigate to the **Generic Events** category and open the **WPP Trace** view.
285
+
286
+
### Process Monitor
259
287
260
-
In **Process Monitor**, we can include Registry and Process events and events where Path contains `\CLSID\` or `\AppID` strings or ends with `.dll`, as in the image below:
288
+
In **[Process Monitor](https://learn.microsoft.com/en-us/sysinternals/downloads/procmon)**, we can include Registry and Process events and events where Path contains `\CLSID\` or `\AppID` strings or ends with `.dll`, as in the image below:
261
289
262
290

263
291
264
292
The collected events should tell us which COM objects the application initiated and in which way. For example, if procmon shows a DLL path read from the `InprocServer32` and then we see this dll loaded, we may assume that the application created a given COM object (the event call stack may be an additional proof). If the COM server runs in a standalone process or a remote machine, other keys will be queried. We may then check the Process Tree or Network events for more details. [COM registry keys official documentation](https://learn.microsoft.com/en-us/windows/win32/com/com-registry-keys) is thorough, so please consult it to learn more.
265
293
266
-
In **wtrace**, we need to pick the proper handlers and define filters. An example command line might look as follows:
294
+
### wtrace
267
295
268
-
```
296
+
In **[wtrace](https://github.com/lowleveldesign/wtrace)**, we need to pick the proper handlers and define filters. An example command line might look as follows:
As you can see, wtrace may additionally show information about RPC (Remote Procedure Call) events.
273
303
274
-
## Troubleshooting .NET COM interop
304
+
Troubleshooting .NET COM interop
305
+
--------------------------------
275
306
276
307
A native COM object must be wrapped into a Runtime Callable Wrapper (RCW) to be accessible to managed code. RCW binds a managed object (for example, `System.__Com`) and a native COM class instance. COM Callable Wrappers (CCW) work in the opposite direction - thanks to them, we may expose .NET objects to the COM world. Interestingly, the object interop usage is saved in the object's SyncBlock. Therefore, it should not come as a surprise that the **!syncblk** command from [the SOS extension](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/sos-debugging-extension) presents information about RCWs and CCWs:
277
308
@@ -402,7 +433,8 @@ Finally, to find who is keeping our managed object alive, we could use the **!gc
Copy file name to clipboardExpand all lines: guides/windbg.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -76,7 +76,7 @@ Installing WinDbg
76
76
77
77
### WinDbgX (WinDbgNext, formely WinDbg Preview)
78
78
79
-
On modern systems download the [appinstaller](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/) file and choose Install in the context menu. If you are on Windows Server 2019 and you don't see the Install option in the context menu, there is a big chance you're missing the App Installer package on your system. In that case, you may use **[this PowerShell script](/assets/windbg-install.ps1.txt)** ([created by @Izybkr](https://github.com/microsoftfeedback/WinDbg-Feedback/issues/19#issuecomment-1513926394) with my minor updates to make it work with latest WinDbg releases).
79
+
On modern systems download the [appinstaller](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/) file and choose Install in the context menu. If you are on Windows Server 2019 and you don't see the Install option in the context menu, there is a big chance you're missing the App Installer package on your system. In that case, you may download and run **[this PowerShell script](/assets/other/windbg-install.ps1.txt)** ([created by @Izybkr](https://github.com/microsoftfeedback/WinDbg-Feedback/issues/19#issuecomment-1513926394) with my minor updates to make it work with latest WinDbg releases).
0 commit comments