diff --git a/src/ddebug/gdb/gdbinterface.d b/src/ddebug/gdb/gdbinterface.d index 91fb190..b307861 100644 --- a/src/ddebug/gdb/gdbinterface.d +++ b/src/ddebug/gdb/gdbinterface.d @@ -66,6 +66,7 @@ class ConsoleDebuggerInterface : DebuggerBase, TextWriter { } +import std.process; class GDBInterface : ConsoleDebuggerInterface { protected int commandId; @@ -77,8 +78,100 @@ class GDBInterface : ConsoleDebuggerInterface { return commandId; } + Pid terminalPid; + string terminalTty; + + string startTerminal(string termExecutable) { + Log.d("Starting terminal"); + import std.random; + import std.file; + import std.path; + import std.string; + import core.thread; + uint n = uniform(0, 0x10000000, rndGen()); + terminalTty = null; + string termfile = buildPath(tempDir, format("dlangide-term-name-%07x.tmp", n)); + Log.d("temp file for tty name: ", termfile); + try { + terminalPid = spawnProcess([ + termExecutable, + "-title", + "DLangIDE External Console", + "-e", + "echo 'DlangIDE External Console' && tty > " ~ termfile ~ " && sleep 1000000" + ]); + for (int i = 0; i < 20; i++) { + Thread.sleep(dur!"msecs"(100)); + if (!isTerminalActive) { + Log.e("Failed to get terminal TTY"); + return null; + } + if (!exists(termfile)) { + Thread.sleep(dur!"msecs"(20)); + break; + } + } + // read TTY from file + if (exists(termfile)) { + terminalTty = readText(termfile); + if (terminalTty.endsWith("\n")) + terminalTty = terminalTty[0 .. $-1]; + // delete file + remove(termfile); + } + } catch (Exception e) { + Log.e("Failed to start terminal ", e); + killTerminal(); + } + if (terminalTty.length == 0) { + Log.i("Cannot start terminal"); + killTerminal(); + } else { + Log.i("Terminal: ", terminalTty); + } + return terminalTty; + } + + bool isTerminalActive() { + if (terminalPid is null) + return false; + auto res = tryWait(terminalPid); + if (res.terminated) { + Log.d("isTerminalActive: Terminal is stopped"); + wait(terminalPid); + terminalPid = Pid.init; + return false; + } else { + return true; + } + } + + void killTerminal() { + if (terminalPid is null) + return; + try { + Log.d("Trying to kill terminal"); + kill(terminalPid, 9); + Log.d("Waiting for terminal process termination"); + wait(terminalPid); + terminalPid = Pid.init; + Log.d("Killed"); + } catch (Exception e) { + Log.d("Exception while killing terminal", e); + terminalPid = Pid.init; + } + } + + string terminalExecutableFileName = "xterm"; override void startDebugging(string debuggerExecutable, string executable, string[] args, string workingDir, DebuggerResponse response) { string[] debuggerArgs; + terminalTty = startTerminal(terminalExecutableFileName); + if (terminalTty.length == 0) { + response(ResponseCode.CannotRunDebugger, "Cannot start terminal"); + return; + } + debuggerArgs ~= "-tty"; + debuggerArgs ~= terminalTty; debuggerArgs ~= "--interpreter=mi"; debuggerArgs ~= "--silent"; debuggerArgs ~= "--args"; @@ -89,16 +182,18 @@ class GDBInterface : ConsoleDebuggerInterface { Log.i("Debugger process state:"); if (state == ExternalProcessState.Running) { response(ResponseCode.Ok, "Started"); - sendCommand("-break-insert main"); + //sendCommand("-break-insert main"); sendCommand("-exec-run"); } else { response(ResponseCode.CannotRunDebugger, "Error while trying to run debugger process"); + return; } } override void stop() { if (_debuggerProcess !is null) _debuggerProcess.kill(); + killTerminal(); super.stop(); } diff --git a/src/dlangide.d b/src/dlangide.d index 88f11c9..6d8421b 100644 --- a/src/dlangide.d +++ b/src/dlangide.d @@ -122,9 +122,9 @@ version(USE_GDB_DEBUG) { Log.d("startDebugging result: ", code, " : ", msg); //assert(code == ResponseCode.NotImplemented); }); - Thread.sleep(dur!"msecs"(2000)); + Thread.sleep(dur!"msecs"(200000)); debugger.stop(); - Thread.sleep(dur!"msecs"(2000)); + Thread.sleep(dur!"msecs"(200000)); destroy(debugger); Log.d("Testing of GDB debugger is finished"); }