`
qinchong637
  • 浏览: 1892 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

代码调试经验之一

阅读更多
背景:好久之前的代码。用于在一些特定环境下辅助调试。
想调试代码,但又不想在release版本当中生产任何实际的代码,于是我写了如下的头文件:
调试时还是有点方便的,呵呵。
// DBG_HELPER.H
//  [4/14/2010]
// BY qinchong637#gmail.com
//////////////////////////////////////////////////////////////////////////
// 描述:
//     使用<<输出信息到控制台、文件、调试器。
// 设计目标:
//     本文件中的功能仅仅在_DEBUG下才有实际作用,在release版本下无任何作用
//     本文件中各种类、函数的release版本经过编译器优化后,无任何实际代码生成
// 
// _DBG_PROMPT : 当前代码行所在的文件和行号
// dbg2console : 将信息输出到控制台
// dbg2debugger : 将信息输出到调试器,目前仅在Windows下有效。
// dbg2file : 将信息输出到文件
// dbg2file_global : dbg2file的全局变量版本(然而并非线程安全,建议在程序初始化时就定义一个该类别的变量),这里采用的方法有待改进
// 注意:
//     1、在release版本中使用dbg2file_global会出现警告,是因为重载()时返回了一个临时变量的引用,
//     通常这会有潜在的危险,但这里可以忽略掉,编译器进行优化时这段代码会被去掉,不会生成任何实际的代码
//     2、输出指针所指对象时,需使用static_cast,否则会出现运行时错误,原因未明。如:dbg2file()<<*pInt; => dbg2file()<<static_cast<int>(*pInt);
//////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef _DBG_HELPER_H_QC637_FSEYE_HOTMAIL_528
#define _DBG_HELPER_H_QC637_FSEYE_HOTMAIL_528

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <tchar.h>

#ifdef WIN32
#include <windows.h>
#endif

#ifdef DBG_DEFAULT_MT_POLICY
	#pragma message("*** DBG_HELPER.H : Another DBG_DEFAULT_MT_POLICY defined anywhere alse and this maybe cause an error***")	
#else
	#ifdef _DBG_SINGLE_THREADED
	#define DBG_DEFAULT_MT_POLICY single_threaded
	#else
	#define DBG_DEFAULT_MT_POLICY multi_threaded
#endif

#endif

#define _DBG_FILE_VERSION _T("1.0.0")

#ifdef _DBG_PROMPT
	#pragma message("*** DBG_HELPER.H : Another _DBG_PROMPT defined anywhere else and this maybe cause a an error***")
#else
	#define _DBG_PROMPT __FILE__##<<_T(": ")<<__LINE__<<_T(": ")
#endif


// 有关UNICODE 的定义
#if defined _UNICODE
typedef std::wstring		tstring;
typedef std::wostringstream	tostringstream;
typedef std::wostream		tostream;
typedef std::wofstream		tofstream;
typedef std::wstringstream	tstringstream;

#define tcout				std::wcout
#else
typedef std::string			tstring;
typedef std::ostringstream	tostringstream;
typedef std::stringstream	tstringstream;
typedef std::ostream		tostream;
typedef std::ofstream		tofstream;

#define	tcout				std::cout
#endif

namespace dbg{

class single_threaded
{
public:
	single_threaded(){}
	virtual ~single_threaded(){}

	virtual void lock(){}
	virtual void unlock(){}
private:
};

#ifdef WIN32
class multi_threaded
{
public:
	multi_threaded(){
#ifdef _DEBUG
		static bool isinitialised = false;
		if (!isinitialised) {
			InitializeCriticalSection(get_critsec());
			isinitialised = true;
		}
#endif
	}

	multi_threaded(const multi_threaded &) {;}

	virtual ~multi_threaded(){}
	virtual void lock() {
#ifdef _DEBUG
		EnterCriticalSection(get_critsec());
#endif
	}

	virtual void unlock() {
#ifdef _DEBUG
		LeaveCriticalSection(get_critsec());
#endif
	}

private:
#ifdef _DEBUG
	CRITICAL_SECTION *get_critsec()
	{
		static CRITICAL_SECTION g_critsec;
		return &g_critsec;
	}
#endif
};
#endif	// end of WIN32

template<class mt_policy=DBG_DEFAULT_MT_POLICY>
class glock_dbg : public mt_policy
{

};

template<class mt_policy=DBG_DEFAULT_MT_POLICY>
class lock_block : public mt_policy
{
public:

	lock_block() {this->lock();}
	~lock_block() {this->unlock();}
};

// 
class dbg2console 
{
};

class dbg2debugger
{
};

#ifdef _DEBUG
	
class dbg2file_global;
class dbg2file 
{
public:
	dbg2file(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) 
	{
		// vc6 下UNICODE版本有问题,因为vc6的fstream中open不支持wchar_t
		ostr_.open(szFile, mode);
	}
	~dbg2file() 
	{
		if (ostr_.is_open()) {
			ostr_.close();
		}
	}

public:
	tofstream ostr_;
private:
	dbg2file() {}
	void open(const TCHAR *szFile, std::ios::openmode mode=std::ios::out)
	{
		ostr_.open(szFile, mode);
	}

	friend class dbg2file_global;
};

class dbg2file_global
{
public:
	dbg2file_global(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) 
	{
		static bool isinitialised = false;
		if (!isinitialised) {
			getInst().open(szFile, mode);
			isinitialised = true;
		}
	}
	~dbg2file_global() 
	{
	}

	dbg2file &operator()(){return getInst();}
private:
	static dbg2file& getInst()
	{
		static dbg2file ostr_;
		return ostr_;
	}
};

template<typename T>
inline dbg2file & operator <<(dbg2file &out, const T &obj)
{
	out.ostr_<<obj;
	return out;
}

template<typename T>
inline dbg2console & operator <<(dbg2console &out, const T &obj)
{
	tcout<<obj;
	return out;
}

template<typename T>
inline dbg2debugger & operator <<(dbg2debugger &out, const T &obj)
{
	tstringstream strs;
	strs<<obj;
	tstring str = strs.str();
	OutputDebugString(str.c_str());
	return out;
}


#else
// RELEASE VERSION
// Take the same interface as in the DEBUG version

class dbg2file 
{
public:
	dbg2file(const TCHAR *szFile, std::ios::openmode mode=std::ios::out|std::ios::app) 
	{
	}
	~dbg2file() 
	{
	}
};

class dbg2file_global
{
public:
	dbg2file_global(const TCHAR *szFile, std::ios::openmode mode=std::ios::out) 
	{
	}
	~dbg2file_global() 
	{
	}

	// have a warning here. but no problems.
	dbg2file &operator()(){return dbg2file(NULL, 0);}
private:
};

template<typename T>
inline dbg2file & operator <<(dbg2file &out, const T &obj)
{
	return out;
}

template<typename T>
inline dbg2console & operator <<(dbg2console &out, const T &obj)
{
	return out;
}

template<typename T>
inline dbg2debugger & operator <<(dbg2debugger &out, const T &obj)
{
	return out;
}

#endif // end of release version

}

#endif	// end of file

分享到:
评论

相关推荐

    html代码调试工具

    Firefox浏览器以其开源、安全和可扩展性著称,是开发人员常用的浏览器之一,因为它支持各种开发工具,如Firebug。 接下来,`firebug-1.4.5-fx.xpi` 是Firebug的扩展文件,它是Firefox的一个插件,允许用户在浏览器...

    PID算法原理、调试经验以及代码

    PID算法是一种广泛应用于工业自动化控制系统的反馈控制算法...通过理解其原理和积累调试经验,我们可以有效地运用PID来改善系统的稳定性和响应速度。在实际工程中,常常需要反复试验和调整参数,以达到最佳的控制效果。

    示例代码调试资源

    在IT行业中,编程和调试是核心技能之一,特别是在处理复杂任务如多线程和内存管理时。本资源包“示例代码调试资源”显然是为了帮助开发者理解和应用这些关键概念。让我们深入探讨一下“多线程”和“循环buffer”这两...

    c++的学习经验代码实例讲解及调试分析

    本文将基于个人的学习经验,结合源代码实例,探讨如何有效地学习C++,以及如何进行代码分析和调试。这些实例涵盖了不同的编程概念,包括基础语法、类与对象、模板、异常处理、内存管理等。以下是针对每个文件名称的...

    串口调试助手(MFC源代码)

    串口通信是计算机通信领域中的基本技术之一,广泛应用于各种设备间的数据交换。本篇将深入探讨“串口调试助手”这一基于MFC(Microsoft Foundation Classes)框架的源代码,通过VS2010开发环境,我们能够学习到如何...

    基于CSerialPort修改类的串口调试助手源代码

    本项目将原有的代码进行了调整,使之能在VS2013环境下顺利编译和运行。这通常涉及到更新项目配置、适应新的编译器标准和库版本,以及可能的代码结构优化。 压缩包中的"MSCOMM.sln"文件是Visual Studio的解决方案...

    AES.rar_AES_AES-128_AES代码调试通过_AES加密_c++ AES

    AES(Advanced Encryption Standard),即高级加密标准,是目前广泛使用的对称加密算法之一。它以其高效性和安全性,在数据保护、网络安全、软件开发等领域扮演着重要角色。AES是由NIST(美国国家标准与技术研究院)...

    用pdt 调试php代码

    3. **XDebug或Zend Debugger**:选择其中之一进行安装。 - **XDebug**:开源的PHP扩展,用于动态调试PHP脚本。 - **Zend Debugger**:由Zend Technologies提供的商业级PHP调试工具。 #### 三、配置PDT进行调试 #...

    Keil C的调试经验.rar_Keil调试_keil

    在IT行业中,嵌入式开发是一项重要的工作领域,而Keil C是许多开发者首选的嵌入式C语言编译器之一。本资料主要探讨的是如何有效地利用Keil C的调试功能,以提升开发效率和代码质量。以下是关于Keil调试的一些关键...

    delphi7编写的一个多功能串口调试软件源代码

    标题中的“delphi7编写的一个多功能串口调试软件源代码”揭示了这个资源是一个使用Delphi 7编程语言开发的串口通信调试工具。Delphi 7是Borland公司(后被Embarcadero Technologies收购)推出的一款集成开发环境...

    串口调试助手源程序(VC工程代码)

    串口通信是计算机通信领域中的基本技术之一,尤其在嵌入式系统、工业控制、物联网设备等应用中扮演着重要角色。本文将深入探讨“串口调试助手”的概念,以及通过VC++6.0编写的源程序,为读者提供一个理解和实践串口...

    Qt5 网络调试助手源代码 漂亮界面

    其次,Qt5的信号与槽机制是其核心特性之一,它简化了对象间的交互。在网络调试助手中,当网络事件发生时(如数据接收、连接状态变化),信号会被触发,对应的槽函数会执行相应的操作,这大大提高了代码的可读性和可...

    VIVADO网口调试代码

    在FPGA(Field-Programmable Gate Array)设计中,VIVADO是一款强大的开发工具,用于实现硬件描述语言(如Verilog或...同时,对于有经验的开发者,这个代码库可以帮助他们快速搭建和调试自己的网络功能,节省大量时间。

    idea远程调试代码(图文详细)

    相比之下,使用远程调试工具能够提供更高效、更准确的调试体验。本文将详细介绍如何使用IntelliJ IDEA(以下简称IDEA)进行远程调试。 #### 二、服务端配置 为了能够让远程服务器支持远程调试功能,我们需要在项目...

    软件调试修炼之道

    《软件调试修炼之道》鼓励开发者将调试视为一个学习和成长的机会,每一次成功的调试都意味着对问题的理解更加深入,对代码的掌控更加自如。在这个过程中,不断积累经验,提升技能,最终成为真正的软件开发大师。 ...

    TCP调试助手源码_tcp助手源码_TCP助手源代码_TCP助手源码_

    总之,TCP调试助手源码是一个宝贵的教育资源,无论是初学者还是经验丰富的开发者,都可以从中学习到TCP编程的精髓,加深对网络通信的理解,并能够运用到实际项目中解决各种问题。通过阅读和研究源代码,你将能够更...

Global site tag (gtag.js) - Google Analytics