windows 程序调试 读书笔记

保持良好的调试心态!

取得正确地错误信息是成功的而且高效的调试的关键。

获得错误信息的方法:

     1。通过测试人员提供的消息(错误报告)。需要为测试人员提供错误报告表单和详细的使用说明;

      2。错误重现。测试人员必须在重现错误的过程中起到积极作用。刚发现错误的时候是错误重现的最佳时期。

     3。错误报告表单的信息。错误表单有一定的格式。错误表单需要详细的说明书,用于指导测试人员正确填写。

通过系统控制面板的设置,使得在win2000系统兰屏下自动将兰屏上信息记录到minidump或者Memory.dump。单击“高级”标签,然后单击“启动和故障恢复”,选择“小内存转储”或者“完全内存转储”。

分析错误信息:
   错误代码,测试人员看到的错误,也就是最后一步报告的情况。
   征兆代码,可能导致观察到的失败的细节代码。
   原因代码,征兆的潜在原因。
   解决代码,需要更改的,可以消除错误而不引入新错误的明确的代码。
   问题的征兆只是最尖但的错误的原因,对于比较难的错误,必须跟踪进去寻找内在原因。
   使用调试器分析。
   动脑分析。
   演绎推理,从事实得到结论。
   排除的过程:
     1。收集有关的事实,
     2。确定可能的解释。
     3。排除与事实不一致的解释。
     4。精炼剩下的解释。
     5。用经验来验证剩下的解释。
     6。假设剩下的解释是真的。
   归纳推理常用于从特殊到一般。
消除错误:
 

   有这样一段代码:
    CSizeDialog dialog;
    dialog.m_size = m_size;
    if(dialog.DoModal() == IDOK)
    {
       int tempVar1,tempVar2,tempVar3,
       m_size = dialog.m_size;
        .......
    }
    if(newblock)
   {
      .......
   }
    作者提到,不管从对话框输入何值,m_size变量的值都不改变,因为tempVar3不该为“,”,应该为“;”,这种解释当然正确,但我觉得这是由于编写代码的不规范造成,因此,在编写代码时,一次只定义一个变量。

  海森堡不确定定理:“位置越精确,当时的动量就越不精确。”该原理指出,对某种现象的绝对的观察和测量是不可能的,这样就导致不确定性。
   在调试器的交互环境中运行程序会改变程序的行为。不要在还不明白做什么的情况下就去编程序。

   保守维护的规则(维护阶段):
   1。如果不是错误代码,一定不要修改。不敢它是多么丑陋,多么让你看着不顺眼。
   2。如果是错误代码,修改并完善。

   开发无错误软件的最好方法是采取负责的态度。

   松耦合的程序对程序测试十分重要。

   注意编程风格。

    结构良好的代码具有更加有用的调用栈。
    要写出能被“人”读懂的代码。

    用const代替#define来创建常量。
    用enum代替#define来创建常量集合。
    用内联函数来代替#define宏。
    用new和delete代替malloc和free。
    用输入输出流(iostreams)代替stdio。

    new不仅分配内存,还调用了类的构造函数;delete先调用对象析构函数然后喜爱释放内存。
    要在头文件中声明所有共享的外部符号,而且保留函数原型中的参数名。
    书中37页,变量初始化问题。

    位掩码

    布尔表达式应该检查是否为假而不是检查是否为真。
    溢出,使用Limits.h中定义的最小值和最大值来作为整型数据类型的大小限制。

    在做除法时,如果不能保证除数不为0.0,那就要处理可能要出现的异常。

    不要匆忙使用强制类型转换,为了保证安全性,每一个强制类型转换都需要你手工进行类型检测。

     避免使用强制类型转换的技术:
     避免使用多态数据类型;
     使用更加广泛的基类;
     提供特殊的存取函数;

 让编译器隐式处理类型;
 如果你在visual

c++中使用dynamic_cast,记住要在project设置里面选择Enable time Type

Information选项。
   在程序中仔细地使用const是一种好方法,能帮助编译器在编译时刻帮你发现

错误。

    如果循环变量的增加操作在每次循环的时候必须执行的话,那么就使用for语

句而不是while语句。
   
    构造函数中的虚函数并不像一般的虚函数,也就是说,如果基类的构造函数

调用了一个虚函数,调用的实际是虚函数的基类版本,而不是重载后的派生类版

本。

   一定要保证析构函数的异常在析构函数中得到处理。

 big three 法则:如果一个类需要一个析构函数,或者一个拷贝构造函数,或

者一个复制运算符,那么它就三个都需要。

   一旦构造函数分配了资源,编译器对这些函数的实现就会肯定会出错。(?)
   尽量采用编译时刻检查而不是运行时刻检查。

   总是使用/W4警告级别。

    在调试版本里总是使用/GZ编译选项。

    抑制假的警告消息:
     使用宏  #ifdef _DEBUG
             #define UNUSED(x)
             #else
             #define UNUSED(x) x
             #endif
             #define UNUSED_ALWAYS(x) x

    #pragma warning编译器指示

     /WX编译选项(把所有的警告都当成错误来对待)
    通过使用断言来自动检测运行时刻错误。

    断言是用来发现运行时刻错误的。断言发现的错误是关于程序实现方面的,

而不是诸如用户输入错误、资源分配错误、文件系统错误或硬件错误等其他类型

的错误。
    断言中的布尔表达式显示的是某个对象或者状态的有效性,而不是正确性。
    断言在条件编译后只存在调试版本里,而不是发布版本里。
    断言不能包含程序代码,也不能有副作用。
    断言是为了给程序员而不是用户提供信息。

    断言类型(66)

    使用最能匹配你的数据的断言。
    防御式编程。
    不管使用什么技术,垃圾输入都不应该导致垃圾输出。
    需要防御性的编程的标准问题包括:错误的输入数据、内存或者硬盘空间不

够、不能打开一个文件、外设不能访问、网络连接不上或者甚至程序中还有错误


   断言不是错误处理的替代品。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值