Reputation: 3032
First of all, is it possible to view local variables in C# code in WinDbg.exe by adding SOS.dll?
I loaded the SOS.dll extension into WinDbg.exe by using .cordll -ve -u -l
command. The machine is x86. The result of the command is:
CLRDLL: Loaded DLL C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll
Automatically loaded SOS Extension
CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll
I thought the SOS.dll has been loaded successfully. Then I want to insert a BreakPoint in the code. By testing the F9 seems not work. So I use the !bpmd
command to insert a break point, like this:
0:004> !bpmd MyCode.exe Program.Main
PDB symbol for clr.dll not loaded
Found 1 methods in module 00714044...
MethodDesc = 00714d50
Setting breakpoint: bp 00760869 [Demo.Program.Main(System.String[])]
Adding pending breakpoints...
0:004> bl
1 e Disable Clear 00760869 0001 (0001) 0:****
But the result is:
0:004> g
eax=00000024 ebx=00000001 ecx=00eff73c edx=77592740 esi=00000000 edi=77621a20
eip=77592740 esp=00eff73c ebp=00eff750 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
77592740 c3
Why the breakpoint is not hit?
Hope anyone could give me some help!
Upvotes: 1
Views: 1233
Reputation: 59208
You didn't post the full debug session, but let me draw a few conclusions:
!bpmd
worked immediately, which means the Main method was already jitted.In the following example, I am using this program:
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());
}
}
Please provide such an example yourself next time, so we don't need to come up with an example ourselves.
I compile it in Release mode, AnyCPU with 32 bit preferred.
I am debugging with WinDbg Preview 1.2103.01004.0
Launch the application in WinDbg, so that it will stop at the initial breakpoint like this:
ntdll!LdrpDoDebuggerBreak+0x2b:
77ee1a62 cc int 3
0:000>
We need .NET SOS, so
0:000> sxe ld clrjit
0:000> *** Wait until .NET is loaded
0:000> g
And some time later, .NET is available
ModLoad: 72180000 7220a000 C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
[...]
ntdll!NtMapViewOfSection+0xc:
77ea2c0c c22800 ret 28h
0:000>
Get yourself a copy of the SOSEX extension and load it. It simplifies things.
0:000> .load D:\debug\ext\sosex\x86\sosex.dll
0:000>
Set a breakpoint at 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)
Note the "pending JIT", which means Main()
has not been run yet. Let's wait for it:
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
We are in 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]
If you step throught the code with !mt
and !mgu
, you'll reach the second Console.WriteLine()
call:
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]
Have a look at local variables and parameters using !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]
So: there is only 1 local variable with a value of 10. And the parameter is
0:000> !do 0309522c
Name: System.String
[...]
String: 10SO67212401.Program <-- string value
Fields:
[...]
a concatenated string made of "10" and the name of the object.
Try this in debug mode and you'll see non-optimized version of variables.
Upvotes: 1