【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.h)Win32 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のDebugViewでOutputDebugStringの出力を捕捉できます。受信、フィルタ、ファイル保存の手順は「DebugViewでリリース後のログを見る」を参照してください。Release固有の不具合をPDBや最適化設定まで含めて追う場合は「Releaseビルドのデバッグ手順」へ進みます。


まとめ

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