summaryrefslogtreecommitdiffstats
path: root/private/windbg/doc/newuser.txt
blob: a75c86f8825def5d214e27eedb534d11cffc5726 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
WinDbg New User Document

This document serves to describe the fundamentals of using WinDbg, the NT hosted source level debugger.
WinDbg supports the following types of debugging:
1.	user mode applications
2.	csr and all server side
3.	user mode drivers (video, etc.)
4.	wow applications, dos (real mode & v86 mode) on i386 only
5.	kernel debugging (kernel, drivers, etc.)
6.	kernel mode crash debugging (NT style core dumps)
7.	remote debugging (net based named pipes & serial)

Where Do I Get The Current Version Of WinDbg?

The latest build is the best place to get your copy of WinDbg.  If you do not want to update to the latest build or cannot you can still get the latest WinDbg very easily.  Copy the script GWINDBG.CMD from \\kernel\scratch\wesw.  It will copy the WinDbg binaries from any build release server to any directory on your machine or directly to your mstools directory.  The syntax for the script is:

GWINDBG [share point] [destination directory]
Example:	gwindbg \\ntx864\freebins.544  d:\windbg	// this copies to a specific dir
		gwindbg \\ntx864\freebins.544		// this copies to your mstools dir

If you are one of those people that like to live on the edge the you can always get binaries from \\kernel\scratch\wesw\windbg.   The binaries for each platform are located in separate machine directories.  You do not need the above mentioned script, just copy the all the files from the appropriate machine directory.  If you do this I suggest that you put the binaries into a separate directory so that your mstools binaries are preserved.  

There is one special consideration for kernel debugging and that is the kernel extensions.  The extensions MUST match the system that you are debugging.  Therefore if you copy down new WinDbg binaries be sure to use the correct extensions DLL.  You may want to save different versions if the extensions DLLs for each build that you are debugging.  There are currently 3 extension DLLs, one for each platform: wextsalp.dll, wextsmip.dll, wextsx86.dll.

Building Your Project For WinDbg

WinDbg uses symbolic debugging information that is generated by the compiler to relate memory addresses to variable names and source line numbers.  WinDbg supports the following types of symbolic debugging information:
1.	COFF, global publics and line numbers
2.	CodeView, NB08 and NB09 style
3.	16 bit SYM files for WOW debugging
4.	NT images that have the debug data striped to a DBG file

To get the best use of Windbg you should set your build environment as follows:
set NTDEBUG=ntsd
set NTDEBUGTYPE=windbg
set MSC_OPTIMIZATION=/Od /Oi

Ultimately these build environment settings cause the compiler and linker to get the following flags set:
Compiler:  /Z7 /Od /Oi
Linker:    debug:full debugtype:cv

Setting the optimization flag to /Od /Oi causes optimizations to be turned off with the exception of intrinsics.  Leaving intrinsics on is necessary for some directories because CRT functions like strcpy, strlen, etc. are used but libc is not linked in the project.  The removal of optimizations is necessary for correct source stepping and local variable display.  When optimizations are turned on the compiler schedules instructions and may leave local variables in registers, both can play havoc on WinDbg.  We may be able to correct this in the future by changing the symbolic debug information that is generated by the compiler/packer.  

If you are debugging a component that you didn't build, one that came with the build, you can debug it with WinDbg and get the same results as from NTSD/KD.  

For building WINSRV/GDI/USER/etc you must use native C++ not CFRONT, to do that you must set BLDCRT=1 in your environment.  You should also use precompiled headers, to that do the following:
1.	copy gre\precomp.pre gre\precomp.hxx
2.	edit gre\sources
line 43: prepend '#' to !IF 0   --> #!IF 0
line 49: prepend '#' to !ENDIF  --> #!ENDIF
SOURCES= line, add precomp.hxx as FIRST file in file list
3.	if you are use native C++ also: copy client\mfrec.nat client\mfrec.cxx

For building a X86 kernel with WinDbg symbols you must delete 2 lines from makefile.def so that the kernel will be linked as a relocatable image.  To change makefile.def  do the following:
Search for "-base:0x80100000"
Delete the line that was found and the previous line that specifies "-fixed"
Save the makefile.def and re-link your kernel.


Setting Up Your WinDbg Environment

