← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2554: Store crash reports in a CrashLog.txt file

 

------------------------------------------------------------
revno: 2554
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2011-06-13 00:41:02 +0200
message:
  Store crash reports in a CrashLog.txt file
removed:
  LICENSE-GeoIP.txt
added:
  win32/CrashLogger.cpp
  win32/CrashLogger.h
renamed:
  LICENSE-OpenSSL.txt => ThirdPartyLicenses.txt
modified:
  Compile.txt
  SConstruct
  changelog.txt
  dwt/include/dwt/Application.h
  dwt/src/Application.cpp
  installer/DCPlusPlus.nsi
  win32/SConscript
  win32/main.cpp
  ThirdPartyLicenses.txt


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'Compile.txt'
--- Compile.txt	2011-06-04 18:26:04 +0000
+++ Compile.txt	2011-06-12 22:41:02 +0000
@@ -107,13 +107,17 @@
 
 4.  Other information and submitting patches
 
-		a. By the way, with doxygen, graphviz and some luck you can use the supplied doxygen
-		configuration file to generate some nice docs...just check that the paths in doxyfile are
-		correct (graphviz)...
-		
+		a. With doxygen, graphviz and some luck, you can use the supplied doxygen configuration
+		file to generate some nice docs. Just check that the paths in the doxyfile are correct.
+
 		b. In the event you experience crashing you can check the howto guide for debugging
 		at <https://answers.launchpad.net/dcplusplus/+faq/337>
 
+		Note that DCPlusPlus.exe is stripped by default when it has been built with MinGW;
+		debugging symbols instead reside in DCPlusPlus.pdb. To get GDB to swallow it, start it with
+		the following command:
+			gdb -e DCPlusPlus.exe -s DCPlusPlus.pdb
+
 		c. Linux / Unix:
 
 			Look at <http://launchpad.net/linuxdcpp> for the *nix port of DC++ - they'll gladly accept any help. 	

=== removed file 'LICENSE-GeoIP.txt'
--- LICENSE-GeoIP.txt	2004-09-27 12:12:46 +0000
+++ LICENSE-GeoIP.txt	1970-01-01 00:00:00 +0000
@@ -1,74 +0,0 @@
-There are two licenses, one for the C library software, and one for
-the database.
-
-SOFTWARE LICENSE (C library)
-
-The GeoIP C Library is licensed under the GPL.  For details see
-the COPYING file.
-
-OPEN DATA LICENSE (GeoIP Standard Edition Database)
-
-Copyright (c) 2003 MaxMind LLC.  All Rights Reserved.
-
-All advertising materials and documentation mentioning features or use of
-this database must display the following acknowledgment:
-"This product includes GeoIP data created by MaxMind, available from
-http://maxmind.com/";
-
-Redistribution and use with or without modification, are permitted provided
-that the following conditions are met:
-1. Redistributions must retain the above copyright notice, this list of
-conditions and the following disclaimer in the documentation and/or other
-materials provided with the distribution. 
-2. All advertising materials and documentation mentioning features or use of
-this database must display the following acknowledgement:
-"This product includes GeoIP data created by MaxMind, available from
-http://maxmind.com/";
-3. "MaxMind" may not be used to endorse or promote products derived from this
-database without specific prior written permission.
-
-THIS DATABASE IS PROVIDED BY MAXMIND.COM ``AS IS'' AND ANY 
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
-DISCLAIMED. IN NO EVENT SHALL MAXMIND.COM BE LIABLE FOR ANY 
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
-DATABASE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Some parts of this software distribution are derived from the APNIC, ARIN and
-RIPE databases (copyright details below). The author of this module makes no
-claims of ownership on those parts.
-
-APNIC conditions of use:
-
-The files are freely available for download and use on the condition that APNIC
-will not be held responsible for any loss or damage arising from the application
-of the information contained in these reports.
-
-APNIC endeavours to the best of its ability to ensure the accuracy of these
-reports; however, APNIC makes no guarantee in this regard.
-
-In particular, it should be noted that these reports seek to indicate the
-country where resources were first allocated or assigned. It is not intended
-that these reports be considered as an authoritative statement of the location
-in which any specific resource may currently be in use.
-
-ARIN database copyright:
-
-Copyright (c) American Registry for Internet Numbers. All rights reserved.
-
-RIPE database copyright:
-
-The information in the RIPE Database is available to the public for agreed
-Internet operation purposes, but is under copyright. The copyright statement is:
-
-"Except for agreed Internet operational purposes, no part of this publication
-may be reproduced, stored in a retrieval system, or transmitted, in any form or
-by any means, electronic, mechanical, recording, or otherwise, without prior
-permission of the RIPE NCC on behalf of the copyright holders. Any use of this
-material to target advertising or similar activities is explicitly forbidden and
-may be prosecuted. The RIPE NCC requests to be notified of any such activities
-or suspicions thereof."

