changeset 70:6bdecc3f4569

Get rid of win32 bindings
author korDen
date Sat, 28 Aug 2010 10:51:32 +0400
parents c876339731a4
children 8e24ef1dd139
files commands.txt dbg/CallStackInfo.d dbg/image/PE.d dbg/ui/CrashWindow.d dlib/CrashHandler.d main.d
diffstat 6 files changed, 665 insertions(+), 874 deletions(-) [+]
line wrap: on
line diff
--- a/commands.txt	Tue Aug 24 16:59:45 2010 +0400
+++ b/commands.txt	Sat Aug 28 10:51:32 2010 +0400
@@ -19,11 +19,7 @@
 ddmd.def
 C:\dmd2.032\src\dmd\dmd.lib
 main.d
-win32\windef.d
-win32\winuser.d
-win32\wingdi.d
-dlib\CrashHandler.d
-dbg\ui\CrashWindow.d
+dbg\CallStackInfo.d
 dbg\Debug.d
 dbg\symbol\CodeView.d
 dbg\image\PE.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbg/CallStackInfo.d	Sat Aug 28 10:51:32 2010 +0400
@@ -0,0 +1,257 @@
+/**
+ A simple runtime crash handler which collects various informations about
+ the crash such as registers, stack traces, and loaded modules.
+
+ TODO:
+	* Threading support
+	* Stack dumps
+
+ Authors:
+	Jeremie Pelletier
+
+ License:
+	Public Domain
+*/
+module dbg.CallStackInfo;
+
+import dbg.Debug;
+import dbg.image.PE;
+
+import core.stdc.stdio;
+import core.sys.windows.windows;
+
+class CallStackInfo
+{
+	this(EXCEPTION_POINTERS* e = null)
+	{
+		size_t[16] buff;
+		size_t[] backtrace = buff[];
+		size_t numTraces = 0;
+		
+		bool skipFirst = false;
+		
+		size_t ip = void, bp = void;
+		if (e !is null) {
+			ip = e.ContextRecord.Eip;
+			bp = e.ContextRecord.Ebp;
+			
+			error = _d_translate_se_to_d_exception(e.ExceptionRecord);
+			append(backtrace, numTraces, ip);
+		} else {
+			asm {
+				mov bp, EBP;
+			}
+		}
+		
+		while (true) {
+			ip = cast(size_t)*(cast(void**)bp + 1);
+			if (ip == 0) break;
+			
+			append(backtrace, numTraces, ip);
+			
+			bp = cast(size_t)*cast(void**)bp;
+		}
+		
+		frames = new StackFrameInfo[numTraces];
+		ResolveStackFrames(backtrace[0..numTraces], frames);
+	}
+	
+	Throwable error;
+	StackFrameInfo[] frames;
+
+	string toString() {
+		string text;
+		
+		if (error !is null) {	
+			text ~= error.toString() ~ "\n";			
+		}
+		
+		text ~= "Stack trace:\n------------------\n";
+		char buffer[128];
+		foreach(ref frame; frames) {
+			with(frame.fileLine) if(line) {
+				auto len = snprintf(buffer.ptr, buffer.length, "%u", line);
+				text ~= file ~ ":" ~ buffer[0 .. len] ~ "\r\n";
+			}
+		}
+
+		text ~= '\0';
+
+		return text;
+	}
+	
+	void dump() {
+		if (error !is null) {	
+			printf("%.*s\n", error.toString());
+		}
+		
+		printf("Stack trace:\n------------------\n");
+		foreach(ref frame; frames) {
+			with(frame.fileLine) if (line) {
+				printf("%.*s:%d\r\n", file, line);
+			}
+		}
+	}
+
+private:
+
+	struct StackFrameInfo {
+		size_t			va;
+		string			moduleName;
+		SymbolInfo		symbol;
+		FileLineInfo	fileLine;
+	}
+
+	struct DebugImage {
+		DebugImage*			next;
+		string				moduleName;
+		size_t				baseAddress;
+		uint				rvaOffset;
+		IExecutableImage	exeModule;
+		ISymbolicDebugInfo	debugInfo;
+	}
+
+	void ResolveStackFrames(size_t[] backtrace, StackFrameInfo[] frames) const {
+		StackFrameInfo* frame = void;
+		DebugImage* imageList, image = void;
+		char[255] buffer = void;
+		uint len = void;
+		uint rva = void;
+
+		version(Windows) MEMORY_BASIC_INFORMATION mbi = void;
+
+		foreach(i, va; backtrace) {
+			frame = &frames[i];
+			frame.va = va;
+
+			// mbi.Allocation base is the handle to stack frame's module
+			VirtualQuery(cast(void*)va, &mbi, MEMORY_BASIC_INFORMATION.sizeof);
+			if(!mbi.AllocationBase) break;
+
+			image = imageList;
+			while(image) {
+				if(image.baseAddress == cast(size_t)mbi.AllocationBase) break;
+				image = image.next;
+			}
+
+			if(!image) {
+				image = new DebugImage;
+
+				with(*image) {
+					next = imageList;
+					imageList = image;
+					baseAddress = cast(size_t)mbi.AllocationBase;
+
+					len = GetModuleFileNameA(cast(HMODULE)baseAddress, buffer.ptr, buffer.length);
+					moduleName = buffer[0 .. len].idup;
+					if (len != 0) {
+						exeModule = new PEImage(moduleName);
+						rvaOffset = baseAddress + exeModule.codeOffset;
+						debugInfo = exeModule.debugInfo;
+					}
+				}
+			}
+
+			frame.moduleName = image.moduleName;
+
+			if(!image.debugInfo) continue;
+
+			rva = va - image.rvaOffset;
+
+			with(image.debugInfo) {
+				frame.symbol = ResolveSymbol(rva);
+				frame.fileLine = ResolveFileLine(rva);
+			}
+		}
+
+		while(imageList) {
+			image = imageList.next;
+			delete imageList.debugInfo;
+			delete imageList.exeModule;
+			delete imageList;
+			imageList = image;
+		}
+	}
+}
+
+void CrashHandlerInit() {
+	//SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS);
+	SetErrorMode(0);
+	SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
+}
+
+enum EXCEPTION_EXECUTE_HANDLER = 1;
+
+extern(Windows) int UnhandledExceptionHandler(EXCEPTION_POINTERS* e) {
+	scope CallStackInfo info = new CallStackInfo(e);
+	info.dump();
+
+	return EXCEPTION_EXECUTE_HANDLER;
+}
+
+extern (Windows) extern UINT SetErrorMode(UINT);
+alias LONG function(EXCEPTION_POINTERS*) PTOP_LEVEL_EXCEPTION_FILTER;
+extern (Windows) PTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(PTOP_LEVEL_EXCEPTION_FILTER);
+
+void append(T)(T[] array, ref size_t index, T value)
+{
+	size_t capacity = array.length;
+	assert(capacity >= index);
+	if (capacity == index) {
+		if (capacity < 8) {
+			capacity = 8;
+		} else {
+			array.length = capacity * 2;
+		}
+	}
+	
+	array[index++] = value;
+}
+
+struct EXCEPTION_POINTERS {
+	EXCEPTION_RECORD* ExceptionRecord;
+	CONTEXT*          ContextRecord;
+}
+
+const size_t EXCEPTION_MAXIMUM_PARAMETERS = 15;
+
+struct EXCEPTION_RECORD {
+	DWORD ExceptionCode;
+	DWORD ExceptionFlags;
+	EXCEPTION_RECORD* ExceptionRecord;
+	PVOID ExceptionAddress;
+	DWORD NumberParameters;
+	DWORD[EXCEPTION_MAXIMUM_PARAMETERS] ExceptionInformation;
+}
+
+const MAXIMUM_SUPPORTED_EXTENSION = 512;
+
+struct CONTEXT {
+	DWORD ContextFlags;
+	DWORD Dr0;
+	DWORD Dr1;
+	DWORD Dr2;
+	DWORD Dr3;
+	DWORD Dr6;
+	DWORD Dr7;
+	FLOATING_SAVE_AREA FloatSave;
+	DWORD SegGs;
+	DWORD SegFs;
+	DWORD SegEs;
+	DWORD SegDs;
+	DWORD Edi;
+	DWORD Esi;
+	DWORD Ebx;
+	DWORD Edx;
+	DWORD Ecx;
+	DWORD Eax;
+	DWORD Ebp;
+	DWORD Eip;
+	DWORD SegCs;
+	DWORD EFlags;
+	DWORD Esp;
+	DWORD SegSs;
+	BYTE[MAXIMUM_SUPPORTED_EXTENSION] ExtendedRegisters;
+}
+
+extern(C) Throwable _d_translate_se_to_d_exception(EXCEPTION_RECORD* exception_record);
\ No newline at end of file
--- a/dbg/image/PE.d	Tue Aug 24 16:59:45 2010 +0400
+++ b/dbg/image/PE.d	Sat Aug 28 10:51:32 2010 +0400
@@ -12,9 +12,7 @@
 */
 module dbg.image.PE;
 
