DrMinGW is a fancy crash detection program for MinGW programs. Details can be found here:


One of the really cool features of DrMinGW is you can alternatively invoke a DLL from your program to catch your crashes, instead of requiring you or your testers to install DrMinGW.

The problem is the library and DLL aren’t available for download, and building it from sources requires SCONS, which I can’t seem to get to work with it. So, my solution is to build it manually. Unfortunately, building it requires knowledge of some of the secret defines set by SCONS.

After much digging, building the DLL should have been:

gcc -c -I include -DPACKAGE="drmingw" -DPACKAGE_VERSION="0.4.4" exchndl.c
gcc -shared -o exchndl.dll exchndl.o -lbfd -liberty -lintl -mwindows -Wl,--out-implib,libexchndl.a

The samples can be built now as follows:

gcc -o test.exe -O0 -gstabs3 test.c exchndl2.cxx
g++ -o testcpp.exe -O0 -gstabs3 testcpp.cxx exchndl2.cxx

NOTE: “-gstabs3” symbols are required by DrMingW.

Now you can run test.exe or testcpp.exe and watch them crash. Be sure copy exchndl.dll alongside the executables. The way it works is: If there’s no DLL, then nothing happens; If there is a DLL, an RPT report file is written.

If you read the documentation for DrMinGW, what may not be entirely obvious with exchndl.dll is that it doesn’t pop up a box, but instead writes an RPT file relative your executable (myapp.exe -> myapp.RPT).

Relative the executable is alright for debugging, but once your game/app is installed by a user you no longer have permission to write relative your executable (unless you get elevated privileges). My solution is to write the report file somewhere safe instead. Below is a modified “OnStartup()” function that places the report in your roaming profile. Overwrite the original function found inside “exchndl.c” (#includes and all).

#include <shlobj.h>
#include <direct.h>

static void OnStartup(void) __attribute__((constructor));

void OnStartup(void)
	// Install the unhandled exception filter function
	prevExceptionFilter = SetUnhandledExceptionFilter(TopLevelExceptionFilter);
	// Figure out what the report file will be named, and store it away
	if(GetModuleFileName(NULL, szLogFileName, MAX_PATH))
		LPTSTR lpszDot;
		// Look for the '.' before the "EXE" extension.  Replace the extension
		// with "RPT"
		if((lpszDot = _tcsrchr(szLogFileName, _T('.'))))
			lpszDot++;	// Advance past the '.'
			_tcscpy(lpszDot, _T("RPT"));	// "RPT" -> "Report"
			_tcscat(szLogFileName, _T(".RPT"));
	else if(GetWindowsDirectory(szLogFileName, MAX_PATH))
		_tcscat(szLogFileName, _T("EXCHNDL.RPT"));

		LPTSTR lpszSlash;
		static TCHAR szLogFileCopy[MAX_PATH];
		// Back up the filename part, as we're about to destroy it
		if((lpszSlash = _tcsrchr(szLogFileName, _T('\\')))) {
			lpszSlash++; // Advance past the '\'
			_tcscpy(szLogFileCopy, lpszSlash); // Copy just the name part
			// Overwrite szLogFileName to a safe place to write things
			SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, 1, szLogFileName );

			// Modify this line to change the folder where your report is written
			// (Just in case) Create the directory
			_tmkdir( szLogFileName );
			// Finally, copy the name part

Now if you’re to browse to your roaming profile directory, you’ll find the report.


Static libintl

When building the DLL, a static alternative to libintl (the -lintl part) can be found here:


Be sure to link against “libintl.a” and “win_iconv.c”.

gcc -c -I include -DPACKAGE="drmingw" -DPACKAGE_VERSION="0.4.4" exchndl.c
gcc -shared -o exchndl.dll exchndl.o -lbfd -liberty libintl/libintl.a libintl/win_iconv.c -mwindows -Wl,--out-implib,libexchndl.a
strip exchndl.dll

Stripping to cut down the size. Should be closer to 700K now instead of 5M.

NEW: Pidgen’s Modified DrMinGW

The folks behind the Pidgen chat client have provided an improved version of the original DrMinGW (exchndl.dll):


It exists because of a discussion over here on how exploitable it could be:


And more details on the exploit itself are here. A pretty blatant one that probably every application that loads dll’s is venerable to in some way.

One solution… maybe. MinGW lacks Softpub.h (and wintrust.lib), so this maybe a VC build only thing. I’m not sure though if MinGW’s DLL loader is the same as VC. Heh, getting very Windows meta here. 😀