Debugger.Log and LogMessage

Calls to Debugger.Log in a debuggee can generate a ICorDebugManagedCallback::LogMessage managed debug event.  This is the managed equivalent of kernel32!OutputDebugString. Other managed functions (like Debug.Write) may degenerate to calls to Debugger.Log too.
Your debugger needs to subscribe log messages by calling ICorDebugProcess::EnableLogMessages(TRUE) for the process being debugged.

The Log call looks like:

public static void Log(
    int level,
    string category,
    string message

The event is exposed via callback, which looks like this:

HRESULT LogMessage(
    [in] ICorDebugAppDomain *pAppDomain,
    [in] ICorDebugThread *pThread,   <--
ICorDebugThread for the thread that called Debugger.Log.
    [in] LONG lLevel,  <-- 'level' parameter to Log
    [in] WCHAR *pLogSwitchName,  <-- 'category' parameter to Log
    [in] WCHAR *pMessage  <-- 'message' parameter to log.

VS handles this debug event by printing the log message to the Output Window.  A fancier debugger could use this as a pipeline for the debuggee to issue commands to the debugger.

You can kind of think of this as a cross-process TraceListener. If MDbg was fancier, we could have connected this LogMessage to a TraceListener .

Comments (4)

  1. Brian C. Barnes says:

    Works Great. My main app has a TraceListener to look for trace messages from user scripts. When running under my debugger, this TraceListener also echos trace messages using OutputDebugString. My debugging app subscribes to the Log messages, and outputs them to a log window. That way, when running scripts under the debugger, any Trace messages in the script end up going to the debugger. Just what I wanted. Thanks Mike and Rick Byers for help on this.

  2. Both Debugger.Log and OutputDebugString have some key similarities:

    The both log string for debugging…

  3. There&#39;s a good reason that methods on a &quot;System.Diagnostics.Debugger&quot; class are still compiled

Skip to main content