Cordbg是和.Net Framework,以及Windows SDK一起ship的托管代码的调试工具,相对于VS来说,它是一个比较low-level的调试工具.
本文的主要目的,就是看看Cordbg如何来进行托管调试,然后演示下其功能,看看其和其它的托管调试工具,譬如MDBG和windbg+SOS有啥不同.
Mdbg,是一个使用dbgeng.dll的调试接口来开发的一个开源调试工具,版本ms现在是2.0,很久没更新了,主要是如果想依托MS的调试接口来开发一个调试器的话,可以参考这个open source的调试工具实现.不过mdbg也有一些比较有意思不错的命令.
调试环境:
VS2008, Shared Source CLI 2.0, Clix.exe, Cordbg (Ver 2.0)
最新的MS关于Cordbg的命令行参考可以参考:
http://msdn.microsoft.com/en-us/library/a6zb7c8d.aspx#cpgrfruntimedebuggercordbgexeanchor4
A Victim Sample:
D:\Rotor\sscli20\binaries.x86dbg.rotor\test>type hello.cs
using System;
public class Hello
{
public static void Main()
{
string name = null;
int age = 0;
Console.Write("Enter your name: ");
name = Console.ReadLine();
Console.Write("Enter your age: ");
age = int.Parse(Console.ReadLine());
Console.WriteLine("Welcome {0}! You are {1} years old.",name, age);
}
}
这里,咱使用自己编译出来的csc.exe:
D:\Rotor\sscli20\binaries.x86dbg.rotor\test>csc
Microsoft (R) Shared Source CLI C# Compiler version 2.0.0001
for Microsoft (R) Shared Source CLI version 2.0.0
Copyright (C) Microsoft Corporation. All rights reserved.
还有cordbg也是build出来的,还是build出来的好:
D:\Rotor\sscli20\binaries.x86dbg.rotor\test>cordbg
Microsoft (R) Common Language Runtime Test Debugger Shell Version 2.0.50826.0
Copyright (c) Microsoft Corporation. All rights reserved.
(cordbg)
编译victim sample:
D:\Rotor\sscli20\binaries.x86dbg.rotor\test>csc /debug+ hello.cs
Microsoft (R) Shared Source CLI C# Compiler version 2.0.0001
for Microsoft (R) Shared Source CLI version 2.0.0
Copyright (C) Microsoft Corporation. All rights reserved.
得到两个编译之后的文件,hello.exe和hello.ildb,一个是可执行文件,一个是sscli调试下生成的symbol文件.
然后加载cordbg开始调试:
D:\Rotor\sscli20\binaries.x86dbg.rotor\test>cordbg hello.exe
Microsoft (R) Common Language Runtime Test Debugger Shell Version 2.0.50826.0
Copyright (c) Microsoft Corporation. All rights reserved.
(cordbg) run hello.exe
Process 3036/0xbdc created.
[thread 0x6e4] Thread created.
005: {
(cordbg)
这种是直接启动hello.exe,然后停到源代码第五行的大括号上面,也可以attach到一个process上面去.这个时候,可以直接查看源代码,使用show命令:
(cordbg) sh
001: using System;
002: public class Hello
003: {
004: public static void Main()
005:* {
006: string name = null;
007: int age = 0;
008:
009: Console.Write("Enter your name: ");
010: name = Console.ReadLine();
011: Console.Write("Enter your age: ");
012: age = int.Parse(Console.ReadLine());
013: Console.WriteLine("Welcome {0}! You are {1} years old.",name, age);
014: }
015: }
(cordbg)
*号显示的地方,表示的是当前调试step到的地方,一开始的时候是刚进入到main函数.也可以直接显示diassemble之后的代码:
(cordbg) dis
*[IL:0000] 00: nop
[IL:0001] 14: ldnull
[IL:0002] 0a: stloc.0
[IL:0003] 16: ldc.i4.0
[IL:0004] 0b: stloc.1
[IL:0005] 72:01000070 ldstr 70000001
(cordbg)
下一个断点:
(cordbg) b hello::Main
#1 <UnknownModule>!hello::Main:0 [unbound]
(cordbg) b
#1 <UnknownModule>!hello::Main:0 [unbound]
显示调用堆栈:
(cordbg) w
Thread 0x6e4 Current State:Normal
0)* hello!Hello::Main +0028 in D:\Rotor\sscli20\binaries.x86dbg.rotor\test\hello
.cs:5
--- Managed transition ---
(cordbg)
想往前step一下的时候,可以使用:
ss[ingle] Step into the next native or IL instruction
so Step over the next source line
si Step into the next source line
s[tep] Step into the next source line
i[n] Step into the next source line
(cordbg) s
006: string name = null;
(cordbg)
显示寄存器内容:
(cordbg) reg
Thread 0xf84:
EIP = 038bfdb3 ESP = 001ae75c EBP = 001ae778 EAX = 00000000 ECX = 00000000
EDX = 001aed30 EBX = 7ffd5000 ESI = 00000000 EDI = 00000000
ST0 = n/a ST1 = n/a ST2 = n/a ST3 = n/a ST4 = n/a
ST5 = n/a ST6 = n/a ST7 = n/a
EFL = 0246 CS = 001b CY = 0 PE = 1 AC = 0 ZR = 1 PL = 0 EI = 1 UP = 0 OV = 0
ControlWord = ffff027f StatusWord = ffff0020 TagWord = ffffffff
ErrorOffset = 79c04362 ErrorSelector = 051c001b DataOffset = 001aaf28
DataSelector = ffff0023 Cr0NpxState = 00000000
(cordbg)
基本命令还有一些,不过大部分对经常使用基于dbgeng.dll的调试工具的人来说都不陌生.不过有一个命令使用起来特别有意思,感觉在显示call tree方面是目前为止看到最强悍的:
Wt Track native instruction count and display call tree
(cordbg) wt
15 Hello::Main
20 Console::Write
55 Console::get_Out
40 Console::InitializeStdOutError
62 Console::get_InternalSyncObject
28 Object::.ctor
48 Console::get_InternalSyncObject
82 Console::InitializeStdOutError
54 Console::OpenStandardOutput
46 Console::GetStandardFile
24 SafeFileHandle::.ctor
33 SafeHandleZeroOrMinusOneIsInvalid::.ctor
22 SafeHandle::.ctor
20 CriticalFinalizerObject::.ctor
28 Object::.ctor
17 CriticalFinalizerObject::.ctor
53 SafeHandle::.ctor
22 GC::.cctor
28 Object::.ctor
24 GC::.cctor
61 GC::SuppressFinalize
7 SafeHandle::.ctor
41 BCLDebug::get_SafeHandleStackTracesEnabled
40 BCLDebug::CheckRegistry
22 AppDomain::get_CurrentDomain
26 Thread::GetDomain
74 Thread::get_CurrentThread
<Ctrl-C>
Async break not allowed at this time.
ControlC Trap
62 Thread::GetDomain
1054 instructions total
(cordbg)
这里的输出要很久才能显示完,故输出了几行就ctrl+c打断了.
总的来说,用cordbg来进行托管调试还是不错的,包含了windbg+sos的大部分功能.但是功能没有windbg+sos强大,也没有windbg图形化调试各个窗口的状态实时查看的清楚.所以,在某些场合下用用还是可以的.
Enjoy it. Cheer!
Lbq1221119@cnblogs first posted http://sscli.cnblogs.com
2008-11-13 00:53:28 AM