-version(Windows) {
-
-import std.c.string : strncmp;
+import core.stdc.string : strncmp;
 import dbg.Debug;
 import dbg.symbol.CodeView;
 //import dbg.symbol.COFF;
@@ -24,24 +22,7 @@
 //import sys.windows.Information : CloseHandle;
 //import sys.windows.Image;
 
-import win32.windows;
-import win32.winbase;
-
-enum IMAGE_SIZEOF_NT_OPTIONAL64_HEADER = 240;
-
-struct IMAGE_NT_HEADERS64 {
-    DWORD Signature;
-    IMAGE_FILE_HEADER FileHeader;
-    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
-}
-
-auto IMAGE_FIRST_SECTION64( const(IMAGE_NT_HEADERS64*) ntheader ) {
-	return cast(PIMAGE_SECTION_HEADER) ((cast(UINT_PTR)ntheader) + IMAGE_NT_HEADERS64.OptionalHeader.offsetof + (cast(PIMAGE_NT_HEADERS64)(ntheader)).FileHeader.SizeOfOptionalHeader);
-}
-
-auto IMAGE_FIRST_SECTION32( const(IMAGE_NT_HEADERS32*) ntheader ) {
-	return cast(PIMAGE_SECTION_HEADER)((cast(UINT_PTR)ntheader) + IMAGE_NT_HEADERS32.OptionalHeader.offsetof + (cast(PIMAGE_NT_HEADERS32)ntheader).FileHeader.SizeOfOptionalHeader);
-}
+import core.sys.windows.windows;
 
 class PEImage : IExecutableImage {
 	/**
@@ -62,9 +43,9 @@
 			null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, null);
 		if(_file == INVALID_HANDLE_VALUE) SystemException();
 
-		GetFileSizeEx(_file, &_fileSize);
+		_fileSize = GetFileSize(_file, null);
 
-		_map = CreateFileMapping(_file, null, PAGE_READONLY, 0, 0, null);
+		_map = CreateFileMappingA(_file, null, PAGE_READONLY, 0, 0, null);
 		if(!_map) SystemException();
 
 		_view = cast(const(ubyte)*)MapViewOfFile(_map, FILE_MAP_READ, 0, 0, 0);
@@ -139,7 +120,7 @@
 	 Get the raw image data
 	*/
 	const(ubyte)[] data() const {
-		return _view[0 .. cast(size_t)_fileSize.QuadPart];
+		return _view[0 .. _fileSize];
 	}
 
 	/**
@@ -310,13 +291,13 @@
 	 Verify a file offset before accessing it
 	*/
 	void CheckOffset(long offset) const {
-		if(offset > _fileSize.QuadPart) throw new PECorruptedException(this);
+		if (offset > _fileSize) throw new PECorruptedException(this);
 	}
 
 	string							_filename;
 	HANDLE							_file;
 	HANDLE							_map;
-	LARGE_INTEGER					_fileSize;
+	size_t							_fileSize;
 	bool							_is64;
 
 	union {
@@ -358,4 +339,267 @@
 	}
 }
 
-} // version(Windows)
+align(2):
+struct IMAGE_DOS_HEADER {
+	WORD     e_magic;
+	WORD     e_cblp;
+	WORD     e_cp;
+	WORD     e_crlc;
+	WORD     e_cparhdr;
+	WORD     e_minalloc;
+	WORD     e_maxalloc;
+	WORD     e_ss;
+	WORD     e_sp;
+	WORD     e_csum;
+	WORD     e_ip;
+	WORD     e_cs;
+	WORD     e_lfarlc;
+	WORD     e_ovno;
+	WORD[4] e_res;
+	WORD     e_oemid;
+	WORD     e_oeminfo;
+	WORD[10] e_res2;
+	LONG     e_lfanew;
+}
+
+align(4) struct IMAGE_NT_HEADERS32 {
+	DWORD                 Signature;
+	IMAGE_FILE_HEADER     FileHeader;
+	IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+}
+
+align(4) struct IMAGE_NT_HEADERS64 {
+	DWORD                 Signature;
+	IMAGE_FILE_HEADER     FileHeader;
+	IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+}
+
+align(4):
+struct IMAGE_FILE_HEADER {
+	WORD  Machine;
+	WORD  NumberOfSections;
+	DWORD TimeDateStamp;
+	DWORD PointerToSymbolTable;
+	DWORD NumberOfSymbols;
+	WORD  SizeOfOptionalHeader;
+	WORD  Characteristics;
+}
+
+struct IMAGE_OPTIONAL_HEADER32 {
+	WORD  Magic;
+	BYTE  MajorLinkerVersion;
+	BYTE  MinorLinkerVersion;
+	DWORD SizeOfCode;
+	DWORD SizeOfInitializedData;
+	DWORD SizeOfUninitializedData;
+	DWORD AddressOfEntryPoint;
+	DWORD BaseOfCode;
+	DWORD BaseOfData;
+	DWORD ImageBase;
+	DWORD SectionAlignment;
+	DWORD FileAlignment;
+	WORD  MajorOperatingSystemVersion;
+	WORD  MinorOperatingSystemVersion;
+	WORD  MajorImageVersion;
+	WORD  MinorImageVersion;
+	WORD  MajorSubsystemVersion;
+	WORD  MinorSubsystemVersion;
+	DWORD Win32VersionValue;
+	DWORD SizeOfImage;
+	DWORD SizeOfHeaders;
+	DWORD CheckSum;
+	WORD  Subsystem;
+	WORD  DllCharacteristics;
+	DWORD SizeOfStackReserve;
+	DWORD SizeOfStackCommit;
+	DWORD SizeOfHeapReserve;
+	DWORD SizeOfHeapCommit;
+	DWORD LoaderFlags;
+	DWORD NumberOfRvaAndSizes;
+	IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] DataDirectory;
+}
+
+alias ulong ULONGLONG;
+
+struct IMAGE_OPTIONAL_HEADER64 {
+	WORD      Magic;
+	BYTE      MajorLinkerVersion;
+	BYTE      MinorLinkerVersion;
+	DWORD     SizeOfCode;
+	DWORD     SizeOfInitializedData;
+	DWORD     SizeOfUninitializedData;
+	DWORD     AddressOfEntryPoint;
+	DWORD     BaseOfCode;
+	ULONGLONG ImageBase;
+	DWORD     SectionAlignment;
+	DWORD     FileAlignment;
+	WORD      MajorOperatingSystemVersion;
+	WORD      MinorOperatingSystemVersion;
+	WORD      MajorImageVersion;
+	WORD      MinorImageVersion;
+	WORD      MajorSubsystemVersion;
+	WORD      MinorSubsystemVersion;
+	DWORD     Win32VersionValue;
+	DWORD     SizeOfImage;
+	DWORD     SizeOfHeaders;
+	DWORD     CheckSum;
+	WORD      Subsystem;
+	WORD      DllCharacteristics;
+	ULONGLONG SizeOfStackReserve;
+	ULONGLONG SizeOfStackCommit;
+	ULONGLONG SizeOfHeapReserve;
+	ULONGLONG SizeOfHeapCommit;
+	DWORD     LoaderFlags;
+	DWORD     NumberOfRvaAndSizes;
+	IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] DataDirectory;
+}
+
+enum  {
+	IMAGE_DOS_SIGNATURE    = 0x5A4D,
+	IMAGE_OS2_SIGNATURE    = 0x454E,
+	IMAGE_OS2_SIGNATURE_LE = 0x454C,
+	IMAGE_VXD_SIGNATURE    = 0x454C,
+	IMAGE_NT_SIGNATURE     = 0x4550
+}
+
+const size_t
+	IMAGE_NUMBEROF_DIRECTORY_ENTRIES =  16,
+	IMAGE_SIZEOF_ROM_OPTIONAL_HEADER =  56,
+	IMAGE_SIZEOF_STD_OPTIONAL_HEADER =  28,
+	IMAGE_SIZEOF_NT_OPTIONAL32_HEADER = 224,
+	IMAGE_SIZEOF_NT_OPTIONAL64_HEADER = 240,
+	IMAGE_SIZEOF_SHORT_NAME          =   8,
+	IMAGE_SIZEOF_SECTION_HEADER      =  40,
+	IMAGE_SIZEOF_SYMBOL              =  18,
+	IMAGE_SIZEOF_AUX_SYMBOL          =  18,
+	IMAGE_SIZEOF_RELOCATION          =  10,
+	IMAGE_SIZEOF_BASE_RELOCATION     =   8,
+	IMAGE_SIZEOF_LINENUMBER          =   6,
+	IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR  =  60,
+	SIZEOF_RFPO_DATA                 =  16;
+
+struct IMAGE_DATA_DIRECTORY {
+	DWORD VirtualAddress;
+	DWORD Size;
+}
+
+// IMAGE_OPTIONAL_HEADER.Magic
+enum : WORD {
+	IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x010B,
+	IMAGE_ROM_OPTIONAL_HDR_MAGIC  = 0x0107,
+	IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x020B
+}
+
+struct IMAGE_SECTION_HEADER {
+	BYTE[IMAGE_SIZEOF_SHORT_NAME] Name;
+	union _Misc {
+		DWORD PhysicalAddress;
+		DWORD VirtualSize;
+	}
+	_Misc Misc;
+	DWORD VirtualAddress;
+	DWORD SizeOfRawData;
+	DWORD PointerToRawData;
+	DWORD PointerToRelocations;
+	DWORD PointerToLinenumbers;
+	WORD  NumberOfRelocations;
+	WORD  NumberOfLinenumbers;
+	DWORD Characteristics;
+}
+
+// IMAGE_SECTION_HEADER.Characteristics
+const DWORD
+	IMAGE_SCN_TYPE_REG               = 0x00000000,
+	IMAGE_SCN_TYPE_DSECT             = 0x00000001,
+	IMAGE_SCN_TYPE_NOLOAD            = 0x00000002,
+	IMAGE_SCN_TYPE_GROUP             = 0x00000004,
+	IMAGE_SCN_TYPE_NO_PAD            = 0x00000008,
+	IMAGE_SCN_TYPE_COPY              = 0x00000010,
+	IMAGE_SCN_CNT_CODE               = 0x00000020,
+	IMAGE_SCN_CNT_INITIALIZED_DATA   = 0x00000040,
+	IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
+	IMAGE_SCN_LNK_OTHER              = 0x00000100,
+	IMAGE_SCN_LNK_INFO               = 0x00000200,
+	IMAGE_SCN_TYPE_OVER              = 0x00000400,
+	IMAGE_SCN_LNK_REMOVE             = 0x00000800,
+	IMAGE_SCN_LNK_COMDAT             = 0x00001000,
+	IMAGE_SCN_MEM_FARDATA            = 0x00008000,
+	IMAGE_SCN_GPREL                  = 0x00008000,
+	IMAGE_SCN_MEM_PURGEABLE          = 0x00020000,
+	IMAGE_SCN_MEM_16BIT              = 0x00020000,
+	IMAGE_SCN_MEM_LOCKED             = 0x00040000,
+	IMAGE_SCN_MEM_PRELOAD            = 0x00080000,
+	IMAGE_SCN_ALIGN_1BYTES           = 0x00100000,
+	IMAGE_SCN_ALIGN_2BYTES           = 0x00200000,
+	IMAGE_SCN_ALIGN_4BYTES           = 0x00300000,
+	IMAGE_SCN_ALIGN_8BYTES           = 0x00400000,
+	IMAGE_SCN_ALIGN_16BYTES          = 0x00500000,
+	IMAGE_SCN_ALIGN_32BYTES          = 0x00600000,
+	IMAGE_SCN_ALIGN_64BYTES          = 0x00700000,
+	IMAGE_SCN_ALIGN_128BYTES         = 0x00800000,
+	IMAGE_SCN_ALIGN_256BYTES         = 0x00900000,
+	IMAGE_SCN_ALIGN_512BYTES         = 0x00A00000,
+	IMAGE_SCN_ALIGN_1024BYTES        = 0x00B00000,
+	IMAGE_SCN_ALIGN_2048BYTES        = 0x00C00000,
+	IMAGE_SCN_ALIGN_4096BYTES        = 0x00D00000,
+	IMAGE_SCN_ALIGN_8192BYTES        = 0x00E00000,
+	IMAGE_SCN_LNK_NRELOC_OVFL        = 0x01000000,
+	IMAGE_SCN_MEM_DISCARDABLE        = 0x02000000,
+	IMAGE_SCN_MEM_NOT_CACHED         = 0x04000000,
+	IMAGE_SCN_MEM_NOT_PAGED          = 0x08000000,
+	IMAGE_SCN_MEM_SHARED             = 0x10000000,
+	IMAGE_SCN_MEM_EXECUTE            = 0x20000000,
+	IMAGE_SCN_MEM_READ               = 0x40000000,
+	IMAGE_SCN_MEM_WRITE              = 0x80000000;
+
+// ImageDirectoryEntryToDataEx()
+enum : USHORT {
+	IMAGE_DIRECTORY_ENTRY_EXPORT             =  0,
+	IMAGE_DIRECTORY_ENTRY_IMPORT,
+	IMAGE_DIRECTORY_ENTRY_RESOURCE,
+	IMAGE_DIRECTORY_ENTRY_EXCEPTION,
+	IMAGE_DIRECTORY_ENTRY_SECURITY,
+	IMAGE_DIRECTORY_ENTRY_BASERELOC,
+	IMAGE_DIRECTORY_ENTRY_DEBUG,
+	IMAGE_DIRECTORY_ENTRY_COPYRIGHT,      // =  7
+	IMAGE_DIRECTORY_ENTRY_ARCHITECTURE       =  7,
+	IMAGE_DIRECTORY_ENTRY_GLOBALPTR,
+	IMAGE_DIRECTORY_ENTRY_TLS,
+	IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
+	IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+	IMAGE_DIRECTORY_ENTRY_IAT,
+	IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT,
+	IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, // = 14
+}
+
+IMAGE_SECTION_HEADER* IMAGE_FIRST_SECTION32(const(IMAGE_NT_HEADERS32)* h) {
+	return cast(IMAGE_SECTION_HEADER*)((cast(char*)&h.OptionalHeader) + h.FileHeader.SizeOfOptionalHeader);
+}
+
+IMAGE_SECTION_HEADER* IMAGE_FIRST_SECTION64(const(IMAGE_NT_HEADERS64)* h) {
+	return cast(IMAGE_SECTION_HEADER*)((cast(char*)&h.OptionalHeader) + h.FileHeader.SizeOfOptionalHeader);
+}
+
+struct IMAGE_DEBUG_DIRECTORY {
+	DWORD Characteristics;
+	DWORD TimeDateStamp;
+	WORD  MajorVersion;
+	WORD  MinorVersion;
+	DWORD Type;
+	DWORD SizeOfData;
+	DWORD AddressOfRawData;
+	DWORD PointerToRawData;
+}
+
+enum : DWORD {
+	IMAGE_DEBUG_TYPE_UNKNOWN,
+	IMAGE_DEBUG_TYPE_COFF,
+	IMAGE_DEBUG_TYPE_CODEVIEW,
+	IMAGE_DEBUG_TYPE_FPO,
+	IMAGE_DEBUG_TYPE_MISC,
+	IMAGE_DEBUG_TYPE_EXCEPTION,
+	IMAGE_DEBUG_TYPE_FIXUP,
+	IMAGE_DEBUG_TYPE_OMAP_TO_SRC,
+	IMAGE_DEBUG_TYPE_OMAP_FROM_SRC,
+	IMAGE_DEBUG_TYPE_BORLAND // = 9
+}
\ No newline at end of file
--- a/dbg/ui/CrashWindow.d	Tue Aug 24 16:59:45 2010 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,372 +0,0 @@
-/**
- A window used to display the data from a CrashInfo struct generated by the
- runtime's crash handler.
-
- TODO:
-	* Send report - need SMTP implementation
-	* Save report
-
- Authors:
-	Jeremie Pelletier
-
- License:
-	Public Domain
-*/
-module dbg.ui.CrashWindow;
-
-import std.c.string;
-import dlib.CrashHandler;
-import dbg.Debug : SystemException;
-
-import std.stdio;
-
-private enum {
-	ReportWindowWidth		= 640,
-	ReportWindowHeight		= 480,
-	ReportWindowMinWidth	= 320,
-	ReportWindowMinHeight	= 240,
-	ReportWindowTitle		= "Unhandled exception!"
-}
-
-// ----------------------------------------------------------------------------
-// W i n 3 2
-// ----------------------------------------------------------------------------
-
-version(Windows) {
-
-import win32.windows;
-
-private enum {
-	ID_LABEL			= 100,
-	ID_SAVE_BTN			= 101,
-	ID_SEND_BTN			= 102,
-	ID_CLOSE_BTN		= 103,
-	ID_REPORT			= 104
-}
-
-enum CLEARTYPE_QUALITY = 5;
-enum LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x20;
-
-/**
- Create the crash window for the given crash information, the routine will
- return when the window is closed.
-*/
-void ShowCrashWindow(CrashInfo* crashInfo)
-in {
-	assert(crashInfo);
-}
-body {
-	try {
-
-	HINSTANCE inst = GetModuleHandle(null);
-
-	WNDCLASSEXA wc;
-	wc.cbSize = WNDCLASSEX.sizeof;
-	wc.lpfnWndProc = &ReportWndProc;
-	wc.hInstance = inst;
-	wc.hIcon = cast(HICON)LoadImage(HINSTANCE.init, MAKEINTRESOURCE(OIC_ERROR), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
-	wc.hCursor = cast(HCURSOR)LoadImage(HINSTANCE.init, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE);
-	wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
-	wc.lpszClassName = "CrashWindowClass";
-
-	if(!RegisterClassExA(&wc)) SystemException();
-	scope(exit) if(!UnregisterClassA("CrashWindowClass", inst)) SystemException();
-
-	RECT rc = void;
-	GetClientRect(GetDesktopWindow(), &rc);
-	
-	writeln(crashInfo.toString);
-
-	HWND wnd = CreateWindowExA(
-		WS_EX_WINDOWEDGE,
-		"CrashWindowClass", ReportWindowTitle,
-		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
-		(rc.right >> 1) - (ReportWindowWidth >> 1), (rc.bottom >> 1) - (ReportWindowHeight >> 1),
-		ReportWindowWidth, ReportWindowHeight,
-		HWND.init, HMENU.init, inst, cast(void*)crashInfo.toString.ptr
-	);
-	if(!wnd) SystemException();
-
-	MSG msg = void;
-	while(GetMessage(&msg, HWND.init, 0, 0)) {
-		TranslateMessage(&msg);
-		DispatchMessage(&msg);
-	}
-
-	} // try
-	catch(Throwable e) {
-		MessageBoxA(HWND.init, (e.toString ~ '\0').ptr, "Crash Window Error!", MB_ICONERROR | MB_OK);
-	}
-}
-
-private:
-
-__gshared HWND saveButton, sendButton, closeButton, reportField;
-
-extern(Windows)
-LRESULT ReportWndProc(HWND wnd, uint msg, WPARAM w, LPARAM l) {
-	try {
-
-	switch(msg) {
-	case WM_CREATE:
-		HINSTANCE inst = cast(HINSTANCE).GetModuleHandle(null);
-		CREATESTRUCT* cs = cast(CREATESTRUCT*)l;
-
-		LOGFONTA lf;
-		lf.lfHeight = 15;
-		lf.lfWeight = FW_REGULAR;
-		lf.lfCharSet = DEFAULT_CHARSET;
-		lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
-		lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-		lf.lfQuality = CLEARTYPE_QUALITY;
-		lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
-
-		HFONT font = .CreateFontIndirectA(&lf);
-		if(!font) SystemException();
-
-		HINSTANCE iconMod = LoadLibraryExA("shell32.dll", null,
-			DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
-
-		HWND CreateButton(string caption, uint id, ushort iconId) {
-			HWND ret = CreateWindowExA(
-				0, "BUTTON", caption.ptr, WS_CHILD | WS_VISIBLE,
-				0, 0, 0, 0, wnd, cast(HMENU)id, inst, null
-			);
-			if(!ret) SystemException();
-
-			SendMessageA(ret, WM_SETFONT, cast(WPARAM)font, 0);
-
-			if(iconMod) {
-				HANDLE icon = LoadImage(iconMod, MAKEINTRESOURCE(iconId), IMAGE_ICON, 24, 24, 0);
-				if(icon) SendMessageA(ret, BM_SETIMAGE, IMAGE_ICON, cast(uint)icon);
-			}
-
-			return ret;
-		}
-
-		saveButton = CreateButton("Save Report", ID_SAVE_BTN, 7);
-		sendButton = CreateButton("Send Report", ID_SEND_BTN, 27);
-		closeButton = CreateButton("Close", ID_CLOSE_BTN, 28);
-
-		if(iconMod) FreeLibrary(cast(HMODULE)iconMod);
-
-		enum ReportFont = "Courier New\0";
-		lf.lfHeight = 14;
-		lf.lfFaceName[0 .. ReportFont.length] = ReportFont;
-
-		font = CreateFontIndirectA(&lf);
-		if(!font) SystemException();
-
-		reportField = CreateWindowExA(
-			WS_EX_CLIENTEDGE, "EDIT", null,
-			WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE |
-				ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL,
-			0, 0, 0, 0, wnd, cast(HMENU)ID_REPORT, inst, null
-		);
-		if(!reportField) SystemException();
-
-		SendMessageA(reportField, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5));
-		SendMessageA(reportField, WM_SETFONT, cast(WPARAM)font, 0);
-		SendMessageA(reportField, WM_SETTEXT, 0, cast(LPARAM)cs.lpCreateParams);
-
-		break;
-
-	case WM_DESTROY:
-		PostQuitMessage(0);
-		break;
-
-	case WM_GETMINMAXINFO:
-		MINMAXINFO* mm = cast(MINMAXINFO*)l;
-		mm.ptMinTrackSize.x = ReportWindowMinWidth;
-		mm.ptMinTrackSize.y = ReportWindowMinHeight;
-		break;
-
-	case WM_SIZE:
-		int width = LOWORD(l), halfWidth = width >> 1;
-		int height = HIWORD(l);
-
-		enum {
-			BtnWidth = 125,
-			BtnHeight = 35,
-			NumBtns = 3,
-			Pad = 10,
-			ReportHPad = Pad * 2,
-			ReportVPad = BtnHeight + Pad * 3,
-			BtnVPad = BtnHeight + Pad,
-			BtnHalfWidth = (BtnWidth * NumBtns + (Pad * (NumBtns - 1))) >> 1
-		}
-
-		if(!MoveWindow(reportField, Pad, Pad, width - ReportHPad, height - ReportVPad, true))
-			SystemException();
-
-		void Move(HWND wnd, int i) {
-			if(!MoveWindow(wnd, halfWidth - BtnHalfWidth + BtnWidth * i + Pad * i,
-				height - BtnVPad, BtnWidth, BtnHeight, true))
-					SystemException();
-		}
-
-		Move(saveButton, 0);
-		Move(sendButton, 1);
-		Move(closeButton, 2);
-
-		break;
-
-	case WM_COMMAND:
-		if(HIWORD(w) != BN_CLICKED) break;
-
-		int id = LOWORD(w);
-
-		// GetSaveFileName fails on win7.. no idea why
-		if(id == ID_SAVE_BTN) {
-			/*char[256] path = void;
-			path[0 .. 11] = "Report.txt\0";
-
-			OPENFILENAMEA ofn;
-			ofn.lStructSize = OPENFILENAME.sizeof;
-			ofn.hwndOwner = wnd;
-			ofn.lpstrFilter = "Text File\0*.txt\0\0";
-			ofn.lpstrFile = path.ptr;
-			ofn.nMaxFile = path.length;
-			ofn.Flags = OFN_OVERWRITEPROMPT;
-
-			try {
-				if(!GetSaveFileNameA(&ofn)) SystemException();
-
-				uint len = strlen(path.ptr);
-				if(path[len-4 .. len] != ".txt") path[len .. len + 5] = ".txt\0";
-
-				HANDLE file = CreateFileA(path.ptr, GENERIC_WRITE, 0,
-					null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, null);
-
-				if(file == INVALID_HANDLE_VALUE) SystemException();
-				scope(exit) if(!CloseHandle(file)) SystemException();
-
-				char* text;
-				SendMessageA(reportField, WM_GETTEXT, 0, cast(LPARAM)text);
-				len = strlen(text);
-
-				uint written = void;
-				if(!WriteFile(file, text, len, &written, null))
-					SystemException();
-
-				if(written != len) throw new SystemException("Couldn't write entire data.");
-
-				id = ID_CLOSE_BTN;
-			}
-			catch(SystemException e) {
-				MessageBoxA(wnd, (e.toString ~ '\0').ptr, "Error!", MB_OK | MB_ICONERROR);
-			}*/
-
-			MessageBoxA(wnd, "TODO", "Error!", MB_OK | MB_ICONERROR);
-		}
-
-		if(id == ID_SEND_BTN)
-			MessageBoxA(wnd, "TODO", "Error!", MB_OK | MB_ICONERROR);
-
-		if(id == ID_CLOSE_BTN)
-			SendMessageA(wnd, WM_CLOSE, 0, 0);
-
-		break;
-
-	default:
-		return DefWindowProcA(wnd, msg, w, l);
-	}
-
-	} // try
-	catch(Exception e) {
-		MessageBoxA(HWND.init, (e.toString ~ '\0').ptr, "Crash Window Handler Error!", MB_ICONERROR | MB_OK);
-		PostQuitMessage(0);
-	}
-
-	return 0;
-}
-
-} // version(Windows)
-
-else version(Gnome) {
-
-import std.c.stdio;	
-
-import ext.Gnome.gtk;
-import ext.Gnome.gobject;
-
-void ErrorGUI(in ErrorReport* report) {
-	int argc;
-	if(!gtk_init_check(&argc, null)) {
-		printf("gtk failed!\n");
-		Pause;
-	}
-
-	void SetSignal(A, B)(A* widget, string signal, B callback) {
-		g_signal_connect(cast(void*)widget, signal.ptr, cast(GCallback)callback, null);
-	}
-
-	// Create the report window
-	GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-	gtk_window_set_title(cast(GtkWindow*)window, ReportWindowTitle);
-	gtk_window_set_default_size(cast(GtkWindow*)window, ReportWindowWidth, ReportWindowHeight);
-	gtk_window_set_icon_name(cast(GtkWindow*)window, GTK_STOCK_DIALOG_ERROR);
-
-	SetSignal(window, "destroy", &gtk_main_quit);
-
-	// Create the root box
-	GtkWidget* vbox = gtk_vbox_new(false, 0);
-	gtk_container_add(cast(GtkContainer*)window, vbox);
-
-	// Create the report edit
-	GtkWidget* view = gtk_text_view_new();
-	gtk_text_view_set_editable(cast(GtkTextView*)view, false);
-	gtk_text_view_set_cursor_visible(cast(GtkTextView*)view, false);
-
-	GtkTextBuffer* buffer = gtk_text_view_get_buffer(cast(GtkTextView*)view);
-	gtk_text_buffer_set_text(buffer, report.dumpText.ptr, -1);
-
-	gtk_box_pack_start(cast(GtkBox*)vbox, view, true, true, 0);
-
-	// Create the buttons box
-	GtkWidget* hbox = gtk_hbutton_box_new();
-	gtk_box_set_spacing(cast(GtkBox*)hbox, 10);
-	gtk_button_box_set_layout(cast(GtkButtonBox*)hbox, GTK_BUTTONBOX_CENTER);
-	gtk_box_pack_start(cast(GtkBox*)vbox, hbox, false, true, 10);
-
-	// Create the buttons
-	GtkWidget* CreateButton(B)(string label, string stockId, B callback) {
-		GtkWidget* button = gtk_button_new_with_label(label.ptr);
-
-		GtkWidget* image = gtk_image_new_from_stock(stockId.ptr, GTK_ICON_SIZE_BUTTON);
-		gtk_button_set_image(cast(GtkButton*)button, image);
-
-		gtk_container_add(cast(GtkContainer*)hbox, button);
-
-		if(callback) SetSignal(button, "clicked", callback);
-
-		return button;
-	}
-
-	CreateButton("Save Report", GTK_STOCK_SAVE_AS, &OnClickSave);
-	CreateButton("Send Report", GTK_STOCK_CONNECT, &OnClickSend);
-	GtkWidget* close = CreateButton("Close", GTK_STOCK_CLOSE, null);
-
-	g_signal_connect_swapped(cast(void*)close, "clicked",
-		cast(GCallback)(&gtk_widget_destroy), cast(void*)(window));
-
-	// Display the window and run the main loop
-	gtk_widget_show_all(window);
-	gtk_main();
-}
-
-extern(C):
-
-void OnClickSave(GtkButton* button, gpointer user_data) {
-	// TODO
-}
-
-void OnClickSend(GtkButton* button, gpointer user_data) {
-	// TODO
-}
-
-} // version(Gnome)
-else version (NobodyCares)
-{
-}
-else static assert(0);
--- a/dlib/CrashHandler.d	Tue Aug 24 16:59:45 2010 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,465 +0,0 @@
-/**
- A simple runtime crash handler which collects various informations about
- the crash such as registers, stack traces, and loaded modules.
-
- TODO:
-	* Threading support
-	* Stack dumps
-
- Authors:
-	Jeremie Pelletier
-
- License:
-	Public Domain
-*/
-module dlib.CrashHandler;
-
-debug = CrashHandler;
-
-import std.c.stdio;
-import dbg.Debug;
-import dbg.ui.CrashWindow;
-
-version(X86) {}
-else static assert(0, "Unsupported architecture.");
-
-version(DigitalMars) {
-	//import dlib.dmd.ErrorHandling;
-}
-else static assert(0, "Unsupported compiler.");
-
-version(Windows) {
-	import win32.windows;
-	import win32.psapi;
-	import std.windows.syserror;
-	//import sys.windows.Memory;
-	//import dlib.Module;
-	import dbg.image.PE;
-	import dbg.symbol.CodeView;
-}
-else version(Posix) {
-	import core.sys.posix.ucontext;
-	import core.stdc.signal;
-	import core.stdc.stdlib : free, exit, EXIT_FAILURE;
-}
-else static assert(0, "Unsupported platform.");
-
-/**
- Register the crash handler
-*/
-void CrashHandlerInit() {
-	version(Windows) {
-		//SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS);
-		SetErrorMode(0);
-		SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
-	}
-	else version(Posix) {
-	assert(0);
-	/+	sigaction_t sa;
-		sa.sa_handler = cast(sighandler_t)&SignalHandler;
-		sigemptyset(&sa.sa_mask);
-		sa.sa_flags = SA_RESTART | SA_SIGINFO;
-
-		sigaction(SIGILL, &sa, null);
-		sigaction(SIGFPE, &sa, null);
-		sigaction(SIGSEGV, &sa, null);+/
-	}
-	else static assert(0);
-}
-
-/**
- Information collected by the crash handler
-*/
-struct CrashInfo {
-	struct Registers {
-		version(X86) {
-			uint EAX, EBX, ECX, EDX;
-			uint EDI, ESI;
-			uint EBP, ESP;
-		}
-		else static assert(0);
-	}
-
-	struct Module {
-		string fileName;
-		ushort[4] fileVersion;
-	}
-
-	Throwable	error;
-	string		moduleName;
-	Registers	registers;
-	size_t[]	backtrace;
-	Module[]	modules;
-
-	void Dump() {
-		// TODO: support more dump methods
-		version(Windows) ShowCrashWindow(&this);
-	}
-
-	/**
-	 Formats the crash info as plain-text
-	*/
-	string toString() {
-		string text;
-		char[255] buffer = void;
-		uint len = void;
-
-		text ~= error.toString();
-		text ~= "\r\n\r\n";
-
-		version(X86) {
-			with(registers) len = snprintf(buffer.ptr, buffer.length,
-				" Registers:\r\n" ~
-				"========================================\r\n" ~
-				"  EAX=0x%08X  EBX=0x%08X  ECX=0x%08X  EDX=0x%08X\r\n" ~
-				"  EDI=0x%08X  ESI=0x%08X  EBP=0x%08X  ESP=0x%08X\r\n",
-				EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP
-			);
-			text ~= buffer[0 .. len] ~ "\r\n";
-		}
-		else static assert(0);
-
-		text ~= " Stack Trace:\r\n" ~
-			"========================================\r\n";
-
-		scope auto frames = new StackFrameInfo[backtrace.length];
-		ResolveStackFrames(frames);
-
-		foreach(ref frame; frames) {
-			//len = snprintf(buffer.ptr, buffer.length, "%p", frame.va);
-			//text ~= "  " ~ buffer[0 .. len] ~ ": " ~ frame.moduleName ~ "\r\n";
-
-			//with(frame.symbol) if(name.length) {
-			//	len = snprintf(buffer.ptr, buffer.length, "%X", offset);
-			//	text ~= "    " ~ name ~ " @ 0x" ~ buffer[0 .. len] ~ "\r\n";
-			//}
-
-			with(frame.fileLine) if(line) {
-				len = snprintf(buffer.ptr, buffer.length, "%u", line);
-				text ~= "    " ~ file ~ ":" ~ buffer[0 .. len] ~ "\r\n";
-			}
-
-			//text ~= "\r\n";
-		}
-/+
-		text ~= " Loaded Modules:\r\n" ~
-			"========================================\r\n";
-
-		foreach(mod; modules) {
-			len = snprintf(buffer.ptr, buffer.length, "%hu.%hu.%hu.%hu",
-				mod.fileVersion[0], mod.fileVersion[1],
-				mod.fileVersion[2], mod.fileVersion[3]);
-
-			text ~= "  " ~ mod.fileName ~ "\r\n    " ~ buffer[0 .. len] ~ "\r\n";
-		}
-+/
-		text ~= '\0';
-
-		return text;
-	}
-
-private:
-
-	struct StackFrameInfo {
-		size_t			va;
-		string			moduleName;
-		SymbolInfo		symbol;
-		FileLineInfo	fileLine;
-	}
-
-	struct DebugImage {
-		DebugImage*			next;
-		string				moduleName;
-		size_t				baseAddress;
-		uint				rvaOffset;
-		IExecutableImage	exeModule;
-		ISymbolicDebugInfo	debugInfo;
-	}
-
-	version(X86) {
-	void ResolveStackFrames(StackFrameInfo[] frames) const {
-		StackFrameInfo* frame = void;
-		DebugImage* imageList, image = void;
-		char[255] buffer = void;
-		uint len = void;
-		uint rva = void;
-
-		version(Windows) MEMORY_BASIC_INFORMATION mbi = void;
-
-		foreach(i, va; backtrace) {
-			frame = &frames[i];
-			frame.va = va;
-
-			version(Windows) {
-				// mbi.Allocation base is the handle to stack frame's module
-				VirtualQuery(cast(void*)va, &mbi, MEMORY_BASIC_INFORMATION.sizeof);
-				if(!mbi.AllocationBase) break;
-
-				image = imageList;
-				while(image) {
-					if(image.baseAddress == cast(size_t)mbi.AllocationBase) break;
-					image = image.next;
-				}
-
-				if(!image) {
-					image = new DebugImage;
-
-					with(*image) {
-						next = imageList;
-						imageList = image;
-						baseAddress = cast(size_t)mbi.AllocationBase;
-
-//						printf("%d\n", baseAddress);
-
-						len = GetModuleFileNameA(cast(HMODULE)baseAddress, buffer.ptr, buffer.length);
-						moduleName = buffer[0 .. len].idup;
-						if (len == 0) {
-							MessageBox(HANDLE.init, moduleName.ptr, sysErrorString(GetLastError()).ptr, 0);
-						}
-
-						exeModule = new PEImage(moduleName);
-						rvaOffset = baseAddress + exeModule.codeOffset;
-						debugInfo = exeModule.debugInfo;
-					}
-				}
-			}
-			else version(POSIX)
-			{
-				assert(0);
-			}
-			else static assert(0);
-
-			frame.moduleName = image.moduleName;
-
-			if(!image.debugInfo) continue;
-
-			rva = va - image.rvaOffset;
-
-			with(image.debugInfo) {
-				frame.symbol = ResolveSymbol(rva);
-				frame.fileLine = ResolveFileLine(rva);
-			}
-		}
-
-		while(imageList) {
-			image = imageList.next;
-			delete imageList.debugInfo;
-			delete imageList.exeModule;
-			delete imageList;
-			imageList = image;
-		}
-	}
-	} // version(X86)
-	else static assert(0);
-}
-
-// ----------------------------------------------------------------------------
-// W i n d o w s  C r a s h  H a n d l e r
-// ----------------------------------------------------------------------------
-
-version(Windows) {
-
-extern(C) Throwable _d_translate_se_to_d_exception(EXCEPTION_RECORD* exception_record);
-
-/**
- D exceptions are built on top of Windows' SEH, a simple registered callback
- will catch any exceptions unwinding past a thread's entry point.
-*/
-extern(Windows)
-int UnhandledExceptionHandler(EXCEPTION_POINTERS* e) {
-	CrashInfo crashInfo = void;
-	char[256] buffer = void;
-	uint len = void;
-	size_t ip = void, bp = void;
-
-	try {
-		with(crashInfo) {
-
-		version(DigitalMars)
-			error = _d_translate_se_to_d_exception(e.ExceptionRecord);
-		else
-			static assert(0);
-
-		len = GetModuleFileNameA(GetModuleHandle(null), buffer.ptr, buffer.length);
-		moduleName = buffer[0 .. len].idup;
-
-		version(X86) with(*e.ContextRecord) {
-			with(registers) {
-				EAX = Eax, EBX = Ebx, ECX = Ecx, EDX = Edx;
-				EDI = Edi, ESI = Esi;
-				EBP = Ebp, ESP = Esp;
-			}
-
-			ip = Eip;
-			bp = Ebp;
-		}
-		else static assert(0);
-
-		backtrace = null;
-		while(ip) {
-			backtrace ~= ip;
-
-			ip = cast(size_t)*(cast(void**)bp + 1);
-			bp = cast(size_t)*cast(void**)bp;
-		}
-
-		HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
-			0, GetCurrentProcessId());
-
-		if(process == INVALID_HANDLE_VALUE) SystemException();
-		scope(exit) if(!CloseHandle(process)) SystemException();
-
-		scope HMODULE[] hmodules = new HMODULE[64];
-		uint size = HMODULE.sizeof * hmodules.length;
-		uint sizeNeeded = void;
-		uint nModules = void;
-
-	GetModules:
-		/*
-		if(!EnumProcessModules(process, hmodules.ptr, size, &sizeNeeded))
-			SystemException();
-
-		nModules = sizeNeeded / HMODULE.sizeof;
-		/*/
-		nModules = 0;
-		//*/
-		
-		if(sizeNeeded > size) {
-			hmodules.length = nModules;
-			size = sizeNeeded;
-			goto GetModules;
-		}
-
-		Module mod = void;
-		char[] versionInfo;
-		VS_FIXEDFILEINFO* fixedVersionInfo = void;
-
-		modules = null;
-		foreach(i; 0 .. nModules) {
-			len = GetModuleFileNameA(hmodules[i], buffer.ptr, buffer.length);
-			mod.fileName = buffer[0 .. len].idup;
-
-			sizeNeeded = GetFileVersionInfoSizeA(buffer.ptr, &size);
-
-			if(sizeNeeded) {
-				if(versionInfo.length < sizeNeeded) versionInfo.length = sizeNeeded;
-
-				if(!GetFileVersionInfoA(buffer.ptr, 0, versionInfo.length, versionInfo.ptr))
-					SystemException();
-
-				if(!VerQueryValueA(versionInfo.ptr, cast(char*)"\\".ptr, cast(void**)&fixedVersionInfo, &size))
-					SystemException();
-
-				with(*fixedVersionInfo) with(mod) {
-					fileVersion[0] = HIWORD(dwProductVersionMS);
-					fileVersion[1] = LOWORD(dwProductVersionMS);
-					fileVersion[2] = HIWORD(dwProductVersionLS);
-					fileVersion[3] = LOWORD(dwProductVersionLS);
-				}
-			}
-			else {
-				mod.fileVersion[] = 0;
-			}
-
-			modules ~= mod;
-		}
-
-		} // with(crashInfo)
-
-		crashInfo.Dump();
-	}
-	catch(Throwable e) {
-		debug MessageBoxA(HWND.init, (e.toString ~ '\0').ptr, "Exception Handler Error!", MB_ICONERROR | MB_OK);
-	}
-
-	return EXCEPTION_EXECUTE_HANDLER;
-}
-
-} // version(Windows)
-
-// ----------------------------------------------------------------------------
-// P o s i x  C r a s h  H a n d l e r
-// ----------------------------------------------------------------------------
-
-else version(Posix) {
-
-/**
- This handler catches system signals and throws the appropriate D exception.
- The exception will unwind down to the thread's entry point where it is catched
- and sent to UnhandledExceptionHandler().
-*/
-extern(C)
-void SignalHandler(int signum, siginfo_t* siginfo, ucontext_t* ucontext) {
-	string msg = void;
-
-	switch(signum) {
-	case SIGILL:	msg = "Illegal instruction";		break;
-	case SIGFPE:	msg = "Floating-point exception";	break;
-	case SIGSEGV:	msg = "Segmentation fault";			break;
-	default:		msg = "Unknown signal";
-	}
-	assert(0);
-/+
-	SystemException e = new SystemException(msg);
-
-	e._context = ucontext;
-	e.GetBackTrace();
-
-	// The kernel fixed the stack frame to make us believe we called this
-	// routine ourselves, with the nasty side effect of losing the faulty
-	// routine's address. The undocumented parameter ucontext contains our
-	// lost EIP.
-	version(X86) {
-		// It should be the 3rd frame: 
-		//	SignalHandler() -> GetBackTrace() -> backtrace()
-		if(e._backtrace.length > 2)
-			e._backtrace[2] = cast(void*)ucontext.uc_mcontext.gregs[REG_EIP];
-	}
-	else static assert(0);
-	throw e;+/
-}
-
-/**
- This handler is called when an exception unwinds down to the thread's entry
- point, which should catch it and manually call this routine.
-*/
-void UnhandledExceptionHandler(Throwable e) {
-assert(0);
-/+	ErrorReport crashInfo = void;
-
-	with(crashInfo) {
-	/+error = e;
-
-	// Get the module filename
-	// TODO
-
-	// Dump the general purpose registers
-	if(e._context) {
-		gregset_t gregs = e._context.uc_mcontext.gregs;
-
-		version(X86) {
-			registers.Eax = gregs[REG_EAX];
-			registers.Ebx = gregs[REG_EBX];
-			registers.Ecx = gregs[REG_ECX];
-			registers.Edx = gregs[REG_EDX];
-			registers.Edi = gregs[REG_EDI];
-			registers.Esi = gregs[REG_ESI];
-			registers.Ebp = gregs[REG_EBP];
-			registers.Esp = gregs[REG_ESP];
-		}
-		else static assert(0);
-	}
-
-	// Dump stack backtrace
-	addresses = e._backtrace;
-
-	// Dump the loaded modules
-	// TODO+/
-
-	} // with(crashInfo)
-
-	crashInfo.Dump();+/
-}
-
-} // version(Posix)
-else static assert(0);
--- a/main.d	Tue Aug 24 16:59:45 2010 +0400
+++ b/main.d	Sat Aug 28 10:51:32 2010 +0400
@@ -31,8 +31,7 @@
 
 import core.memory;
 