=== modified file 'SConstruct'
--- SConstruct	2011-05-04 19:32:00 +0000
+++ SConstruct	2011-06-12 22:41:02 +0000
@@ -245,6 +245,8 @@
 	conf.env.Append(CPPDEFINES='HAVE_HTMLHELP_H')
 if conf.CheckCXXHeader('natupnp.h', '<>'):
 	conf.env.Append(CPPDEFINES='HAVE_NATUPNP_H')
+if 'gcc' in env['TOOLS'] and conf.CheckCXXHeader('bfd.h', '<>'):
+	conf.env.Append(CPPDEFINES='HAVE_BFD_H')
 env = conf.Finish()
 
 dev.boost = dev.build('boost/')

=== renamed file 'LICENSE-OpenSSL.txt' => 'ThirdPartyLicenses.txt'
--- LICENSE-OpenSSL.txt	2007-10-16 07:40:22 +0000
+++ ThirdPartyLicenses.txt	2011-06-12 22:41:02 +0000
@@ -1,3 +1,91 @@
+--- backtrace-mingw license ---
+
+	Copyright (c) 2010 ,
+		Cloud Wu . All rights reserved.
+
+		http://www.codingnow.com
+
+	Use, modification and distribution are subject to the "New BSD License"
+	as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.
+
+--- GeoIP license ---
+
+There are two licenses, one for the C library software, and one for
+the database.
+
+SOFTWARE LICENSE (C library)
+
+The GeoIP C Library is licensed under the GPL.  For details see
+the COPYING file.
+
+OPEN DATA LICENSE (GeoIP Standard Edition Database)
+
+Copyright (c) 2003 MaxMind LLC.  All Rights Reserved.
+
+All advertising materials and documentation mentioning features or use of
+this database must display the following acknowledgment:
+"This product includes GeoIP data created by MaxMind, available from
+http://maxmind.com/";
+
+Redistribution and use with or without modification, are permitted provided
+that the following conditions are met:
+1. Redistributions must retain the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other
+materials provided with the distribution. 
+2. All advertising materials and documentation mentioning features or use of
+this database must display the following acknowledgement:
+"This product includes GeoIP data created by MaxMind, available from
+http://maxmind.com/";
+3. "MaxMind" may not be used to endorse or promote products derived from this
+database without specific prior written permission.
+
+THIS DATABASE IS PROVIDED BY MAXMIND.COM ``AS IS'' AND ANY 
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL MAXMIND.COM BE LIABLE FOR ANY 
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+DATABASE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Some parts of this software distribution are derived from the APNIC, ARIN and
+RIPE databases (copyright details below). The author of this module makes no
+claims of ownership on those parts.
+
+APNIC conditions of use:
+
+The files are freely available for download and use on the condition that APNIC
+will not be held responsible for any loss or damage arising from the application
+of the information contained in these reports.
+
+APNIC endeavours to the best of its ability to ensure the accuracy of these
+reports; however, APNIC makes no guarantee in this regard.
+
+In particular, it should be noted that these reports seek to indicate the
+country where resources were first allocated or assigned. It is not intended
+that these reports be considered as an authoritative statement of the location
+in which any specific resource may currently be in use.
+
+ARIN database copyright:
+
+Copyright (c) American Registry for Internet Numbers. All rights reserved.
+
+RIPE database copyright:
+
+The information in the RIPE Database is available to the public for agreed
+Internet operation purposes, but is under copyright. The copyright statement is:
+
+"Except for agreed Internet operational purposes, no part of this publication
+may be reproduced, stored in a retrieval system, or transmitted, in any form or
+by any means, electronic, mechanical, recording, or otherwise, without prior
+permission of the RIPE NCC on behalf of the copyright holders. Any use of this
+material to target advertising or similar activities is explicitly forbidden and
+may be prosecuted. The RIPE NCC requests to be notified of any such activities
+or suspicions thereof."
+
+--- OpenSSL license ---
 
   LICENSE ISSUES
   ==============

