Commands
Common WinDbg Commands (Thematically Grouped)
By Robert Kuster
Collapse
Also check the "!lmi" command.
Collapse
exr -1
.exr 7c901230
!cppexr 7c901230
display most recent exception
display exception at address 7c901230
display c++ exception at address 7c901230
Collapse
Collapse
Collapse
Collapse
With bp, the breakpoint location is always converted to an address. In contrast, a bu or a bm breakpoint is always associated with the symbolic value.
Simple Examples
Breakpoitns with options
Breakpoints with commands: The command will be executed when the breakpoint is hit.
Howto set a brekpoint in your code programatically?
kernel32!DebugBreak
ntdll!DbgBreakPoint
__asm int 3 (x86 only)
Collapse
Collapse
To get more than 3 Function Arguments from the stack
dd ChildEBP+8 (Parameters start at ChildEBP+8)
dd ChildEBP+8 (frame X) == dd ESP (frame X-1)
Collapse
Collapse
Collapse
Determine stack usage for a thread
Stack Identifier Memory Identifier ^ --------------------------------------------------------- -------------- <- _TEB.StackBase SubRegionBase3 + SubRegionSize3 | | | MEM_COMMIT | | | |------------| <- _TEB.StackLimit SubRegionBase3 ^, SubRegionBase2 + SubRegionSize2 | PAGE_GUARD | |------------| SubRegionBase2 ^, SubRegionBase1 + SubRegionSize1 | | |MEM_RESERVED| | | |------------| <- _TEB.DeallocationStack AllocationBase or RegionBase, SubRegionBase1 ^ DeallocationStack: dt ntdll!_TEB TebAddr DeallocationStack
From MSDN CreateThread > dwStackSize > "Thread Stack Size":
"Each new thread receives its own stack space, consisting of both committed and reserved memory. By default, each thread uses 1 Mb of reserved memory, and one page of committed memory. The system will commit one page block from the reserved stack memory as needed."
Collapse
20) Memory: Heap
Cmd
!heap
!heap -b, -B
!heap -flt
!heap -stat
!heap -p
Variants / Params
!heap -?
!heap
!heap -h
!heap -h [HeapAddr | Idx | 0]
!heap -v [HeapAddr | Idx | 0]
!heap -s [HeapAddr | 0]
!heap -i [HeapAddr]
!heap -x [-v] Address
!heap -l
!heap Heap -b [alloc | realloc | free] [Tag]
!heap Heap -B [alloc | realloc | free]
!heap -flt s Size
!heap -flt r SizeMin SizeMax
!heap -stat
!heap -stat -h [HeapHandle | 0]
!heap -p -?
!heap -p
!heap -p -h HeapHandle
!heap -p -a UserAddr
!heap -p -all
Description
Brief help
List heaps with index and HeapAddr
List heaps with index and range (= startAddr(=HeapAddr), endAddr)
Detailed heap info [Idx = heap Idx, 0 = all heaps]
Validate heap [Idx = heap Idx, 0 = all heaps]
Summary info, i.e. reserved and committed memory [Idx = heap Idx, 0 = all heaps]
Detailed info for a block at given address
Search heap block containing the address (v = search the whole process virtual space)
Search for potentially leaked heap blocks
Set conditional breakpoint in the heap manager [Heap = HeapAddr | Idx | 0]
Remove a conditional breakpoint
Dump info for allocations matching the specified size
Filter by range
Dump heap handle list
Dump usage statistic for every AllocSize [HeapHandle = given heap | 0 = all heaps].
The statistic includes AllocSize, #blocks, TotalMem for each AllocSize.
Extended page heap help
Summary for NtGlobalFlag, HeapHandle + NormalHeap list **
Detailed info about a page heap with Handle
Details of heap allocation containing UserAddr. Prints backtraces when available.
Details of all allocations in all heaps in the process.
The output includes UserAddr and AllocSize for every HeapAlloc call.
It seems that the following applies for windows XP SP2:
a) Normal heap
CreateHeap -> creates a _HEAP
AllocHeap -> creates a _HEAP_ENTRY
b) Page heap enabled (gflags.exe /i +hpa)
CreateHeap -> creates a _DPH_HEAP_ROOT (+ _HEAP + 2x _HEAP_ENTRY)**
AllocHeap -> creates a _DPH_HEAP_BLOCK
** With page heap enabled there will still be a _HEAP with two constant _HEAP_ENTRY's for every CreateHeap call.
Collapse
Who allocated memory - who called HeapAlloc?
Select "Create user mode stack trace database" for your image in GFlags (gflags.exe /i +ust)
From WinDbg's command line do a !heap -p -a , where is the address of your allocation ***.
While !heap -p -a will dump a call-stack, no source information will be included.
To get source information you must additionally enable page heap in step 1 (gflags.exe /i +ust +hpa)
Do a dt ntdll!_DPH_HEAP_BLOCK StackTrace , where is the DPH_HEAP_BLOCK address retrieved in step 3.
Do a dds ", where is the value retrieved in step 5.
Note that dds will dump the stack with source information included.
Who created a heap - who called HeapCreate?
Select "Create user mode stack trace database" and "Enable page heap" for your image in GFlags (gflags.exe /i +ust +hpa)
a) From WinDbg's command line do a !heap -p -h , where is the value returned by HeapCreate. You can do a !heap -stat or !heap -p to get all heap handles of your process.
b) Alternatively you can use !heap -p -all to get addresses of all _DPH_HEAP_ROOT's of your process directly.
Do a dt ntdll!_DPH_HEAP_ROOT CreateStackTrace , where is the address of a _DPH_HEAP_ROOT retrieved in step 2
Do a dds , where is the value retrieved in step 3.
Finding memory leaks
From WinDbg's command line do a !address –summary.
If RegionUsageHeap or RegionUsagePageHeap are growing, then you might have a memory leak on the heap. Proceed with the following steps.
Enable "Create user mode stack trace database" for your image in GFlags (gflags.exe /i +ust)
From WinDbg's command line do a !heap -stat, to get all active heap blocks and their handles.
Do a !heap -stat -h 0. This will list down handle specific allocation statistics for every AllocSize.
For every AllocSize the following is listed: AllocSize, #blocks, and TotalMem. Take the AllocSize with maximum TotalMem.
Do a !heap -flt s . =AllocSize that we determined in the previous step. This command will list down all blocks with that particular size.
Do a !heap -p -a to get the stack trace from where you have allocated that much bytes. Use the that you got in step 4.
To get source information you must additionally enable page heap in step 1 (gflags.exe /i +ust +hpa)
Do a dt ntdll!_DPH_HEAP_BLOCK StackTrace , where is the DPH_HEAP_BLOCK address retrieved in step 5.
Do a dds ", where is the value retrieved in step 7.
Note that dds will dump the stack with source information included.
*** What is a ?
is usually the address returned by HeapAlloc:
int AllocSyze = 0x100000; // == 1 MB BYTE* pUserAddr = (BYTE*) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, AllocSyze);
Often any address in the range [UserAddr....UserAddr+AlloSize] is also a valid parameter:
!heap -p -a [UserAddr....UserAddr+AlloSize]
Collapse
Enable 19-ProcessesAndThreads and 22-StringManipulation logging: