里维埃舰长级巡防舰:驱动调试输出

来源:百度文库 编辑:九乡新闻网 时间:2024/04/20 11:49:50
第一次接触并尝试写驱动程序,,,结果关于这个调试信息的查看让我折腾了好久。。。《windows驱动开发技术详解》书上说用KdPrint宏调来打印调试信息(实际是调用了DbgPrint()函数)。程序编译、链接均没问题,,但当我用drivermonitor打开helloDDK(for NT).sys的时候,只是显示“Load the driver successfully!”...并无打印信息(书上的截图确实有调试信息的出现)。然后换了种方法,开启dbgview后再加载驱动,dbgview仍然不显示任何信息。。。在OSR查了下资料,摘录如下:The problem: Your DbgPrint or KdPrint messages don't appear in WinDbg (or KD) when you run your driver on Windows Vista.The reason?  Vista automatically maps DbgPrint and friends to DbgPrintEx.  Now, you may recall that DbgPrintEx allows you to control the conditions under which messages will be sent to the kernel debugger by filtering messages via a component name and level in the function call and an associated filter mask in either the registry or in memory. In Vista, DbgPrint and KdPrint are mapped to component "DPFLTR_DEFAULT_ID" and level "DPFLTR_INFO_LEVEL".  Of course, in Vista, xxx_INFO_LEVEL output is disabled by default.  So, by default, your DbgPrint/KdPrint doesn't get sent to the kernel debugger. How to fix it? Two choices:Enable output of DbgPrint/KdPrint messages by default --Open the key "HKLM\SYSTEM\CCS\Control\Session Manager\Debug Print Filter".  Under this key, create a  value with the name "DEFAULT"  Set the value of this key equal to the DWORD value 8 to enable xxx_INFO_LEVEL output as well as xxx_ERROR_LEVEL output.  Or try setting the mask to 0xF so you get all output.  You must reboot for these changes to take effect.
Specifically change the component filter mast for DPFLTR.  In early releases of Vista/LH you changed the default printout mask by specifying a mask value for the DWORD at Kd_DPFLTR_MASK ("ed Kd_DPFLTR_MASK").  In build 5308 (the February CTP of Vista), it seems that the mask variable has changed and you need to set the mask value for the DWORD at Kd_DEFAULT_MASK ("ed Kd_DEFAULT_MASK).  In either case, specify 8 to enable DPFLTR_INFO_LEVEL output in addition to DPFLTR_ERROR_LEVEL output, or 0xF to get all levels of output.
See the WDK documentation for Reading and Filtering Debugging Messages (follow the path: Driver Development Tools\Tools for Debugging Drivers\Using Debugging Code in a Driver\Debugging Code Overview) for the complete details on the use of DbgPrintEx/KdPrintEx.  Or look at the Debugging Tools For Windows documentation (Appendix A) on DbgPrintEx. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 按以上方法添加了相应的项和键,键值填成8,重启后,依然不显示调试信息,于是后改称了0xf,还是不行- -,其实跟这个并无关系。。。  于是查了多方资料,通过查询DPFLTR_DEFAULT_ID最后在MSDN上查到了以下函数: 
The KdPrintEx macro sends a string to the kernel debugger if certain conditions are met.A call to KdPrintEx requires double parentheses.ULONG  KdPrintEx ( (    IN ULONG  ComponentId,    IN ULONG  Level,    IN PCHAR  Format,    . . . .  [arguments]     ) ) ;Parameters
ComponentId
Specifies the component calling this routine. This must be one of the component name filter IDs defined in the Ntddk.h Windows Driver Kit (WDK) header file. To avoid mixing your driver's output with the output of Windows components, you should use only the following values for ComponentId:
DPFLTR_IHVVIDEO_ID
DPFLTR_IHVAUDIO_ID
DPFLTR_IHVNETWORK_ID
DPFLTR_IHVSTREAMING_ID
DPFLTR_IHVBUS_ID
DPFLTR_IHVDRIVER_ID Level
Specifies the severity of this message. This can be any 32-bit integer. Values between 0 and 31 (inclusive) are treated differently than values between 32 and 0xFFFFFFFF. For details, see Reading and Filtering Debugging Messages.
Format
Specifies a pointer to the format string to print. The Format string supports all the printf-style formatting codes. However, the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, and %wZ) can only be used with IRQL = PASSIVE_LEVEL.
arguments
Specifies arguments for the format string, as in printf. Return Value
If successful, KdPrintEx returns the NTSTATUS code STATUS_SUCCESS; otherwise, it returns the appropriate error code.Comments
KdPrintEx is identical to the DbgPrintEx routine in code that is compiled in a checked build environment. This routine has no effect if compiled in a free build environment. Only kernel-mode drivers can call the KdPrintEx routine.KdPrintEx either passes the specified string to the kernel debugger or does nothing at all, depending on the values of ComponentId, Level, and the corresponding component filter masks. For details, see Reading and Filtering Debugging Messages.Unless it is absolutely necessary, you should not obtain a string from user input or another process and pass it to KdPrintEx. If you do use a string that you did not create, you must verify that this is a valid format string, and that the format codes match the argument list in type and quantity. The best coding practice is for all Format strings to be static and defined at compile time.There is no upper limit to the size of the Format string or the number of arguments. However, any single call to KdPrintEx will only transmit 512 bytes of information. There is also a limit to the size of the DbgPrint buffer. See The DbgPrint Buffer and the Debugger for details.Requirements
Versions: Available in Microsoft Windows XP and later.Headers: This routine is defined in ntddk.h and ndis.h; component filter IDs are defined in ntddk.h, ndis.h, and wdm.h. Include ntddk.h or ndis.h.
See Also
DbgPrint, DbgPrintEx, KdPrint------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------源代码相应的作出了改变,依然不行。。。(快吐血了...),一开始是觉得自己参数输入不正确,但一一对应过后发现参数输入并无问题。。。最后问题却出在了KdPrintEx()宏中需要对字符串再加一对括号(这个错误确实很囧)。。。于是干脆全部换成了DbgPrintEx()函数(书上说应该尽量调用宏,因为调用宏能够在Check版中显示调试信息,在Free版中能够隐藏调试信息,而直接调用DbgPrintEx()两个版本均显示调试信息)本已为差不多了,,结果却发现了两个link error!!~~其中一个说是 error LNK2019: unresolved external symbol __imp__DbgPrintEx
      referenced in function _DriverEntry@8.. 
