Re: 驱动程序中Log的编写

Windows内核调试

驱动程序中Log的编写


holly 2008-08-11, 18:07 下午

最近调试驱动程序,以前写服务程序经常写一些Log的,在驱动中为了实现Log,着实让我头大了一回,不知道各位有什么经验可以分享。

设计了几个LogFile的操作函数,普通的驱动代码使用上没有什么问题,但是当驱动中使用了KeAttachProcess这样的进程上下文切换之后驱动会经常的兰屏,调试了几天才发现Log的影响,目前只能在使用KeAttachProcess前禁止Log,调用KeDetachProcess之后再次打开Log。

Log的写操作代码如下:

#define MAX_STRBUF_LENGTH 1024
BOOLEAN _cdecl WriteLine(HANDLE hLogFile, LPSTR lpszLine, ...)
{
 if(!g_bLogValid)
  return TRUE;
 va_list pParam;
 va_start(pParam, lpszLine);

 LPSTR lpszOutput = (LPSTR)ExAllocatePoolWithTag(NonPagedPool, MAX_STRBUF_LENGTH, 'FZM0');
 if(lpszOutput != NULL)
 {
  LARGE_INTEGER curTime;
  LARGE_INTEGER localTime;
  TIME_FIELDS  timeNow;

  KeQuerySystemTime(&curTime);
  ExSystemTimeToLocalTime(&curTime, &localTime);
  RtlTimeToTimeFields(&localTime, &timeNow);

  RtlZeroMemory(lpszOutput, MAX_STRBUF_LENGTH);
  RtlStringCbPrintfA(lpszOutput, MAX_STRBUF_LENGTH, "%04d-%02d-%02d %02d::%02d::%02d %04d ",
   timeNow.Year,
   timeNow.Month,
   timeNow.Day,
   timeNow.Hour,
   timeNow.Minute,
   timeNow.Second,
   timeNow.Milliseconds);

  ULONG nLen;
  RtlStringCchLengthA(lpszOutput, MAX_STRBUF_LENGTH, (size_t*)&nLen);

  RtlStringCbVPrintfA(lpszOutput+nLen, MAX_STRBUF_LENGTH-nLen, lpszLine, pParam);
  DbgPrint(lpszOutput);

  RtlStringCchLengthA(lpszOutput, MAX_STRBUF_LENGTH, (size_t*)&nLen);
  IO_STATUS_BLOCK ioStatusBlock;
  if(hLogFile != NULL)
  {
   ZwWriteFile(hLogFile, NULL, NULL, NULL,
    &ioStatusBlock, (PVOID)lpszOutput, nLen, NULL, NULL);
  }

  ExFreePoolWithTag(lpszOutput, 'FZM0');
  return TRUE;
 }
 return FALSE;
}

对于KeAttachProcess上下文切换影响什么不是很确定,贴出来抛砖引玉!


 

Re: 驱动程序中Log的编写


Coding 2008-08-12, 09:25 上午
我有类似的经历,DbgPrint和sprintf导致driver的stack fault。
大概的猜测是运行在过高的IRQL上,因为当我去掉在 Interrupt handle函数里面的Log语句以后,就没有问题了。

Re: 驱动程序中Log的编写


格蠹老雷 2008-08-12, 12:30 下午
在Windows驱动程序中可以用以下两种方法来写Log:
1)使用IoAllocateErrorLogEntry和IoWriteErrorLogEntry来写基于ELF的日志,在事件管理器中可以观察。
2)使用Vista新引入的CLFS。
如果你有《软件调试》,那么第15.3节(P412)和15.5节(P416-420)分别介绍了这两种方法。

Re: 驱动程序中Log的编写


holly 2008-08-12, 15:41 下午
谢谢Raymond的提示!
《软件调试》确实博大精深,目前还没有读到日志这个部分。
刚刚大致浏览了关键的几页,感觉我更需要的可能是ETW的部分,因为我的目的在于调试输出,和服务器程序的日志的事件记录不同。
不知道我的理解是否正确,再次感谢Raymond!

to Coding:
你说的情况有可能,不过如果能够确定是IROL级别影响的话,可以在WriteLog的部分增加对当前IRQL的判断来局部处理Log的代码,我还没有试过,回头也试下看。

Re: 驱动程序中Log的编写


holly 2008-08-20, 17:17 下午
经过一段时间的测试,在Log的写入代码中添加对IRQL的判断之后确实没有因为Log的问题再出现蓝屏。
看来如果需要全面的Log,仍需要采用Raymond的方法写日志或者ETW。

Re: 驱动程序中Log的编写


MJ0011 2008-09-25, 19:25 下午
学习

Re: 驱动程序中Log的编写


MJ0011 2008-10-03, 12:20 下午
IoAllocateErrorLogEntry太垃圾了,,,最多只能写255个字节啊。。。
CLFS又只有VISTA能用。。。

Re: 驱动程序中Log的编写


格蠹老雷 2008-10-04, 19:52 下午

很多驱动程序(包括微软自己的)使用ETW(Event Trace for Windows)来代替Log机制辅助调试,可以将信息以二进制形式输出给系统中的ETW消耗器。这种方法比上面说的两种Log都强大。但是因为它与传统意义的log有所不同,所以《软件调试》没有将其放入Log中讨论,前面回帖时也没有提。

顺便欢迎MJ0011光临本站。

Re: 驱动程序中Log的编写


ufphpc 2008-11-26, 13:46 下午
学习

Powered by Community Server Powered by CnForums.Net