CExceptionLogger v1.11
Welcome to CExceptionLogger, a freeware C++ class and DLL which
intercepts and logs details about unhandled exceptions such as access violations,
stack overflows and division by zero. The class was originally based upon the February 2002
MSDN article called "Under the Hood: Improved Error Reporting with DBGHELP 5.1 by
Matt Pietrek.
By default the CExceptionLogger class will generate a log file with the name
"YYMMDDHHMMSSmmm_name of exe.exception" in your temp directory. In this file (which is ASCII if the CExceptionLogger is
build as ASCII and UNICODE if the CExceptionLogger is build as a UNICODE) is the
following information:
- Date and Time when the exception occurred
- Exception Code
- Details about exception if an access violation
- Details about exception address including linear address, section, offset
and module path
- Full path of the process
- Current Win32 working directory
- Command line for the process
- Process ID
- Thread ID where the exception occurred.
- Computer Name, User Name, Number of Processors, Page Size, Various Memory
stats, Object counts, Windows version, Windows Build, Service Pack level,
Suite Information, Register Owner, Registered
Organisation, Processor Details, various Wow64 values, various terminal
services related values, The Windows install type, Windows Directory, Windows System directory,
Shared Windows Directory, Boot type,
Monitor and display device info, mouse info, network status, current
hardware profile values, code page details
and locale and language details.
- Environment strings which the current process is using
- Enumeration of all the processes currently running including
i) Name
ii) Process ID
iii) Reference Count
iv) Parent Process ID
v) Base Thread priority
- Enumeration of all the threads in the process including
i) Thread ID
ii) Priority and Delta priority
iii) References
iv) Creation Time
v) Kernel and User Time
- Enumeration of the Modules in the process including
i) Name and full path
ii) Global and per Process reference count
iii) module handle
iv) size
v) All symbols for that module fully expanded (see details later)
- All the x86 registers (or x64 registers if compiled for 64 bit Windows)
- Call Stack where exception occurred, including section, offset, module,
function and line information.
- At each stack frame as well as for all modules, all variables and parameters
all also logged. All basic types such as voids, chars, shorts, words, ints,
DWORDS, floats, doubles and longs are logged. UDT's including structs, unions
and classes are also fully recursed into to display their members. Info for
each type includes its name, address, type and value. In addition if the variable
is a array, each value in the array is fully logged. In addition each call stack
frame can display a raw stack dump in addition to the raw machine code around
that stack frame.
If you are using the DLL version of the code, the level of information can be configured via registry values. See the code
in ExceptHandler.cpp for details.
In addition, again by default, you will get a minidump file generated with
the name "YYMMDDHHMMSSmmm_name of exe.dmp" in your temp directory. You can load
this file up into Visual Studio to do post mortem analysis of the crash almost
as easy as if the crash occurred when the application is being debugged
normally.
Copyright
- You are allowed to include the source code in
any product (commercial, shareware, freeware or otherwise) when your product
is released in binary form.
- You are allowed to modify the source code in
any way you want except you cannot modify the copyright details at the top
of each module.
- If you want to distribute source code with
your application, then you are only allowed to distribute versions released
by the author. This is to maintain a single distribution point for the
source code.
Usage
- As of v1.11, the classes are now designed for VC 2005 or later.
They will not compile on earlier releases of VC.
- You should add the ExceptHandler.cpp/h files directly to your C++
project or alternatively use the DLL version (XCPTHLR.dll) of the exception handler
if you do not want to pull in the C++ code directly into your project, and
then arrange for your app
to get it installed early on in its lifetime via a call to LoadLibrary. You
can also simply link to the XCPTHLR.dll import library if you want to take a
static dependency on the XCPTHLR.dll DLL.
- A prebuilt ASCII x86 and ASCII x64 DLL is provided in the zip file.
- You should follow the
instructions at
http://msdn2.microsoft.com/en-us/library/bb204861(VS.85).aspx on how to
enable symbol creation for your release builds.
- Also remember to ship the resultant pdb files with your code (or arrange
for them to be somehow available) so that CExceptionLogger can give the source
and line information in the resultant log.
- You will also need to deploy the v6.6 or later dbghelp.dll file to your
application's install directory. A version of this redistributable file is
included in the Release directory in the zip file. You can also obtain it by
installing the "Debugging Tools for Windows" component which comes with any
recent Microsoft Windows SDK.
- Please note that due to all the symbols which even a very small app has,
each log file of an exception can generate upwards of 500K of data or more. My opinion
on this is that disk space is cheap while developers time looking for an intermittent
release only bug is not!!!!!.
- The code also specifies that as much info as possible as logged into the
minidump file. In the sample app, this generates a 115+ MB dmp file for VC
2005.
- References:
Bugslayer, MSJ, August 1998 by John Robbins,
http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0898/bugslayer0898.htm
Under the Hood, MSDN, March 2002 by Matt Pietrek,
http://msdn.microsoft.com/msdnmag/issues/02/03/Hood/Hood0203.asp
Crash Dump Analysis on the MSDN,
http://msdn2.microsoft.com/en-us/library/bb204861(VS.85).aspx. This
article explains what a minidump is, how it relates to Windows Error
Reporting (WER), how to setup your release build project to produce pdb
symbols and how you can analyze a minidump using the Visual Studio debugger.
History
V1.0 (14 March 2002)
V1.01 (20 March 2003)
- Now includes flags to limit what is displayed in the log file.
- These flag values and the location of the log file can now optionally be
configured at run time via registry values.
V1.02 (26 March 2003)
- Tidied up #pragma message text
- Removed the unused variable m_bAppendToLog
- Changed the default flags the class uses
- Flag values and location of the log file can now optionally be configured
at run time via an API in the XCPTHLR dll itself. This is now documented and
implemented in the XCPTHLR module.
- Reworked the sample app to be a GUI based app, where you can change the
crash handler flags manually. Also the crash is now generated by hitting a button.
V1.03 (27 March 2003)
- Now pulls in DbgHelp support via GetProcAddress. This makes the code more
robust in the absence of the DbgHelp dll.
V1.04 (19 April 2003)
- Now optionally writes out the raw machine code at each call stack frame
- Now optionally writes out the raw stack at each call stack frame.
- Now optionally writes out the process list on the machine
- Now optionally writes out system details including Computer Name, User Name,
Number of Processors, Page Size, lowest memory address, highest memory address,
OS details, OS version, OS Build, OS service pack, OS type, Windows Directory,
Windows System Directory, Registered Organisation and Registered User.
- Now optionally writes out the environment strings
- Tidied up some indentation and alignment problems.
V1.05 (20 April 2003)
- Removed usage of CRT function "_tcsicmp" in preference to lstrcmpi
- Removed old unused pragma error entry
- Now optionally writes out stats as returned from GlobalMemoryStatus
- Code now requires a recent copy of the Platform SDK to compile
- Now optionally writes out display device stats
- Now optionally writes out Code page stats
- Now optionally writes out Locale and language stats
- Now optionally writes out boot type
V1.06 (22 April 2003)
- Fixed a problem in LogRawMemory which was causing an access violation.
- Now uses GetDC and GetDevCaps to report screen settings instead of EnumDisplaySettings
as a more reliable mechanism.
V1.07 (1 June 2003)
- Now optionally logs the File Version details for all processes and dlls
which are included in the log files.
V1.08 (19 November 2003)
- Fixed a bug in CExceptionLogger::GetAddressDetails in the usage of VirtualQuery.
Thanks to Fredrik Savander for reporting this problem.
V1.09 (21 July 2006)
- Updated copyright details.
- Integrated the functionality of _EXCEPTION_LOGGER_DATA into the
CExceptionLogger class
- Code now uses newer C++ style casts instead of C style casts.
- Updated the code to clean compile on VC 2005
- Now includes support for logging of Windows Longhorn Server and Windows
Vista
- Now includes support for logging of Windows Server 2003 R2
- Now includes support for logging of various suite flags including:
Embedded, Storage Server, Security Appliance, BackOffice components, MS
Small Business Server, Enterprise Edition, Terminal Services, Datacenter
Edition, Home Edition, Web Edition, Media Center Edition, Tablet Edition
- Updated documentation to use the same style as the web site.
- Now logs the GDI and User object count.
- Now reports Page Faults, Peak Working Set Size, Working Set Size, Peak
Paged pool, Paged pool usage, Peak Non-paged pool usage, Non-paged pool
usage, Peak Pagefile usage and Pagefile usage.
- Now reports if running on Wow64
- Now reports the process handle count
- Now reports if the process is running in a terminal services environment
- Now reports the Terminal services Session id value
- Updated code to work correctly for x64 Windows.
- Exception log file can now be accessed by other apps while
CExceptionLogger is writing to it.
- Now reports the info returned from GetNativeSystemInfo
- Now reports the info returned from GetSystemWow64Directory
- Now reports if 3D-Now, cmpxchg, Floating point software emulation,
Pentium FDIV bug, MMX, DEP, PAE, RDTSC, SSE, SSE2, SSE3, cmpxchg16b and
cmp8xchg16 are supported
- Now reports the Shared Windows directory
- Now reports if the program is running on the Terminal Services session
currently attached to the physical console
- Now reports on various Terminal Services values returned from
WTSQuerySessionInformation
- Now reports the total number of pages commited by the system, the
current maximum number of page commits, the maximum number of page commit
totals since last reboot, the total amount of physical memory in pages, the
amount of physical memory available to user process in pages, the total
amount of system cache memory in pages, the total amount of the sum of paged
and nonpaged kernel pools in pages, the total amount of paged kernel pool in
pages, the total amount of nonpaged kernel pool in pages, the size of a
page, the total number of open handles, the total number of processes and
the total number of threads.
- Added support for returning information from WTSQuerySessionInformation.
- Memory dump is shown as upper case hex now.
- Now reports the info returned from GetCurrentHwProfile.
- Segment registers are now shown as 4 byte values
V1.10 (24 January 2008)
- Updated to support creating minidumps
- The location for the logging file and the minidump file is now your temp
directory. This means that files will be correctly created even with
least-privileged user accounts, and it also prevents the files from taking
up hard drive space after they are no longer needed.
- The name for the logging file is "YYMMDDHHMMSSmmm_name of
exe.exception".
- The name for the minidump file is "YYMMDDHHMMSSmmm_name of exe.dmp".
- Support for EXCEPTION_LOGGER_ONE_EXCEPTION_PER_FILE has been dropped as
now the filenames include timestamps to make them unique.
- Updated sample app to clean compile on VC 2005 + VC 2008.
- Updated copyright details.
- Updated sample app to remove VC 6 style appwizard comments
- Updated sample app to use C++ style casts instead of C style casts
- Because the logging and minidump files now are hard coded to include
timestamps, the SetXCPTHLRFileName function has been replaced with
SetXCPTHLRDirectory. By default this is set to your temp directory. A
corollary SetXCPTHLRDirectory function is now also available.
- Updated usage instructions in the documentation.
- Binaries included in download are now build with VC 2005 SP1
V1.11 (4 June 2012)
- Updated copyright details.
- The code now only supports VC 2005 or later.
- Updated project settings to more modern defaults.
- Code now compiles cleanly using Code Analysis (/analyze)
- Fixed a bug in reporting of the SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentType
value.
- The class and DLL now allows the exception handler to be tested in debug
mode through the use of XCPTHLRGenerateSampleException and CExceptionLogger::GenerateSampleException
- Fixed a file handle leak in CExceptionLogger::GenerateMiniDump.
- The Log directory and not the Log file name is now read from the registry.
- The default flag values and the location of the log directory are now
read from HKEY_CURRENT_USER instead of HKEY_LOCAL_MACHINE. This helps avoid
Registry virtualization issues on Windows Vista or later.
- Fixed issues in the format string when using a MEMORYSTATUS struct with
GlobalMemoryStatus.
- The Processor architecture as returned from GetSystemInfo is now logged.
- The Allocation granularity as returned from GetSystemInfo is now logged.
- The Processor level as returned from GetSystemInfo is now logged.
- The Processor revision as returned from GetSystemInfo is now
logged.
- The active processor mask as returned from GetSystemInfo is now logged.
- LogSystemDetails now supports logging information about Windows Server
2008, 2008 R2, 2012, Vista, 7 and 8.
- More OSVERSIONINFOEX::wSuiteMask values are now logged
- LogSystemDetails now support GR_GDIOBJECTS_PEAK
- LogSystemDetails now supports GR_USEROBJECTS_PEAK
- LogSystemDetails now supports IsProcessorFeaturePresent(PF_CHANNELS_ENABLED)
- LogSystemDetails now supports IsProcessorFeaturePresent(PF_XSAVE_ENABLED)
- The data logged by calling GetNativeSystemInfo is now consistent with
the same set of data which GetSystemInfo reports.
- LogSystemDetails now logs details for all the CPUs on the computer
- LogSystemDetails now supports BuildGUID, BuildLab, BuildLabEx &
InstallDate values from HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion
- Code now displays detailed information about multi monitor setups
- The code now correctly reports 24 and 32 bit color depths via
WTS_CLIENT_DISPLAY when in a terminal services environment.
- Fixed a problem getting a function pointer to
WTSGetActiveConsoleSessionId function.
- SetDirectory method now supports auto expansion of system environment
variables
- Fixed a bug in the setup of the "IMAGEHLP_LINE64 LineInfo" prior to the
call to SymGetLineFromAddr64. Thanks to Michael Schaart for reporting this
issue.
- WTSInitialProgram and WTSSessionId details are now displayed when in a
terminal services environment.
Planned Enhancements
- If you have any other suggested improvements, please let me know so that
I can incorporate them into the next release.
Contacting the Author
PJ Naughter
Email: pjna@naughter.com
Web: http://www.naughter.com
4 June 2012