在SSCLI中调试托管代码

SSCLI只实现了部分.NET调试功能,而且不支持在Visual Studio里直接调试SSCLI环境里执行的托管程序,在SSCLI里只能用其自带的cordbg.exe调试SSCLI环境下的托管程序。

因为.NET Framework 2.0 SDK也自带了cordbg.exe,所以需要在SSCLI环境里(即执行了 env.bat 命令初始化过的SSCLI),否则会采用错误的cordbg版本调试SSCLI程序。

我们将用下面这个C#程序来演示cordbg的用法,其是SSCLI自带的例子,源码位于:samples\howto\basedatatypes\stringformat

using System;
using System.IO;
using System.Globalization;

public enum Color
{
    Red = 25,
    Blue,
    Green
}//enum Color

public class stringFormat
{
    public static void Main(string[] args)
    {
        DateTime d = DateTime.Now;

        PrintFormat(d, "d");

        Console.WriteLine("AbbreviatedDayNames = new string [] {Sund, Mond, Tues, Weds, Thur, Frid, Satu}");
        DateTimeFormatInfo dtfi = new DateTimeFormatInfo();
        dtfi.AbbreviatedDayNames =
                   new string[] { "Sund", "Mond", "Tues", "Weds", "Thur", "Frid", "Satu" };
        PrintFormat(d, "ddd", dtfi);
        Console.WriteLine("------------------------------------------------------------------------------\n");

        // Enum formatting
        Console.WriteLine("Enum Formatting");
        Console.WriteLine
          (
          "Name: {0}, Enum Value: {1}, Enum Value Hex: {2}",
          Color.Green.ToString("G"),
          Color.Green.ToString("D"),
          Color.Green.ToString("X")
          );
        Console.WriteLine();

        //Number standard formats
        double num = System.Math.PI * -3.0;
        PrintFormat(num, "c4");
    } //Main()

    public static void PrintFormat(IFormattable inputData, string formatString)
    {
        PrintFormat(inputData, formatString, null);
    }//PrintFormat()

    public static void PrintFormat(IFormattable inputData,
                                   string formatString,
                                   IFormatProvider provider)
    {
        try
        {
            if (provider == null)
            {
                Console.WriteLine("{0}\t{1}",
                                  formatString,
                                  inputData.ToString(formatString, provider));
            }//if
            else
            {
                string formstr = "{0} in the custom " + formatString + " format is {1:" + formatString + "}";
                Console.WriteLine(string.Format(provider, formstr, inputData, inputData));
            }//else
        }//try
        catch (Exception e)
        {
            Console.WriteLine("Exception in PrintFormat(): {0}", e.Message);
            Console.WriteLine("Data was {0}, Format string was: {1}, Type was {2}",
                               inputData,
                               formatString,
                               inputData.GetType().Name);
        }//catch
    }//PrintFormat
}//class stringformat

编译的时候,需要打开C#编译器的“/debug”调试开关才能生成调试版本的程序,便于调试器(cordbg)调试程序:

csc /debug stringformat.cs

注意:csc命令也要在初始化SSCLI环境之后才能运行,否则也会用到.NET Framework SDK自带的csc命令。

命令执行完毕之后,会看到编译器除了输出stringformat.exe可执行文件以外,还生成了stringformat.ildb这个调试用的符号文件。

执行下面的命令开始调试:

cordbg stringformat.exe

cordbg运行界面如下图:

cordbg-interface-overview.png

与在Visual Studio这些IDE调试程序不同,cordbg一开始并不会直接运行被调试程序,而是先中断程序的执行 – 即在第15行Main函数的入口处中断,等待命令输入。这是因为需要留出时间让开发人员准备调试工作 – 如设置断点之类的。在命令行里输入“help”命令可以查看cordbg里可用的命令,下一篇文章将讲解cordbg的命令用法。

这里我们演示几个基本的命令,下表我用批注(以#号开头的粗体字体)说明每个命令的意义:

C:\sscli20\research\chapter1>cordbg stringformat.exe
Microsoft (R) Common Language Runtime Test Debugger Shell Version 2.0.50826.0
Copyright (c) Microsoft Corporation.  All rights reserved.

#
# run 命令用来启动被调试程序,如果执行cordbg命令时,传入了被调试程序文件的参数,
# 则会自动执行这个命令
#

(cordbg) run stringformat.exe
Process 1588/0x634 created.
[thread 0xe4] Thread created.

#
# 当前程序中断的位置,前面的 015 表示当前中断的位置是第15行
#

015:     {

#
# 在源码的第18行设置断点
#

(cordbg) break 18
Breakpoint #1 has bound to C:\sscli20\research\chapter1\stringformat.exe.
#1      c:\sscli20\research\chapter1\stringformat.cs:18 Main+0x7(il) [active]

#
# 恢复程序的执行
#

(cordbg) g
break at #1     c:\sscli20\research\chapter1\stringformat.cs:18 Main+0x7(il) [ac
tive]

#
# 触发了断点并中断执行程序
#

018:         PrintFormat(d, "d");

#
# 查看局部变量d的值
#

(cordbg) p d
d=<System.DateTime>
  dateData=0x88d21f5af1505bc5
  
#
# 查看所有函数参数、局部变量和全局变量
#

(cordbg) p
args=(0x00d4217c) array with dims=[0]
CS$0$0000=<null>
d=<System.DateTime>
dtfi=<null>
num=0
$result=(strong handle, Size: 4) (0x00d43fe0) <System.Reflection.TargetParameter
CountException>
$thread=(0x00d42830) <System.Threading.Thread>

#
# 调用一个函数,需要给出函数所属类型的全名 – 即包括命名空间,
# 类名和函数名之间用“::”分隔,参数通过空格分隔
#

(cordbg) funceval System.DateTime::ToString d
There are 4 possible matches for the method ToString. Pick one:

#
# 因为有函数重载的关系,所以cordbg会列出可选的函数,并让开发人员指定
# 所要调用的函数。
#

0) none, abort the operation.
1) [060002eb] String ToString()
2) [060002ec] String ToString(String)
3) [060002ed] String ToString(IFormatProvider)
4) [060002ee] String ToString(String, IFormatProvider)

Please make a selection (0-4): 1
Function evaluation complete.
$result=(strong handle, Size: 4) (0x00d5b6a0) "2015/2/25 21:41:26"
018:         PrintFormat(d, "d");

#
# funceval调用函数的结果被保存到一个叫 $result 的变量里,在执行后续的funceval
# 命令时,可以重用上一个命令的调用结果
#

(cordbg) funceval System.Console::WriteLine $result
There are 19 possible matches for the method WriteLine. Pick one:
0) none, abort the operation.
1) [060006d4] Void WriteLine()
... ...
14) [060006e1] Void WriteLine(String)
... ...
19) [060006e6] Void WriteLine(String, Object[])

Please make a selection (0-19): 14
2015/2/25 21:41:26
Function evaluation complete, no result.

018:         PrintFormat(d, "d");

#
# k命令用来终止当前正在执行的被调试进程
#

(cordbg) k
Terminating current process...
Process exited.

#
# exit命令退出cordbg程序
#

(cordbg) exit
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容