From 705aa2b5f3569af0ca16ac62e5e69e83b6e9eb51 Mon Sep 17 00:00:00 2001
From: Vadim Lopatin <coolreader.org@gmail.com>
Date: Thu, 5 Nov 2015 17:38:07 +0300
Subject: [PATCH] windows debugger support, initial

---
 dlangide_msvc.visualdproj     | 14 ++++----
 src/ddebug/windows/windebug.d | 62 +++++++++++++++++++++++++++++------
 src/dlangide.d                | 11 +++++++
 3 files changed, 70 insertions(+), 17 deletions(-)

diff --git a/dlangide_msvc.visualdproj b/dlangide_msvc.visualdproj
index 5881de4..7864180 100644
--- a/dlangide_msvc.visualdproj
+++ b/dlangide_msvc.visualdproj
@@ -72,7 +72,7 @@
   <debuglevel>0</debuglevel>
   <debugids>DebugInfo DCD</debugids>
   <versionlevel>0</versionlevel>
-  <versionids>Unicode  USE_FREETYPE USE_OPENGL EmbedStandardResources</versionids>
+  <versionids>Unicode  USE_FREETYPE USE_OPENGL EmbedStandardResources USE_WIN_DEBUG</versionids>
   <dump_source>0</dump_source>
   <mapverbosity>0</mapverbosity>
   <createImplib>0</createImplib>
@@ -248,7 +248,7 @@
   <pic>0</pic>
   <cov>0</cov>
   <nofloat>0</nofloat>
-  <Dversion>2.043</Dversion>
+  <Dversion>2</Dversion>
   <ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
   <allinst>0</allinst>
   <stackStomp>0</stackStomp>
@@ -276,7 +276,7 @@
   <debuglevel>0</debuglevel>
   <debugids>DebugInfo DCD</debugids>
   <versionlevel>0</versionlevel>
-  <versionids>Unicode  USE_FREETYPE USE_OPENGL EmbedStandardResources</versionids>
+  <versionids>Unicode  USE_FREETYPE USE_OPENGL EmbedStandardResources USE_WIN_DEBUG</versionids>
   <dump_source>0</dump_source>
   <mapverbosity>0</mapverbosity>
   <createImplib>0</createImplib>
@@ -441,10 +441,6 @@
     </Folder>
     <File path="src\dlangide\tools\editortool.d" />
    </Folder>
-   <Folder name="workspace">
-    <File path="src\dlangide\workspace\project.d" />
-    <File path="src\dlangide\workspace\workspace.d" />
-   </Folder>
    <Folder name="ui">
     <File path="src\dlangide\ui\commands.d" />
     <File path="src\dlangide\ui\dsourceedit.d" />
@@ -456,6 +452,10 @@
     <File path="src\dlangide\ui\settings.d" />
     <File path="src\dlangide\ui\wspanel.d" />
    </Folder>
+   <Folder name="workspace">
+    <File path="src\dlangide\workspace\project.d" />
+    <File path="src\dlangide\workspace\workspace.d" />
+   </Folder>
   </Folder>
   <File path="src\dlangide.d" />
  </Folder>
diff --git a/src/ddebug/windows/windebug.d b/src/ddebug/windows/windebug.d
index d7622fe..d0da941 100644
--- a/src/ddebug/windows/windebug.d
+++ b/src/ddebug/windows/windebug.d
@@ -1,30 +1,52 @@
 // just an attempt to implement D debugger for win32
 module ddebug.windows.windebug;
 
+version(Windows):
+version(USE_WIN_DEBUG):
+
+import dlangui.core.logger;
 import win32.windows;
 
 import std.utf;
