Visual Studioで単一スレッドをデバッグする方法は?


254

いくつかのプロジェクトで解決策があります。異なるプロジェクトにはいくつかのブレークポイントがあります。最初のスレッドがこれらのブレークポイントの1つにヒットしたことをトレースし、他のスレッドが同じコードブロックに入っているにもかかわらず、その単一のスレッドのトレースを続けたいと思います。

私は、これは=であるブレークポイント、スレッド名に条件を定義することによって可能である知っている...またはスレッドID = ...しかし、私の場合は重いですロードされたASP.NETのアプリケーションをして、すぐに私は添付としてw3wp.exe多くのスレッドはブレークポイントにヒットします。のようなものが必要ThreadLocal<break-point>です。

出来ますか?もしそうなら、どうですか?


7
@Paolo:このWebアプリケーションは大規模なWebファームの中心として機能し、バグのある状況をテストシナリオで模倣することは不可能です。
Xaqron

VS 2019の場合、これを試してみてください:stackoverflow.com/a/61868591/8579563
Gozo

回答:


150

他のスレッドはコードを実行しないため、スレッドのフリーズ/フリーズは正しくありません。

最も正確で使いやすい方法は次のとおりです。

  1. ブレークポイントウィンドウでCtrl + Aを押します(すべてのブレークポイントを選択します)。
  2. 右クリックして「フィルター...」を選択します。
  3. 「ThreadId =(current thread id)」と入力します。

Visual Studio 2015以降、プロセスは似ています。

  1. ブレークポイントウィンドウでCtrl + Aを押します(すべてのブレークポイントを選択します)。
  2. 右クリックして「設定...」を選択します。
  3. 「条件」をチェックし、ドロップダウンから「フィルター」を選択します
  4. 「ThreadId =(current thread id)」と入力します。

したがって、すべてのスレッドが実行されますが、デバッガーは現在のスレッドでのみヒットします。


51
これにより、「Step」デバッガーコマンドが他のスレッドに入るのを防ぎますか?それは私が抱えていた大きな問題でした。私は自分のスレッドをステップ実行していて、突然、まったく関係のないコードの部分にいます。Visual Studioで開発していないため、テストできません。
Matt Faus、2014年

8
ブレークポイントウィンドウを右クリックしても「フィルター」コマンドはありません...とにかく現在のスレッドIDをどのようにして見つけますか?-イミディエイトウィンドウに移動して、タイピングをしますSystem.Threading.Thread.CurrentThread.ManagedThreadIdか?
BrainSlugs83

5
私のVS(2015、Community Edition)では、複数のブレークポイントの設定を一度に変更することはできません。したがって、フィルタは1つずつしか設定できません。
robert4

5
私は永遠にこの問題に直面し、最後の仕事で誓うことができました。あなたが作業しているスレッドに固執するEclipseのようなビジュアルスタジオ作品を作成する設定を見つけましたが、それを見つけることも参照することもできませんそれに。私はそれを夢見たかどうか疑問になり始めています。
2016

7
-1これは、ブレークポイントのみを許可し、実際のデバッグは許可しないためです。単一のスレッドのデバッグでは、ステップオーバー/ステップインはこの方法では機能しません。
セルジュ・ロガッチ2017年

338

これが私がしたことです:

  1. 探していたスレッドにのみヒットすることがわかっていた条件付きブレークポイントを設定します。

  2. ブレークポイントがヒットし、目的のスレッドが表示されたら、Visual Studioの[スレッド]ウィンドウ(デバッグ中、[デバッグ]-> [ウィンドウ]-> [スレッド])で、Ctrl+ A(すべてのスレッドを選択)し、次にCtrl+現在のスレッドをクリックします。 。デバッグするスレッド以外のすべてのスレッドを選択する必要があります。

  3. 右クリックして、「フリーズ」を選択します。