=== modified file 'changelog.txt'
--- changelog.txt	2011-06-04 18:26:04 +0000
+++ changelog.txt	2011-06-12 22:41:02 +0000
@@ -30,6 +30,7 @@
 * DC++ survives a Windows theme change better (poy)
 * Remove the license page from the installer
 * Update OpenSSL to version 1.0.0d
+* [L#189241] Store crash reports in a CrashLog.txt file (poy)
 
 -- 0.782 2011-03-05 --
 * Prevent a remote crash triggered via malformed user commands (poy)

=== modified file 'dwt/include/dwt/Application.h'
--- dwt/include/dwt/Application.h	2011-04-15 20:53:17 +0000
+++ dwt/include/dwt/Application.h	2011-06-12 22:41:02 +0000
@@ -130,8 +130,7 @@
 	void callAsync(const Callback& f);
 
 	/** Runs the message pump, and doesn't return until application should quit.
-	 * Normally this function will be called from your
-	 * "SmartWinMain(SmartWin::Application & app )" function as the last function.
+	 * Normally this function is called from dwtMain.
 	 */
 	void run();
 

=== modified file 'dwt/src/Application.cpp'
--- dwt/src/Application.cpp	2011-06-02 18:20:54 +0000
+++ dwt/src/Application.cpp	2011-06-12 22:41:02 +0000
@@ -41,7 +41,7 @@
 #include <dwt/widgets/Control.h>
 #include <assert.h>
 
-extern int SmartWinMain(dwt::Application & app);
+extern int dwtMain(dwt::Application& app);
 
 namespace dwt {
 
@@ -275,13 +275,11 @@
 
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 {
-	unsigned int retVal = 0;
-
 	dwt::Application::init(nCmdShow);
 
-	retVal = SmartWinMain(dwt::Application::instance()); // Call library user's startup function.
+	int ret = dwtMain(dwt::Application::instance()); // Call library user's startup function.
 
 	dwt::Application::uninit();
 
-	return retVal;
+	return ret;
 }

=== modified file 'installer/DCPlusPlus.nsi'
--- installer/DCPlusPlus.nsi	2011-06-04 19:55:52 +0000
+++ installer/DCPlusPlus.nsi	2011-06-12 22:41:02 +0000
@@ -96,9 +96,9 @@
   File "dcppboot.xml"
   File "DCPlusPlus.chm"
   File "DCPlusPlus.exe"
+  File "DCPlusPlus.pdb"
   File "License.txt"
-  File "LICENSE-GeoIP.txt"
-  File "LICENSE-OpenSSL.txt"
+  File "ThirdPartyLicenses.txt"
 
   ; Add the whole locale directory
   File /r "locale"
@@ -199,11 +199,13 @@
   Delete "$INSTDIR\cshelp.rtf"
   Delete "$INSTDIR\dcppboot.xml"
   Delete "$INSTDIR\DCPlusPlus.chm"
+  Delete "$INSTDIR\DCPlusPlus.pdb"
   Delete "$INSTDIR\License.txt"
-  Delete "$INSTDIR\LICENSE-GeoIP.txt"
-  Delete "$INSTDIR\LICENSE-OpenSSL.txt"
+  Delete "$INSTDIR\LICENSE-GeoIP.txt" ; now in ThirdPartyLicenses; remove if present.
+  Delete "$INSTDIR\LICENSE-OpenSSL.txt" ; now in ThirdPartyLicenses; remove if present.
   Delete "$INSTDIR\mingwm10.dll" ; no longer required, remove if present.
   Delete "$INSTDIR\GeoIPCountryWhois.csv"
+  Delete "$INSTDIR\ThirdPartyLicenses.txt"
 
   ; Delete the whole locale directory
   RMDir /r "$INSTDIR\locale"

=== added file 'win32/CrashLogger.cpp'
--- win32/CrashLogger.cpp	1970-01-01 00:00:00 +0000
+++ win32/CrashLogger.cpp	2011-06-12 22:41:02 +0000
@@ -0,0 +1,399 @@
+/*
+* Copyright (C) 2001-2011 Jacek Sieka, arnetheduck on gmail point com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "stdafx.h"
+#include "CrashLogger.h"
+
+#include <dcpp/Util.h>
+#include <dcpp/version.h>
+#include "WinUtil.h"
+
+namespace {
+
+FILE* f;
+
+#if defined(__MINGW32__) && defined(HAVE_BFD_H) && !defined(_WIN64)
+
+/* This backtrace writer for MinGW comes from the backtrace-mingw project by Cloud Wu:
+<http://code.google.com/p/backtrace-mingw/> */
+
+/*
+	Copyright (c) 2010 ,
+		Cloud Wu . All rights reserved.
+
+		http://www.codingnow.com
+
+	Use, modification and distribution are subject to the "New BSD License"
+	as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.
+*/
+
+#include <bfd.h>
+#include <imagehlp.h>
+
+struct bfd_ctx {
+	bfd * handle;
+	asymbol ** symbol;
+};
+
+struct bfd_set {
+	char * name;
+	bfd_ctx * bc;
+	bfd_set *next;
+};
+
+struct find_info {
+	asymbol **symbol;
+	bfd_vma counter;
+	const char *file;
+	const char *func;
+	unsigned line;
+};
+
+void lookup_section(bfd *abfd, asection *sec, void *opaque_data)
+{
+	find_info *data = reinterpret_cast<find_info*>(opaque_data);
+
+	if (data->func)
+		return;
+
+	if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
+		return;
+
+	bfd_vma vma = bfd_get_section_vma(abfd, sec);
+	if (data->counter < vma || vma + bfd_get_section_size(sec) <= data->counter)
+		return;
+
+	bfd_find_nearest_line(abfd, sec, data->symbol, data->counter - vma, &(data->file), &(data->func), &(data->line));
+}
+
+void find(bfd_ctx * b, DWORD offset, const char **file, const char **func, unsigned *line)
+{
+	find_info data = { b->symbol, offset };
+
+	bfd_map_over_sections(b->handle, &lookup_section, &data);
+
+	*file = data.file;
+	*func = data.func;
+	*line = data.line;
+}
+
+bool init_bfd_ctx(bfd_ctx *bc, const char * procname)
+{
+	bc->handle = 0;
+	bc->symbol = 0;
+
+	bfd *b = bfd_openr(procname, 0);
+	if (!b) {
+		fprintf(f, "Failed to open bfd from %s\r\n", procname);
+		return false;
+	}
+
+	int r1 = bfd_check_format(b, bfd_object);
+	int r2 = bfd_check_format_matches(b, bfd_object, 0);
+	int r3 = bfd_get_file_flags(b) & HAS_SYMS;
+
+	if (!(r1 && r2 && r3)) {
+		bfd_close(b);
+		fprintf(f, "Failed to init bfd from %s\r\n", procname);
+		return false;
+	}
+
+	void *symbol_table;
+
+	unsigned dummy = 0;
+	if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) {
+		if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) {
+			free(symbol_table);
+			bfd_close(b);
+			fprintf(f, "Failed to read symbols from %s\r\n", procname);
+			return false;
+		}
+	}
+
+	bc->handle = b;
+	bc->symbol = reinterpret_cast<asymbol**>(symbol_table);
+
+	return true;
+}
+
+void close_bfd_ctx(bfd_ctx *bc)
+{
+	if (bc) {
+		if (bc->symbol) {
+			free(bc->symbol);
+		}
+		if (bc->handle) {
+			bfd_close(bc->handle);
+		}
+	}
+}
+
+bfd_ctx * get_bc(bfd_set *set, const char *procname)
+{
+	while(set->name) {
+		if (strcmp(set->name, procname) == 0) {
+			return set->bc;
+		}
+		set = set->next;
+	}
+	bfd_ctx bc;
+	if(!init_bfd_ctx(&bc, procname)) {
+		return 0;
+	}
+	set->next = reinterpret_cast<bfd_set*>(calloc(1, sizeof(*set)));
+	set->bc = reinterpret_cast<bfd_ctx*>(malloc(sizeof(bfd_ctx)));
+	memcpy(set->bc, &bc, sizeof(bc));
+	set->name = strdup(procname);
+
+	return set->bc;
+}
+
+void release_set(bfd_set *set)
+{
+	while(set) {
+		bfd_set * temp = set->next;
+		free(set->name);
+		close_bfd_ctx(set->bc);
+		free(set);
+		set = temp;
+	}
+}
+
+// add some x64 defs that MinGW is missing.
+#define DWORD64 DWORD
+#define STACKFRAME64 STACKFRAME
+#define IMAGEHLP_SYMBOL64 IMAGEHLP_SYMBOL
+#define StackWalk64 StackWalk
+#define SymFunctionTableAccess64 SymFunctionTableAccess
+#define SymGetModuleBase64 SymGetModuleBase
+#define SymGetSymFromAddr64 SymGetSymFromAddr
+
+#elif defined(_MSC_VER)
+
+#include <dbghelp.h>
+
+// Nothing special for MSVC besides that include file.
+
+#else
+
+#define NO_BACKTRACE
+
+#endif
+
+inline void writeAppInfo() {
+	fputs(Util::formatTime(APPNAME " has crashed on %Y-%m-%d at %H:%M:%S.\r\n", time(0)).c_str(), f);
+	fputs("Please report this data to the " APPNAME " team for further investigation.\r\n\r\n", f);
+
+	fprintf(f, APPNAME " version: %s\r\n", fullVersionString.c_str());
+	fprintf(f, "TTH: %S\r\n", WinUtil::tth.c_str());
+
+#ifdef __MINGW32__
+	fputs("Compiled with GCC " __VERSION__, f);
+#else
+	fprintf(f, "Compiled with MS Visual Studio %d", _MSC_VER);
+#endif
+#ifdef _DEBUG
+	fputs(" (debug)", f);
+#endif
+#ifdef _WIN64
+	fputs(" (x64)", f);
+#endif
+	fputs("\r\n", f);
+}
+
+inline void writePlatformInfo() {
+	OSVERSIONINFOEX ver = { sizeof(OSVERSIONINFOEX) };
+	if(!::GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&ver)))
+		ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+	if(::GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&ver))) {
+		fprintf(f, "Windows version: major = %d, minor = %d, build = %d, SP = %d, type = %d\r\n",
+			ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber, ver.wServicePackMajor, ver.wProductType);
+
+	} else {
+		fprintf(f, "Windows version: unknown\r\n");
+	}
+
+	SYSTEM_INFO info;
+	::GetNativeSystemInfo(&info);
+	fprintf(f, "Processors: %d * %s\n", info.dwNumberOfProcessors,
+		(info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ? "x64" :
+		(info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) ? "x86" :
+		(info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) ? "ia64" :
+		"[unknown architecture]");
+}
+
+#ifndef NO_BACKTRACE
+
+inline void writeBacktrace(LPCONTEXT context)
+{
+	HANDLE process = GetCurrentProcess();
+	HANDLE thread = GetCurrentThread();
+
+#ifdef __MINGW32__
+	SymSetOptions(SYMOPT_DEFERRED_LOADS);
+#else
+	SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
+#endif
+
+	if(!SymInitialize(process, 0, TRUE)) {
+		fputs("Failed to init symbol context\r\n", f);
+		return;
+	}
+
+#ifdef __MINGW32__
+	bfd_init();
+	bfd_set *set = reinterpret_cast<bfd_set*>(calloc(1, sizeof(*set)));
+
+	bfd_ctx *bc = 0;
+#endif
+
+	STACKFRAME64 frame;
+	memset(&frame, 0, sizeof(frame));
+
+	frame.AddrPC.Mode = AddrModeFlat;
+	frame.AddrFrame.Mode = AddrModeFlat;
+	frame.AddrStack.Mode = AddrModeFlat;
+
+#ifdef _WIN64
+	frame.AddrPC.Offset = context->Rip;
+	frame.AddrFrame.Offset = context->Rbp;
+	frame.AddrStack.Offset = context->Rsp;
+
+#define WALK_ARCH IMAGE_FILE_MACHINE_AMD64
+
+#else
+	frame.AddrPC.Offset = context->Eip;
+	frame.AddrFrame.Offset = context->Ebp;
+	frame.AddrStack.Offset = context->Esp;
+
+#define WALK_ARCH IMAGE_FILE_MACHINE_I386
+
+#endif
+
+	char symbol_buffer[sizeof(IMAGEHLP_SYMBOL64) + 255];
+	char module_name_raw[MAX_PATH];
+
+	// get the current module address.
+	HMODULE module = ::GetModuleHandle(0);
+
+	for(uint8_t depth = 0; depth <= 128; ++depth) {
+
+		if(!StackWalk64(WALK_ARCH, process, thread, &frame, context,
+			0, SymFunctionTableAccess64, SymGetModuleBase64, 0)) { break; }
+
+		HMODULE module_base = reinterpret_cast<HMODULE>(SymGetModuleBase64(process, frame.AddrPC.Offset));
+
+		const char * module_name = 0;
+		if(module_base) {
+			if(module_base == module) {
+				module_name = "DCPlusPlus.pdb";
+			} else if(GetModuleFileNameA(module_base, module_name_raw, MAX_PATH)) {
+				module_name = module_name_raw;
+			}
+		}
+		if(module_name) {
+#ifdef __MINGW32__
+			bc = get_bc(set, module_name);
+#endif
+		} else {
+			module_name = "[unknown module]";
+		}
+
+		const char* file = 0;
+		const char* func = 0;
+		unsigned line = 0;
+
+#ifdef __MINGW32__
+		if(bc) {
+			find(bc, frame.AddrPC.Offset, &file, &func, &line);
+		}
+#endif
+
+		if(file == 0) {
+			DWORD64 dummy = 0;
+			IMAGEHLP_SYMBOL64* symbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(symbol_buffer);
+			symbol->SizeOfStruct = (sizeof *symbol) + 255;
+			symbol->MaxNameLength = 254;
+			if(SymGetSymFromAddr64(process, frame.AddrPC.Offset, &dummy, symbol)) {
+				file = symbol->Name;
+			} else {
+				file = "[unknown file]";
+			}
+		}
+
+#ifdef _MSC_VER
+		IMAGEHLP_LINE64 info = { sizeof(IMAGEHLP_LINE64) };
+		DWORD dummy = 0;
+		if(SymGetLineFromAddr64(process, frame.AddrPC.Offset, &dummy, &info)) {
+			func = file;
+			file = info.FileName;
+			line = info.LineNumber;
+		}
+#endif
+
+		if(func == 0) {
+			fprintf(f, "0x%x - %s - %s\r\n", frame.AddrPC.Offset, module_name, file);
+		} else {
+			fprintf(f, "0x%x - %s - %s (%d) - in function %s\r\n", frame.AddrPC.Offset, module_name, file, line, func);
+		}
+	}
+
+#ifdef __MINGW32__
+	release_set(set);
+#endif
+
+	SymCleanup(process);
+}
+
+#endif // NO_BACKTRACE
+
+LONG WINAPI exception_filter(LPEXCEPTION_POINTERS info)
+{
+	f = fopen((Util::getPath(Util::PATH_USER_LOCAL) + "CrashLog.txt").c_str(), "w");
+	if(f) {
+		writeAppInfo();
+
+		fprintf(f, "Exception code: %x\r\n", info->ExceptionRecord->ExceptionCode);
+
+		writePlatformInfo();
+
+#ifdef NO_BACKTRACE
+		fputs("\r\nStack trace unavailable: this program hasn't been compiled with backtrace support\r\n", f);
+#else
+		fputs("\r\nWriting the stack trace...\r\n\r\n", f);
+		writeBacktrace(info->ContextRecord);
+#endif
+
+		fputs("\r\nInformation about the crash has been written.\r\n", f);
+		fclose(f);
+	}
+	return EXCEPTION_CONTINUE_SEARCH;
+}
+
+LPTOP_LEVEL_EXCEPTION_FILTER prevFilter;
+
+} // anonymous namespace
+
+CrashLogger::CrashLogger() {
+	prevFilter = SetUnhandledExceptionFilter(exception_filter);
+}
+
+CrashLogger::~CrashLogger() {
+	SetUnhandledExceptionFilter(prevFilter);
+}

