Windows スケジューラを使用して、作成した exe を実行しています。
スケジューラーが exe を開始したときにデバッグ セッションにジャンプするにはどうすればよいですか?
更新 1. Thread.Sleep を実行してから、プロセスにアタッチすることを考えていました。試してみると、デバッガーは既にプロセスに接続されていると表示されます...
Windows スケジューラを使用して、作成した exe を実行しています。
スケジューラーが exe を開始したときにデバッグ セッションにジャンプするにはどうすればよいですか?
更新 1. Thread.Sleep を実行してから、プロセスにアタッチすることを考えていました。試してみると、デバッガーは既にプロセスに接続されていると表示されます...
プログラム内からDebugBreak()を呼び出すだけです。
MSDN ページによると、DebugBreak は次のことを行います。
現在のプロセスでブレークポイント例外を発生させます。これにより、呼び出し元のスレッドは、例外を処理するようにデバッガーに通知できます。
別のプロセスでブレークポイント例外を発生させるには、DebugBreakProcess 関数を使用します。
この時点でデバッガーをアタッチし、プログラムの実行を続行できます。
このソリューションの唯一の問題は、プログラムが実行されるたびにブレークしないように、コード内の DebugBreak() を条件付きにする必要があることです。おそらく、環境変数、レジストリ設定、またはスケジューラーがプログラムに渡して起動時に確実に中断するパラメーターを介してこれを実現します。
環境変数を読み取る未テストのコード例を次に示します。
int main()
{
char *debugBreakChar = getenv("DEBUG_BREAK");
int debugBreak = atoi(debugBreakChar);
if (debugBreak)
{
DebugBreak();
}
// Rest of the program follows here
}
あとは、環境変数をシステム変数として設定し、スケジューラと同じシェル コンテキストからアクセスできるようにするだけです (再起動するとこれが実現します)。
set DEBUG_BREAK=1
これで、プログラムは起動時に中断され、デバッガーをアタッチできるようになります。環境変数を 0 に変更するか、設定を解除すると、プログラムを正常に実行できます。
環境変数はコンテキストベースであり、スケジューラが同じ環境コンテキストから実行されることを知る必要があるため、この点で少し面倒です。レジストリ値はこれよりも優れており、代わりにコードでRegQueryValueExを使用してレジストリ値を読み取ることができます (この関数を使用するには、windows.h を含める必要があります)。
プロセスへのアタッチは (Visual Studio 内から) 機能しますが、メイン ロジックを開始する前にアタッチできるように、プロセスが高速な場合はコードの先頭にスリープ ステートメントを追加する必要がある場合があります。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
プロセスの起動時にプロセスにデバッガーをアタッチするキーを設定できます。これを行う方法については、このKB 記事を参照してください。
このアプローチにはいくつかの落とし穴があります。
VS を使用してデバッグするには、実行可能ファイルの IFEO オプションで実際に VSJitDebugger.exe を指定する必要があります。また、手動で使用するデバッグ エンジンを指定する必要があります。詳細はこちら。
Visual Studio の [デバッグ] メニューの [プロセスにアタッチ]。