一看是obj内的问题,一开始认为是缺少某个lib文件,但想了下,既然编译成功,不可能缺少相应的库文件啊。。。在https://www.osronline.com/showthread.cfm?link=130218下找到了这个问题答案:Link against ntoskrnl.lib, not wdm.lib (by removing DRIVERTYPE=wdm in your sources). DbgPrintEx is not a WDM function. 原因如下:
WDM is a subset of the NT driver model as snapshotted by win9x releases over time, ending with WinME. Since win9x is no longer supported or released, the idea of WDM in terms of cross OS compat is no longer relevant. What remains of WDM is the name and the overall model, even if it is only supported by one OS family. WDM itself in terms of APIs has grown, but wdm.lib has not kept pace b/c it still matches the win9x subset of WDM. Any driver which targets win2k and beyond should really just link against ntoskrnl.lib
在sources中将DRIVERTYPE=WDM删掉后,发现编译成功了!!!原来是因为当指定驱动类型为WDM后源程序会调用wdm.lib,而DbgPrintEx()是winNT以上的OS才支持的函数,wdm.lib自win9X后并无扩展,因此没有DbgPrintEx()。。所以链接器提示找不到DbgPrintEx()...当我兴奋的打开dbgView的时候发现,,还跟以前一样。。。一片空白!!!查询了dbgview的使用手册后发现自己的使用方法并无错误啊。。。于是闲着无事用build工具上vista相应的X86 check版本的build,编译成功后,抱着尝试心态看了下DbgView...所有的调试信息均打印出来了!!!(天呐~~~感动啊)但是,遗留了一个问题:用vista相应的X86 check版本的build成功编译NT程序,,加载后不但没有调试信息,反而蓝屏!在OSR上下载了一个工具,用来修改相应的调试信息过滤器的属性(之前改过没成功),该工具有两个版本,wlh和wxp版本,之前的成功是因为我使用的是wlh版本的工具来修改键值,但NT驱动却蓝屏了(代码应该没问题),后来尝试着用该工具的wxp版本,reboot后重新用xp下的build工具重新编译了一下,成功看到wdm的调试信息。但nt调试信息仍然没出来。。。不懂为什么自己添加键的时候没成功,而用了它的工具后就可以了,,应该是自己添加错误了吧。随后尝试着将NT驱动源代码下的DbgPrintEx()改称DbgPrint(),用monitor加载,,成功看到调试信息!!!总结如下:1、win7/vista下确实需要修改调试信息过滤的键值(不知道我为什么没成功- -),而且该修改竟然存在wxp和wlh两个版本(网站上并无说明)。如果自己修改不成功可以借助别人做的工具。2、修改过键值后,DbgPrintEx()函数用于WDM驱动调试信息的编写,而DbgPrint()函数用于NT驱动。3、关于DbgPrintEx()在WDM驱动源代码下有时会无法链接成功的问题,上面已有说明,解决方法是将“DRIVERTYPE=WDM”一句删掉。4、关于build工具,使用不同版本要配合相应的键值的修改,这样才能成功打印调试信息。目前存在的问题:1、编程成功NT驱动后(用DbgPrint()的情况下),尽管DbgView能看到调试信息,monitor上却看不到。2、用vista相应的X86 check版本的build工具编译出来的NT驱动,加载后蓝屏。问题还在探索中......最后,,总结出来一句话:书始终是过时的,要对相应的知识进行相应的环境变更,这样才能取得更快的进展。。。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xw_1120/archive/2009/12/22/5055030.aspx