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: 126.96.36.199 File Version: 188.8.131.52 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.