これで、Visual Studioは解凍されたスレッドのみをステップ実行します。おそらくすべてのフリーズされたスレッドをループする必要があるため、これを行うとかなり遅くなるようですが、マルチスレッドのデバッグにある程度の正気をもたらしました。


1
これは、異なるスレッドで実行されている約8つのタスクがあるコンテキストでは機能しません。他のすべてのスレッドをフリーズして「ステップオーバー」しますが、IDEはしばらくフリーズしてから、とにかく別のスレッドにジャンプします。
メタナイト

3
@Diego:私はもうプロジェクトに取り組んでいませんが、1つを除いてすべてのスレッドを凍結すると、バグが発生した状況でスレッドが補完的だったため、バグの原因となったシナリオが変更されます。これはエレガントなソリューションですが、この機能はVSに組み込む必要があるようです。
Xaqron

3
@ Meta-Knight メインスレッド以外のすべてのスレッドフリーズする必要があります。このようにすると、IDEはフリーズしません
Alex Zhukovskiy 2013

15

まさにあなたが探しているものを実行するVisual Studio 2010+拡張機能をリリースしました。そしてそれは無料です:)。

プレゼンテーション

このVisual Studio拡張機能は、2つのショートカットとツールバーボタンを追加して、開発者がマルチスレッドアプリケーションのデバッグ中にシングルスレッドに簡単に集中できるようにします。

これにより、手動で[スレッド]ウィンドウに移動してすべてのスレッドをフリーズ/解凍する必要性が大幅に減少します。

特徴

以降の実行を現在のスレッドのみに制限します。他のすべてのスレッドを凍結します。ショートカット:CTRL + T + Tまたはスノーフレークボタン。(IDに基づいて)次の単一スレッドに切り替えます。現在のスレッドを変更し、他のすべてのスレッドをフリーズします。ショートカット:CTRL + T + JまたはNextボタン。

こちらのギャラリー公式ページ、またはGithubリポジトリで確認してください。


どのバージョンのVSを使用していますか?
Erwin Mayer

拡張機能をインストールしましたが、機能させることができませんでした(現在のプロジェクトでは、VS2010を使用しています)。[ちなみに、スレッドがアクティブになるという問題は、スレッドが作成されたときに発生するものです。これはおそらく標準的な動作なので、以前のコメントは削除しました]。
wip 2013年

3
これをチェックします。あなたは、マイクロソフトの最大のデバッグ失敗の1つを解決しようと試みた地球上で唯一の人かもしれません。
2015

悲しいかな、vs2012にはインストールされません。新しいバージョンをお持ちですか、それとも自分でビルドできるようにソースコードを共有しますか?
火曜日2015

@stuソースコードはCodeplexにあります。singlethread.codeplex.comVS 2012およびVS 2013で動作するはずですが、更新していません(誰も要求しておらず、私自身も必要がありません)。VS 2012+で簡単に機能させ、Codeplexでコミットできる場合は、ギャラリーにもプッシュできます。
Erwin Mayer

13

Webアプリケーションのように複数のスレッドが生成されている場合、@ MattFausの回答は機能しません。私が代わりにしたことは次のとおりです

  • ブレークポイントを設定して、必要な関数のスレッドに割り込みます。
  • スレッドがブレークポイントに到達して一時停止したら、ブレークポイントを削除し、F8、F10、F11を使用してデバッグを続行します。これにより、他のスレッドが実行できるようになります。

すべての上位の回答を読んだ後、この回避策は私のために働いた。
スワンナンパンガム2017

9

私が使用した少し異なるアプローチ:

  1. 通常のブレークポイントを作成し、ヒットさせます
  2. スレッドウィンドウで、現在デバッグしているマネージスレッドIDを探します。
  3. ブレークポイントウィンドウとセレクターフィルターでブレークポイントを右クリックします。
  4. ThreadId = xxxと入力します。xxxは2からのスレッドIDです。
  5. 他のスレッドを停止したり、ブレークポイントにヒットしたりせずにデバッグできるようになりました

