Sometimes there is no private PDB file available for a module in a crash dump although we know they exist for different versions of the same module. The typical example is when we have a public PDB file loaded automatically and we need access to structure definitions, for example, _TEB or _PEB. In this case we need to force WinDbg to load an additional PDB file just to be able to use these structure definitions. This can be achieved by loading an additional module at a different address and forcing it to use another private PDB file. At the same time we want to keep the original module to reference the correct PDB file albeit the public one. Let’s look at one concrete example.
I was trying to get stack limits for a thread by using !tebcommand:
0:000> !teb
TEB at 7efdd000
*** Your debugger is not using the correct symbols
***
*** In order for this command to work properly, your symbol path
*** must point to .pdb files that have full type information.
***
*** Certain .pdb files (such as the public OS symbols) do not
*** contain the required information. Contact the group that
*** provided you with these symbols if you need this command to
*** work.
***
*** Type referenced: ntdll!_TEB
***
error InitTypeRead( TEB )…
0:000> dt ntdll!*
lm command showed that the symbol file was loaded and it was correct so perhaps it was the public symbol file or _TEB definition was missing in it:
0:000> lm m ntdll
start end module name
7d600000 7d6f0000 ntdll (pdb symbols) c:\websymbols\wntdll.pdb\ 40B574C84D5C42708465A7E4A1E4D7CC2\wntdll.pdb
I looked at the size of wntdll.pdb and it was 1,091Kb. I searched for other ntdll.pdb files, found one with the bigger size 1,187Kb and appended it to my symbol search path:
0:000> .sympath+ C:\websymbols\ntdll.pdb\ DCE823FCF71A4BF5AA489994520EA18F2
Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols; C:\websymbols\ntdll.pdb\DCE823FCF71A4BF5AA489994520EA18F2
Then I looked at my symbol cache folder for ntdll.dll, chose a path to a random one and loaded it at the address not occupied by other modules forcing to load symbol files and ignore a mismatch if any:
0:000> .reload /f /i C:\websymbols\ntdll.dll\45D709FFf0000\ntdll.dll=7E000000
0:000> lm
start end module name
...
...
...
7d600000 7d6f0000 ntdll (pdb symbols) c:\websymbols\wntdll.pdb\40B574C84D5C42708465A7E4A1E4D7CC2\wntdll.pdb
7d800000 7d890000 GDI32 (deferred)
7d8d0000 7d920000 Secur32 (deferred)
7d930000 7da00000 USER32 (deferred)
7da20000 7db00000 RPCRT4 (deferred)
7e000000 7e000000 ntdll_7e000000 (pdb symbols) C:\websymbols\ntdll.pdb\DCE823FCF71A4BF5AA489994520EA18F2\ntdll.pdb
The additional ntdll.dll was loaded at 7e000000 address and its module name became ntdll_7e000000. Because I knew TEB address I could see the values of _TEB structure fields immediately:
0:000> dt -r1 ntdll_7e000000!_TEB 7efdd000
+0×000 NtTib : _NT_TIB
+0×000 ExceptionList : 0×0012fec0 _EXCEPTION_REGISTRATION_RECORD
+0×004 StackBase : 0×00130000
+0×008 StackLimit : 0×0011c000
+0×00c SubSystemTib : (null)
+0×010 FiberData : 0×00001e00
+0×010 Version : 0×1e00
+0×014 ArbitraryUserPointer : (null)
+0×018 Self : 0×7efdd000 _NT_TIB
+0×01c EnvironmentPointer : (null)
+0×020 ClientId : _CLIENT_ID
+0×000 UniqueProcess : 0×00000e0c
+0×004 UniqueThread : 0×000013dc
+0×028 ActiveRpcHandle : (null)
+0×02c ThreadLocalStoragePointer : (null)
+0×030 ProcessEnvironmentBlock : 0×7efde000 _PEB
+0×000 InheritedAddressSpace : 0 ”
+0×001 ReadImageFileExecOptions : 0×1 ”
+0×002 BeingDebugged : 0×1 ”
+0×003 BitField : 0 ”
+0×003 ImageUsesLargePages : 0y0
+0×003 SpareBits : 0y0000000 (0)
+0×004 Mutant : 0xffffffff
+0×008 ImageBaseAddress : 0×00400000
+0×00c Ldr : 0×7d6a01e0 _PEB_LDR_DATA
+0×010 ProcessParameters : 0×00020000 _RTL_USER_PROCESS_PARAMETERS
+0×014 SubSystemData : (null)
+0×018 ProcessHeap : 0×00210000
+0×01c FastPebLock : 0×7d6a00e0 _RTL_CRITICAL_SECTION
+0×020 AtlThunkSListPtr : (null)
+0×024 SparePtr2 : (null)
+0×028 EnvironmentUpdateCount : 1
+0×02c KernelCallbackTable : 0×7d9419f0
+0×030 SystemReserved : [1] 0
+0×034 SpareUlong : 0
+0×038 FreeList : (null)
+0×03c TlsExpansionCounter : 0
+0×040 TlsBitmap : 0×7d6a2058
+0×044 TlsBitmapBits : [2] 0xf
+0×04c ReadOnlySharedMemoryBase : 0×7efe0000
+0×050 ReadOnlySharedMemoryHeap : 0×7efe0000
+0×054 ReadOnlyStaticServerData : 0×7efe0cd0 -> (null)
+0×058 AnsiCodePageData : 0×7efb0000
+0×05c OemCodePageData : 0×7efc1000
+0×060 UnicodeCaseTableData : 0×7efd2000
+0×064 NumberOfProcessors : 8
+0×068 NtGlobalFlag : 0×70
+0×070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
+0×078 HeapSegmentReserve : 0×100000
+0×07c HeapSegmentCommit : 0×2000
+0×080 HeapDeCommitTotalFreeThreshold : 0×10000
+0×084 HeapDeCommitFreeBlockThreshold : 0×1000
+0×088 NumberOfHeaps : 5
+0×08c MaximumNumberOfHeaps : 0×10
+0×090 ProcessHeaps : 0×7d6a06a0 -> 0×00210000
+0×094 GdiSharedHandleTable : (null)
+0×098 ProcessStarterHelper : (null)
+0×09c GdiDCAttributeList : 0
+0×0a0 LoaderLock : 0×7d6a0180 _RTL_CRITICAL_SECTION
+0×0a4 OSMajorVersion : 5
+0×0a8 OSMinorVersion : 2
+0×0ac OSBuildNumber : 0xece
+0×0ae OSCSDVersion : 0×200
+0×0b0 OSPlatformId : 2
+0×0b4 ImageSubsystem : 2
+0×0b8 ImageSubsystemMajorVersion : 4
+0×0bc ImageSubsystemMinorVersion : 0
+0×0c0 ImageProcessAffinityMask : 0
+0×0c4 GdiHandleBuffer : [34] 0
+0×14c PostProcessInitRoutine : (null)
+0×150 TlsExpansionBitmap : 0×7d6a2050
+0×154 TlsExpansionBitmapBits : [32] 1
+0×1d4 SessionId : 1
+0×1d8 AppCompatFlags : _ULARGE_INTEGER 0×0
+0×1e0 AppCompatFlagsUser : _ULARGE_INTEGER 0×0
+0×1e8 pShimData : (null)
+0×1ec AppCompatInfo : (null)
+0×1f0 CSDVersion : _UNICODE_STRING “Service Pack 2″
+0×1f8 ActivationContextData : (null)
+0×1fc ProcessAssemblyStorageMap : (null)
+0×200 SystemDefaultActivationContextData : 0×00180000 _ACTIVATION_CONTEXT_DATA
+0×204 SystemAssemblyStorageMap : (null)
+0×208 MinimumStackCommit : 0
+0×20c FlsCallback : 0×002137b0 -> (null)
+0×210 FlsListHead : _LIST_ENTRY [ 0×2139c8 - 0×2139c8 ]
+0×218 FlsBitmap : 0×7d6a2040
+0×21c FlsBitmapBits : [4] 0×33
+0×22c FlsHighIndex : 5
+0×034 LastErrorValue : 0
+0×038 CountOfOwnedCriticalSections : 0
+0×03c CsrClientThread : (null)
+0×040 Win32ThreadInfo : (null)
+0×044 User32Reserved : [26] 0
+0×0ac UserReserved : [5] 0
+0×0c0 WOW32Reserved : 0×78b81910
+0×0c4 CurrentLocale : 0×409
+0×0c8 FpSoftwareStatusRegister : 0
+0×0cc SystemReserved1 : [54] (null)
+0×1a4 ExceptionCode : 0
+0×1a8 ActivationContextStackPointer : 0×00211ea0 _ACTIVATION_CONTEXT_STACK
+0×000 ActiveFrame : (null)
+0×004 FrameListCache : _LIST_ENTRY [ 0×211ea4 - 0×211ea4 ]
+0×00c Flags : 0
+0×010 NextCookieSequenceNumber : 1
+0×014 StackId : 0×9444f8
+0×1ac SpareBytes1 : [40] “”
+0×1d4 GdiTebBatch : _GDI_TEB_BATCH
+0×000 Offset : 0
+0×004 HDC : 0
+0×008 Buffer : [310] 0
+0×6b4 RealClientId : _CLIENT_ID
+0×000 UniqueProcess : 0×00000e0c
+0×004 UniqueThread : 0×000013dc
+0×6bc GdiCachedProcessHandle : (null)
+0×6c0 GdiClientPID : 0
+0×6c4 GdiClientTID : 0
+0×6c8 GdiThreadLocalInfo : (null)
+0×6cc Win32ClientInfo : [62] 0
+0×7c4 glDispatchTable : [233] (null)
+0xb68 glReserved1 : [29] 0
+0xbdc glReserved2 : (null)
+0xbe0 glSectionInfo : (null)
+0xbe4 glSection : (null)
+0xbe8 glTable : (null)
+0xbec glCurrentRC : (null)
+0xbf0 glContext : (null)
+0xbf4 LastStatusValue : 0xc0000135
+0xbf8 StaticUnicodeString : _UNICODE_STRING “mscoree.dll”
+0×000 Length : 0×16
+0×002 MaximumLength : 0×20a
+0×004 Buffer : 0×7efddc00 “mscoree.dll”
+0xc00 StaticUnicodeBuffer : [261] 0×6d
+0xe0c DeallocationStack : 0×00030000
+0xe10 TlsSlots : [64] (null)
+0xf10 TlsLinks : _LIST_ENTRY [ 0×0 - 0×0 ]
+0×000 Flink : (null)
+0×004 Blink : (null)
+0xf18 Vdm : (null)
+0xf1c ReservedForNtRpc : (null)
+0xf20 DbgSsReserved : [2] (null)
+0xf28 HardErrorMode : 0
+0xf2c Instrumentation : [14] (null)
+0xf64 SubProcessTag : (null)
+0xf68 EtwTraceData : (null)
+0xf6c WinSockData : (null)
+0xf70 GdiBatchCount : 0×7efdb000
+0xf74 InDbgPrint : 0 ”
+0xf75 FreeStackOnTermination : 0 ”
+0xf76 HasFiberData : 0 ”
+0xf77 IdealProcessor : 0×3 ”
+0xf78 GuaranteedStackBytes : 0
+0xf7c ReservedForPerf : (null)
+0xf80 ReservedForOle : (null)
+0xf84 WaitingOnLoaderLock : 0
+0xf88 SparePointer1 : 0
+0xf8c SoftPatchPtr1 : 0
+0xf90 SoftPatchPtr2 : 0
+0xf94 TlsExpansionSlots : (null)
+0xf98 ImpersonationLocale : 0
+0xf9c IsImpersonating : 0
+0xfa0 NlsCache : (null)
+0xfa4 pShimData : (null)
+0xfa8 HeapVirtualAffinity : 0
+0xfac CurrentTransactionHandle : (null)
+0xfb0 ActiveFrame : (null)
+0xfb4 FlsData : 0×002139c8
+0xfb8 SafeThunkCall : 0 ”
+0xfb9 BooleanSpare : [3] “”
Of course, if I knew in advance that StackBase and StackLimit were the second and the third double words I could have just dumped the first 3 double words at TEB address:
0:000> dd 7efdd000 l3
7efdd000 0012fec0 00130000 0011c000