现在的位置: 首页 > 综合 > 正文

VC 2005——DEGUGGING

2013年10月12日 ⁄ 综合 ⁄ 共 3706字 ⁄ 字号 评论关闭

本文作者所提出的几个减少DEBUGGIN痛苦的方法(There are four broad strategies you can adopt to make debugging as painless as possible:):
1.Don’t re-invent the wheel. 理解并使用各种已有的库。
2.Develop and test your code incrementally. 渐进集成
3.Code defensively.

比如①declare member functions of native C++ classes that don’t modify an object as const.
        ②Use const parameters where appropriate.
        ③Don’t use ‘magic numbers’ in your code—define const objects with the required values.
  
4.Include debugging code that checks and validates data and conditions in your program from the outset.

普遍存在的BUG(Common Bugs)
其中大多数是由于无效指针或者是由于错误指针所引起的,所以对指针操作要加倍小心!!!
The common ways in which bad pointers arise are:
① Failing to initialize a pointer when you declare it
② Failing to set a pointer to free store memory to null when you delete the space allocated
③ Returning the address of a local variable from a function
④ Failing to implement the copy constructor and assignment operator for classes that allocate free store memory

在程序中加入Debugging代码
1.使用标准库<cassert>中的void assert(int expression);
如果将 #define NDEBUG放在#include <cassert>之后则assert语句失效。
若传递给assert的值为非零,则此语句没有作用,若传递的值为零,则会弹出一个诊断对话框,显示出错的源文件名、源文件出错的行号,然后assert()调用abort()结束函数。

2.使用预编译条件
#ifdef _DEBUG
// Code for debugging purposes...
#endif // _DEBUG

另外,也可以自定义预编译变量以支持更小的调试粒度,但建议将自定义的变量放在_DEBUG块中,以便在Release模式中自动隐身。
#ifdef _DEBUG
#define MYDEBUG
#define VOLUMEDEBUG
#endif

当预编译变量很多时,也可以将以上内容单独做成一个头文件以导入
#include “DebugStuff.h”
#ifdef MYDEBUG
// Trace constructor calls
cerr << “/nDefault Name constructor called.”;
#endif

用预编译变量Controlling Free Store Debug Operations,可以自动检测内存泄漏
_CRTDBG_ALLOC_MEM_DF
When this bit is on, it turns on debug allocation so the free store state can be tracked.
_CRTDBG_DELAY_FREE_MEM_DF
When this is on, it prevents memory from being freed by delete, so that you can determine what happens under low-memory conditions.
_CRTDBG_CHECK_ALWAYS_DF
When this is on, it causes the _CrtCheckMemory()  function to be called automatically at every new and delete operation. This function verifies the integrity of the free store, checking, for example, that blocks have not been overwritten by storing values beyond the range of an array. A report is output if any defect is discovered. This slows execution but catches errors quickly.
_CRTDBG_CHECK_CRT_DF
When this is on, the memory used internally by the runtime library is tracked in debug operations.
_CRTDBG_LEAK_CHECK_DF
Causes leak checking to be performed at program exit by automatically calling _CrtDumpMemoryLeaks(). You only get output from this if your program has failed to free all the memory that it allocated.
默认的是只打开_CRTDBG_ALLOC_MEM_DF位,其它全部关闭。

可以用如下方式设置:
int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);              // Get current flag
flag |= _CRTDBG_LEAK_CHECK_DF;
flag &= ~_CRTDBG_CHECK_CRT_DF;
_CrtSetDbgFlag(flag);

或者直接:
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);

默认的free store调试的输出不是标准输出流,而是debug消息窗口,若想输出到stdout需要如下设置:
int _CrtSetReportMode(int reportType, int reportMode);
变量reportType如下:
_CRT_WARN
Warning messages of various kinds. The output when a memory leak is detected is a warning.
_CRT_ERROR
Catastrophic errors that report unrecoverable problems.
_CRT_ASSERT
Output from assertions (not output from the assert() function that I discussed earlier).

变量reportMode如下:
_CRTDBG_MODE_DEBUG
This is the default mode, which sends output to a debug string that you see in the debug window when running under control of the debugger.
_CRTDBG_MODE_FILE
Output is to be directed to an output stream.
_CRTDBG_MODE_WNDW
Output is presented in a message box.
_CRTDBG_REPORT_MODE
If you specify this, the _CrtSetReportMode() function just returns the current report mode.

可以用位操作符对以上位置符进行组合。
例示:CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);

此例仅仅设置输出目的地为文件流,仍需确定具体文件:
_HFILE _CrtSetReportFile(int reportType, _HFILE reportFile);
其中第二个参数是一个文件流的指针,可以为以下之一:
_CRTDBG_FILE_STDERR
Output is directed to the standard error stream, stderr.
_CRTDBG_FILE_STDOUT
Output is directed to the standard output stream, stdout.
_CRTDBG_REPORT_FILE
If you specify this argument, the _CrtSetReportFile() function will just return the current destination.
例示:_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);

抱歉!评论已关闭.