WinDbg sosex 无法调试
WinDbg sosex unable to debug
我正在尝试调试托管代码。 .exe
文件是为 x64
构建的
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DebugTutorial
{
class Program
{
public static void Foo2()
{
Console.WriteLine("Foo2");
}
public static void Foo1()
{
Console.WriteLine("Foo1");
}
public static void Parent()
{
Foo1();
Console.WriteLine("Parent");
}
static void Main(string[] args)
{
Foo1();
Foo2();
Parent();
}
}
}
我正在执行下一个命令:
0:000> .load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
0:000> .load C:\Users\Anton\Downloads\sosex_64\sosex.dll
0:000> .symfix
0:000> .reload /f
Reloading current modules
.*** WARNING: Unable to verify checksum for DebugTutorial.exe
....
0:000> lm
start end module name
00000252`916b0000 00000252`916b6000 DebugTutorial C (pdb symbols) C:\ProgramData\dbg\sym\DebugTutorial.pdb\B430DC1915A0462AB2D21E18458D70E71\DebugTutorial.pdb
00007ffb`233a0000 00007ffb`23404000 MSCOREE (pdb symbols) C:\ProgramData\dbg\sym\mscoree.pdbE66277C518120A967A3BFBC1850C941\mscoree.pdb
00007ffb`30280000 00007ffb`304f3000 KERNELBASE (pdb symbols) C:\ProgramData\dbg\sym\kernelbase.pdb\CD6C76E6120253287103CD7E22CC0A5D1\kernelbase.pdb
00007ffb`32900000 00007ffb`329b1000 KERNEL32 (pdb symbols) C:\ProgramData\dbg\sym\kernel32.pdb\CA130BEBF44E36EAC20C5E95752843F61\kernel32.pdb
00007ffb`33ca0000 00007ffb`33e81000 ntdll (pdb symbols) C:\ProgramData\dbg\sym\ntdll.pdb927C40B68E505CD22742795247114C1\ntdll.pdb
0:000> !mbp DebugTutorial Foo1
The CLR has not yet been initialized in the process.
Breakpoint resolution will be attempted when the CLR is initialized.
0:000> .load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
0:000> .reload /f
Reloading current modules
.*** WARNING: Unable to verify checksum for DebugTutorial.exe
....
0:000> !mbp DebugTutorial Foo1
The breakpoint could not be set because a breakpoint has already been specified for this source location.
如果我用 F9 热键设置断点,我会看到下一个
0:000> g
Unable to insert breakpoint 0 at 00000252`916b002e, Win32 error 0n998
"Invalid access to memory location."
bp0 at 00000252`916b002e failed
WaitForEvent failed
ntdll!LdrpDoDebuggerBreak+0x31:
00007ffb`33d6c93d eb00 jmp ntdll!LdrpDoDebuggerBreak+0x33 (00007ffb`33d6c93f)
Win32 error 0n998
为什么?怎么了?如何使用 windbg 调试 .net?
.load ...\clr.dll
正在尝试加载 .NET 框架作为 WinDbg 的插件。那行不通的。 WinDbg 的 .NET 插件称为 SOS,您通常使用 .loadby sos clr
。但是,对于 session.
的其余部分来说,这应该无关紧要。
首先,您使用的是 !mbp
,它与源文件和行号一起使用。但是,您将它与模块和方法一起使用。
其次,即使是!mbm
,参数DebugTutorial Foo1
也不正确。格式为 module!namespace.class.method
。幸运的是,您可以使用通配符。尝试 !mbm *!*method
第三,恕我直言,如果 .NET 框架已经加载并且关于 jitting,您会得到关于命令是否有效的更好反馈。使用 sxe ld clrjit
来实现。
我们开始吧:
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffd`fe112cfc cc int 3
0:000> sxe ld clrjit
0:000> *** Wait until .NET is loaded
0:000> g
(3bc4.33bc): Unknown exception - code 04242420 (first chance)
ModLoad: 00007ffd`d2530000 00007ffd`d265b000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clrjit.dll
ntdll!NtMapViewOfSection+0x14:
00007ffd`fe0dfb94 c3 ret
0:000> .load E:\...\sosex.dll
0:000> !mbm *!*Foo1
0:000> !mbl
0 e : disable *!*FOO1 ILOffset=0: pass=1 oneshot=false thread=ANY
SODebugMBP!DebugTutorial.Program.Foo1() (PENDING JIT)
0:000> g
Breakpoint: JIT notification received for method DebugTutorial.Program.Foo1() in AppDomain 0000028c1a58ea00.
Breakpoint set at DebugTutorial.Program.Foo1() in AppDomain 0000028c1a58ea00.
Breakpoint 2 hit
00007ffd`730804e8 90 nop
0:000> !clrstack
OS Thread Id: 0x13d4 (0)
Child SP IP Call Site
000000d4d8afeaa0 00007ffd730804e8 DebugTutorial.Program.Foo1() [C:\...\Program.cs @ 14]
000000d4d8afead0 00007ffd730804a2 DebugTutorial.Program.Main(System.String[]) [C:\...\Program.cs @ 26]
000000d4d8afed30 00007ffdd2666da3 [GCFrame: 000000d4d8afed30]
我正在尝试调试托管代码。 .exe
文件是为 x64
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DebugTutorial
{
class Program
{
public static void Foo2()
{
Console.WriteLine("Foo2");
}
public static void Foo1()
{
Console.WriteLine("Foo1");
}
public static void Parent()
{
Foo1();
Console.WriteLine("Parent");
}
static void Main(string[] args)
{
Foo1();
Foo2();
Parent();
}
}
}
我正在执行下一个命令:
0:000> .load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
0:000> .load C:\Users\Anton\Downloads\sosex_64\sosex.dll
0:000> .symfix
0:000> .reload /f
Reloading current modules
.*** WARNING: Unable to verify checksum for DebugTutorial.exe
....
0:000> lm
start end module name
00000252`916b0000 00000252`916b6000 DebugTutorial C (pdb symbols) C:\ProgramData\dbg\sym\DebugTutorial.pdb\B430DC1915A0462AB2D21E18458D70E71\DebugTutorial.pdb
00007ffb`233a0000 00007ffb`23404000 MSCOREE (pdb symbols) C:\ProgramData\dbg\sym\mscoree.pdbE66277C518120A967A3BFBC1850C941\mscoree.pdb
00007ffb`30280000 00007ffb`304f3000 KERNELBASE (pdb symbols) C:\ProgramData\dbg\sym\kernelbase.pdb\CD6C76E6120253287103CD7E22CC0A5D1\kernelbase.pdb
00007ffb`32900000 00007ffb`329b1000 KERNEL32 (pdb symbols) C:\ProgramData\dbg\sym\kernel32.pdb\CA130BEBF44E36EAC20C5E95752843F61\kernel32.pdb
00007ffb`33ca0000 00007ffb`33e81000 ntdll (pdb symbols) C:\ProgramData\dbg\sym\ntdll.pdb927C40B68E505CD22742795247114C1\ntdll.pdb
0:000> !mbp DebugTutorial Foo1
The CLR has not yet been initialized in the process.
Breakpoint resolution will be attempted when the CLR is initialized.
0:000> .load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
0:000> .reload /f
Reloading current modules
.*** WARNING: Unable to verify checksum for DebugTutorial.exe
....
0:000> !mbp DebugTutorial Foo1
The breakpoint could not be set because a breakpoint has already been specified for this source location.
如果我用 F9 热键设置断点,我会看到下一个
0:000> g
Unable to insert breakpoint 0 at 00000252`916b002e, Win32 error 0n998
"Invalid access to memory location."
bp0 at 00000252`916b002e failed
WaitForEvent failed
ntdll!LdrpDoDebuggerBreak+0x31:
00007ffb`33d6c93d eb00 jmp ntdll!LdrpDoDebuggerBreak+0x33 (00007ffb`33d6c93f)
Win32 error 0n998
为什么?怎么了?如何使用 windbg 调试 .net?
.load ...\clr.dll
正在尝试加载 .NET 框架作为 WinDbg 的插件。那行不通的。 WinDbg 的 .NET 插件称为 SOS,您通常使用 .loadby sos clr
。但是,对于 session.
首先,您使用的是 !mbp
,它与源文件和行号一起使用。但是,您将它与模块和方法一起使用。
其次,即使是!mbm
,参数DebugTutorial Foo1
也不正确。格式为 module!namespace.class.method
。幸运的是,您可以使用通配符。尝试 !mbm *!*method
第三,恕我直言,如果 .NET 框架已经加载并且关于 jitting,您会得到关于命令是否有效的更好反馈。使用 sxe ld clrjit
来实现。
我们开始吧:
ntdll!LdrpDoDebuggerBreak+0x30:
00007ffd`fe112cfc cc int 3
0:000> sxe ld clrjit
0:000> *** Wait until .NET is loaded
0:000> g
(3bc4.33bc): Unknown exception - code 04242420 (first chance)
ModLoad: 00007ffd`d2530000 00007ffd`d265b000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clrjit.dll
ntdll!NtMapViewOfSection+0x14:
00007ffd`fe0dfb94 c3 ret
0:000> .load E:\...\sosex.dll
0:000> !mbm *!*Foo1
0:000> !mbl
0 e : disable *!*FOO1 ILOffset=0: pass=1 oneshot=false thread=ANY
SODebugMBP!DebugTutorial.Program.Foo1() (PENDING JIT)
0:000> g
Breakpoint: JIT notification received for method DebugTutorial.Program.Foo1() in AppDomain 0000028c1a58ea00.
Breakpoint set at DebugTutorial.Program.Foo1() in AppDomain 0000028c1a58ea00.
Breakpoint 2 hit
00007ffd`730804e8 90 nop
0:000> !clrstack
OS Thread Id: 0x13d4 (0)
Child SP IP Call Site
000000d4d8afeaa0 00007ffd730804e8 DebugTutorial.Program.Foo1() [C:\...\Program.cs @ 14]
000000d4d8afead0 00007ffd730804a2 DebugTutorial.Program.Main(System.String[]) [C:\...\Program.cs @ 26]
000000d4d8afed30 00007ffdd2666da3 [GCFrame: 000000d4d8afed30]