Index: src/backtracegenerator.h =================================================================== --- src/backtracegenerator.h +++ src/backtracegenerator.h @@ -84,6 +84,7 @@ State m_state; BacktraceParser * m_parser = nullptr; QString m_parsedBacktrace; + bool m_debuggerKilled; #ifdef BACKTRACE_PARSER_DEBUG BacktraceParser * m_debugParser = nullptr; Index: src/backtracegenerator.cpp =================================================================== --- src/backtracegenerator.cpp +++ src/backtracegenerator.cpp @@ -37,7 +37,8 @@ BacktraceGenerator::BacktraceGenerator(const Debugger & debugger, QObject *parent) : QObject(parent), m_debugger(debugger), m_proc(nullptr), - m_temp(nullptr), m_state(NotLoaded) + m_temp(nullptr), m_state(NotLoaded), + m_debuggerKilled(false) { m_parser = BacktraceParser::newParser(m_debugger.codeName(), this); m_parser->connectToGenerator(this); @@ -103,6 +104,7 @@ // and take the appropriate steps if so QString stdinFile = m_debugger.backendValueOfParameter(QStringLiteral("ExecInputFile")); Debugger::expandString(stdinFile, Debugger::ExpansionUsageShell, m_temp->fileName()); + m_temp->close(); if (!stdinFile.isEmpty() && QFile::exists(stdinFile)) { m_proc->setStandardInputFile(stdinFile); } @@ -140,39 +142,49 @@ QString line = QString::fromLocal8Bit(m_output.constData(), pos + 1); m_output.remove(0, pos + 1); - emit newLine(line); - line = line.simplified(); - if (line.startsWith(QLatin1String("Process ")) && line.endsWith(QLatin1String(" detached"))) { - // lldb is acting on a detach command (in lldbrc) + if (line.simplified() == QStringLiteral("(lldb) exit")) { + // lldb is acting on the exit command (from lldbrc) // Anything following this line doesn't interest us, and lldb has been known // to turn into a zombie instead of exitting, thereby blocking us. // Tell the process to quit if it's still running, and pretend it did. if (m_proc && m_proc->state() == QProcess::Running) { - m_proc->terminate(); + // give it a bit of time before termination if (!m_proc->waitForFinished(500)) { - m_proc->kill(); + m_debuggerKilled = true; + m_proc->terminate(); } - if (m_proc) { - slotProcessExited(0, QProcess::NormalExit); + if (m_proc && !m_proc->waitForFinished(500)) { + // insist harder. + m_proc->kill(); } + slotProcessExited(0, QProcess::NormalExit); } return; } + emit newLine(line); } } void BacktraceGenerator::slotProcessExited(int exitCode, QProcess::ExitStatus exitStatus) { - //these are useless now - m_proc->deleteLater(); - m_temp->deleteLater(); - m_proc = nullptr; - m_temp = nullptr; + QString errorString; + if (m_proc) { + errorString = m_proc->errorString(); + //these are useless now + m_proc->deleteLater(); + m_proc = nullptr; + m_temp->deleteLater(); + m_temp = nullptr; + } //mark the end of the backtrace for the parser emit newLine(QString()); - if (exitStatus != QProcess::NormalExit || exitCode != 0) { + // killing the debugger processes will raise an error; ignore it. + if (!m_debuggerKilled && (exitStatus != QProcess::NormalExit || exitCode != 0)) { + if (!errorString.isEmpty()) { + qCCritical(DRKONQI_LOG) << m_debugger.command() << "encountered an error:" << errorString; + } m_state = Failed; emit someError(); return; @@ -193,5 +205,3 @@ emit done(); } - - Index: src/data/debuggers/internal/lldbrc =================================================================== --- src/data/debuggers/internal/lldbrc +++ src/data/debuggers/internal/lldbrc @@ -30,6 +30,5 @@ Backends=KCrash [KCrash] -Exec=lldb -p %pid -ExecInputFile=%tempfile -BatchCommands=settings set term-width 200\nthread info\nbt all\ndetach +Exec=lldb -X -p %pid -s %tempfile +BatchCommands=settings set term-width 200\nthread info\nbt all\ndetach\nexit