【MFC】OutputDebugString() で自作ログ出力

【MFC】OutputDebugString() で自作ログ出力

MFC の TRACE マクロは手軽ですが、Debug ビルド限定で、Release ビルドでは何も出力しません。デバッガがアタッチされていない環境でもログを拾いたい場面では、Win32 API の OutputDebugString が使えます。
この記事では、OutputDebugString使い方と TRACE との違いを解説します。

今やりたいこと読む記事
コードからログを出したいこの記事(OutputDebugString)
デバッガなしでログを受け取りたいDebugViewでログを捕捉する
Release 固有の不具合をPDBや最適化設定まで含めて追いたいReleaseビルドのデバッグ手順

目次

OutputDebugString の基本

OutputDebugString は、デバッガの出力ウィンドウに文字列を送る Win32 API です。

OutputDebugString(_T("ここを通過しました\n"));

Visual Studio でデバッグ実行中なら、出力ウィンドウ(Ctrl+Alt+O)に表示されます。TRACE と異なり、Release ビルドでもコンパイルされ、呼び出されます。


TRACE との違い

TRACEOutputDebugString
定義場所MFC マクロ(afx.hWin32 API(debugapi.h
Release ビルド消える(何も出力しない)残る(呼び出される)
書式指定printf 形式で直接書ける文字列のみ(書式は自前で組み立てる)
デバッガなしで捕捉不可DebugView 等で可能

書式付き出力を行うヘルパー

OutputDebugString 単体では printf 形式の書式指定ができません。CString::Format_stprintf_s と組み合わせて使います。

// CString::Format を使う例
CString msg;
msg.Format(_T("値 = %d, 名前 = %s\n"), nValue, strName.GetString());
OutputDebugString(msg);

よく使うなら、ヘルパー関数を用意すると便利です。

void DebugLog(LPCTSTR fmt, ...)
{
    va_list args;
    va_start(args, fmt);

    CString msg;
    msg.FormatV(fmt, args);
    OutputDebugString(msg);

    va_end(args);
}

// 使い方
DebugLog(_T("OnTimer: count = %d\n"), m_nCount);

Release ビルドで使う際の注意

OutputDebugString は Release ビルドでも呼び出されます。以下の点に注意してください。

  • パフォーマンス面では、デバッガがアタッチされていない場合はほぼゼロコストですが、文字列の組み立て処理は実行されます。高頻度ループ内に入れると影響が出ることがあります
  • 情報漏洩にも注意します。Release ビルドの出力は DebugView 等で誰でも見えるため、機密情報(パスワード、認証トークンなど)は出力しないでください
  • Release で出力を無効にしたい場合は、条件コンパイルで #ifdef _DEBUG で囲むか、マクロで切り替えます
#ifdef _DEBUG
#define MY_TRACE(fmt, ...) DebugLog(fmt, __VA_ARGS__)
#else
#define MY_TRACE(fmt, ...) ((void)0)
#endif

デバッガなしで出力を見る:DebugView

Visual Studio をアタッチできない環境では、Sysinternals の DebugViewOutputDebugString の出力を捕捉できます。受信、フィルタ、ファイル保存の手順は「DebugViewでリリース後のログを見る」を参照してください。Release 固有の不具合をPDBや最適化設定まで含めて追う場合は「Releaseビルドのデバッグ手順」へ進みます。


まとめ

  • OutputDebugString は Release ビルドでも動作する Win32 API のログ出力です
  • TRACE は Debug 限定、OutputDebugString は Release でも残る点が最大の違いです
  • 書式付き出力にはヘルパー関数を用意するのが実務的です
  • Release で使う場合は、機密情報の漏洩とパフォーマンスに注意してください
目次