メソッドにブレークポイントを設定し、引数を出力し、特定の引数で中断するか、一致しない場合は続行する必要があることがよくあります。ネイティブ コードでは、bp <symbol> "commands"
. ただし、これはマネージド アプリケーションであるため、メソッドが常に JITted であるとは限りません。そのため、!sos.bpmd が利用可能です。ただし、コマンド引数はサポートしていません。!sosex.mbm は別のオプションであり、ドキュメントには、コマンド引数を受け入れることができることが示されています。から!sosex.help mbm
:
"command" - 引用符で囲まれた文字列パラメーターを 1 つだけ指定できます。この文字列の内容は、対応するネイティブ ブレークポイントにコマンド パラメータとして渡されます。
これらのオプションの詳細については、「bp」コマンドのデバッガ ドキュメントを参照してください。
これは、このコマンド引数が などのネイティブ ブレークポイント コマンドに渡されることを意味しますbp
。ただし、同じbp
コマンドが受け入れることができるコマンド引数の解析に失敗します。
以下は私の試みです。
0:022> $ Set a breakpoint on Foo.Bar.CBase!Foo.Bar.CBase.set_Item.
0:022> !sosex.mbm Foo.Bar.CBase!Foo.Bar.CBase.set_Item
The breakpoint could not be resolved immediately.
Further attempts will be made as modules are loaded.
Breakpoint set at Foo.Bar.CBase.set_Item(System.String, System.Object) in AppDomain 0000000001f32cc0.
0:022> $ Breakpoint set. Check the native address.
0:022> !sosex.mbl
AppDomain 0000000001eceee0
--------------------------
0 eu: disable Foo.Bar.CBase!Foo.Bar.CBase.SET_ITEM ILOffset=0: pass=1 oneshot=false thread=ANY
AppDomain 0000000001f32cc0
--------------------------
0 e : disable Foo.Bar.CBase!Foo.Bar.CBase.SET_ITEM ILOffset=0: pass=1 oneshot=false thread=ANY
Foo.Bar.CBase!Foo.Bar.CBase.set_Item(string, object)
0 e 000007ff005cc799
0:022> $ Clear the breakpoint.
0:022> $ !sosex.mbc 0
0:022> $ Set breakpoint on same address with command argument.
0:022> bp 000007ff005cc799 "as /mu ${/v:col} (@rdx+0x10); .block { .printf \"Column: %mu, Value: %mu\\n\", @rdx+10, @r8+10; .if (0 != $scmp( \"${col}\", \"opt_id\")) { gc } }"
0:022> $ Check the set breakpoint.
0:022> bl
0 e 000007ff`005cc799 0001 (0001) 0:**** "as /mu ${/v:col} (@rdx+0x10); .block { .printf \"Column: %mu, Value: %mu\\n\", @rdx+10, @r8+10; .if (0 != $scmp( \"${col}\", \"opt_id\")) { gc } }"
0:022> $ Continue execution.
0:022> g
Column: abc_id, Value: 80
Column: hoge_id, Value: N
Column: priority, Value:
Column: opt_id, Value: ZEI
000007ff`005cc799 488b542430 mov rdx,qword ptr [rsp+30h] ss:00000000`056cae00=000000013f7ed498
0:022> $ Outputs arguments and continues on non-match. Breaks on match. Expected results.
コマンド引数は有効なようで、私が望むように機能します。このようなブレークポイントは頻繁に発生するタスクであるため、上記の複数の手順を実行するよりも、1 つのコマンドですべてを設定することをお勧めします。ドキュメントから判断できる限りsosex.mbm
、次のことができるはずです。
0:022> $ Cleanup. Clear the breakpoint.
0:022> bc 0
0:022> $ Ensure that the alias is not defined.
0:022> ad /q ${/v:col}
0:022> $ Try to set the same breakpoint with sosex.mbm.
0:022> !sosex.mbm Foo.Bar.CBase!Foo.Bar.CBase.set_Item "as /mu ${/v:col} (@rdx+0x10); .block { .printf \"Column: %mu, Value: %mu\\n\", @rdx+10, @r8+10; .if (0 != $scmp( \"${col}\", \"opt_id\")) { gc } }"
syntax error
^ Quotes required in ' .printf \"Column: %mu, Value: %mu\\n\", @rdx+10, @r8+10; .if (0 != $scmp( \"${col}\", \"opt_id\")) { gc } '
失敗し、引用符が必要であることを示していますが、どこにあるかはわかりません。構文は少し複雑なので、もう少し単純なものを試してみましょう。
0:022> $ Output RDX and R8 when the breakpoint is hit.
0:022> !sosex.mbm Foo.Bar.CBase!Foo.Bar.CBase.set_Item "r @rdx; r @r8"
syntax error
^ Syntax error in '!sosex.mbm Foo.Bar.CBase!Foo.Bar.CBase.set_Item "r @rdx; r @r8"'
今回は構文エラーですが、ここでも特定できません。別のものを試してみましょう。
0:022> $ Output RDX when the breakpoint is hit, and then continue.
0:022> !sosex.mbm Foo.Bar.CBase!Foo.Bar.CBase.set_Item "r @rdx; gc"
syntax error
^ Extra character error in '!sosex.mbm Foo.Bar.CBase!Foo.Bar.CBase.set_Item "r @rdx; gc"'
別のエラーですが、今回は余分な文字についてですが、問題ないようです。もっと簡単なことを試してみましょう。
0:022> $ Output RDX when the breakpoint is hit.
0:022> !sosex.mbm Foo.Bar.CBase!Foo.Bar.CBase.set_Item "r @rdx"
The breakpoint could not be resolved immediately.
Further attempts will be made as modules are loaded.
Breakpoint set at Foo.Bar.CBase.set_Item(System.String, System.Object) in AppDomain 0000000001f32cc0.
ついに成功。このことから私が導き出した結論はsosex.mbm
、複数のステートメントが含まれていない限り、単一のコマンド引数しか受け入れられないということです。ドキュメントが示すように、単一のコマンド引数がネイティブ ブレークポイント (bp など) に渡されるだけの場合、そのような制限はありません。
この動作は予期されたものですか、それとも何か間違ったことをしていますか? これを達成する別の方法はありますか?上記の回避策を使用できますが、そのようなブレークポイントを設定する必要があることが多いため、これを行うためのより直接的な方法を見つけたいと考えています。
sosex のバージョン 4.5.0.783 を使用していることに注意してください。これは、ダウンロード可能な最新バージョンです。