「ユーザー環境でだけ挙動がおかしい」と言われても、現場にVisual Studioを持ち込めないことはよくあります。アプリがOutputDebugStringでデバッグ出力を送っていても、それを拾う手段がなければ調査が止まってしまいます。
この記事では、SysinternalsのDebugViewを使って、デバッガのない環境でもアプリのデバッグ出力を拾い、フィルタし、ログファイルに保存するまでの流れをまとめています。
| 今やりたいこと | 読む記事 |
|---|---|
| コードからログを出したい | OutputDebugStringの使い方 |
| デバッガなしでログを受け取りたい | この記事(DebugView) |
| Release固有の不具合をPDBや最適化設定まで含めて追いたい | Releaseビルドのデバッグ手順 |
DebugViewでできること
DebugViewは、WindowsのOutputDebugStringや、Debug構成で実行されるMFCのTRACEによる出力をリアルタイムで表示するツールです。デバッガが付いていなくても出力を拾えるところに価値があります。
| 出力方法 | Visual Studio出力ウィンドウ | DebugView |
|---|---|---|
| OutputDebugString / TRACE | デバッグ実行中のみ表示 | デバッガなしでも表示 |
| printf / std::cout | コンソールに表示 | 非対応(標準出力は拾わない) |
「配布済みのRelease版アプリから状況を見たい」「客先のテストPCでしか起きないログを拾いたい」といった場面で役立ちます。
手順1:入手と起動
DebugViewはMicrosoftのSysinternalsから入手できます。インストーラはなく、Dbgview.exeを置いて実行するだけです。
- Microsoft SysinternalsのDebugViewページからダウンロード
- Dbgview.exeを起動する。通常のWin32出力を拾うだけなら標準ユーザーで開始できます
DebugView v5.0は標準ユーザーで起動し、カーネルモードのキャプチャなど権限が必要な操作を選んだ時点でUAC昇格を求めます。サービス、別セッション、権限の異なるプロセスの出力を調べる場合は、必要に応じて昇格やCapture Global Win32を使ってください。
手順2:Captureメニューで取りたい出力を選ぶ
現在のDebugViewは起動するとキャプチャを開始します。目的の出力が見えない場合や対象を切り替える場合は、Captureメニューで設定を確認します。画面構成はv4.90とv5.0で異なりますが、通常のアプリではCapture Win32を確認する点は同じです。
- Capture Win32:通常のアプリ(ユーザーモード)からのOutputDebugStringを拾う
- Capture Global Win32:他のセッション(サービス・他ユーザー)の出力も拾う。管理者権限が必要
- Capture Kernel:カーネルモードドライバからのDbgPrintを拾う
- Pass-Through:DebugViewが拾ったあとも、VSのデバッガ側でも見えるように通す

重要な制約として、同じ出力を同時に2つのツールが独占的に受け取ることはできません。DebugViewが受けている最中は、Visual StudioのデバッガがOutputDebugStringを見られないことがあります(Pass-Through有効時を除く)。
手順3:アプリを起動して流れを見る
キャプチャを有効にしたまま、調べたいアプリを普通に起動します。アプリがOutputDebugString / TRACEを呼ぶと、DebugViewの一覧にリアルタイムで行が追加されていきます。

各行には次の情報が並びます。
- #:通し番号
- Time:キャプチャされた時刻(設定で経過秒にも切り替え可)
- Debug Print:プロセスIDとメッセージ本文
自作アプリなら、ログに共通のプレフィクス(例 [MYAPP])を付けておくと後で効きます。他のアプリやシステム側の出力と混じっても、一瞬で自分のログだけ引けるからです。
手順4:Filter/Highlightで必要な行だけに絞る
ログはすぐ埋もれます。Edit > Filter/Highlight...(Ctrl + L)で、表示する行と強調する行を絞り込みます。
- Include:ここにマッチする行だけを表示する
- Exclude:邪魔な行を隠す
- Highlight:特定パターンにだけ色を付ける(最大5色)

ワイルドカード * と ? が使えます。たとえばMYAPP*ERROR* のように複合条件で、エラー行だけ赤くすると、長時間キャプチャからでも原因位置がすぐ目に入ります。
手順5:ログをファイルに残す
調査中のログは後から見返したくなることが多いので、その場でファイルに保存できる運用を用意しておきます。
- File > Save As...:現在画面に見えている範囲をテキストで保存
- File > Log to File...:キャプチャと同時に、リアルタイムでファイルへ書き出し続ける

長時間の監視はLog to Fileがおすすめです。画面が流れて見失ってもファイルには残っており、あとからfindstrやVS Codeで解析できます。
リモートモードでネットワーク越しに見る
客先PCにDebugViewを走らせておき、手元のマシンからネットワーク越しにそのログを見ることもできます。
- 客先PC:Dbgview.exe /a(エージェントモード)で起動、ファイアウォールで受信を許可
- 手元:Computer > Connect... から客先PCの名前やIPを指定して接続
ユーザーにDebugViewのUIを操作させずに済むので、操作手順を説明する手間を減らせます。ネットワーク構成次第ですが、試す価値はあります。
自分のコードで試す
動作を確かめるだけなら、自分のアプリの適当な処理にOutputDebugStringを数行仕込むだけで十分です。たとえば プレフィクス付きで5行ほどログを出す次のようなコードを通ると、DebugView側に順に流れてきます。MFCのTRACEでも挙動は同じです。
for (int i = 1; i <= 5; ++i)
{
CString msg;
msg.Format(_T("[MyApp] step=%d status=running\n"), i);
OutputDebugString(msg);
}
OutputDebugString(_T("[MyApp] step=done status=ok\n"));
DebugViewのCapture Win32を有効にしてから、このコードを含むアプリを起動すると、[MyApp] のログが順に流れてきます。Filter/HighlightでMyApp* をIncludeに入れれば、他のアプリのログと混じっても自分の出力だけ見えます。
まとめ
- [ ] DebugViewはReleaseビルドのデバッグ出力を拾える。デバッガがない現場に強い
- [ ] 通常のWin32出力は標準ユーザーで確認できる。別セッションやカーネル出力では必要に応じて昇格する
- [ ] 自作アプリの出力には 共通プレフィクス を付けておく。後で自分のログだけ絞り込みやすくなる
- [ ] 長時間監視はFile > Log to File... で流し撮り、あとから解析
- [ ] VSデバッガとDebugViewの二重受信は基本できないので、切り分けて使う
