0

我经常需要在方法上设置断点,打印参数,并在特定参数上中断或在不匹配时继续。在本机代码中,我会使用bp <symbol> "commands". 但这是一个托管应用程序,因此该方法并不总是 JITted。因此,!sos.bpmd 可用;但是,它不支持命令参数。!sosex.mbm 是另一个选项,文档表明它可以接受命令参数。来自!sosex.help mbm

"command" - 可以指定一个带引号的字符串参数。此字符串的内容将作为命令参数传递到相应的本机断点。

有关这些选项的更多详细信息,请参阅“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.

commands 参数似乎是有效的,并且可以按照我的意愿进行。这样的断点是一项频繁的任务,所以我更喜欢用一个命令来设置整个事情,而不是通过上述多个步骤。据我可以从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 版本。这是可供下载的最新版本。

4

1 回答 1

1

你没有做错什么。我可以看到为什么带有嵌入式引号的命令会失败。SOSEX 在解析带引号的字符串方面并不是非常复杂。但是,您的简单命令应该会成功。我会解决这个问题并回复你。

于 2014-08-11T20:48:12.287 回答