创建简单调试器类的第一步
这个类可以让你了解如何制作自己的调试类。
引言
通常,程序员大约 80% 的时间都花在调试代码上。这表明调试的重要性。通常,MSVC++ 提供了优秀的调试器以及调试 API,但它存在一些限制。例如,你无法拥有像 printf
这样的调试打印函数。
背景
为了辅助调试,任何开发者都可以创建自己的调试类,其中包含执行任何所需功能的函数。作为实现这一目标的第一步,我开发了 DBG
类,其中包含两个对调试有用的函数:
DbgPrint()
,它像printf()
一样用于打印,以及GetLinkageLog()
,它将所有内存链接记录到调试窗口。
这两个函数都使用了 MSVC++ 调试 API。你可以修改这些函数,或者从这里提供的代码开始定义你自己的函数。
Using the Code
debug.zip 文件可以从上面的链接下载,其中包含两个文件:debug.h 和 debug.cpp。要使用它们,只需将这两个文件添加到你的项目的头文件和源代码目录中,并在你的项目的 stdafx.h 中添加 #include "debug.h"
指令。
在 debug.h 中,我已经添加了必要的定义和包含文件以启用调试。DBG
类声明如下:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define PRINT_SIZE 100
class DBG
{ char* strPrint;
int ptr;
public:
DBG()
{
strPrint = new char [ PRINT_SIZE ];
ptr = 0;
}
~DBG()
{
delete strPrint;
}
void GetLinkageLog( );
void DbgPrint( char *str , ... );
};
要使用 DBG
类,你只需创建该类的对象并使用其函数。以下是一些简单的代码片段,说明了如何使用 DBG 类:
#define SERVER_PORT 12345
#define BUF_SIZE 100 // block transfer size
#define QUEUE_SIZE 10
int _tmain(int argc, _TCHAR* argv[])
{
int b, l, on = 1;
char recvbuf<buf_size> = { };
SOCKET s, sa;
struct sockaddr_in channel; // holds IP address
WORD wVersionRequested;
WSADATA wsaData;
int err;
int bytesRecv;
DBG obj;
obj.DbgPrint( "MAIN : %d ", 1 );
//--- INITIALIZATION -----------------------------------
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
printf("WSAStartup error %ld", WSAGetLastError() );
WSACleanup();
return false;
}
//------------------------------------------------------
char* a = new char [ 50 ] ;
obj.GetLinkageLog( );</buf_size>
请注意,我的 DbgPrint()
只支持 %d
、%c
、%s
和 %f
格式说明符,因为我只在 DbgPrint()
函数的 union
和 switch
语句中定义了这些,如下所示。当然,你可以轻松添加其他格式说明符或删除任何不需要的说明符。
#include "stdafx.h"
void DBG::DbgPrint( char* str, ... )
{
va_list vl;
int i;
char* temp = this->strPrint;
// str is the last argument specified; all
// others must be accessed using the variable-
// argument macros.
va_start( vl, str );
// Step through the list.
for( i = 0; str[i] != '\0'; ++i ) {
union Printable_t {
int d;
float f;
char c;
char *s;
} Printable;
switch( str[i] ) { // Type to expect.
case '%' :
switch( str[++i] ) {
case 'd':
Printable.d = va_arg( vl, int );
this->ptr = sprintf ( temp, "%d", Printable.d );
temp = temp + this->ptr ;
break;
case 'f':
Printable.f = va_arg( vl, double );
this->ptr = sprintf ( temp, "%f", Printable.f );
temp = temp + this->ptr ;
break;
case 'c':
Printable.c = va_arg( vl, char );
this->ptr = sprintf ( temp, "%c", Printable.c );
temp = temp + this->ptr ;
break;
case 's':
Printable.s = va_arg( vl, char * );
this->ptr = sprintf ( temp, "%s", Printable.s );
temp = temp + this->ptr ;
break;
default:
break;
}
break;
default:
this->ptr = sprintf ( temp, "%c", str[i] );
temp = temp + this->ptr ;
break;
}
}
OutputDebugString( this->strPrint );
va_end( vl );
}
关注点
以这里提供的代码为起点,任何感兴趣的人都可以创建自己的调试类。