While troubleshooting released application on remote production site, it is very useful to grasp a state of the process for further analysis. There are several scenarios in which the following information about process state is helpful:
- modules (DLLs) loaded into process and their versions
- threads and their call stacks
- process and thread performance
An utility ProcessSnapshot takes advantage of Debugging Tools API (dbghelp.dll – note the dialog also displays DLL version in the right bottom corner) and writes this helpful information to text file and it can also take a sequence of the snapshots to compare thread performance and/or stacks and check the difference.
The generated file is in the directory of the utility application and looks like:
Snapshot
System Time: 10/14/2008 8:46:33 PM
Local Time: 10/14/2008 11:46:33 PM
Performance
Creation System Time: 10/14/2008 8:46:28 PM
Kernel Time: 0.094 s
User Time: 0.031 s
Modules
Module: ProcessSnapshot.exe @00400000
Base Address: 0x00400000
Base Size: 0x0005b000 (372736)
Name: ProcessSnapshot.exe
Path: D:\Projects\Utilities\ProcessSnapshot\Release\ProcessSnapshot.exe
Product Version: 1.0.0.1
File Version: 1.0.0.125
Module: ntdll.dll @7c900000
Base Address: 0x7c900000
Base Size: 0x000af000 (716800)
Name: ntdll.dll
Path: C:\WINDOWS\system32\ntdll.dll
Product Version: 5.1.2600.5512
File Version: 5.1.2600.5512
[...]
Threads
Thread: 3824
Base Priority: 8
Creation System Time: 10/14/2008 8:46:57 PM
Kernel Time: 0.063 s
User Time: 0.031 s
Call Stack
ntdll!7c90e4f4 KiFastSystemCallRet (+ 0) @7c900000
USER32!7e4249c4 GetCursorFrameInfo (+ 460) @7e410000
USER32!7e424a06 DialogBoxIndirectParamAorW (+ 54) @7e410000
USER32!7e4247ea DialogBoxParamW (+ 63) @7e410000
ProcessSnapshot!00403f45 ATL::CDialogImpl<CMainDialog,ATL::CWindow>::DoModal (+ 67) [c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlwin.h, 3478] (+ 28) @00400000
ProcessSnapshot!00403b6f CProcessSnapshotModule::RunMessageLoop (+ 74) [d:\projects\utilities\processsnapshot\processsnapshot.cpp, 67] (+ 0) @00400000
ProcessSnapshot!004049b9 ATL::CAtlExeModuleT<CProcessSnapshotModule>::Run (+ 17) [c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlbase.h, 3552] (+ 0) @00400000
ProcessSnapshot!004041c3 ATL::CAtlExeModuleT<CProcessSnapshotModule>::WinMain (+ 48) [c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlbase.h, 3364] (+ 5) @00400000
ProcessSnapshot!00434477 wWinMain (+ 5) [*d:\projects\utilities\processsnapshot\release\processsnapshot.inj:5, 14] (+ 0) @00400000
ProcessSnapshot!00415058 __tmainCRTStartup (+ 274) [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c, 263] (+ 27) @00400000
!00360033
How exactly this can facilitate troubleshooting problems with software. Here are several scenarios:
- the applications shows an unexpected error message and it is desired to find out the position and call stack
- the application deadlocks and call stacks are required for further troubleshooting
- the application maxes out CPU load on one of the cores and the thread needs to be identified
- the applciation runs slowly and bottleneck thread is to be find out
- the application loads undesired third party module (or otherwise has it mapped into process, esp. antivirus software, or a DLL hosting undesired DirectShow filter) or a module with improper version
In all mentioned above scenarios the snapshot is very helpful for troubleshooting, profiling, fixing.
Update 23-Dec-2008. The application auto-enables SeDebugPrivilege (SE_DEBUG_NAME) so that snapshot could be taken from processes such as service processes.
A binary [Win32, x64] and Visual C++ .NET 2008 source code are available from SVN.
