您没有发布完整的调试会话,但让我得出几个结论:
- 您在线程 4 上,这意味着您已经超出了初始断点。 (否则只有线程 0)
-
!bpmd 立即生效,这意味着 Main 方法已经被 jitted 了。
- 由于 Main 方法已经被 jitted,所以它已经运行了。
- 由于 Main 方法已经运行,没有理由再次中断(除非您递归调用它的可能性很小)
MRE
在下面的例子中,我使用的是这个程序:
class Program
{
static void Main()
{
int x = 5;
var p = new Program();
var i = x;
Console.WriteLine("Debug now.");
Console.ReadLine();
// Ensure variables are needed
Console.WriteLine(x+i+p.ToString());
}
}
下次请自己提供这样的例子,这样我们就不需要自己拿出例子了。
我在Release模式下编译,首选32位AnyCPU。
我正在使用 WinDbg Preview 1.2103.01004.0 进行调试
如何中断 Program.Main()?
在 WinDbg 中启动应用程序,使其在初始断点处停止,如下所示:
ntdll!LdrpDoDebuggerBreak+0x2b:
77ee1a62 cc int 3
0:000>
我们需要 .NET SOS,所以
0:000> sxe ld clrjit
0:000> *** Wait until .NET is loaded
0:000> g
一段时间后,.NET 可用
ModLoad: 72180000 7220a000 C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
[...]
ntdll!NtMapViewOfSection+0xc:
77ea2c0c c22800 ret 28h
0:000>
获取SOSEX extension 的副本并加载它。它简化了事情。
0:000> .load D:\debug\ext\sosex\x86\sosex.dll
0:000>
在 Program.Main 处设置断点:
0:000> !mbm *!*Program.Main
0:000> !mbl
2 e : disable *!*PROGRAM.MAIN ILOffset=0: pass=1 oneshot=false thread=ANY
SO67212401!SO67212401.Program.Main(string[]) (PENDING JIT)
注意“待处理的 JIT”,这意味着 Main() 尚未运行。让我们拭目以待:
0:000> g
ModLoad: 77b10000 77ba6000 C:\WINDOWS\SysWOW64\OLEAUT32.dll
Breakpoint: JIT notification received for method SO67212401.Program.Main(System.String[]) in AppDomain 01090fe8.
Breakpoint set at SO67212401.Program.Main(System.String[]) in AppDomain 01090fe8.
Breakpoint 2 hit
我们在Main()!
0:000> !clrstack
OS Thread Id: 0x5614 (0)
Child SP IP Call Site
00efed3c 01560853 SO67212401.Program.Main(System.String[]) [C:\...\SO67212401\Program.cs @ 9]
00efeebc 7529f036 [GCFrame: 00efeebc]
如何查看局部变量?
如果您使用!mt 和!mgu 单步执行代码,您将到达第二个Console.WriteLine() 调用:
0:000> !clrstack
OS Thread Id: 0x5614 (0)
Child SP IP Call Site
00efed38 736d4f64 System.Console.WriteLine(System.String)
00efed3c 015608a3 SO67212401.Program.Main(System.String[]) [C:\...\Program.cs @ 16]
00efeebc 7529f036 [GCFrame: 00efeebc]
使用!clrstack -l -p查看局部变量和参数:
0:000> !clrstack -l -p
OS Thread Id: 0x5614 (0)
Child SP IP Call Site
00efed38 736d4f64 System.Console.WriteLine(System.String)
PARAMETERS:
value (<CLR reg>) = 0x0309522c
00efed3c 015608a3 SO67212401.Program.Main(System.String[]) [C:\...\Program.cs @ 16]
PARAMETERS:
args = <no data>
LOCALS:
<no data>
<no data>
0x00efed3c = 0x0000000a
00efeebc 7529f036 [GCFrame: 00efeebc]
所以:只有1个局部变量,值为10。参数是
0:000> !do 0309522c
Name: System.String
[...]
String: 10SO67212401.Program <-- string value
Fields:
[...]
由“10”和对象名称组成的串联字符串。
在调试模式下试试这个,你会看到非优化版本的变量。