-import dlib.CrashHandler;
-import dbg.ui.CrashWindow;
+import dbg.CallStackInfo;
 
 import dmd.Util;
 
@@ -41,10 +40,142 @@
 	EXIT_SUCCESS = 0,
 }
 
-extern (C) extern __gshared bool rt_trapExceptions;
+version (Windows)
+{
+    private import core.stdc.wchar_;
+
+    extern (Windows) alias int function() FARPROC;
+    extern (Windows) FARPROC    GetProcAddress(void*, in char*);
+    extern (Windows) void*      LoadLibraryA(in char*);
+    extern (Windows) int        FreeLibrary(void*);
+    extern (Windows) void*      LocalFree(void*);
+    extern (Windows) wchar_t*   GetCommandLineW();
+    extern (Windows) wchar_t**  CommandLineToArgvW(wchar_t*, int*);
+    extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
+    pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
+}
+
+shared bool _d_isHalting = false;
+__gshared string[] _d_args = null;
+
+extern (C) void gc_init();
+extern (C) void gc_term();
+extern (C) void _minit();
+extern (C) void _moduleCtor();
+extern (C) void _moduleDtor();
+extern (C) bool runModuleUnitTests();
+extern (C) void thread_joinAll();
+
+import rt.memory;
+
+extern (C) int main(int argc, char** argv)
+{
+    char[][] args;
+    int result;
+
+    version (OSX)
+    {   /* OSX does not provide a way to get at the top of the
+         * stack, except for the magic value 0xC0000000.
+         * But as far as the gc is concerned, argv is at the top
+         * of the main thread's stack, so save the address of that.
+         */
+        __osx_stack_end = cast(void*)&argv;
+    }
+
+    version (FreeBSD) version (D_InlineAsm_X86)
+    {
+        /*
+         * FreeBSD/i386 sets the FPU precision mode to 53 bit double.
+         * Make it 64 bit extended.
+         */
+        ushort fpucw;
+        asm
+        {
+            fstsw   fpucw;
+            or      fpucw, 0b11_00_111111; // 11: use 64 bit extended-precision
+                                           // 111111: mask all FP exceptions
+            fldcw   fpucw;
+        }
+    }
+
+    version (Posix)
+    {
+        _STI_monitor_staticctor();
+        _STI_critical_init();
+    }
 
-static this() {
-	rt_trapExceptions = false;
+    version (Windows)
+    {
+        wchar_t*  wcbuf = GetCommandLineW();
+        size_t    wclen = wcslen(wcbuf);
+        int       wargc = 0;
+        wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
+        assert(wargc == argc);
+
+        char*     cargp = null;
+        size_t    cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
+
+        cargp = cast(char*) alloca(cargl);
+        args  = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
+
+        for (size_t i = 0, p = 0; i < wargc; i++)
+        {
+            int wlen = wcslen(wargs[i]);
+            int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
+            args[i]  = cargp[p .. p+clen];
+            p += clen; assert(p <= cargl);
+            WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
+        }
+        LocalFree(wargs);
+        wargs = null;
+        wargc = 0;
+    }
+    else version (Posix)
+    {
+        char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
+        scope(exit) free(am);
+
+        for (size_t i = 0; i < argc; i++)
+        {
+            auto len = strlen(argv[i]);
+            am[i] = argv[i][0 .. len];
+        }
+        args = am[0 .. argc];
+    }
+    _d_args = cast(string[]) args;
+	
+	void runMain()
+    {
+        result = main(_d_args);
+    }
+
+    void runAll()
+    {
+        gc_init();
+        initStaticDataGC();
+        version (Windows)
+            _minit();
+        _moduleCtor();
+        _moduleTlsCtor();
+        if (runModuleUnitTests())
+            runMain();
+        else
+            result = EXIT_FAILURE;
+        _moduleTlsDtor();
+        thread_joinAll();
+        _d_isHalting = true;
+        _moduleDtor();
+        gc_term();
+    }
+
+    runAll();
+
+    version (Posix)
+    {
+        _STD_critical_term();
+        _STD_monitor_staticdtor();
+    }
+    return result;
 }
 
 int main(string[] args)