diff src/dbgprocess.d @ 1:4a9dcbd9e54f

-files of 0.13 beta -fixes so that it now compiles with the current dmd version
author marton@basel.hu
date Tue, 05 Apr 2011 20:44:01 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbgprocess.d	Tue Apr 05 20:44:01 2011 +0200
@@ -0,0 +1,221 @@
+/*  Ddbg - Win32 Debugger for the D programming language
+ *  Copyright (c) 2007 Jascha Wetzel
+ *  All rights reserved. See LICENSE.TXT for details.
+ */
+module dbgprocess;
+
+import win32.winbase;
+import win32.windef;
+
+import std.string;
+import std.c.string;
+
+import util;
+import breakpoint;
+import dbgthread;
+import callstack;
+import codeview.coff;
+
+/**************************************************************************************************
+
+**************************************************************************************************/
+class DbgProcess
+{
+public:
+	HANDLE		process_handle;
+	uint        processId,
+                mainThreadId;
+	DLL[]		loaded_dlls;
+
+	DbgThread[uint]	    threads;
+
+    /**********************************************************************************************
+
+    **********************************************************************************************/
+	DLL loadDLL(LOAD_DLL_DEBUG_INFO* lddi)
+	{
+		DLL dll					= new DLL;
+		dll.filehandle		    = lddi.hFile;
+		dll.base				= cast(uint)lddi.lpBaseOfDll;
+		dll.debug_info_offset	= lddi.dwDebugInfoFileOffset;
+		dll.debug_info_size	= lddi.nDebugInfoSize;
+		loaded_dlls ~= dll;
+
+		size_t filesize = GetFileSize(lddi.hFile, null);
+		if ( filesize == 0 )
+		{
+			debug DbgIO.println("Couldn't get DLL %s image size: %s", dll.image.name, lastError);
+			return dll;
+		}
+
+		ubyte[] buf;
+		buf.length = filesize;
+		if ( !ReadFile(lddi.hFile, cast(void*)buf.ptr, buf.length, &filesize, null) || filesize != buf.length )
+		{
+			debug DbgIO.println("Couldn't read DLL image for %s: %s", dll.image.name, lastError);
+			return dll;
+		}
+		dll.image = new COFFImage;
+		dll.image.load(buf);
+
+		return dll;
+	}
+
+    /**********************************************************************************************
+
+    **********************************************************************************************/
+	DLL findDLL(size_t vaddress)
+	{
+		foreach ( dll; loaded_dlls )
+		{
+			if ( vaddress < dll.base )
+				continue;
+			assert( dll !is null );
+			assert( dll.image !is null );
+			uint size_image = dll.image.imageSize;
+			if ( vaddress-dll.base > size_image )
+				continue;
+			return dll;
+		}
+		return null;
+	}
+
+    /**********************************************************************************************
+        Loads the given thread's stack and the index of the current frame pointer (ebp).
+        Returns: Arrays of uints.
+    **********************************************************************************************/
+	CallStack loadStack(DbgThread thread)
+	{
+		CONTEXT ctx;
+		if ( !thread.getContext(ctx, CONTEXT_CONTROL) )
+            throw new Exception("Couldn't get thread's context");
+
+		CallStack stack = new CallStack(thread.stack_base, ctx.Esp, ctx.Ebp);
+		uint read = readProcessMemory(ctx.Esp, stack.data.ptr, stack.data.length);
+		if ( read == 0 )
+            throw new Exception("Couldn't read thread's stack memory");
+		else if ( read < stack.data.length )
+			stack.data.length = read;
+		return stack;
+	}
+
+    /**********************************************************************************************
+        Read from debuggee's memory.
+        Returns: #bytes read
+    **********************************************************************************************/
+	size_t readProcessMemory(size_t address, void* data, size_t size, bool changeProtect=false)
+	{
+		uint oldprot;
+		if( changeProtect && !VirtualProtectEx(process_handle, cast(void*)address, size, PAGE_READONLY, &oldprot) ) {
+			debug DbgIO.println("readProcessMemory(): Failed to obtain read access to page at 0x%08x: %s", address, lastError);
+			return false;
+		}
+
+		size_t numbytes;
+		if( !ReadProcessMemory(process_handle, cast(void*)address, data, size, &numbytes) ) {
+			debug DbgIO.println("ReadProcessMemory() returned false reading address 0x%08x: %s", address, lastError);
+            return 0;
+		}
+		if ( numbytes != size ) {
+			debug DbgIO.println("readProcessMemory(): Failed to read at address 0x%08x: %s", address, lastError);
+		}
+
+		if( changeProtect && !VirtualProtectEx(process_handle, cast(void*)address, size, oldprot, &oldprot) ) {
+			DbgIO.println("writeProcessMemory(): Failed to restore access to page at 0x%08x: %s", address, lastError);
+			return 0;
+		}
+
+		return numbytes;
+	}
+
+    /**********************************************************************************************
+        Write to debuggee's memory.
+        Returns success.
+    **********************************************************************************************/
+	size_t writeProcessMemory(size_t address, void* data, size_t size)
+	{
+		uint oldprot;
+
+		if( !VirtualProtectEx(process_handle, cast(void*)address, size, PAGE_EXECUTE_READWRITE, &oldprot) )
+		{
+			DbgIO.println("writeProcessMemory(): Failed to obtain write access to page at 0x%08x: %s", address, lastError);
+			return false;
+		}
+
+		size_t numbytes;
+		if( !WriteProcessMemory(process_handle, cast(void*)address, data, size, &numbytes) )
+			DbgIO.println("writeProcessMemory(): Failed to write byte at 0x%08x: %s", address, lastError);
+
+		if( !VirtualProtectEx(process_handle, cast(void*)address, size, oldprot, &oldprot) )
+		{
+			DbgIO.println("writeProcessMemory(): Failed to restore access to page at 0x%08x: %s", address, lastError);
+			return false;
+		}
+
+		if ( !FlushInstructionCache(process_handle, cast(void*)address, numbytes) )
+		{
+			DbgIO.println("writeProcessMemory(): FlushInstructionCache failed for 0x%08x: %s", address, lastError());
+			return false;
+		}
+
+		return numbytes;
+	}
+
+    /**********************************************************************************************
+
+    **********************************************************************************************/
+	ClassInfo getClassInfo(size_t obj_ptr)
+	{
+		uint	vtbl,
+				ci_ptr;
+		readProcessMemory(obj_ptr, &vtbl, size_t.sizeof);
+		readProcessMemory(vtbl, &ci_ptr, size_t.sizeof);
+		ubyte[] data;
+		data.length = ClassInfo.classinfo.init.length;
+		readProcessMemory(ci_ptr, data.ptr, data.length);
+		return cast(ClassInfo)data.ptr;
+	}
+
+    /**********************************************************************************************
+        simple check for invalidity of a memory block
+    **********************************************************************************************/
+    const size_t MEMCHECK_MIN = 0x1000;
+    bool isInvalidMem(size_t ptr, size_t len)
+    {
+        uint tmp;
+        if ( uint.sizeof != readProcessMemory(ptr, &tmp, uint.sizeof)
+            || uint.sizeof != readProcessMemory(ptr+len-uint.sizeof, &tmp, uint.sizeof) )
+            return true;
+        return false;
+    }
+
+    /**********************************************************************************************
+
+    **********************************************************************************************/
+    MEMORY_BASIC_INFORMATION[] walkMemory()
+    {
+        SYSTEM_INFO                 si;
+        MEMORY_BASIC_INFORMATION[]  mbis;
+        GetSystemInfo(&si);
+        for ( void* ptr = si.lpMinimumApplicationAddress; ptr < si.lpMaximumApplicationAddress; )
+        {
+            mbis.length = mbis.length + 1;
+            VirtualQueryEx(process_handle, ptr, &mbis[$-1], MEMORY_BASIC_INFORMATION.sizeof);
+            ptr = mbis[$-1].BaseAddress + mbis[$-1].RegionSize;
+        }
+        return mbis;
+    }
+}
+
+/**************************************************************************************************
+
+**************************************************************************************************/
+class DLL
+{
+public:
+	HANDLE	filehandle;
+	uint	base,
+			debug_info_offset,
+			debug_info_size;
+	COFFImage	image;
+}