これは、2番目のスレッドがブレークポイントに到達する前に、上記を実行する時間があることを前提としています。そうでない場合、上記を実行する前に他のスレッドがブレークポイントにヒットした場合は、スレッドウィンドウでスレッドを右クリックして、フリーズを選択できます。


3
+1。「これは、2番目のスレッドがブレークポイントに到達する前に時間があることを前提としています」。セミコロンをロックで囲み、セミコロンにブレークポイントを設定します。ブレークポイントに初めてヒットしたときは、ブレークポイントを無効にします。ロックが原因で他のスレッドが入ることはできません。 lock(m_someObject) { ; }
bluedog 2015年

Googleを保存するには、[デバッグ]> [ウィンドウ]> [スレッド]の下にスレッドウィンドウがあります。
Gabe

2

VS 2019では:

  1. どこかにブレークポイントを設定します。
  2. スレッドが来るまでF5(続行)を押します。
  3. ブレークポイントをクリックして削除します。
  4. F10またはF11でスレッドをステップできます。

VS2015でも機能します!
先史時代のペンギン

1

同じハードウェアまたは新しいマシン(クラスター化)のいずれかで、ライブサーバーにアプリケーションの別のインスタンスを追加し、そのインスタンスのみをデバッグすることをお勧めします。ユーザーがトリガーしているコードにブレークポイントを追加しません。それが選択肢でない場合は、さらにトレースを追加します。

ただし、これが絶対に必要であり、ソリューション統計が必要な場合は、リクエストがIPアドレスからのものである場合にのみブレークするブレークポイントを追加できます。これを行うには、検査する条件付きブレークポイントを追加しますHttpContext.Request.UserHostAddress。ただし、これによりアプリケーションの速度が大幅に低下することに注意してください。


それが私が試したことです。問題は、このインスタンスが同じドメインで動作していない(IPまたは別のドメインで実行されている)ことであり、これにより多くの証明書の問題(SSL、WCFなど)が発生し、低負荷ではバグのある状況は発生しません。
Xaqron

どれを試したかわかりません。条件付きブレークポイントを試しましたか?
シュタイナー

はい、一意性を確保するために、管理対象のIDに基づいて名前を付けました。次に、割り当てられているIdを推測し、推測に基づいて条件を設定することは困難です。推測が近い場合もあれば、スレッドをキャッチするのに長い時間がかかる場合もあります。
Xaqron

1

他のすべてのスレッドを停止したくない場合(おそらく、リクエストに応答する必要がある実行中のアプリケーションにVisual Studioデバッガーを接続している場合)、ブレークポイントを自動的に作成および削除するマクロを使用できます。

これは、Visual Studioでマルチスレッドプログラムをデバッグする際のスタックオーバーフローの質問「ステップオーバー」に対する回答で提案されています

ただし、リンクは行ごとのデバッグ方法を説明するだけです。マクロを変更して(問題がなければ)、現在のスレッドでのみ停止するように(たとえば、指定された範囲の行にある)すべてのブレークポイントを変更することをお勧めします。


1

これはVisual Studio 2015では少し異なると思います。ブレークポイントのいくつかの点が変更されましたが、hzdbyte(上記)から受け入れられた回答を適用する方法は次のとおりです。

コーディングマージンのブレークポイントで、右クリック> [条件]> [条件式]から[フィルター]に変更します。これにより、ThreadIdでフィルタリングできます。

または、[ブレークポイント]ウィンドウのブレークポイントで、右クリック> [設定]> [条件]ボックスをチェックして、上記を実行します。


1

行のサイドバーを右クリックして、ブレークポイント条件を設定します。「条件」を選択し、スレッド名を引用符で囲んで以下を入力します。

System.Threading.Thread.CurrentThread.Name == "name_of_your_thread"

あるいは、「スレッド」ウィンドウからスレッドの「マネージドID」を取得し、次のように使用して同じことを行うことができます。

System.Threading.Thread.CurrentThread.ManagedThreadId == your_managed_thread_id

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.