在Windows高效排错中提到了调试重定向。书中没有详细介绍。今天恰好有机会在虚拟机上从头开始配置了一下,所以把详细的内容记录在这里,算是补充。
文章本身使用英文写的。由于书中是用中文,所以又不得不用中文自己翻译自己一遍。我日,自己翻译自己的东西,感觉太别扭了。
另外我也是被CSDN的编辑逼到绝路了,总算逼出一篇新的文章。我理解新书需要在blog上多多宣传和介绍,才能让潜在的读者在购买前有具体的了解,以便让适合的读者找到书,让不适合的读者不要浪费钱。但是我的blog都是在MSN Space上,我也实在不想把以前所有的blog都一个一个搬过来。原因在于我在MSN Space上的blog,虽然技术上是证据确凿,真实有效,但是语言上是很随便的,里面的好多语言放在技术网站上怕引人误会。如果读者需要了解书中的大体内容,可以参考下这些资料:
1.书中所有外部连接的索引。从这个索引上,读者可以大致看到书中所包含的知识面和深度
http://blog.csdn.net/eparg/archive/2007/09/19/1792015.aspx
2.Blog中的文章。里面讨论了一些技术问题和调试方法,都是跟书中的内容密切相关的。
3.Windows高效排错PDF文档。这个PDF文档其实是这本书的前身。我把这个PDF整理后,就成了这本书的第一章
http://blogs.msdn.com/lixiong/articles/687510.aspx
4.这本书的目录草稿。链接在:
http://blog.csdn.net/eparg/archive/2007/10/11/1820806.aspx
1.Run msconfig and enables kernel debug in the VM OS:
这里以Windows Server 2008作为目标系统演示。首先在虚拟机中运行msconfig,然后如图配置,激活debug,并且把debug输出到COM1口。
2.In the properties pages of Virtual Machine, redirect the COM1 to a named pipe
在对应的虚拟机设定中,把COM1口重定向到物理机器的named pipe。
3.In the host machine, use the following command to start kd:
kd -k com:pipe,port=\\.\pipe\newtoolpipe,resets=0,reconnect
接下来就可以在物理机器中用
kd -k com:pipe,port=\\.\pipe\newtoolpipe,resets=0,reconnect
命令连接到kd了。
4.Restart the Virtual Machine, the kd session will be active. Then you can perform the kernel debugging.
这个时候重新启动虚拟机,物理机的kd连接就会自动开始,接下来就可以进行kernel debug了
Under kernel debugger session, you are able to perform the followings:
在kernel debug会话中,可以进行如下操作。
1.When the kernel debugger session is attached, the target OS is running by default. At this time, the debugger ignores any input. If the target OS is running, there is no command prompt in the debugger session. Like the following:
当kernel debugger加载的时候,目标操作系统默认情况下是不会挂起的。这个时候,调试器会忽略调试输入。同时调试器没有调试符出现。如图
2.To perform the kernel debugging, you need to breakin the debugger to stop the OS. In debugger session, type ctrl+C or ctrl+break. If ctrl+C closes the debugger session, you just need to rerun the same kd command to reconnect. When the kernel debugger breaks in, it shows kd> as the prompt and you are able to input kernel debug command. At this time, the target OS halts:
如果要进行kernel debug,首先应该挂起目标机器。在调试器会话中,通过ctrl+C或者ctrl+break可以做到。如果不小心把调试会话也连同关掉了,只需要重新运行上面的kd命令就可以重新打开。当目标机器被kd挂起后,调试器的提示符变成kd>。这个时候可以输入kernel调试命令了。
3.To resumes the execution, just type command “g” in debugger. Then the OS continues to run, and the kd> prompts disappears.
如果要恢复执行,直接通过g命令就可以。这个时候目标OS恢复执行,kd>提示符消失。
4.To redirect user mode debugging session in to kernel debugger, you need to use “ntsd” with “–d” parameter. The following demo shows how to redirect a user mode notepad debugging session into kernel.
如果要重定向用户态调试到核心态,需要在目标机器中使用用户态调试程序ntsd,加上-d参数。下面的demo演示了如何把notepad的调试冲定向到核心态。
5.In VM, starts notepad.exe. Then use “ntsd –d –pn notepad.exe” to start the user mode debug, and redirects the debug session into kernel debugger. After you type the command in VM, both the notepad.exe and the VM OS stops. In kernel debugger session, the user mode debug output shows, and the prompt turns to 0:001>. Then you are able to type user mode debug command like thread switching.
首先在VM中启动notepad,然后用ntsd –d –pn notepad.exe 启动用户态调试,-d参数重定向调试到核心态。当摁下ntsd命令的回车后,notepad和目标OS都会同时挂起。在调试会话中,会看到用户态调试的输出,以及用户态调试器的提示符0:000>。这个时候可以输入用户态调试命令进行调试。虚拟机和调试会话的截图如下。
VM:
Debug session:
6.When the debug session is stopped by user mode, there are three options to switch the status.
Option 1 is to use “g” command to resume both the user mode application and the OS.
Option 2 is to use “.breakin” command to switch from user mode debug into kernel mode debug. If you want to switch back from kernel mode debug into user mode debug, use “g” command.
Option 3 is to use .sleep command to get into sleep mode.
For detailed explanation about the context switching, please refer to windbg’s help file, in “Controlling the User-Mode Debugger from the Kernel Debugger” section.
当调试会话处于用户态模式下,有三种切换选择
首先可以用g命令恢复用户态程序和目标OS的执行。
其次可以用”.breakin”命令从用户态切换到核心态。如果想从核心态切换回原来的用户态,直接输入”g”命令就可以
第三种选择是.sleep命令。
关于上面三种模式的切换,详细信息请参考windbg帮助文件中的” Controlling the User-Mode Debugger from the Kernel Debugger”
7.I use “g” to resume the notepad execution, and then close the notepad application. It triggers the process exit debug event, and breaks into user mode again. If I try to use “g” command to continue, it shows “No runnable debuggees error” because the notepad process is dying. Here to resume the execution, we need to use “q” command.
这里我通过g命令恢复notepad的执行。然后关闭notepad程序。于是notepad的process exit debug event就会触发,同时切入到调试器。这个时候如果试图用”g”命令,得到的结果是” No runnable debuggees error”,原因是notepad程序正在退出,无法g执行了。这个时候可以直接用q命令退出用户态调试,恢复OS的执行。
Above example shows how to setup user mode redirection debug. However, the major question is not about how to do that, it is “why we need to debug user mode application in kernel session?”
上面的步骤演示了如何设定核心态调试,如何重定向用户态调试。但是问题的关键不在于如何做,而是在于为何需要把用户态程序重定向到核心态?
1.For some of the user mode application, it is not convenient to use normal user mode debugger to check. Examples are Windows Services, WinLogon session, and other user mode processes start before Windows Desktop/User session is ready. For such applications, the problem occurs before Windows user interface is ready, there is no way for you to start normal user mode debugger.
Besides redirecting to kernel mode, another way is available here:
How to debug Windows services
http://support.microsoft.com/kb/824344
对某些用户态的程序来说,并不是可以方便地启动普通用户态调试器进行调试。比如Windows Services, WinLogon进程,以及其它先于Windows桌面和用户界面模块启动的进程。对于这样的程序来说,由于需要调试的时机先于用户态界面,就无法启动普通的用户态调试器进行调试。
对于这类程序,除了通过调试重定向外,另一种方便的调试方法是:
How to debug Windows services
http://support.microsoft.com/kb/824344
2.For some of the core application, normal user mode debugging may cause deadlock. An example is lsass.exe process, which is the user mode process for Windows Authentications. As you know, debugging requires authentication. When attaching to lsass.exe process, the OS requires lsass.exe process to perform authentication, but the lsass.exe is being debugged and halted…… In earlier version of Windows, debug redirection is the only way to solve the issue. In current version, normal user mode debugger works well for lsass.exe. Even there might be some confliction, another good way to solve is to use dbgsrv:
Debugging LSASS ... oh what fun, it is to ride..
http://blogs.msdn.com/spatdsg/archive/2005/12/27/507265.aspx
对于某些系统模块来说,直接使用用户态调试器进行调试,可能导致死锁。比如lsass.exe进程是控制Windows认证的用户态进程。调试程序本身需要一定权限,也是要进行认证的。如果用用户态进程调试lsass.exe,首先需要认证,但是管理认证的进程又是正在被调试的lsass.exe…… 在Windows的早期版本中,调试重定向是解决这个问题的唯一办法。在现在的Windows中,普通的用户态调试器在大多数情况下也能直接调试lsass.exe。如果遇上死锁,除了用重定向外,最新的Windbg还支持另外一种解决办法:
Debugging LSASS ... oh what fun, it is to ride..
http://blogs.msdn.com/spatdsg/archive/2005/12/27/507265.aspx
3.If you need to monitor both kernel and user mode issues, combining them into a single session is the most convenient way.
如果需要同时监视用户态程序和核心态的问题,把两者合在一起显然是一种很好的办法。
There are some experiences on using this technique:
使用这种调试方法的一些经验:
1.If you want to redirect user mode debug for some process automatically, you can modify the following key “Image File Execution Options” regkey, which supports debugger auto attach. For example, you can create “notepad.exe” subkey, and create a string value named debugger, the value is “C:\debugger\ntsd.exe –d”. Then everytime notepad starts, the debugger is auto attached and redirected. If you want to ignore the initial and final auto break-in, you can add “–g” and “–G” options.
如果需要对某些用户态进程进行自动重定向,而不是每次都运行ntsd,可以通过修改“Image File Execution Options”完成。比如建立notepad子键,创建字符串键值,名称为debugger,值为” C:\debugger\ntsd.exe –d”。这样每次notepad启动的时候,ntds就会自动启动进行重定向。如果需要忽略进程每次启动和结束时候的调试事件,可以加上-g和-G参数。
2.For user mode debugging, you can always use .dump command to save the dump file to analyze if you do not feel the kernel session comfortable.
对于用户态态调试,如果觉得在kernel session中不方便,可以通过.dump命令把用户态dump保存下来,然后用普通的用户态调试器检查。