Both Debugger.Log and OutputDebugString have some key similarities:
- The both log string for debugging purposes
- Both have thread-affinity. (The debugger can find out which thread logged)
- Data is piped through with no additional semantics in the debugger pipeline.
But they have some key differences.
|Debug events:||Managed debug event, see here for how debugger retreives it.||Native debug event. Retrieved via a OUTPUT_DEBUG_STRING_INFO event|
|Information that’s logged||(level, category string, message string)||(message string)|
|Activation||Can be enabled / disabled (enabled from debugger via ICorDebugProcess::EnableLogMessages, and can be checked via Debugger.IsLogging). Debugger must enable to get the messages.||Always enabled|
|misc||Calls OutputDebugString with category and message strings.|
|Sniffing outside a debugger||Must be attached as a managed debugger to get the managed log events. (DbMon can still sniff the OutputDebugStrings)||Events can be sniffed from DbMon even when a debugger is not attached.|
If you’re writing managed code, you should probably call Debugger.Log() instead of pinvoke out to OutputDebugString.