Unlike NTSD/KD Windbg does not use environment variables to communicate options information.  Because WinDbg is a Windows hosted debugger it uses it's ui to setup the necessary options and then stores the configuration information in the registry.  All configuration data is stored under \\hkey_current_user\software\microsoft\windbg\0012.  The last key is a registry version number and only changes if there are radical changes made to the format of the data that WinDbg stores.  You can use REGEDT32 to save your WinDbg registry data to a disk file and then load the file after you have updated to a newer build.  

WinDbg uses the concept of a 'workspace' to save user configurations.  Workspaces are organized as a 2 level hierarchy.  The first level is the program that is being debugged and the second level is the workspace name:

This gives you the flexibility to have multiple workspaces for a given program, allowing you to save different configurations for different debugging scenarios.  

WinDbg saves the entire state of the debugger in the workspace.  This includes window positions and sizes, colors, debug options, breakpoints, remote debugging options, and much more.  The workspace is NOT saved or created for you, you must explicitly save the workspace before exiting the debugger.  


Notice that the above diagram shows 2 special workspaces, common workspace and <attached process>.  These 2 workspaces are always present.  The common workspace is the root workspace that all other workspaces are derived from.  When you start WinDbg without specifying a workspace it loads the common workspace.  It is not a good idea to simply save your state to the common workspace all the time.  The common workspace should contain those options that are common to all debugging scenarios but not specific to one individual program.  For example saving breakpoints to the common workspace is really the wrong thing to do.  The <attached process> workspace is reserved for the case when you have attached to a faulting process.  The reason WinDbg uses this reserved workspace is because we may not have a program name during process attach.  

The common options that most users need to modify the first time using WinDbg are accessed by using the Options.Debug menu item in WinDbg.  The following list shows the options that most uses modify:
1.	Case sensitivity
on  = WinDbg cares about the case of symbols (default value)
off = doesn't care
2.	Verbose output
on  = print all module load/unload notifications
off = do not print (default value)
3.	Ignore bad symbols
on  = Load debug data even if the checksum/timestamp mismatches
off = Prompt for a user response (default value)
4.	Abbreviated context
on  = Print NTSD style context ( FOO!_main ) 
off = Print WinDbg style context ( {,foo.c,foo.exe}_main ) (default value)
5.	Radix
default is decimal but can be set to hexadecimal
6.	Register trace
on  = Print a register dump and disasm of current instruction after every debug event.  Also enables command repeat by just pushing the enter key.
off = none of this behavior. (default value)
7.	If you are doing CSR debugging the you must do:

sxd 0xc0000037  // this disables an exception that occurs everytime a server side thread goes away.

The last thing you need to change is the symbol path.  This is the path that WinDbg uses to locate the images that contain the symbolic debug information.  The path is specified in the Options.UserDlls menu item.  This menu item presents a dialog that contains an edit box that is titled "Symbol Search Path".  Change this to contain the correct path.  You may enter multiple paths separated by ';' characters.  Environment variable expansion is also supported, so the path "%systemroot%\symbols" is expanded to the correct value.  You may also enter UNC paths to the source servers if you wish.  
Summary:
So the first time you use WinDbg you should do the following:
1.	Run WinDbg
2.	Change all of the options that you want.
3.	Open a command window (Window.Command)
4.	Save to the common workspace
5.	End WinDbg.

You are now ready to use WinDbg for you debugging pleasure.


Helpful Hints To Remember

A complete online WinDbg reference is available through the help facility.  Use the HELP menu item to get complete online help.  For help in the command window you can use the HELP command.  Issuing  the HELP command alone lists all of the available commands.  You can then use the HELP command to get help on a specific command, i.e. HELP BP gives help for the breakpoint command.

WinDbg  defers symbol loading until the symbolic information in needed.  This speeds up the startup time for debuggees and boot times for kernel debugging.  If at any time you would like to force the loading of previously deferred symbols you can use the "ld" command.  The ld command takes one argument, the module name.  Example:  "ld scsiport" will cause symbols to scsiport.sys to be loaded.

WinDbg allows you to set breakpoints in modules that have not yet been loaded.  This is a feature that NTSD/KD never had but is very useful.  WinDbg remembers the breakpoint for the future and when ever a module is loaded it looks to see if the breakpoint can be resolved in that module.  If the breakpoint cannot be resolved WinDbg shows a popup that asks what should be done with the outstanding breakpoint.  Among the choices are "Clear", "Defer", and "Quiet Defer".  I recommend that you select "Quiet Defer", this will tell WinDbg to never ask you again what to do and will keep trying to resolve the breakpoint.

