WindowsGuestDrivers/UpdatedGuestDebugging: Difference between revisions

From KVM
mNo edit summary
No edit summary
 
(11 intermediate revisions by 2 users not shown)
Line 28: Line 28:
<br><tt><nowiki>c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols</nowiki></tt> 
<br><tt><nowiki>c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols</nowiki></tt> 


====About the 3 different symbols====
{| border="1"
{| border="1"
  |'''symbol '''
  |'''symbol '''
Line 49: Line 48:
You can also add that into a *.bat file and create symbols automatically when every building.
You can also add that into a *.bat file and create symbols automatically when every building.


====Run Kernel Debug====
====Run WinDbg====
Then <tt>File->Kernel Debug...</tt> or <tt>[Ctrl+k]</tt> select <tt>COM</tt> tab and set <tt>Baudrate</tt> to 115200 and set port to <tt>COM1</tt>,confirm and wait the target to connect.
Then <tt>File->Kernel Debug...</tt> or <tt>[Ctrl+k]</tt> select <tt>COM</tt> tab and set <tt>Baudrate</tt> to 115200 and set port to <tt>COM1</tt>,confirm and wait the target to connect.
===Setting up the target VM===
===Setting up the target VM===
Line 57: Line 56:
Add <tt>-serial tcp:127.0.0.1:4445</tt> to connect to the host by virtual serial,port is same to the server.
Add <tt>-serial tcp:127.0.0.1:4445</tt> to connect to the host by virtual serial,port is same to the server.
<br>When start up,if Windows XP,2003 or 2000,edit <tt>c:\boot.ini</tt> and duplicate the default boot line,at the end of the duplicated boot line add
<br>When start up,if Windows XP,2003 or 2000,edit <tt>c:\boot.ini</tt> and duplicate the default boot line,at the end of the duplicated boot line add
<tt>/debug /debugport=COM1 /baudrate=115200</tt>.
<br><tt>/debug /debugport=COM1 /baudrate=115200</tt>.
<br>The baudrate and debugport must be identical to kernel mode configure of WinDbg.
<br>The baudrate and debugport must be identical to kernel mode configure of WinDbg.
<br>If Windows7,Vista or up,you must use <tt>BCDedit</tt>(ref:http://technet.microsoft.com/en-us/library/cc709667%28WS.10%29.aspx  and http://msdn.microsoft.com/en-us/library/ff542187.aspx ).
<br>If Windows7,Vista or up,you must use <tt>BCDedit</tt>(ref:http://technet.microsoft.com/en-us/library/cc709667%28WS.10%29.aspx  and http://msdn.microsoft.com/en-us/library/ff542187.aspx ).
Line 65: Line 64:
=Debug=
=Debug=
When Host and target setup completely,restart the target virtual machine and select the DEBUG boot option in the boot menu.
When Host and target setup completely,restart the target virtual machine and select the DEBUG boot option in the boot menu.
<br>Then WinDbg on host will try to connect to the windows guest(target) kernel to debug.
<br>You can <tt>Ctrl+Break</tt> or use the <tt>Pause</tt> button to break the guest running and also you can do anything which the debug tool support.
==About WinDbg==
==About WinDbg==
WinDbg is a multi-purposed debugger for Microsoft Windows, distributed on the web by Microsoft. It can be used to debug user mode applications, drivers, and the operating system itself in kernel mode.
WinDbg is a multi-purposed debugger for Microsoft Windows, distributed on the web by Microsoft. It can be used to debug user mode applications, drivers, and the operating system itself in kernel mode.
<br>Then WinDbg on host will try to connect to the windows guest(target) kernel to debug.
 
<br>You can <tt>Ctrl+Break</tt> or use the <tt>Pause</tt> button to break the guest running and also you can do anything which the debug tool support.


==Compile and build==
==Compile and build==
Line 78: Line 78:
  #include "virtio_test_utils.h"
  #include "virtio_test_utils.h"


VOID DriverUnload(IN PDRIVER_OBJECT DeviceObject);
VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject );


    ULONG; DriverEntry( IN PDRIVER_OBJECT&; DriverObject, IN PVOID; RegistryPath ) {
ULONG DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PVOID RegistryPath ) {
     ULONG initResult = 0;
     ULONG initResult = 0;


Line 90: Line 90:
}
}


VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject ){
VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject ) {
     DbgPrint("Driver Unload successfully\! \n");
     DbgPrint("Driver Unload successfully\! \n");
}
}
Line 102: Line 102:


<tt>viotest>build -cCzg</tt>
<tt>viotest>build -cCzg</tt>
[[Image:build.png]]


