zoukankan      html  css  js  c++  java
  • Visual Studio调试托管代码

    “输出”窗口中的诊断消息

    可以使用 Debug 类或 Trace 类(属于 System.Diagnostics 类库)将运行时消息写到“输出”窗口。 如果只在程序的调试版本中输出,则使用 Debug 类。 如果要同时在调试版本和发布版本中输出,则使用 Trace 类。

    输出方法

    Trace 和 Debug 类提供下列输出方法:

    • 在不中断执行情况下输出信息的各种 Write 方法。 这些方法取代了在 Visual Basic 早期版本中使用的 Debug.Print 方法。

    • Debug.Assert 和 Trace.Assert 方法,如果指定的条件失败,这些方法将中断执行并输出信息。 默认情况下,Assert 方法显示对话框中的信息。 有关更多信息,请参见托管代码中的断言。

    • Debug.Fail 和 Trace.Fail 方法,它们总是中断执行并输出信息。 默认情况下,Fail 方法在对话框中显示信息。

    除了应用程序的程序输出外,**“输出”**窗口还可以显示下列信息:

    • 调试器已经加载或卸载的模块。

    • 引发的异常。

    • 退出的进程。

    • 退出的线程。

    托管代码中的断言

    断言(或 Assert 语句)测试您作为 Assert 语句的参数指定的条件。 如果此条件计算为 true,不发生操作。 如果此条件计算为 false,则断言失败。 如果正在调试版本中运行,则程序进入中断模式。

    在 Visual Basic 和 Visual C# 中,可以使用方法调用,可以从 System.Diagnostics 命名空间下的 Debug 或 Trace 调用 Assert 方法。 在您的程序的发布版本中不包含 Debug 类方法,因此它们不增大或减小发布代码的速度。

    C++ 不支持 Debug 类方法。 使用带有条件编译的 Trace 类(如 #ifdef DEBUG...)可获得同样的效果。 #endif.

    Debug.Assert 方法

    可随意使用 Debug.Assert 方法测试条件,如果代码正确,该条件应保持为真。 例如,假设已编写一个整数除法函数。 根据数学规则,除数永远不能为零。 可以使用断言测试该条件:

    [C#]

     
    int IntegerDivide ( int dividend , int divisor )
        { Debug.Assert ( divisor != 0 );
            return ( dividend / divisor ); }
    

    当在调试器下运行该代码时,将计算断言语句,但是在发行版本中,将不进行该比较,因此没有额外的系统开销。

    以下是另一个示例。 您有一个实现支票活期存款帐户的类,如下所示:

    [C#]

     
    float balance = savingsAccount.Balance;
    Debug.Assert ( amount <= balance );
    savingsAccount.Withdraw ( amount );
    

    在从该帐户中提取钱之前,您想要确保帐户的余额大于准备取出的金额。 可以编写检查余额的断言:

    [C#]

     
    float balance = savingsAccount.Balance;
    Trace.Assert ( amount <= balance );
    savingsAccount.Withdraw ( amount );
    

    注意,当创建代码的发行版本时,对 Debug.Assert 方法的调用将消失。 这意味着在发行版本中检查余额的调用将消失。 若要解决此问题,您应使用不会在发行版本中消失的 Trace.Assert 替换 Debug.Assert:

    与对 Debug.Assert 的调用不同,对 Trace.Assert 的调用会增加发行版本的系统开销。

    Debug.Assert 的副作用

    使用 Debug.Assert 时,确保 Assert 中的任何代码不会更改程序的结果(如果移除 Assert)。 否则,可能会意外地引入一个只在程序的发行版本中出现的 bug。 对于包含函数或过程调用的断言要特别小心,如下面的示例:

    [C#]

     
    // unsafe code
    Debug.Assert (meas(i) != 0 );
    

    乍一看,使用 Debug.Assert 似乎很安全,但是假设每次调用函数 meas 时该函数都会更新计数器。 当生成发行版本时,由于消除了对 meas 的调用,因此计数器将得不到更新。 这是一个带“副作用”的函数的示例。 消除对具有副作用的函数的调用会导致一个只出现在发行版本中的 bug。 为避免这样的问题,请不要将函数调用放在 Debug.Assert 语句中。 改用临时变量:

    [C#]

     
    temp = meas( i );
    Debug.Assert ( temp != 0 );
    

    即使在使用 Trace.Assert 时,也需要避免将函数调用放置到 Assert 语句中。 这样的调用应是安全的,因为在发行版本中没有消除 Trace.Assert 语句。 但是,如果习惯上避免这样的结构,则使用 Debug.Assert 时犯错误的可能性很小。

    Trace 和 Debug 的要求

    如果使用 Visual Studio 向导创建项目,则默认情况下,“发布”配置和“调试”配置中都定义了 TRACE 符号。 默认情况下,只在调试版本中定义 DEBUG 符号。

    否则,若要使 Trace 方法工作,程序必须在源文件的顶部放置以下代码之一:

    • Visual Basic 中的 #Const TRACE = True

    • Visual C# 和 C++ 中的 #define TRACE

    或者,程序必须是用 TRACE 选项生成的:

    • Visual Basic 中的 /d:TRACE=True

    • Visual C# 和 C++ 中的 /d:TRACE

    如果需要在 C# 或 Visual Basic 发行版本中使用 DEBUG 方法,必须在“Release”配置中定义 DEBUG 符号。

    C++ 不支持 Debug 类方法。 使用带有条件编译的 Trace 类(如 #ifdef DEBUG...)可获得同样的效果。 #endif. 可以在**“<项目> 属性页”**对话框中定义这些符号。 有关更多信息,请参见为 Visual Basic 调试配置更改项目设置或更改 C 或 C++ 调试配置的项目设置。

    Assert 参数

    Trace.Assert 和 Debug.Assert 最多有三个参数。 第一个参数是强制的,它是想要检查的条件。 如果仅用一个参数来调用 Trace.Assert(Boolean) 或 Debug.Assert(Boolean),Assert 方法将检查条件,并且如果结果是 false,则向**“输出”**窗口输出调用堆栈的内容。 下面的示例显示 Trace.Assert(Boolean) 和 Debug.Assert(Boolean):

    [C#]

     
    Debug.Assert ( stacksize > 0 );
    Trace.Assert ( stacksize > 0 ); 
    

    第二个和第三个参数(如果有)必须是字符串。 如果调用带有两个或三个参数的 Trace.Assert 或 Debug.Assert,则第一个参数是一个条件。 该方法检查此条件,如果结果为 false,则输出第二个和第三个字符串。 下面的示例演示 Debug.Assert(Boolean, String) 和 Trace.Assert(Boolean, String) 使用两个参数的情况:

    [C#]

     
    Debug.Assert ( stacksize > 0, "Out of stack space" );
    Trace.Assert ( stacksize > 0, "Out of stack space" );
    

    下面的示例显示 Assert 和 Assert:

    [C#]

     
    Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
    Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" ); 
    

    自定义 Assert 行为

    如果在用户界面模式中运行应用程序,则当条件失败时,Assert 方法将显示**“断言失败”**对话框。 断言失败时发生的操作是由 Listeners 或 Listeners 属性控制的。

    可以通过向 Listeners 集合添加 TraceListener 对象、从 Listeners 集合移除 TraceListener 或者重写现有 TraceListener 的 TraceListener.Fail 方法来自定义输出行为,使其行为不同。

    例如,可以重写 TraceListener.Fail 方法来写入事件日志而不是显示**“断言失败”**对话框。

    若要以这种方法自定义输出,则程序必须包含侦听器,并且必须从 TraceListener 继承并重写它的 TraceListener.Fail 方法。

    在配置文件中设置断言

    您可以在程序配置文件和代码中设置断言。

    JIT 优化和调试

    当调试托管应用程序时,Visual Studio 会默认取消优化实时 (JIT) 代码。 取消 JIT 优化意味着您调试的是非优化代码。 由于代码未优化,因此代码会运行得稍慢一些,但您的调试体验会更全面。 由于调试优化代码要更难一些,因此建议仅在遇到优化代码中发生的 bug 无法在非优化版本中重现时使用。

    JIT 优化在 Visual Studio 中由**“在模块加载时取消 JIT 优化”选项控制。 您可以在“选项”对话框中“调试”节点下的“常规”**页上找到此选项。

    如果清除**“在模块加载时取消 JIT 优化”选项,您可以调试优化 JIT 代码,但调试的能力会由于优化代码与源代码不匹配而可能受到限制。 因此,调试器窗口(如“局部变量”和“自动”**窗口)显示的信息可能没有调试非优化代码时显示的信息那么多。

    另一个重要差异是有关使用“仅我的代码”进行调试。 如果您正在使用“仅我的代码”进行调试,调试器就会将优化代码作为非用户代码处理,不在调试时显示。 因此,在调试 JIT 优化代码时,您可能想关闭“仅我的代码”。

    切记,当模块加载时,**“在模块加载时取消 JIT 优化”**选项会取消代码优化。 如果附加到已正在运行的进程,它可能包含已加载的代码、JIT 编译的代码和优化的代码。 **“在模块加载时取消 JIT 优化”选项对这些代码无效,尽管它会影响在附加后加载的模块。 此外,“在模块加载时取消 JIT 优化”**选项不影响用 NGEN 创建的模块,如 WinForms.dll。

  • 相关阅读:
    Mac Pro 安装 Sublime Text 2.0.2,个性化设置,主题 和 插件 收藏
    Mac Pro 编译安装 Nginx 1.8.1
    Mac Pro 解压安装MySQL二进制分发版 mysql-5.6.30-osx10.11-x86_64.tar.gz(不是dmg的)
    Mac Pro 修改主机名
    Mac Pro 软件安装/个性化配置 汇总
    Mac Pro 安装 Homebrew 软件包管理工具
    Mac Pro 使用 ll、la、l等ls的别名命令
    Mac Pro 入门、遇到的问题、个性化设置 汇总
    Linux/UNIX线程(2)
    工作流引擎activiti入门
  • 原文地址:https://www.cnblogs.com/yilang/p/12467615.html
Copyright © 2011-2022 走看看