WinDbg uses a complete C/C++ expression evaluator and all expressions are assumed to be C/C++ expressions.  This means the following:
        dd ntglobalflag        - dumps address of ntglobalflag
        dd &ntglobalflag       - dumps the data in ntglobalflag

Generally it is better to use the '?' operator.  The above becomes:
?ntglobalflag          - dumps the data in ntglobalflag
?ntglobalflag=0x54321  - changes the data in ntglobalflag

        bp dcobj::method       - works only for windbg symbols
        bp dcobj__method       - works for ntsd symbols

in a source window or disassembly window:
            F9                 - set breakpoint on line with cursor
            F7                 - goto cursor
            F8                 - trace into
            F10                - step over


To get an up-to-date stack trace as you debug use the Calls Window.  It will even display source information, file and line number for each stack frame.  Most debugger windows have options associated   with them and can be accessed by clicking on the last icon on the toolbar or using Options.Window_Name from the menu. 

WinDbg's 'K' command supports a variety of modifiers to display additional information:
        1.  B           display return address, frame pointer, & params
        2.  V           display runtime function information
        3.  S           display file and line number

One or all of the modifiers may be used on a 'K' command, i.e. KB or KBS, or KBV, etc.

When WinDbg gets an exception of any kind, access violation, breakpoint, etc., it tries to locate source line number information for the current address of execution.  If source line number information can be found WinDbg will open a source window and position the caret on the source line that corresponds to the current address.  WinDbg tries to correctly locate the C/C++ source file by examining the symbolic debug information.  The debug data contains the full path to the source file for the machine on which it was compiled.  This means that if you build an app on drive d: and running on a machine that has the source tree on drive e: you will have to tell WinDbg where to find the source code.  You can do this in 2 ways.  

First, you can do nothing and when WinDbg cannot find the source it will ask you to browse for the source.  This works fine but if you have source for alot of sub-directories it can be bothersome.  If you choose this method be sure to check the checkbox on the common file open dialog that is labeled "add to search path?", this will allow WinDbg to look in this path the next time it cannot find source.

Second, you can change the source search path that WinDbg uses to find your source code files.  To do this do the following:

Choose the Options.Debug menu item.
Tab to the edit box labeled "Source search path".
Change this to contain the necessary source path for your project.
Save your workspace.



WinDbg Command Line Options

-h		Causes child processes to inherit access to WinDbg's handles
-i		Load the default workspace, just like running without any registry data
-w[n]		Load a workspace, n is the workspace name
-p[pid]		Attach to a running process, pid is the process id
-e[event]	Event id required for WinDbg as an AE debugger
-g		Go now flag, starts executing the process
-k[platform,port,speed]
		Run as a kernel debugger using the arguments as kernel debugger options.
			Platform is the target machine type, I386, mips, alpha.
			Port is the com port, com1...n
			Speed is the com port speed, 9600, 19200, 57600, etc.
-s[pipe]		Start a remote.exe server, pipe is the pipe name
-m		Start WinDbg minimized
-y[path]		Specify a symbol search path, path is the path name
-a		Ignore all bad symbols, still prints a warning message
-l[text]		Sets the window title for WinDbg
-v		Verbose mode on, causes WinDbg to print module load/unload messages


Remote Debugging

WinDbg supports remote debugging through 2 different transport layers, named pipes and serial.  Named pipes is the preferred transport because of its speed and ease of use.  This discussion is oriented towards that transport as a working version of the serial transport is not yet available.  Mail will be sent as soon as it is available.  

Named pipes remote debugging is slightly more complicated than local debugging but once configured it is very easy to use.  When using remote debugging there are 2 machines involved, a host and a target.  The host is the machine that "hosts" WinDbg and the target machine is the machine that executes the process that is debugged.  The debugger is distributed between the 2 machines with the 2 machines communicating through a series of pipes.  Starting a debug session requires the initiation of 2 debuggers, WinDbg and WInDbgRm.  Windbg executes on the host machine and WinDbgRm executes on the target machine. 

To start a remote debug session do the following:
TARGET MACHINE
1.	start WinDbgRm

HOST MACHINE
1.	start WinDbg foo.exe  (foo.exe is the app you want to debug)
2.	Choose the Options.Debugger_DLLs menu item
3.	Pull down the Transport Layer combo box
4.	Choose PIPES entry
5.	Click in the Change button
6.	Tab to the Parameters edit box
7.	Change targethost to the machine name of the target machine
8.	Click on the Ok button
9.	Click on the Ok button
10.	Save the workspace as your remote debugging workspace
11.	Type go in the command window
*** A debugger connection is now established and your application is running.
*** In the case of CSR debugging you would not start windbg with an application name as an argument.  Instead you would type ".attach -1" in the command window.  This connects to the remote machine and attaches to the CSR process.

