格式化驱动输出日志

1、起因

一般在驱动中输出日志使用宏KdPrint,格式如下:

KdPrint(("******", ...));

这个只是在check版本下才输出日志,另外,这里不是手误,确实是需要两层括号。因为该宏如下:

#if DBG
#define KdPrint(_x_) DbgPrint _x_
#else
#define KdPrint(_x_)
#endif
多数时候,驱动开发时,在开发人员本地虚拟机或者实体机上才会连接内核调试。测试人员那边有问题,比如蓝屏了,拿回dump文件分析,或者编译一个check版本的驱动,使用DebugView查看输出日志(经常也需要查看ring3层程序日志定位流程问题)。这个时候经常会有一个头疼的问题,那就是日志太多了。
在ring3层,所有进程的输出,都会在DebugView里显示,特别是全局钩子,com组件一堆的时候,还有其他厂家的,也都在这里显示。(比如暴风影音,还有曾经遇到过一个网页代理软件,注入到浏览器进程里,疯狂的输出日志,一秒钟几十条日志)。

2、解决方式

通常使用过滤条件设置,有时候效果也不够好。比较方便的做法,是自己的日志,按照一定规则显示,比如日志内加上产品,模块信息,如下格式:
产品:模块:详细日志信息
这样,我们上层使用OutPutDebugString时(A或者W都行),可以格式化字符串如下格式:

OutPutDebugStringA("app:module:Create Socket Failed! error code = xxx\n");
通过设置产品过滤条件,能查看整个产品的输出日志,设置产品+模块过滤条件,能查看具体某个模块的日志。

驱动中也可以使用如下格式:

KdPrint(("drivername:some function ExAllocatePoolWithTag failed! error code = %08lX\n", errorcode));

这样后续解决问题方便了,但是无形中开发的工作加重了,特别是维护代码的开发者,在茫茫的代码中修改日志输出,也是已经很无聊的事情!于是写了宏,包括ring0和ring3,使用特别方便,甚至比以前还要便利些,至于以前代码转换,可以使用python之类的脚本语言工具,批量一键转换(略脚本代码)。

ring3层宏定义如下:

#define PRO_MODULE_NANE	"xxx:xxx:"		// 这里根据实际定义
#define ODS_BUFFER_SIZE 1024					// 缓冲大小

#define OutPutModuleNameString( _x_ ) PRO_MODULE_NANE ## _x_
#define xxOutPutDebugString( _x_ , ...) xxODS(OutPutModuleNameString( _x_ ), ##__VA_ARGS__)

// 这是一个函数
void xxODS(const char *szMsg, ... );

void xxODS(const char *szMsg, ... )
{	
	va_list marker;
	// 这个缓冲区,也可以使用全局(或static),但是后者非多线程安全
	char szTmp[ODS_BUFFER_SIZE] = {0};

	va_start( marker ,szMsg );  
	vsprintf(szTmp,szMsg, marker);
	va_end( marker );             	

	OutputDebugStringA(szTmp);	
}

// 比如如下调用:
WCHAR wszFileName[] = {L"wtest.dat"};
CHAR szFileName[] = {"test.dat"};
int icount = 100;

xxOutPutDebugString("wszFileName=%ws,szFileName=%s,count=%d\n", wszFileName, szFileName, icount);

ring0层宏定义如下:

#if DBG
#define xxModuleString(_x_) "xxx:" ## _x_
#define xxDbgPrint(_x_, ...) DbgPrint(xxModuleString(_x_), ##__VA_ARGS__)
#else
#define xxDbgPrint(_x_)
#endif

// 比如如下调用
xxDbgPrint("DriverEntry->IoCreateDevice failed! error code = %08lX\n", status);
 
  




你可能感兴趣的:(windows内核学习)