我经常需要在方法上设置断点,打印参数,打破特定参数或在不匹配时继续。在本机代码中,我会使用bp <symbol> "commands"
。但这是一个托管应用程序,因此该方法并不总是JITted。因此,!sos.bpmd可用;但是,它不支持命令参数。 !sosex.mbm是另一个选项,文档表明它可以接受命令参数。来自!sosex.help mbm
:
&#34;命令&#34; - 可以指定一个带引号的字符串参数。此字符串的内容将作为命令参数传递到相应的本机断点。
有关这些选项的更多详细信息,请参阅&#39; bp&#39;的调试器文档。命令。
这意味着它将此命令参数传递给本地断点命令,例如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.
命令参数似乎是有效的,并按照我的意愿行事。这样的断点是一个常见的任务,所以我更倾向于使用单个命令设置整个事件,而不是通过上述多个步骤。据我可以从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。这是可供下载的最新版本。
答案 0 :(得分:1)
你没有做错任何事。我可以看到为什么带嵌入式引号的命令会失败。 SOSEX在解析引用的字符串方面并不是非常复杂。但是,您的简单命令应该会成功。我将继续努力并回复你。