There are some special comments worth noting about remote debugging.  There are a few features that are especially useful.  You can establish a remote connection and then disconnect and later reconnect.  Furthermore, another user may reconnect to your debug session.  Also, another user may "break in" and take over your remote debug session.  If you are doing CSR debugging  you MUST set the "Disconnect On Exit" option.  This causes WinDbg to disconnect from the target machine instead of terminating the process on the target machine.  This option is found on the Options.Debug dialog.  

To disconnect from a remote debug session you can type the ".disconnect" command in the command window or set the "Disconnect On Exit" option and terminate WinDbg.  

To re-connect to a disconnected target machine type the ".attach" command in the command window.  

To "break in" to a remote debug session that someone else is using change the targethost name in the Options.Debugger_Dlls to the machine that is desired and do a ".attach" command.  The current host machine will get a popup indicating that you are going to break in and the user will have 20 seconds to deny permission, otherwise the current user will be disconnected and you will be connected.

REMOTE.EXE Server in WinDbg

WinDbg can act as a REMOTE.EXE server.  This is analogous to running "REMOTE /S" and then running NTSD in the remote shell.  This gives access to the WinDbg command window to remote users through the use of REMOTE.EXE as a client.  To start the REMOTE.EXE server in WinDbg execute the "remote pipename" command in the command window.  There is one argument to the "remote" command and that is the pipename. 

Example:

IN THE WINDBG COMMAND WINDOW:  (machine name is mymachine) 

	remote foo

ON SOME REMOTE MACHINE IN A CMD SHELL:
	remote /c mymachine foo
	*** Now this user has complete access to the WinDbg command window.

Kernel Debugging

When doing Kernel Debugging you must start windbg with it's first argument as NTOSKRNL or NTOSNRNL.EXE.  Example: start windbg ntoskrnl.exe

To setup WinDbg for Kernel Debugging requires that you set the options in the Options.Kernel_Debugger dialog.  These options are all the ones that you normally set for KD in a series of environment variables.  The options that are required to be set are as follows:
1.	Baud Rate
2.	Port
3.	Platform

The other options on this dialog are optional and you may set them as desired.  

After setting the Kernel Debugger options be sure to save your workspace.  Then change focus to the command window and type "go".  WinDbg will display the following messages: 
Thread Create:  Process=0, Thread=0 Kernel debugger waiting to connect...
When the target system boots and establishes a connection WinDbg will display:
Kernel Debugger connection established

After this message is displayed you can use WinDbg just as you would KD.  To break in to the kernel use CTRL-C just as you would in KD.  If you selected the "Initial Breakpoint" option in the Kernel Debugger options then you will stop at the initial bp just like KD. 

To attach to a dead machine or a running machine to the following:
1.	start WinDbg ntoskrnl
2.	Either set the options as above or load a workspace
3.	In the command window type the "l" or "go" command
4.	If the machine is stopped the you will get an exception, otherwise
you will have to break in.
All your favorite kernel extensions are available exactly as they are in KD.  

WinDbg also supports the debugging of crash dumps.  A crash dump is a NT style core dump that is generated when a machine bug checks.  The facility to generate the dump is coming in a build soon.  To debug a crash dump simply name the crash dump file in the Kernel Debugger options.  All the rest is the same!

***Note:  KD allowed an aliased context of NT! to specify the kernel context.  WinDbg does not allow this and you must use NTOSKRNL! as the context operator.


How Do I Report Problems?

The fastest way to a problem resolution is to send mail to the WINDBG alias.  All of the developers for WinDbg monitor this alias daily.  You can always raise a bug in RAID too.  If you do raise a bug please send mail too.  

When you send mail include a complete description of the problem and how we can reproduce it.  If WinDbg is crashing then the most helpful data is a DrWatson log file.  If you have a retail install then you should automatically get a DrWatson log, otherwise you will need to install DrWatson as you crash debugger.  You can do this by issuing the command "drwtsn32 -I" from a command prompt or from program manager.  The log file is called DRWTSN32.LOG and is located in your windows directory (%systemroot%\drwtsn32.log).  Simply attach the log file to your mail message or include it in the raid bug entry.  If you cannot create a DrWatson log file then get a stack trace from NTSD or WINDBG.