diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index e1e0222d02b..c83b349e80a 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -904,14 +904,6 @@ class Dumper(DumperBase): except: # Could have been deleted in the mean time. pass - self.ignoreStops = 0 - if platform.system() == 'Linux': - if self.startMode_ == DebuggerStartMode.AttachCore: - pass - else: - if self.useTerminal_: - self.ignoreStops = 1 - if self.platform_: self.debugger.SetCurrentPlatform(self.platform_) # sysroot has to be set *after* the platform @@ -1450,9 +1442,6 @@ class Dumper(DumperBase): if self.isInterrupting_: self.isInterrupting_ = False self.reportState("inferiorstopok") - elif self.ignoreStops > 0: - self.ignoreStops -= 1 - self.process.Continue() else: self.reportState("stopped") else: diff --git a/src/libs/utils/consoleprocess.cpp b/src/libs/utils/consoleprocess.cpp index bd6f6231b8c..18f6a73e6da 100644 --- a/src/libs/utils/consoleprocess.cpp +++ b/src/libs/utils/consoleprocess.cpp @@ -611,6 +611,18 @@ bool ConsoleProcess::start() return true; } +void Utils::ConsoleProcess::kickoffProcess() +{ +#ifdef Q_OS_WIN + // Not used. +#else + if (d->m_stubSocket && d->m_stubSocket->isWritable()) { + d->m_stubSocket->write("c", 1); + d->m_stubSocket->flush(); + } +#endif +} + void ConsoleProcess::interruptProcess() { #ifdef Q_OS_WIN diff --git a/src/libs/utils/consoleprocess.h b/src/libs/utils/consoleprocess.h index ce53e0d87c7..16373fe76e0 100644 --- a/src/libs/utils/consoleprocess.h +++ b/src/libs/utils/consoleprocess.h @@ -90,6 +90,7 @@ public: bool isRunning() const; // This reflects the state of the console+stub qint64 applicationPID() const; + void kickoffProcess(); void interruptProcess(); void killProcess(); void killStub(); diff --git a/src/libs/utils/process_stub_unix.c b/src/libs/utils/process_stub_unix.c index 271404fe3bb..d7a7ff15b09 100644 --- a/src/libs/utils/process_stub_unix.c +++ b/src/libs/utils/process_stub_unix.c @@ -57,6 +57,7 @@ extern char **environ; static int qtcFd; static char *sleepMsg; static int chldPipe[2]; +static int blockingPipe[2]; static int isDebug; static volatile int isDetached; static volatile int chldPid; @@ -236,10 +237,21 @@ int main(int argc, char *argv[]) perror("Cannot create status pipe"); doExit(3); } + /* The debugged program is not supposed to inherit these handles. But we cannot * close the writing end before calling exec(). Just handle both ends the same way ... */ fcntl(chldPipe[0], F_SETFD, FD_CLOEXEC); fcntl(chldPipe[1], F_SETFD, FD_CLOEXEC); + + if (isDebug) { + /* Create execution start notification pipe. The child waits on this until + the parent writes to it, triggered by an 'c' message from Creator */ + if (pipe(blockingPipe)) { + perror("Cannot create blocking pipe"); + doExit(3); + } + } + switch ((chldPid = fork())) { case -1: perror("Cannot fork child process"); @@ -262,9 +274,15 @@ int main(int argc, char *argv[]) #ifdef __linux__ prctl(PR_SET_PTRACER, atoi(argv[ArgPid])); #endif - /* Stop the child to allow the debugger to attach */ - if (isDebug) - kill(chldPid, SIGSTOP); + /* Block to allow the debugger to attach */ + if (isDebug) { + char buf; + int res = read(blockingPipe[0], &buf, 1); + if (res < 0) + perror("Could not read from blocking pipe"); + close(blockingPipe[0]); + close(blockingPipe[1]); + } if (env) environ = env; @@ -296,6 +314,7 @@ int main(int argc, char *argv[]) break; } else { int i; + char c = 'i'; for (i = 0; i < nbytes; ++i) { switch (buffer[i]) { case 'k': @@ -305,13 +324,12 @@ int main(int argc, char *argv[]) kill(chldPid, SIGKILL); } break; - case 'i': - if (chldPid > 0) { - int res = kill(chldPid, SIGINT); - if (res) - perror("Stub could not interrupt inferior"); - } + case 'c': { + int res = write(blockingPipe[1], &c, 1); + if (res < 0) + perror("Could not write to blocking pipe"); break; + } case 'd': isDetached = 1; break; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 42ee110f7e8..3d5c6c07188 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1147,26 +1147,6 @@ void GdbEngine::handleStopResponse(const GdbMi &data) return; } - // Ignore signals from the process stub. - const GdbMi frame = data["frame"]; - if (terminal() - && data["reason"].data() == "signal-received" - && data["signal-name"].data() == "SIGSTOP") - { - const QString from = frame["from"].data(); - const QString func = frame["func"].data(); - if (from.endsWith("/ld-linux.so.2") - || from.endsWith("/ld-linux-x86-64.so.2") - || func == "clone" - || func == "kill") - { - showMessage("INTERNAL CONTINUE AFTER SIGSTOP FROM STUB", LogMisc); - notifyInferiorSpontaneousStop(); - continueInferiorInternal(); - return; - } - } - if (!m_onStop.isEmpty()) { notifyInferiorStopOk(); showMessage("HANDLING QUEUED COMMANDS AFTER TEMPORARY STOP", LogMisc); @@ -1184,6 +1164,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data) QString fullName; QString function; QString language; + const GdbMi frame = data["frame"]; if (frame.isValid()) { const GdbMi lineNumberG = frame["line"]; function = frame["function"].data(); // V4 protocol @@ -4919,7 +4900,9 @@ void GdbEngine::handleStubAttached(const DebuggerResponse &response, qint64 main notifyEngineRunAndInferiorStopOk(); continueInferiorInternal(); } else { - showMessage("INFERIOR ATTACHED AND RUNNING"); + showMessage("INFERIOR ATTACHED"); + QTC_ASSERT(terminal(), return); + terminal()->kickoffProcess(); //notifyEngineRunAndInferiorRunOk(); // Wait for the upcoming *stopped and handle it there. } diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp index c54336c0456..24b1f72f23d 100644 --- a/src/plugins/debugger/terminal.cpp +++ b/src/plugins/debugger/terminal.cpp @@ -183,6 +183,11 @@ TerminalRunner::TerminalRunner(RunControl *runControl, const Runnable &stubRunna this, [this] { reportDone(); }); } +void TerminalRunner::kickoffProcess() +{ + m_stubProc.kickoffProcess(); +} + void TerminalRunner::interruptProcess() { m_stubProc.interruptProcess(); diff --git a/src/plugins/debugger/terminal.h b/src/plugins/debugger/terminal.h index 410d0fb7d91..ceacf3fddd7 100644 --- a/src/plugins/debugger/terminal.h +++ b/src/plugins/debugger/terminal.h @@ -77,6 +77,7 @@ public: qint64 applicationPid() const { return m_applicationPid; } qint64 applicationMainThreadId() const { return m_applicationMainThreadId; } + void kickoffProcess(); void interruptProcess(); void setRunAsRoot(bool on);