After build completely,the driver(<tt>viotest.sys,viotest.inf</tt>) will be exported into the <tt>...\viotest\objchk_wxp_x86\i386\</tt>.
After build completely,the driver(<tt>viotest.sys,viotest.inf</tt>) will be exported into the <tt>...\viotest\objchk_wxp_x86\i386\</tt>.
Line 121: Line 122:
<br>Meanwhile,the WinDbg will hit the breakpoint at <tt>viotest.c:DriverEntry()</tt>.
<br>Meanwhile,the WinDbg will hit the breakpoint at <tt>viotest.c:DriverEntry()</tt>.
<br>And the related source file will be opened to view.
<br>And the related source file will be opened to view.
<br>You can see the breakpoints position with highlight label in the source code and watch the variables value,check the callstacks etc. All behaviors of WinDbg are similar to other debuggers.
<br>You can see the breakpoints position with highlight label in the source code
[[Image:breakpoint.png]]
also can watch the variables value,check the callstacks etc. All behaviors of WinDbg are similar to other debuggers.
[[Image:variable.png]]
[[Image:stack.png]]
<br>The debug message will be show in the WinDbg.
<br>The debug message will be show in the WinDbg.


Line 138: Line 143:
==Other Debug Method==
==Other Debug Method==
* Using Debug message(print):
* Using Debug message(print):
The message can be viewed by another tool [http://technet.microsoft.com/en-us/sysinternals/bb896647 DebugView],it can be used in target guest(without WinDbg) only environment to debug the driver with the <tt>DbgPrint()</tt> debug message.  
:The message can be viewed by another tool [http://technet.microsoft.com/en-us/sysinternals/bb896647 DebugView],it can be used in target guest(without WinDbg) only environment to debug the driver with the <tt>DbgPrint()</tt> debug message. It is also a available method to debug the driver.
It is also a available method to debug the driver.


* Using crash dump (kernel memory dump)with WinDbg
* Using crash dump (kernel memory dump)with WinDbg
TBD.
 
:''TBD.''
 


==Problems may be encountered==
==Problems may be encountered==
Line 152: Line 158:


=References=
=References=
*1).[[GuestDebugging]] 
*1).[[WindowsGuestDrivers/GuestDebugging | Guest Debugging]] 
*2).http://msdn.microsoft.com/library/windows/hardware/gg507680 
*2).http://msdn.microsoft.com/library/windows/hardware/gg507680 
*3).Debugging tools for Windows HELP
*3).Debugging tools for Windows HELP

Latest revision as of 14:29, 13 November 2011

Introduction

This page mainly introduce HOWTO use WinDbg to debug windows guest driver based on qemu.

Setup

To debug windows guest in kernel mode,we generally need a host computer as a remote debugger which runs the WinDbg and a target computer as a debuggee.

Connection between the host and target

To allow debug windows guest kernel on QEMU,we have to connect the two virtual machines by using a virtual non-modem serial cable.The QEMU serial redirection ability can help us. The simplest way is creating two windows guest virtual machines (one host,the other as target)on a same physical machine. It is feasible that the host virtual machine and target run on two different physical machines by connecting the virtual serial cable via TCP.

Setting up the host and target virtual machine

Setting up the host VM

start the host VM and install Windbg

/usr/local/bin/qemu-system-x86_64 \--enable-kvm \-m 1024 \-drive file=win-host.img \-chardev stdio,id=mon0 \-mon chardev=mon0 \-serial tcp::4445,server,nowait

Add the -serial tcp::4445,server,nowait to enable the serial redirection ability.The port number 4445 can be any valid tcp port.
Using the server option and nowait option QEMU opens a port which a client socket application can connect to it,the host will continue running without any wait.
After startup,get and install the latest version of the Debugging Tools for Windows.Get them from the website:http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx  or a ISO image file.
You may need restart the host virtual machine to complete the installation. When debugging a windows driver especially kernel-mode driver,symbols typically should be installed.

Set Symbols path

You can set symbols file path by File->Symbol File Path...or [Ctrl+S].

c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols

also by add windows system environment variable _NT_SYMBOL_PATH,set the value to:
c:\symbols\local_symbols;c:\driver\symbols;SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols

symbol info
*SRV*c:\symbols\websymbols*http://msdl.microsoft.com/download/symbols* If symbols not found in local symbols,the WinDbg will automatic download symbols from the URL address http://msdl.microsoft.com/download/symbols . And the symbols download will be stored in the directory: c:\symbols\websymbols
c:\symbols\local_symbols The symbols of current windows version.They can be acquired by website: http://msdn.microsoft.com/en-us/windows/hardware/gg463028
c:\driver\symbols This mean the symbols(*.pdb files) will be produced after build process of the driver. We can use the WinDDK debugging tool symstore.exe to create own symbols server.

Creating local symbols server

C:\WinDDK\7600.16385.1\Debuggers>symstore.exe add /r /f C:\development\virtio-test\kvm-guest-drivers-windows\viotest\objchk_wxp_x86\i386 /s C:\driver\symbols\ /t "DriverSymbols" /v "1.0"