-
-version(Windows):
+import core.thread;
+import std.format;
 
 
-class WinDebugger {
-    this() {
+class WinDebugger : Thread {
+    string _exefile;
+    string _args;
+
+    this(string exefile, string args) {
+        super(&run);
+        _exefile = exefile;
+        _args = args;
     }
 
+    private void run() {
+        Log.i("Debugger thread started");
+        if (startDebugging())
+            enterDebugLoop();
+        Log.i("Debugger thread finished");
+        _finished = true;
+    }
+
+    private shared bool _finished;
     STARTUPINFOW _si; 
     PROCESS_INFORMATION _pi;
 
-    bool startDebugging(string exefile, string args) {
+    bool startDebugging() {
+
+        Log.i("starting debug for '" ~ _exefile ~ "' args: " ~ _args);
+
         _stopRequested = false;
         _si = STARTUPINFOW.init;
         _si.cb = _si.sizeof;
         _pi = PROCESS_INFORMATION.init;
 
-        string cmdline = "\"" ~ exefile ~ "\"";
-        if (args.length > 0)
-            cmdline = cmdline ~ " " ~ args;
-        wchar[] exefilew = cast(wchar[])toUTF16(exefile);
+        string cmdline = "\"" ~ _exefile ~ "\"";
+        if (_args.length > 0)
+            cmdline = cmdline ~ " " ~ _args;
+        wchar[] exefilew = cast(wchar[])toUTF16(_exefile);
         exefilew ~= cast(dchar)0;
         wchar[] cmdlinew = cast(wchar[])toUTF16(cmdline);
         cmdlinew ~= cast(dchar)0;
@@ -37,31 +59,40 @@ class WinDebugger {
                             cast(const wchar*)NULL, &_si, &_pi)) {
             return false;
         }
+        Log.i("Executable '" ~ _exefile ~ "' started successfully");
         return true;
     }
 
     uint onCreateThreadDebugEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onCreateThreadDebugEvent");
         return DBG_CONTINUE;
     }
     uint onCreateProcessDebugEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onCreateProcessDebugEvent");
         return DBG_CONTINUE;
     }
     uint onExitThreadDebugEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onExitThreadDebugEvent");
         return DBG_CONTINUE;
     }
     uint onExitProcessDebugEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onExitProcessDebugEvent");
         return DBG_CONTINUE;
     }
     uint onLoadDllDebugEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onLoadDllDebugEvent");
         return DBG_CONTINUE;
     }
     uint onUnloadDllDebugEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onUnloadDllDebugEvent");
         return DBG_CONTINUE;
     }
     uint onOutputDebugStringEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onOutputDebugStringEvent");
         return DBG_CONTINUE;
     }
     uint onRipEvent(ref DEBUG_EVENT debug_event) {
+        Log.d("onRipEvent");
         return DBG_TERMINATE_PROCESS;
     }
 
@@ -175,16 +206,27 @@ class WinDebugger {
     bool _stopRequested;
 
     bool enterDebugLoop() {
+        Log.i("entering debug loop");
         _continueStatus = DBG_CONTINUE;
         DEBUG_EVENT debug_event;
+        debug_event = DEBUG_EVENT.init;
+
         for(;;)
         {
-            if (!WaitForDebugEvent(&debug_event, INFINITE))
+            if (!WaitForDebugEvent(&debug_event, INFINITE)) {
+                uint err = GetLastError();
+                Log.e("WaitForDebugEvent returned false. Error=" ~ format("%08x", err));
                 return false;
+            }
+            Log.i("processDebugEvent");
             processDebugEvent(debug_event);
+            if (_continueStatus == DBG_TERMINATE_PROCESS)
+                break;
             ContinueDebugEvent(debug_event.dwProcessId,
                                debug_event.dwThreadId,
                                _continueStatus);
         }
+        Log.i("exiting debug loop");
+        return true;
     }
 }
diff --git a/src/dlangide.d b/src/dlangide.d
index ebbda3f..1981bc1 100644
--- a/src/dlangide.d
+++ b/src/dlangide.d
@@ -56,6 +56,10 @@ extern (C) int UIAppMain(string[] args) {
         }
     }
 
+    version(USE_WIN_DEBUG) {
+        debuggerTest();
+    }
+
     // create window
     Window window = Platform.instance.createWindow("Dlang IDE", null, WindowFlag.Resizable, 700, 470);
     // set window icon
@@ -81,6 +85,13 @@ extern (C) int UIAppMain(string[] args) {
     return Platform.instance.enterMessageLoop();
 }
 
+version(USE_WIN_DEBUG) {
+    void debuggerTest() {
+        import ddebug.windows.windebug;
+        WinDebugger debugger = new WinDebugger("test\\dmledit.exe", "");
+        debugger.start();
+    }
+}
 
 unittest {
     void jsonTest() {