=== added file 'win32/CrashLogger.h'
--- win32/CrashLogger.h	1970-01-01 00:00:00 +0000
+++ win32/CrashLogger.h	2011-06-12 22:41:02 +0000
@@ -0,0 +1,27 @@
+/*
+* Copyright (C) 2001-2011 Jacek Sieka, arnetheduck on gmail point com
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef DCPLUSPLUS_WIN32_CRASH_LOGGER_H
+#define DCPLUSPLUS_WIN32_CRASH_LOGGER_H
+
+struct CrashLogger {
+	CrashLogger();
+	~CrashLogger();
+};
+
+#endif // DCPLUSPLUS_WIN32_CRASH_LOGGER_H

=== modified file 'win32/SConscript'
--- win32/SConscript	2011-04-15 20:53:17 +0000
+++ win32/SConscript	2011-06-12 22:41:02 +0000
@@ -17,6 +17,13 @@
 
 env.Append(LIBS = ['comctl32', 'ws2_32', 'ole32', 'gdi32', 'comdlg32', 'iphlpapi', 'winmm', 'shlwapi', 'oleaut32', 'uuid'])
 
+# add libs for the crash logger.
+if env['LINK'] == 'g++': # MinGW
+	if 'HAVE_BFD_H' in env['CPPDEFINES']:
+		env.Append(LIBS = ['bfd', 'iberty', 'imagehlp'])
+elif env['LINK'] == 'link': # MSVC
+	env.Append(LIBS = ['dbghelp'])
+
 env.Append(CPPPATH = ['#/openssl/include', '#/bzip2', '#/zlib', '#/miniupnpc', '#/dwt/include'])
 
 openssl_lib = '#/openssl/lib/'
@@ -38,4 +45,9 @@
 dev.i18n(source_path, env, [sources,headers], 'dcpp-win32')
 
 ret = env.Program(target, [sources, res, dev.client, dev.zlib, dev.boost, dev.bzip2, dev.miniupnpc, dev.natpmp, dev.dwt, dev.intl])
+
+if 'gcc' in env['TOOLS']:
+	# strip debug info to a separate PDB file
+	env.Command(target + '.pdb', target + '.exe', 'strip --only-keep-debug "$SOURCE" -o "$TARGET"')
+
 Return('ret')

=== modified file 'win32/main.cpp'
--- win32/main.cpp	2011-04-07 13:40:55 +0000
+++ win32/main.cpp	2011-06-12 22:41:02 +0000
@@ -20,6 +20,7 @@
 
 #include <exception>
 
+#include "CrashLogger.h"
 #include "SingleInstance.h"
 #include "WinUtil.h"
 #include "MainWindow.h"
@@ -75,7 +76,7 @@
 }
 #endif
 
-int SmartWinMain(dwt::Application& app) {
+int dwtMain(dwt::Application& app) {
 #ifdef _DEBUG
 	old_handler = std::set_terminate(&term_handler);
 
@@ -93,6 +94,8 @@
 
 	Util::initialize();
 
+	CrashLogger crashLogger;
+
 	string configPathHash;
 	{
 		std::string configPath = Util::getPath(Util::PATH_USER_CONFIG);