You can also add that into a *.bat file and create symbols automatically when every building.

Run WinDbg

Then File->Kernel Debug... or [Ctrl+k] select COM tab and set Baudrate to 115200 and set port to COM1,confirm and wait the target to connect.

Setting up the target VM

/usr/local/bin/qemu-system-x86_64 \--enable-kvm \-m 1024 \-drive file=win-target.img \-chardev stdio,id=mon0 \-mdev=mon0 \-serial tcp:127.0.0.1:4445

Add -serial tcp:127.0.0.1:4445 to connect to the host by virtual serial,port is same to the server.
When start up,if Windows XP,2003 or 2000,edit c:\boot.ini and duplicate the default boot line,at the end of the duplicated boot line add
/debug /debugport=COM1 /baudrate=115200.
The baudrate and debugport must be identical to kernel mode configure of WinDbg.
If Windows7,Vista or up,you must use BCDedit(ref:http://technet.microsoft.com/en-us/library/cc709667%28WS.10%29.aspx  and http://msdn.microsoft.com/en-us/library/ff542187.aspx ).
Change the boot opition:
bcdedit /dbgsettings SERIAL \[DEBUGPORT:COM1\] \[BAUDRATE:115200\]

Debug

When Host and target setup completely,restart the target virtual machine and select the DEBUG boot option in the boot menu.
Then WinDbg on host will try to connect to the windows guest(target) kernel to debug.
You can Ctrl+Break or use the Pause button to break the guest running and also you can do anything which the debug tool support.

About WinDbg

WinDbg is a multi-purposed debugger for Microsoft Windows, distributed on the web by Microsoft. It can be used to debug user mode applications, drivers, and the operating system itself in kernel mode.


Compile and build

We first create a simple windows driver for test,it is named viotest and added in the kvm-windows-guest-driver project to maintain. The source code:

#include "virtio_test.h"
#include "virtio_test_utils.h"

VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject );

ULONG DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PVOID RegistryPath ) {

   ULONG initResult = 0;
   DbgPrint("Viostor driver started...built on %s %s\n", \__DATE__, \__TIME__);
   DriverObject->DriverUnload = DriverUnload;
   DbgPrint("Initialize returned 0x%x\n", initResult);
   return initResult;

}

VOID DriverUnload( IN PDRIVER_OBJECT DeviceObject ) {

   DbgPrint("Driver Unload successfully\! \n");

}

Add Makefile and SOURCES file into the project The driver only include DriverEntry(),DriverUnload() and some message print. The driver is not related to any specific device. All the simplification are done in order to increase the convenience of debug.

Then using WinDDK build tool to build the driver,I use the "Windows XP x86 checked build".

viotest>build -cCzg Build.png

After build completely,the driver(viotest.sys,viotest.inf) will be exported into the ...\viotest\objchk_wxp_x86\i386\.

Load,install and debug the driver

After the process mentioned below,we copy the viotest directory to the target guest. HOST: WinDbg is now running in the host guest. We Ctrl+Break to pause the debugger,and set breakpoints:

kd> bu !viotest:DriverEntry
kd> bu !viotest:DriverUnload

You can use "bl" to watch breakpoints set.
F5,continue.
Using tool [DriverStudio] to load,start,stop the driver on target. File->Open select the viotest.sys, and then start (Go)the driver.
Meanwhile,the WinDbg will hit the breakpoint at viotest.c:DriverEntry().
And the related source file will be opened to view.
You can see the breakpoints position with highlight label in the source code Breakpoint.png also can watch the variables value,check the callstacks etc. All behaviors of WinDbg are similar to other debuggers. Variable.png Stack.png
The debug message will be show in the WinDbg.


"viotest driver started...build on Nov 1 2011 05:04:18"
"Initialize return 0x0"


When stop(unload) the driver,the breakpoint will also be hit at DriverUnload().
The debug message will also be show in the WinDbg

"Driver Unload sucessfully\!"

Other Debug Method

  • Using Debug message(print):
The message can be viewed by another tool DebugView,it can be used in target guest(without WinDbg) only environment to debug the driver with the DbgPrint() debug message. It is also a available method to debug the driver.
  • Using crash dump (kernel memory dump)with WinDbg
TBD.


Problems may be encountered

  • WinDbg somtimes exit unexpectedly when connecting to the target
I have not found the exact reason,but I found this problem often appears when changing the QEMU virtual hardware configuration or the target is not be shut off normally.It may be the Windows registry conflict cause this issue.
  • WinDbg and virtual machine runs slowly
It is recommended by Avi Kivity( avi@redhat.com)using QEMU-KVM which is significantly faster,especially running Windows,but the WinDbg will almost exit everytime when using qemu-kvm git.

References

(author: Cao,Bing Bu )