forked from qt-creator/qt-creator
Debugger: Move external terminal into separate RunWorker
Change-Id: Ifb9701f840195ba90db48a0f6fa07b28e0409648 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -180,7 +180,7 @@ namespace Internal {
|
|||||||
|
|
||||||
static inline bool isCreatorConsole(const DebuggerRunParameters &sp)
|
static inline bool isCreatorConsole(const DebuggerRunParameters &sp)
|
||||||
{
|
{
|
||||||
return !boolSetting(UseCdbConsole) && sp.useTerminal
|
return !boolSetting(UseCdbConsole) && sp.inferior.runMode == ApplicationLauncher::Console
|
||||||
&& (sp.startMode == StartInternal || sp.startMode == StartExternal);
|
&& (sp.startMode == StartInternal || sp.startMode == StartExternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +428,7 @@ void CdbEngine::consoleStubProcessStarted()
|
|||||||
attachParameters.inferior.commandLineArguments.clear();
|
attachParameters.inferior.commandLineArguments.clear();
|
||||||
attachParameters.attachPID = ProcessHandle(m_consoleStub->applicationPID());
|
attachParameters.attachPID = ProcessHandle(m_consoleStub->applicationPID());
|
||||||
attachParameters.startMode = AttachExternal;
|
attachParameters.startMode = AttachExternal;
|
||||||
attachParameters.useTerminal = false;
|
attachParameters.inferior.runMode = ApplicationLauncher::Gui; // Force no terminal.
|
||||||
showMessage(QString("Attaching to %1...").arg(attachParameters.attachPID.pid()), LogMisc);
|
showMessage(QString("Attaching to %1...").arg(attachParameters.attachPID.pid()), LogMisc);
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
if (!launchCDB(attachParameters, &errorMessage)) {
|
if (!launchCDB(attachParameters, &errorMessage)) {
|
||||||
@@ -542,7 +542,7 @@ bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage
|
|||||||
// register idle (debuggee stop) notification
|
// register idle (debuggee stop) notification
|
||||||
<< "-c"
|
<< "-c"
|
||||||
<< ".idle_cmd " + m_extensionCommandPrefix + "idle";
|
<< ".idle_cmd " + m_extensionCommandPrefix + "idle";
|
||||||
if (sp.useTerminal) // Separate console
|
if (sp.inferior.runMode == ApplicationLauncher::Console) // Separate console
|
||||||
arguments << "-2";
|
arguments << "-2";
|
||||||
if (boolSetting(IgnoreFirstChanceAccessViolation))
|
if (boolSetting(IgnoreFirstChanceAccessViolation))
|
||||||
arguments << "-x";
|
arguments << "-x";
|
||||||
@@ -610,7 +610,8 @@ bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage
|
|||||||
|
|
||||||
// Make sure that QTestLib uses OutputDebugString for logging.
|
// Make sure that QTestLib uses OutputDebugString for logging.
|
||||||
const QString qtLoggingToConsoleKey = QStringLiteral("QT_LOGGING_TO_CONSOLE");
|
const QString qtLoggingToConsoleKey = QStringLiteral("QT_LOGGING_TO_CONSOLE");
|
||||||
if (!sp.useTerminal && !inferiorEnvironment.hasKey(qtLoggingToConsoleKey))
|
if (sp.inferior.runMode != ApplicationLauncher::Console
|
||||||
|
&& !inferiorEnvironment.hasKey(qtLoggingToConsoleKey))
|
||||||
inferiorEnvironment.set(qtLoggingToConsoleKey, QString(QLatin1Char('0')));
|
inferiorEnvironment.set(qtLoggingToConsoleKey, QString(QLatin1Char('0')));
|
||||||
|
|
||||||
m_process.setEnvironment(mergeEnvironment(inferiorEnvironment.toStringList(),
|
m_process.setEnvironment(mergeEnvironment(inferiorEnvironment.toStringList(),
|
||||||
|
@@ -425,7 +425,6 @@ void StartApplicationDialog::run(bool attachRemote)
|
|||||||
}
|
}
|
||||||
|
|
||||||
StandardRunnable inferior = newParameters.runnable;
|
StandardRunnable inferior = newParameters.runnable;
|
||||||
debugger->setUseTerminal(newParameters.runnable.runMode == ApplicationLauncher::Console);
|
|
||||||
const QString inputAddress = dialog.d->channelOverrideEdit->text();
|
const QString inputAddress = dialog.d->channelOverrideEdit->text();
|
||||||
if (!inputAddress.isEmpty())
|
if (!inputAddress.isEmpty())
|
||||||
debugger->setRemoteChannel(inputAddress);
|
debugger->setRemoteChannel(inputAddress);
|
||||||
|
@@ -106,7 +106,6 @@ QDebug operator<<(QDebug str, const DebuggerRunParameters &sp)
|
|||||||
<< " debugger environment=<" << sp.debugger.environment.size() << " variables>"
|
<< " debugger environment=<" << sp.debugger.environment.size() << " variables>"
|
||||||
<< " workingDir=" << sp.inferior.workingDirectory
|
<< " workingDir=" << sp.inferior.workingDirectory
|
||||||
<< " attachPID=" << sp.attachPID.pid()
|
<< " attachPID=" << sp.attachPID.pid()
|
||||||
<< " useTerminal=" << sp.useTerminal
|
|
||||||
<< " remoteChannel=" << sp.remoteChannel
|
<< " remoteChannel=" << sp.remoteChannel
|
||||||
<< " abi=" << sp.toolChainAbi.toString() << '\n';
|
<< " abi=" << sp.toolChainAbi.toString() << '\n';
|
||||||
return str;
|
return str;
|
||||||
@@ -329,7 +328,7 @@ public:
|
|||||||
// The state we had before something unexpected happend.
|
// The state we had before something unexpected happend.
|
||||||
DebuggerState m_lastGoodState = DebuggerNotReady;
|
DebuggerState m_lastGoodState = DebuggerNotReady;
|
||||||
|
|
||||||
Terminal m_terminal;
|
// Terminal m_terminal;
|
||||||
ProcessHandle m_inferiorPid;
|
ProcessHandle m_inferiorPid;
|
||||||
|
|
||||||
ModulesHandler m_modulesHandler;
|
ModulesHandler m_modulesHandler;
|
||||||
@@ -545,18 +544,18 @@ void DebuggerEngine::start()
|
|||||||
d->m_lastGoodState = DebuggerNotReady;
|
d->m_lastGoodState = DebuggerNotReady;
|
||||||
d->m_progress.setProgressValue(200);
|
d->m_progress.setProgressValue(200);
|
||||||
|
|
||||||
d->m_terminal.setup();
|
// d->m_terminal.setup();
|
||||||
if (d->m_terminal.isUsable()) {
|
// if (d->m_terminal.isUsable()) {
|
||||||
connect(&d->m_terminal, &Terminal::stdOutReady, [this](const QString &msg) {
|
// connect(&d->m_terminal, &Terminal::stdOutReady, [this](const QString &msg) {
|
||||||
d->m_runTool->appendMessage(msg, Utils::StdOutFormatSameLine);
|
// d->m_runTool->appendMessage(msg, Utils::StdOutFormatSameLine);
|
||||||
});
|
// });
|
||||||
connect(&d->m_terminal, &Terminal::stdErrReady, [this](const QString &msg) {
|
// connect(&d->m_terminal, &Terminal::stdErrReady, [this](const QString &msg) {
|
||||||
d->m_runTool->appendMessage(msg, Utils::StdErrFormatSameLine);
|
// d->m_runTool->appendMessage(msg, Utils::StdErrFormatSameLine);
|
||||||
});
|
// });
|
||||||
connect(&d->m_terminal, &Terminal::error, [this](const QString &msg) {
|
// connect(&d->m_terminal, &Terminal::error, [this](const QString &msg) {
|
||||||
d->m_runTool->appendMessage(msg, Utils::ErrorMessageFormat);
|
// d->m_runTool->appendMessage(msg, Utils::ErrorMessageFormat);
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
d->queueSetupEngine();
|
d->queueSetupEngine();
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
||||||
@@ -1378,9 +1377,10 @@ DebuggerRunTool *DebuggerEngine::runTool() const
|
|||||||
return d->m_runTool.data();
|
return d->m_runTool.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
Terminal *DebuggerEngine::terminal() const
|
TerminalRunner *DebuggerEngine::terminal() const
|
||||||
{
|
{
|
||||||
return &d->m_terminal;
|
QTC_ASSERT(d->m_runTool, return nullptr);
|
||||||
|
return d->m_runTool->terminalRunner();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEngine::selectWatchData(const QString &)
|
void DebuggerEngine::selectWatchData(const QString &)
|
||||||
|
@@ -74,6 +74,7 @@ class QmlCppEngine;
|
|||||||
class DebuggerToolTipContext;
|
class DebuggerToolTipContext;
|
||||||
class MemoryViewSetupData;
|
class MemoryViewSetupData;
|
||||||
class Terminal;
|
class Terminal;
|
||||||
|
class TerminalRunner;
|
||||||
class ThreadId;
|
class ThreadId;
|
||||||
|
|
||||||
class DebuggerRunParameters
|
class DebuggerRunParameters
|
||||||
@@ -87,7 +88,6 @@ public:
|
|||||||
Utils::Environment stubEnvironment;
|
Utils::Environment stubEnvironment;
|
||||||
Utils::ProcessHandle attachPID;
|
Utils::ProcessHandle attachPID;
|
||||||
QStringList solibSearchPath;
|
QStringList solibSearchPath;
|
||||||
bool useTerminal = false;
|
|
||||||
|
|
||||||
// Used by Qml debugging.
|
// Used by Qml debugging.
|
||||||
QUrl qmlServer;
|
QUrl qmlServer;
|
||||||
@@ -461,7 +461,7 @@ protected:
|
|||||||
void setMasterEngine(DebuggerEngine *masterEngine);
|
void setMasterEngine(DebuggerEngine *masterEngine);
|
||||||
|
|
||||||
ProjectExplorer::RunControl *runControl() const;
|
ProjectExplorer::RunControl *runControl() const;
|
||||||
Terminal *terminal() const;
|
TerminalRunner *terminal() const;
|
||||||
|
|
||||||
static QString msgStopped(const QString &reason = QString());
|
static QString msgStopped(const QString &reason = QString());
|
||||||
static QString msgStoppedBySignal(const QString &meaning, const QString &name);
|
static QString msgStoppedBySignal(const QString &meaning, const QString &name);
|
||||||
|
@@ -2878,8 +2878,9 @@ static void createNewDock(QWidget *widget)
|
|||||||
dockWidget->show();
|
dockWidget->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString formatStartParameters(const DebuggerRunParameters &sp)
|
static QString formatStartParameters(const DebuggerRunTool *debugger)
|
||||||
{
|
{
|
||||||
|
const DebuggerRunParameters &sp = debugger->runParameters();
|
||||||
QString rc;
|
QString rc;
|
||||||
QTextStream str(&rc);
|
QTextStream str(&rc);
|
||||||
str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode
|
str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode
|
||||||
@@ -2893,7 +2894,7 @@ static QString formatStartParameters(const DebuggerRunParameters &sp)
|
|||||||
if (!sp.inferior.executable.isEmpty()) {
|
if (!sp.inferior.executable.isEmpty()) {
|
||||||
str << "Executable: " << QDir::toNativeSeparators(sp.inferior.executable)
|
str << "Executable: " << QDir::toNativeSeparators(sp.inferior.executable)
|
||||||
<< ' ' << sp.inferior.commandLineArguments;
|
<< ' ' << sp.inferior.commandLineArguments;
|
||||||
if (sp.useTerminal)
|
if (debugger->terminalRunner())
|
||||||
str << " [terminal]";
|
str << " [terminal]";
|
||||||
str << '\n';
|
str << '\n';
|
||||||
if (!sp.inferior.workingDirectory.isEmpty())
|
if (!sp.inferior.workingDirectory.isEmpty())
|
||||||
@@ -2928,7 +2929,7 @@ void DebuggerPluginPrivate::runControlStarted(DebuggerRunTool *runTool)
|
|||||||
.arg(runTool->engine()->objectName())
|
.arg(runTool->engine()->objectName())
|
||||||
.arg(runTool->runParameters().toolChainAbi.toString());
|
.arg(runTool->runParameters().toolChainAbi.toString());
|
||||||
showStatusMessage(message);
|
showStatusMessage(message);
|
||||||
showMessage(formatStartParameters(runTool->runParameters()), LogDebug);
|
showMessage(formatStartParameters(runTool), LogDebug);
|
||||||
showMessage(m_debuggerSettings->dump(), LogDebug);
|
showMessage(m_debuggerSettings->dump(), LogDebug);
|
||||||
m_snapshotHandler->appendSnapshot(runTool);
|
m_snapshotHandler->appendSnapshot(runTool);
|
||||||
connectEngine(runTool);
|
connectEngine(runTool);
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "debuggerruncontrol.h"
|
#include "debuggerruncontrol.h"
|
||||||
|
#include "terminal.h"
|
||||||
|
|
||||||
#include "analyzer/analyzermanager.h"
|
#include "analyzer/analyzermanager.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
@@ -76,7 +77,7 @@ namespace Debugger {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
DebuggerEngine *createCdbEngine(QStringList *error, DebuggerStartMode sm);
|
DebuggerEngine *createCdbEngine(QStringList *error, DebuggerStartMode sm);
|
||||||
DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode sm);
|
DebuggerEngine *createGdbEngine(DebuggerStartMode sm);
|
||||||
DebuggerEngine *createPdbEngine();
|
DebuggerEngine *createPdbEngine();
|
||||||
DebuggerEngine *createQmlEngine(bool useTerminal);
|
DebuggerEngine *createQmlEngine(bool useTerminal);
|
||||||
DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal);
|
DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal);
|
||||||
@@ -173,8 +174,13 @@ public:
|
|||||||
Utils::QtcProcess m_proc;
|
Utils::QtcProcess m_proc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
class DebuggerRunToolPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QPointer<TerminalRunner> terminalRunner;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
|
||||||
static bool breakOnMainNextTime = false;
|
static bool breakOnMainNextTime = false;
|
||||||
|
|
||||||
@@ -284,7 +290,13 @@ void DebuggerRunTool::setBreakOnMain(bool on)
|
|||||||
|
|
||||||
void DebuggerRunTool::setUseTerminal(bool on)
|
void DebuggerRunTool::setUseTerminal(bool on)
|
||||||
{
|
{
|
||||||
m_runParameters.useTerminal = on;
|
if (on && !d->terminalRunner && m_runParameters.cppEngineType == GdbEngineType) {
|
||||||
|
d->terminalRunner = new TerminalRunner(this);
|
||||||
|
addStartDependency(d->terminalRunner);
|
||||||
|
}
|
||||||
|
if (!on && d->terminalRunner) {
|
||||||
|
QTC_CHECK(false); // User code can only switch from no terminal to one terminal.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::setCommandsAfterConnect(const QString &commands)
|
void DebuggerRunTool::setCommandsAfterConnect(const QString &commands)
|
||||||
@@ -343,6 +355,7 @@ void DebuggerRunTool::setInferior(const Runnable &runnable)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(runnable.is<StandardRunnable>(), reportFailure(); return);
|
QTC_ASSERT(runnable.is<StandardRunnable>(), reportFailure(); return);
|
||||||
m_runParameters.inferior = runnable.as<StandardRunnable>();
|
m_runParameters.inferior = runnable.as<StandardRunnable>();
|
||||||
|
setUseTerminal(m_runParameters.inferior.runMode == ApplicationLauncher::Console);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::setInferiorExecutable(const QString &executable)
|
void DebuggerRunTool::setInferiorExecutable(const QString &executable)
|
||||||
@@ -469,7 +482,7 @@ void DebuggerRunTool::start()
|
|||||||
|
|
||||||
switch (m_runParameters.cppEngineType) {
|
switch (m_runParameters.cppEngineType) {
|
||||||
case GdbEngineType:
|
case GdbEngineType:
|
||||||
cppEngine = createGdbEngine(m_runParameters.useTerminal, m_runParameters.startMode);
|
cppEngine = createGdbEngine(m_runParameters.startMode);
|
||||||
break;
|
break;
|
||||||
case CdbEngineType: {
|
case CdbEngineType: {
|
||||||
QStringList errors;
|
QStringList errors;
|
||||||
@@ -493,11 +506,11 @@ void DebuggerRunTool::start()
|
|||||||
|
|
||||||
switch (m_runParameters.masterEngineType) {
|
switch (m_runParameters.masterEngineType) {
|
||||||
case QmlEngineType:
|
case QmlEngineType:
|
||||||
m_engine = createQmlEngine(m_runParameters.useTerminal);
|
m_engine = createQmlEngine(terminalRunner() != nullptr);
|
||||||
break;
|
break;
|
||||||
case QmlCppEngineType:
|
case QmlCppEngineType:
|
||||||
if (cppEngine)
|
if (cppEngine)
|
||||||
m_engine = createQmlCppEngine(cppEngine, m_runParameters.useTerminal);
|
m_engine = createQmlCppEngine(cppEngine, terminalRunner() != nullptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_engine = cppEngine;
|
m_engine = cppEngine;
|
||||||
@@ -710,14 +723,6 @@ bool DebuggerRunTool::fixupParameters()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: We can't handle terminals yet.
|
|
||||||
if (rp.useTerminal && rp.cppEngineType == LldbEngineType) {
|
|
||||||
qWarning("Run in Terminal is not supported yet with the LLDB backend");
|
|
||||||
appendMessage(DebuggerPlugin::tr("Run in Terminal is not supported with the LLDB backend."),
|
|
||||||
ErrorMessageFormat);
|
|
||||||
rp.useTerminal = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rp.isNativeMixedDebugging())
|
if (rp.isNativeMixedDebugging())
|
||||||
rp.inferior.environment.set("QV4_FORCE_INTERPRETER", "1");
|
rp.inferior.environment.set("QV4_FORCE_INTERPRETER", "1");
|
||||||
|
|
||||||
@@ -727,8 +732,13 @@ bool DebuggerRunTool::fixupParameters()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Internal::TerminalRunner *DebuggerRunTool::terminalRunner() const
|
||||||
|
{
|
||||||
|
return d->terminalRunner;
|
||||||
|
}
|
||||||
|
|
||||||
DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit)
|
DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit)
|
||||||
: RunWorker(runControl)
|
: RunWorker(runControl), d(new DebuggerRunToolPrivate)
|
||||||
{
|
{
|
||||||
setDisplayName("DebuggerRunTool");
|
setDisplayName("DebuggerRunTool");
|
||||||
|
|
||||||
@@ -745,13 +755,25 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit)
|
|||||||
QString(), QString(), optionalPrompt);
|
QString(), QString(), optionalPrompt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (runConfig)
|
||||||
|
m_runParameters.displayName = runConfig->displayName();
|
||||||
|
|
||||||
|
if (runConfig && !kit)
|
||||||
|
kit = runConfig->target()->kit();
|
||||||
|
QTC_ASSERT(kit, return);
|
||||||
|
|
||||||
|
m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit);
|
||||||
|
m_runParameters.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
|
||||||
|
m_runParameters.macroExpander = kit->macroExpander();
|
||||||
|
m_runParameters.debugger = DebuggerKitInformation::runnable(kit);
|
||||||
|
|
||||||
Runnable r = runnable();
|
Runnable r = runnable();
|
||||||
if (r.is<StandardRunnable>()) {
|
if (r.is<StandardRunnable>()) {
|
||||||
m_runParameters.inferior = r.as<StandardRunnable>();
|
m_runParameters.inferior = r.as<StandardRunnable>();
|
||||||
m_runParameters.useTerminal = m_runParameters.inferior.runMode == ApplicationLauncher::Console;
|
|
||||||
// Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...)
|
// Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...)
|
||||||
m_runParameters.inferior.workingDirectory =
|
m_runParameters.inferior.workingDirectory =
|
||||||
FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory);
|
FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory);
|
||||||
|
setUseTerminal(m_runParameters.inferior.runMode == ApplicationLauncher::Console);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto aspect = runConfig ? runConfig->extraAspect<DebuggerRunConfigurationAspect>() : nullptr) {
|
if (auto aspect = runConfig ? runConfig->extraAspect<DebuggerRunConfigurationAspect>() : nullptr) {
|
||||||
@@ -760,16 +782,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit)
|
|||||||
m_runParameters.multiProcess = aspect->useMultiProcess();
|
m_runParameters.multiProcess = aspect->useMultiProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runConfig)
|
|
||||||
m_runParameters.displayName = runConfig->displayName();
|
|
||||||
|
|
||||||
if (runConfig && !kit)
|
|
||||||
kit = runConfig->target()->kit();
|
|
||||||
QTC_ASSERT(kit, return);
|
|
||||||
|
|
||||||
m_runParameters.macroExpander = kit->macroExpander();
|
|
||||||
|
|
||||||
m_runParameters.debugger = DebuggerKitInformation::runnable(kit);
|
|
||||||
const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH");
|
const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH");
|
||||||
if (!envBinary.isEmpty())
|
if (!envBinary.isEmpty())
|
||||||
m_runParameters.debugger.executable = QString::fromLocal8Bit(envBinary);
|
m_runParameters.debugger.executable = QString::fromLocal8Bit(envBinary);
|
||||||
@@ -787,9 +799,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit)
|
|||||||
if (ok)
|
if (ok)
|
||||||
m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride);
|
m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride);
|
||||||
|
|
||||||
m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit);
|
|
||||||
m_runParameters.sysRoot = SysRootKitInformation::sysRoot(kit).toString();
|
|
||||||
|
|
||||||
// This will only be shown in some cases, but we don't want to access
|
// This will only be shown in some cases, but we don't want to access
|
||||||
// the kit at that time anymore.
|
// the kit at that time anymore.
|
||||||
const QList<Task> tasks = DebuggerKitInformation::validateDebugger(kit);
|
const QList<Task> tasks = DebuggerKitInformation::validateDebugger(kit);
|
||||||
@@ -842,6 +851,7 @@ DebuggerRunTool::~DebuggerRunTool()
|
|||||||
engine->disconnect();
|
engine->disconnect();
|
||||||
delete engine;
|
delete engine;
|
||||||
}
|
}
|
||||||
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
|
void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
|
||||||
|
@@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
class TerminalRunner;
|
||||||
|
class DebuggerRunToolPrivate;
|
||||||
|
} // Internal
|
||||||
|
|
||||||
class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker
|
class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -128,12 +133,15 @@ public:
|
|||||||
void setTestCase(int testCase);
|
void setTestCase(int testCase);
|
||||||
void setOverrideStartScript(const QString &script);
|
void setOverrideStartScript(const QString &script);
|
||||||
|
|
||||||
|
Internal::TerminalRunner *terminalRunner() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void aboutToNotifyInferiorSetupOk();
|
void aboutToNotifyInferiorSetupOk();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool fixupParameters();
|
bool fixupParameters();
|
||||||
|
|
||||||
|
Internal::DebuggerRunToolPrivate *d;
|
||||||
QPointer<Internal::DebuggerEngine> m_engine; // Master engine
|
QPointer<Internal::DebuggerEngine> m_engine; // Master engine
|
||||||
Internal::DebuggerRunParameters m_runParameters;
|
Internal::DebuggerRunParameters m_runParameters;
|
||||||
bool m_isDying = false;
|
bool m_isDying = false;
|
||||||
|
@@ -137,11 +137,6 @@ static bool isMostlyHarmlessMessage(const QStringRef &msg)
|
|||||||
"Invalid argument\\n";
|
"Invalid argument\\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString mainFunction(const DebuggerRunParameters &rp)
|
|
||||||
{
|
|
||||||
return QLatin1String(rp.toolChainAbi.os() == Abi::WindowsOS && !rp.useTerminal ? "qMain" : "main");
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Debuginfo Taskhandler
|
// Debuginfo Taskhandler
|
||||||
@@ -194,8 +189,8 @@ private:
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
GdbEngine::GdbEngine(bool useTerminal, DebuggerStartMode startMode)
|
GdbEngine::GdbEngine(DebuggerStartMode startMode)
|
||||||
: m_startMode(startMode), m_useTerminal(useTerminal), m_terminalTrap(useTerminal)
|
: m_startMode(startMode)
|
||||||
{
|
{
|
||||||
setObjectName("GdbEngine");
|
setObjectName("GdbEngine");
|
||||||
|
|
||||||
@@ -221,26 +216,10 @@ GdbEngine::GdbEngine(bool useTerminal, DebuggerStartMode startMode)
|
|||||||
// Output
|
// Output
|
||||||
connect(&m_outputCollector, &OutputCollector::byteDelivery,
|
connect(&m_outputCollector, &OutputCollector::byteDelivery,
|
||||||
this, &GdbEngine::readDebuggeeOutput);
|
this, &GdbEngine::readDebuggeeOutput);
|
||||||
|
|
||||||
if (isTermEngine()) {
|
|
||||||
if (HostOsInfo::isWindowsHost()) {
|
|
||||||
// Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
|
|
||||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
|
|
||||||
m_stubProc.setMode(ConsoleProcess::Suspend);
|
|
||||||
else
|
|
||||||
m_stubProc.setMode(ConsoleProcess::Debug);
|
|
||||||
} else {
|
|
||||||
m_stubProc.setMode(ConsoleProcess::Debug);
|
|
||||||
m_stubProc.setSettings(ICore::settings());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GdbEngine::~GdbEngine()
|
GdbEngine::~GdbEngine()
|
||||||
{
|
{
|
||||||
if (isTermEngine())
|
|
||||||
m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub
|
|
||||||
|
|
||||||
if (isCoreEngine()) {
|
if (isCoreEngine()) {
|
||||||
if (m_coreUnpackProcess) {
|
if (m_coreUnpackProcess) {
|
||||||
m_coreUnpackProcess->blockSignals(true);
|
m_coreUnpackProcess->blockSignals(true);
|
||||||
@@ -781,9 +760,6 @@ void GdbEngine::interruptInferior()
|
|||||||
|
|
||||||
CHECK_STATE(InferiorStopRequested);
|
CHECK_STATE(InferiorStopRequested);
|
||||||
|
|
||||||
if (terminal()->sendInterrupt())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (usesExecInterrupt()) {
|
if (usesExecInterrupt()) {
|
||||||
runCommand({"-exec-interrupt"});
|
runCommand({"-exec-interrupt"});
|
||||||
} else {
|
} else {
|
||||||
@@ -1079,7 +1055,7 @@ void GdbEngine::handleResultRecord(DebuggerResponse *response)
|
|||||||
Abi abi = rp.toolChainAbi;
|
Abi abi = rp.toolChainAbi;
|
||||||
if (abi.os() == Abi::WindowsOS
|
if (abi.os() == Abi::WindowsOS
|
||||||
&& cmd.function.startsWith("attach")
|
&& cmd.function.startsWith("attach")
|
||||||
&& (rp.startMode == AttachExternal || rp.useTerminal))
|
&& (rp.startMode == AttachExternal || terminal()))
|
||||||
{
|
{
|
||||||
// Ignore spurious 'running' responses to 'attach'.
|
// Ignore spurious 'running' responses to 'attach'.
|
||||||
} else {
|
} else {
|
||||||
@@ -1240,11 +1216,13 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
{
|
{
|
||||||
// Ignore trap on Windows terminals, which results in
|
// Ignore trap on Windows terminals, which results in
|
||||||
// spurious "* stopped" message.
|
// spurious "* stopped" message.
|
||||||
if (m_terminalTrap && (!data.isValid() || !data["reason"].isValid())
|
if (m_expectTerminalTrap) {
|
||||||
&& Abi::hostAbi().os() == Abi::WindowsOS) {
|
m_expectTerminalTrap = false;
|
||||||
m_terminalTrap = false;
|
if ((!data.isValid() || !data["reason"].isValid())
|
||||||
showMessage("IGNORING TERMINAL SIGTRAP", LogMisc);
|
&& Abi::hostAbi().os() == Abi::WindowsOS) {
|
||||||
return;
|
showMessage("IGNORING TERMINAL SIGTRAP", LogMisc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDying()) {
|
if (isDying()) {
|
||||||
@@ -1279,7 +1257,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
// Ignore signals from the process stub.
|
// Ignore signals from the process stub.
|
||||||
const GdbMi frame = data["frame"];
|
const GdbMi frame = data["frame"];
|
||||||
const QString func = frame["from"].data();
|
const QString func = frame["from"].data();
|
||||||
if (runParameters().useTerminal
|
if (terminal()
|
||||||
&& data["reason"].data() == "signal-received"
|
&& data["reason"].data() == "signal-received"
|
||||||
&& data["signal-name"].data() == "SIGSTOP"
|
&& data["signal-name"].data() == "SIGSTOP"
|
||||||
&& (func.endsWith("/ld-linux.so.2")
|
&& (func.endsWith("/ld-linux.so.2")
|
||||||
@@ -1371,8 +1349,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
// This is gdb 7+'s initial *stopped in response to attach that
|
// This is gdb 7+'s initial *stopped in response to attach that
|
||||||
// appears before the ^done is seen.
|
// appears before the ^done is seen.
|
||||||
notifyEngineRunAndInferiorStopOk();
|
notifyEngineRunAndInferiorStopOk();
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
if (terminal())
|
||||||
if (rp.useTerminal)
|
|
||||||
continueInferiorInternal();
|
continueInferiorInternal();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@@ -1497,7 +1474,7 @@ void GdbEngine::handleStop2(const GdbMi &data)
|
|||||||
bool isStopperThread = false;
|
bool isStopperThread = false;
|
||||||
|
|
||||||
if (rp.toolChainAbi.os() == Abi::WindowsOS
|
if (rp.toolChainAbi.os() == Abi::WindowsOS
|
||||||
&& rp.useTerminal
|
&& terminal()
|
||||||
&& reason == "signal-received"
|
&& reason == "signal-received"
|
||||||
&& data["signal-name"].data() == "SIGTRAP")
|
&& data["signal-name"].data() == "SIGTRAP")
|
||||||
{
|
{
|
||||||
@@ -2345,7 +2322,7 @@ QString GdbEngine::breakpointLocation(const BreakpointParameters &data)
|
|||||||
if (data.type == BreakpointAtCatch)
|
if (data.type == BreakpointAtCatch)
|
||||||
return QLatin1String("__cxa_begin_catch");
|
return QLatin1String("__cxa_begin_catch");
|
||||||
if (data.type == BreakpointAtMain)
|
if (data.type == BreakpointAtMain)
|
||||||
return mainFunction(runParameters());
|
return mainFunction();
|
||||||
if (data.type == BreakpointByFunction)
|
if (data.type == BreakpointByFunction)
|
||||||
return '"' + data.functionName + '"';
|
return '"' + data.functionName + '"';
|
||||||
if (data.type == BreakpointByAddress)
|
if (data.type == BreakpointByAddress)
|
||||||
@@ -3800,6 +3777,7 @@ void GdbEngine::startGdb(const QStringList &args)
|
|||||||
showMessage("ENABLING TEST CASE: " + QString::number(test));
|
showMessage("ENABLING TEST CASE: " + QString::number(test));
|
||||||
|
|
||||||
m_gdbProc.disconnect(); // From any previous runs
|
m_gdbProc.disconnect(); // From any previous runs
|
||||||
|
m_expectTerminalTrap = terminal();
|
||||||
|
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
if (rp.debugger.executable.isEmpty()) {
|
if (rp.debugger.executable.isEmpty()) {
|
||||||
@@ -3951,8 +3929,8 @@ void GdbEngine::startGdb(const QStringList &args)
|
|||||||
// Don't use ConsoleCommand, otherwise Mac won't markup the output.
|
// Don't use ConsoleCommand, otherwise Mac won't markup the output.
|
||||||
const QString dumperSourcePath = ICore::resourcePath() + "/debugger/";
|
const QString dumperSourcePath = ICore::resourcePath() + "/debugger/";
|
||||||
|
|
||||||
if (terminal()->isUsable())
|
//if (terminal()->isUsable())
|
||||||
runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice())});
|
// runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice())});
|
||||||
|
|
||||||
const QFileInfo gdbBinaryFile(rp.debugger.executable);
|
const QFileInfo gdbBinaryFile(rp.debugger.executable);
|
||||||
const QString uninstalledData = gdbBinaryFile.absolutePath() + "/data-directory/python";
|
const QString uninstalledData = gdbBinaryFile.absolutePath() + "/data-directory/python";
|
||||||
@@ -3977,9 +3955,7 @@ void GdbEngine::startGdb(const QStringList &args)
|
|||||||
|
|
||||||
void GdbEngine::handleGdbStartFailed()
|
void GdbEngine::handleGdbStartFailed()
|
||||||
{
|
{
|
||||||
if (isTermEngine())
|
if (isPlainEngine())
|
||||||
m_stubProc.stop();
|
|
||||||
else if (isPlainEngine())
|
|
||||||
m_outputCollector.shutdown();
|
m_outputCollector.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4120,7 +4096,7 @@ void GdbEngine::handleInferiorPrepared()
|
|||||||
|
|
||||||
//runCommand("set follow-exec-mode new");
|
//runCommand("set follow-exec-mode new");
|
||||||
if (rp.breakOnMain)
|
if (rp.breakOnMain)
|
||||||
runCommand({"tbreak " + mainFunction(rp)});
|
runCommand({"tbreak " + mainFunction()});
|
||||||
|
|
||||||
// Initial attempt to set breakpoints.
|
// Initial attempt to set breakpoints.
|
||||||
if (rp.startMode != AttachCore) {
|
if (rp.startMode != AttachCore) {
|
||||||
@@ -4316,7 +4292,7 @@ void GdbEngine::debugLastCommand()
|
|||||||
|
|
||||||
bool GdbEngine::isPlainEngine() const
|
bool GdbEngine::isPlainEngine() const
|
||||||
{
|
{
|
||||||
return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && !m_terminalTrap;
|
return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && !terminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GdbEngine::isCoreEngine() const
|
bool GdbEngine::isCoreEngine() const
|
||||||
@@ -4336,7 +4312,7 @@ bool GdbEngine::isAttachEngine() const
|
|||||||
|
|
||||||
bool GdbEngine::isTermEngine() const
|
bool GdbEngine::isTermEngine() const
|
||||||
{
|
{
|
||||||
return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && m_terminalTrap;
|
return !isCoreEngine() && !isAttachEngine() && !isRemoteEngine() && terminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::setupEngine()
|
void GdbEngine::setupEngine()
|
||||||
@@ -4359,30 +4335,7 @@ void GdbEngine::setupEngine()
|
|||||||
|
|
||||||
showMessage("TRYING TO START ADAPTER");
|
showMessage("TRYING TO START ADAPTER");
|
||||||
|
|
||||||
// Currently, GdbEngines are not re-used
|
startGdb();
|
||||||
// // We leave the console open, so recycle it now.
|
|
||||||
// m_stubProc.blockSignals(true);
|
|
||||||
// m_stubProc.stop();
|
|
||||||
// m_stubProc.blockSignals(false);
|
|
||||||
|
|
||||||
m_stubProc.setWorkingDirectory(runParameters().inferior.workingDirectory);
|
|
||||||
// Set environment + dumper preload.
|
|
||||||
m_stubProc.setEnvironment(runParameters().stubEnvironment);
|
|
||||||
|
|
||||||
connect(&m_stubProc, &ConsoleProcess::processError,
|
|
||||||
this, &GdbEngine::stubError);
|
|
||||||
connect(&m_stubProc, &ConsoleProcess::processStarted,
|
|
||||||
this, [this] { startGdb(); });
|
|
||||||
connect(&m_stubProc, &ConsoleProcess::stubStopped,
|
|
||||||
this, &GdbEngine::stubExited);
|
|
||||||
// FIXME: Starting the stub implies starting the inferior. This is
|
|
||||||
// fairly unclean as far as the state machine and error reporting go.
|
|
||||||
|
|
||||||
if (!m_stubProc.start(runParameters().inferior.executable,
|
|
||||||
runParameters().inferior.commandLineArguments)) {
|
|
||||||
// Error message for user is delivered via a signal.
|
|
||||||
handleAdapterStartFailed(QString());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (isCoreEngine()) {
|
} else if (isCoreEngine()) {
|
||||||
|
|
||||||
@@ -4492,8 +4445,8 @@ void GdbEngine::setupInferior()
|
|||||||
|
|
||||||
} else if (isTermEngine()) {
|
} else if (isTermEngine()) {
|
||||||
|
|
||||||
const qint64 attachedPID = m_stubProc.applicationPID();
|
const qint64 attachedPID = terminal()->applicationPid();
|
||||||
const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID();
|
const qint64 attachedMainThreadID = terminal()->applicationMainThreadId();
|
||||||
notifyInferiorPid(ProcessHandle(attachedPID));
|
notifyInferiorPid(ProcessHandle(attachedPID));
|
||||||
const QString msg = (attachedMainThreadID != -1)
|
const QString msg = (attachedMainThreadID != -1)
|
||||||
? QString("Going to attach to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID)
|
? QString("Going to attach to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID)
|
||||||
@@ -4551,9 +4504,12 @@ void GdbEngine::runEngine()
|
|||||||
|
|
||||||
} else if (isTermEngine()) {
|
} else if (isTermEngine()) {
|
||||||
|
|
||||||
const qint64 attachedPID = m_stubProc.applicationPID();
|
const qint64 attachedPID = terminal()->applicationPid();
|
||||||
|
const qint64 mainThreadId = terminal()->applicationMainThreadId();
|
||||||
runCommand({"attach " + QString::number(attachedPID),
|
runCommand({"attach " + QString::number(attachedPID),
|
||||||
[this](const DebuggerResponse &r) { handleStubAttached(r); }});
|
[this, mainThreadId](const DebuggerResponse &r) {
|
||||||
|
handleStubAttached(r, mainThreadId);
|
||||||
|
}});
|
||||||
|
|
||||||
} else if (isPlainEngine()) {
|
} else if (isPlainEngine()) {
|
||||||
|
|
||||||
@@ -4911,7 +4867,7 @@ void GdbEngine::handleInterruptInferior(const DebuggerResponse &response)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleStubAttached(const DebuggerResponse &response)
|
void GdbEngine::handleStubAttached(const DebuggerResponse &response, qint64 mainThreadId)
|
||||||
{
|
{
|
||||||
// InferiorStopOk can happen if the "*stopped" in response to the
|
// InferiorStopOk can happen if the "*stopped" in response to the
|
||||||
// 'attach' comes in before its '^done'
|
// 'attach' comes in before its '^done'
|
||||||
@@ -4923,7 +4879,6 @@ void GdbEngine::handleStubAttached(const DebuggerResponse &response)
|
|||||||
if (runParameters().toolChainAbi.os() == ProjectExplorer::Abi::WindowsOS) {
|
if (runParameters().toolChainAbi.os() == ProjectExplorer::Abi::WindowsOS) {
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
// Resume thread that was suspended by console stub process (see stub code).
|
// Resume thread that was suspended by console stub process (see stub code).
|
||||||
const qint64 mainThreadId = m_stubProc.applicationMainThreadID();
|
|
||||||
if (winResumeThread(mainThreadId, &errorMessage)) {
|
if (winResumeThread(mainThreadId, &errorMessage)) {
|
||||||
showMessage(QString("Inferior attached, thread %1 resumed").
|
showMessage(QString("Inferior attached, thread %1 resumed").
|
||||||
arg(mainThreadId), LogMisc);
|
arg(mainThreadId), LogMisc);
|
||||||
@@ -4956,22 +4911,6 @@ void GdbEngine::handleStubAttached(const DebuggerResponse &response)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::stubError(const QString &msg)
|
|
||||||
{
|
|
||||||
AsynchronousMessageBox::critical(tr("Debugger Error"), msg);
|
|
||||||
notifyEngineIll();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::stubExited()
|
|
||||||
{
|
|
||||||
if (state() == EngineShutdownRequested || state() == DebuggerFinished) {
|
|
||||||
showMessage("STUB EXITED EXPECTEDLY");
|
|
||||||
} else {
|
|
||||||
showMessage("STUB EXITED");
|
|
||||||
notifyEngineIll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString findExecutableFromName(const QString &fileNameFromCore, const QString &coreFile)
|
static QString findExecutableFromName(const QString &fileNameFromCore, const QString &coreFile)
|
||||||
{
|
{
|
||||||
if (fileNameFromCore.isEmpty())
|
if (fileNameFromCore.isEmpty())
|
||||||
@@ -5212,13 +5151,19 @@ QString GdbEngine::msgPtraceError(DebuggerStartMode sm)
|
|||||||
"For more details, see /etc/sysctl.d/10-ptrace.conf\n");
|
"For more details, see /etc/sysctl.d/10-ptrace.conf\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GdbEngine::mainFunction() const
|
||||||
|
{
|
||||||
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
|
return QLatin1String(rp.toolChainAbi.os() == Abi::WindowsOS && !terminal() ? "qMain" : "main");
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Factory
|
// Factory
|
||||||
//
|
//
|
||||||
|
|
||||||
DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode startMode)
|
DebuggerEngine *createGdbEngine(DebuggerStartMode startMode)
|
||||||
{
|
{
|
||||||
return new GdbEngine(useTerminal, startMode);
|
return new GdbEngine(startMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -55,6 +55,7 @@ class DebuggerResponse;
|
|||||||
class DisassemblerAgentCookie;
|
class DisassemblerAgentCookie;
|
||||||
class GdbMi;
|
class GdbMi;
|
||||||
class MemoryAgentCookie;
|
class MemoryAgentCookie;
|
||||||
|
class TerminalRunner;
|
||||||
|
|
||||||
struct CoreInfo
|
struct CoreInfo
|
||||||
{
|
{
|
||||||
@@ -71,7 +72,7 @@ class GdbEngine : public DebuggerEngine
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GdbEngine(bool useTerminal, DebuggerStartMode startMode);
|
explicit GdbEngine(DebuggerStartMode startMode);
|
||||||
~GdbEngine() final;
|
~GdbEngine() final;
|
||||||
|
|
||||||
private: ////////// General Interface //////////
|
private: ////////// General Interface //////////
|
||||||
@@ -382,8 +383,7 @@ private: ////////// General Interface //////////
|
|||||||
QString m_currentThread;
|
QString m_currentThread;
|
||||||
QString m_lastWinException;
|
QString m_lastWinException;
|
||||||
QString m_lastMissingDebugInfo;
|
QString m_lastMissingDebugInfo;
|
||||||
const bool m_useTerminal;
|
bool m_expectTerminalTrap = false;
|
||||||
bool m_terminalTrap;
|
|
||||||
bool usesExecInterrupt() const;
|
bool usesExecInterrupt() const;
|
||||||
bool usesTargetAsync() const;
|
bool usesTargetAsync() const;
|
||||||
|
|
||||||
@@ -441,10 +441,7 @@ private: ////////// General Interface //////////
|
|||||||
void interruptLocalInferior(qint64 pid);
|
void interruptLocalInferior(qint64 pid);
|
||||||
|
|
||||||
// Terminal
|
// Terminal
|
||||||
void handleStubAttached(const DebuggerResponse &response);
|
void handleStubAttached(const DebuggerResponse &response, qint64 mainThreadId);
|
||||||
void stubExited();
|
|
||||||
void stubError(const QString &msg);
|
|
||||||
Utils::ConsoleProcess m_stubProc;
|
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
void handleTargetCore(const DebuggerResponse &response);
|
void handleTargetCore(const DebuggerResponse &response);
|
||||||
@@ -454,6 +451,7 @@ private: ////////// General Interface //////////
|
|||||||
QString coreName() const;
|
QString coreName() const;
|
||||||
|
|
||||||
void continueSetupEngine();
|
void continueSetupEngine();
|
||||||
|
QString mainFunction() const;
|
||||||
|
|
||||||
QString m_executable;
|
QString m_executable;
|
||||||
QString m_coreName;
|
QString m_coreName;
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <debugger/debuggermainwindow.h>
|
#include <debugger/debuggermainwindow.h>
|
||||||
#include <debugger/debuggerprotocol.h>
|
#include <debugger/debuggerprotocol.h>
|
||||||
#include <debugger/debuggertooltipmanager.h>
|
#include <debugger/debuggertooltipmanager.h>
|
||||||
|
#include <debugger/terminal.h>
|
||||||
|
|
||||||
#include <debugger/breakhandler.h>
|
#include <debugger/breakhandler.h>
|
||||||
#include <debugger/disassemblerlines.h>
|
#include <debugger/disassemblerlines.h>
|
||||||
@@ -98,7 +99,6 @@ LldbEngine::LldbEngine()
|
|||||||
|
|
||||||
LldbEngine::~LldbEngine()
|
LldbEngine::~LldbEngine()
|
||||||
{
|
{
|
||||||
m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub
|
|
||||||
m_lldbProc.disconnect();
|
m_lldbProc.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,8 +155,6 @@ void LldbEngine::shutdownEngine()
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
||||||
m_lldbProc.kill();
|
m_lldbProc.kill();
|
||||||
if (runParameters().useTerminal)
|
|
||||||
m_stubProc.stop();
|
|
||||||
notifyEngineShutdownOk();
|
notifyEngineShutdownOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,48 +165,6 @@ void LldbEngine::abortDebuggerProcess()
|
|||||||
|
|
||||||
void LldbEngine::setupEngine()
|
void LldbEngine::setupEngine()
|
||||||
{
|
{
|
||||||
if (runParameters().useTerminal) {
|
|
||||||
QTC_CHECK(false); // See above.
|
|
||||||
if (HostOsInfo::isWindowsHost()) {
|
|
||||||
// Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
|
|
||||||
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
|
|
||||||
m_stubProc.setMode(ConsoleProcess::Suspend);
|
|
||||||
else
|
|
||||||
m_stubProc.setMode(ConsoleProcess::Debug);
|
|
||||||
} else {
|
|
||||||
m_stubProc.setMode(ConsoleProcess::Debug);
|
|
||||||
m_stubProc.setSettings(ICore::settings());
|
|
||||||
}
|
|
||||||
|
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
|
||||||
showMessage("TRYING TO START ADAPTER");
|
|
||||||
|
|
||||||
// Currently, adapters are not re-used
|
|
||||||
// // We leave the console open, so recycle it now.
|
|
||||||
// m_stubProc.blockSignals(true);
|
|
||||||
// m_stubProc.stop();
|
|
||||||
// m_stubProc.blockSignals(false);
|
|
||||||
|
|
||||||
m_stubProc.setWorkingDirectory(runParameters().inferior.workingDirectory);
|
|
||||||
// Set environment + dumper preload.
|
|
||||||
m_stubProc.setEnvironment(runParameters().stubEnvironment);
|
|
||||||
|
|
||||||
connect(&m_stubProc, &ConsoleProcess::processError, this, &LldbEngine::stubError);
|
|
||||||
connect(&m_stubProc, &ConsoleProcess::processStarted, this, &LldbEngine::stubStarted);
|
|
||||||
connect(&m_stubProc, &ConsoleProcess::stubStopped, this, &LldbEngine::stubExited);
|
|
||||||
// FIXME: Starting the stub implies starting the inferior. This is
|
|
||||||
// fairly unclean as far as the state machine and error reporting go.
|
|
||||||
|
|
||||||
if (!m_stubProc.start(runParameters().inferior.executable,
|
|
||||||
runParameters().inferior.commandLineArguments)) {
|
|
||||||
// Error message for user is delivered via a signal.
|
|
||||||
//handleAdapterStartFailed(QString());
|
|
||||||
notifyEngineSetupFailed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
||||||
startLldb();
|
startLldb();
|
||||||
}
|
}
|
||||||
@@ -299,17 +255,17 @@ void LldbEngine::setupInferior()
|
|||||||
DebuggerCommand cmd2("setupInferior");
|
DebuggerCommand cmd2("setupInferior");
|
||||||
cmd2.arg("executable", executable);
|
cmd2.arg("executable", executable);
|
||||||
cmd2.arg("breakonmain", rp.breakOnMain);
|
cmd2.arg("breakonmain", rp.breakOnMain);
|
||||||
cmd2.arg("useterminal", rp.useTerminal);
|
cmd2.arg("useterminal", bool(terminal()));
|
||||||
cmd2.arg("startmode", rp.startMode);
|
cmd2.arg("startmode", rp.startMode);
|
||||||
cmd2.arg("nativemixed", isNativeMixedActive());
|
cmd2.arg("nativemixed", isNativeMixedActive());
|
||||||
cmd2.arg("workingdirectory", rp.inferior.workingDirectory);
|
cmd2.arg("workingdirectory", rp.inferior.workingDirectory);
|
||||||
cmd2.arg("environment", rp.inferior.environment.toStringList());
|
cmd2.arg("environment", rp.inferior.environment.toStringList());
|
||||||
cmd2.arg("processargs", args.toUnixArgs());
|
cmd2.arg("processargs", args.toUnixArgs());
|
||||||
|
|
||||||
if (rp.useTerminal) {
|
if (terminal()) {
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
||||||
const qint64 attachedPID = m_stubProc.applicationPID();
|
const qint64 attachedPID = terminal()->applicationPid();
|
||||||
const qint64 attachedMainThreadID = m_stubProc.applicationMainThreadID();
|
const qint64 attachedMainThreadID = terminal()->applicationMainThreadId();
|
||||||
const QString msg = (attachedMainThreadID != -1)
|
const QString msg = (attachedMainThreadID != -1)
|
||||||
? QString::fromLatin1("Attaching to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID)
|
? QString::fromLatin1("Attaching to %1 (%2)").arg(attachedPID).arg(attachedMainThreadID)
|
||||||
: QString::fromLatin1("Attaching to %1").arg(attachedPID);
|
: QString::fromLatin1("Attaching to %1").arg(attachedPID);
|
||||||
@@ -1100,25 +1056,5 @@ DebuggerEngine *createLldbEngine()
|
|||||||
return new LldbEngine;
|
return new LldbEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::stubStarted()
|
|
||||||
{
|
|
||||||
startLldb();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LldbEngine::stubError(const QString &msg)
|
|
||||||
{
|
|
||||||
AsynchronousMessageBox::critical(tr("Debugger Error"), msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LldbEngine::stubExited()
|
|
||||||
{
|
|
||||||
if (state() == EngineShutdownRequested || state() == DebuggerFinished) {
|
|
||||||
showMessage("STUB EXITED EXPECTEDLY");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showMessage("STUB EXITED");
|
|
||||||
notifyEngineIll();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -154,12 +154,6 @@ private:
|
|||||||
|
|
||||||
QHash<int, DebuggerCommand> m_commandForToken;
|
QHash<int, DebuggerCommand> m_commandForToken;
|
||||||
DebuggerCommandSequence m_onStop;
|
DebuggerCommandSequence m_onStop;
|
||||||
|
|
||||||
// Console handling.
|
|
||||||
void stubError(const QString &msg);
|
|
||||||
void stubExited();
|
|
||||||
void stubStarted();
|
|
||||||
Utils::ConsoleProcess m_stubProc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -25,11 +25,16 @@
|
|||||||
|
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
|
#include "debuggerruncontrol.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/hostosinfo.h>
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
# define DEBUGGER_USE_TERMINAL
|
# define DEBUGGER_USE_TERMINAL
|
||||||
@@ -45,6 +50,10 @@
|
|||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -159,6 +168,67 @@ void Terminal::onSlaveReaderActivated(int fd)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TerminalRunner::TerminalRunner(DebuggerRunTool *debugger)
|
||||||
|
: RunWorker(debugger->runControl())
|
||||||
|
{
|
||||||
|
setDisplayName("TerminalRunner");
|
||||||
|
|
||||||
|
const DebuggerRunParameters &rp = debugger->runParameters();
|
||||||
|
m_stubRunnable = rp.inferior;
|
||||||
|
m_stubRunnable.environment = rp.stubEnvironment;
|
||||||
|
m_stubRunnable.workingDirectory = rp.inferior.workingDirectory;
|
||||||
|
|
||||||
|
connect(&m_stubProc, &ConsoleProcess::processError,
|
||||||
|
this, &TerminalRunner::stubError);
|
||||||
|
connect(&m_stubProc, &ConsoleProcess::processStarted,
|
||||||
|
this, &TerminalRunner::stubStarted);
|
||||||
|
connect(&m_stubProc, &ConsoleProcess::stubStopped,
|
||||||
|
this, &TerminalRunner::stubExited);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalRunner::start()
|
||||||
|
{
|
||||||
|
m_stubProc.setEnvironment(m_stubRunnable.environment);
|
||||||
|
m_stubProc.setWorkingDirectory(m_stubRunnable.workingDirectory);
|
||||||
|
|
||||||
|
if (HostOsInfo::isWindowsHost()) {
|
||||||
|
// Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
|
||||||
|
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)
|
||||||
|
m_stubProc.setMode(ConsoleProcess::Suspend);
|
||||||
|
else
|
||||||
|
m_stubProc.setMode(ConsoleProcess::Debug);
|
||||||
|
} else {
|
||||||
|
m_stubProc.setMode(ConsoleProcess::Debug);
|
||||||
|
m_stubProc.setSettings(Core::ICore::settings());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error message for user is delivered via a signal.
|
||||||
|
m_stubProc.start(m_stubRunnable.executable, m_stubRunnable.commandLineArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalRunner::stop()
|
||||||
|
{
|
||||||
|
m_stubProc.stop();
|
||||||
|
reportStopped();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalRunner::stubStarted()
|
||||||
|
{
|
||||||
|
m_applicationPid = m_stubProc.applicationPID();
|
||||||
|
m_applicationMainThreadId = m_stubProc.applicationMainThreadID();
|
||||||
|
reportStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalRunner::stubError(const QString &msg)
|
||||||
|
{
|
||||||
|
reportFailure(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalRunner::stubExited()
|
||||||
|
{
|
||||||
|
reportStopped();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
@@ -28,7 +28,15 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
|
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <projectexplorer/runnables.h>
|
||||||
|
|
||||||
|
#include <utils/consoleprocess.h>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
|
|
||||||
|
class DebuggerRunTool;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class Terminal : public QObject
|
class Terminal : public QObject
|
||||||
@@ -60,5 +68,28 @@ private:
|
|||||||
QByteArray m_slaveName;
|
QByteArray m_slaveName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TerminalRunner : public ProjectExplorer::RunWorker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TerminalRunner(DebuggerRunTool *runControl);
|
||||||
|
|
||||||
|
qint64 applicationPid() const { return m_applicationPid; }
|
||||||
|
qint64 applicationMainThreadId() const { return m_applicationMainThreadId; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void start() final;
|
||||||
|
void stop() final;
|
||||||
|
|
||||||
|
void stubStarted();
|
||||||
|
void stubExited();
|
||||||
|
void stubError(const QString &msg);
|
||||||
|
|
||||||
|
Utils::ConsoleProcess m_stubProc;
|
||||||
|
ProjectExplorer::StandardRunnable m_stubRunnable;
|
||||||
|
qint64 m_applicationPid = 0;
|
||||||
|
qint64 m_applicationMainThreadId = 0;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
Reference in New Issue
Block a user