debugger: more trk/gdbengine refactoring

This commit is contained in:
hjk
2009-09-14 11:02:36 +02:00
parent 0915342d15
commit d9cf3a8714
6 changed files with 165 additions and 141 deletions

View File

@@ -271,14 +271,14 @@ public:
QLabel *statusLabel() const { return m_statusLabel; }
IDebuggerEngine *currentEngine() const { return m_engine; }
virtual QSharedPointer<DebuggerStartParameters> startParameters() const;
virtual qint64 inferiorPid() const;
public slots:
void startNewDebugger(DebuggerRunControl *runControl,
const QSharedPointer<DebuggerStartParameters> &startParameters);
void exitDebugger();
virtual QSharedPointer<DebuggerStartParameters> startParameters() const;
virtual qint64 inferiorPid() const;
void setQtDumperLibraryName(const QString &dl); // Run Control
void setQtDumperLibraryLocations(const QStringList &dl);
@@ -397,6 +397,7 @@ public:
// one of the interfaces
QAbstractItemModel *threadsModel();
int status() const { return m_status; }
// FIXME: hide this in the engines?
DebuggerStartMode startMode() const;
DebuggerRunControl *runControl() const { return m_runControl; }

View File

@@ -50,6 +50,7 @@ class AbstractGdbAdapter : public QObject
public:
AbstractGdbAdapter(QObject *parent = 0) : QObject(parent) {}
virtual void setEngine(GdbEngine *engine) { m_engine = engine; }
virtual void start(const QString &program, const QStringList &args,
QIODevice::OpenMode mode = QIODevice::ReadWrite) = 0;
virtual void kill() = 0;
@@ -65,7 +66,8 @@ public:
virtual void setEnvironment(const QStringList &env) = 0;
virtual bool isAdapter() const = 0;
virtual void attach(GdbEngine *engine) const = 0;
virtual void attach() = 0;
virtual void interruptInferior() = 0;
signals:
void error(QProcess::ProcessError);
@@ -73,6 +75,9 @@ signals:
void readyReadStandardOutput();
void readyReadStandardError();
void finished(int, QProcess::ExitStatus);
protected:
GdbEngine *m_engine;
};
} // namespace Internal

View File

@@ -145,14 +145,32 @@ static QByteArray parsePlainConsoleStream(const GdbResultRecord &record)
//
///////////////////////////////////////////////////////////////////////
void PlainGdbAdapter::attach(GdbEngine *engine) const
void PlainGdbAdapter::attach()
{
QFileInfo fi(engine->startParameters().executable);
QFileInfo fi(m_engine->startParameters().executable);
QString fileName = fi.absoluteFilePath();
engine->postCommand(_("-file-exec-and-symbols ") + fileName,
m_engine->postCommand(_("-file-exec-and-symbols ") + fileName,
&GdbEngine::handleFileExecAndSymbols, "handleFileExecAndSymbols");
}
void PlainGdbAdapter::interruptInferior()
{
if (m_engine->manager()->startMode() == StartRemote) {
m_engine->postCommand(_("-exec-interrupt"));
return;
}
const qint64 attachedPID = m_engine->inferiorPid();
if (attachedPID <= 0) {
m_engine->debugMessage(
_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"));
return;
}
if (!interruptProcess(attachedPID))
m_engine->debugMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
}
///////////////////////////////////////////////////////////////////////
//
// GdbEngine
@@ -165,10 +183,11 @@ GdbEngine::GdbEngine(DebuggerManager *parent, AbstractGdbAdapter *gdbAdapter) :
#else
m_dumperInjectionLoad(false),
#endif
q(parent),
m_manager(parent),
qq(parent->engineInterface())
{
m_gdbAdapter = gdbAdapter;
m_gdbAdapter->setEngine(this);
m_stubProc.setMode(Core::Utils::ConsoleProcess::Debug);
#ifdef Q_OS_UNIX
m_stubProc.setSettings(Core::ICore::instance()->settings());
@@ -194,7 +213,7 @@ void GdbEngine::initializeConnections()
connect(m_gdbAdapter, SIGNAL(readyReadStandardError()),
this, SLOT(readGdbStandardError()));
connect(m_gdbAdapter, SIGNAL(finished(int, QProcess::ExitStatus)),
q, SLOT(exitDebugger()));
m_manager, SLOT(exitDebugger()));
connect(m_gdbAdapter, SIGNAL(started()),
this, SLOT(startDebugger2()));
@@ -203,7 +222,7 @@ void GdbEngine::initializeConnections()
connect(&m_stubProc, SIGNAL(processStarted()),
this, SLOT(stubStarted()));
connect(&m_stubProc, SIGNAL(wrapperStopped()),
q, SLOT(exitDebugger()));
m_manager, SLOT(exitDebugger()));
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(uploadProcError(QProcess::ProcessError)));
@@ -217,13 +236,13 @@ void GdbEngine::initializeConnections()
this, SLOT(readDebugeeOutput(QByteArray)));
connect(this, SIGNAL(gdbOutputAvailable(int,QString)),
q, SLOT(showDebuggerOutput(int,QString)),
m_manager, SLOT(showDebuggerOutput(int,QString)),
Qt::QueuedConnection);
connect(this, SIGNAL(gdbInputAvailable(int,QString)),
q, SLOT(showDebuggerInput(int,QString)),
m_manager, SLOT(showDebuggerInput(int,QString)),
Qt::QueuedConnection);
connect(this, SIGNAL(applicationOutputAvailable(QString)),
q, SLOT(showApplicationOutput(QString)),
m_manager, SLOT(showApplicationOutput(QString)),
Qt::QueuedConnection);
// FIXME: These trigger even if the engine is not active
@@ -310,11 +329,11 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
"This is the default return value of error().");
}
q->showStatusMessage(msg);
QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
showStatusMessage(msg);
QMessageBox::critical(mainWindow(), tr("Error"), msg);
// act as if it was closed by the core
if (kill)
q->exitDebugger();
m_manager->exitDebugger();
}
void GdbEngine::uploadProcError(QProcess::ProcessError error)
@@ -350,8 +369,8 @@ void GdbEngine::uploadProcError(QProcess::ProcessError error)
"This is the default return value of error().");
}
q->showStatusMessage(msg);
QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
showStatusMessage(msg);
QMessageBox::critical(mainWindow(), tr("Error"), msg);
}
void GdbEngine::readUploadStandardOutput()
@@ -476,34 +495,34 @@ void GdbEngine::handleResponse(const QByteArray &buff)
// symbols-loaded="0"
QByteArray id = record.findChild("id").data();
if (!id.isEmpty())
q->showStatusMessage(tr("Library %1 loaded.").arg(_(id)));
showStatusMessage(tr("Library %1 loaded.").arg(_(id)));
} else if (asyncClass == "library-unloaded") {
// Archer has 'id="/usr/lib/libdrm.so.2",
// target-name="/usr/lib/libdrm.so.2",
// host-name="/usr/lib/libdrm.so.2"
QByteArray id = record.findChild("id").data();
q->showStatusMessage(tr("Library %1 unloaded.").arg(_(id)));
showStatusMessage(tr("Library %1 unloaded.").arg(_(id)));
} else if (asyncClass == "thread-group-created") {
// Archer has "{id="28902"}"
QByteArray id = record.findChild("id").data();
q->showStatusMessage(tr("Thread group %1 created.").arg(_(id)));
showStatusMessage(tr("Thread group %1 created.").arg(_(id)));
} else if (asyncClass == "thread-created") {
//"{id="1",group-id="28902"}"
QByteArray id = record.findChild("id").data();
q->showStatusMessage(tr("Thread %1 created.").arg(_(id)));
showStatusMessage(tr("Thread %1 created.").arg(_(id)));
} else if (asyncClass == "thread-group-exited") {
// Archer has "{id="28902"}"
QByteArray id = record.findChild("id").data();
q->showStatusMessage(tr("Thread group %1 exited.").arg(_(id)));
showStatusMessage(tr("Thread group %1 exited.").arg(_(id)));
} else if (asyncClass == "thread-exited") {
//"{id="1",group-id="28902"}"
QByteArray id = record.findChild("id").data();
QByteArray groupid = record.findChild("group-id").data();
q->showStatusMessage(tr("Thread %1 in group %2 exited.")
showStatusMessage(tr("Thread %1 in group %2 exited.")
.arg(_(id)).arg(_(groupid)));
} else if (asyncClass == "thread-selected") {
QByteArray id = record.findChild("id").data();
q->showStatusMessage(tr("Thread %1 selected.").arg(_(id)));
showStatusMessage(tr("Thread %1 selected.").arg(_(id)));
//"{id="2"}"
#if defined(Q_OS_MAC)
} else if (asyncClass == "shlibs-updated") {
@@ -527,7 +546,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
QByteArray data = GdbMi::parseCString(from, to);
m_pendingConsoleStreamOutput += data;
if (data.startsWith("Reading symbols from ")) {
q->showStatusMessage(tr("Reading %1...").arg(_(data.mid(21))));
showStatusMessage(tr("Reading %1...").arg(_(data.mid(21))));
}
break;
}
@@ -629,7 +648,7 @@ void GdbEngine::stubStarted()
void GdbEngine::stubError(const QString &msg)
{
QMessageBox::critical(q->mainWindow(), tr("Debugger Error"), msg);
QMessageBox::critical(mainWindow(), tr("Debugger Error"), msg);
}
void GdbEngine::readGdbStandardError()
@@ -677,19 +696,7 @@ void GdbEngine::interruptInferior()
return;
}
if (q->startMode() == StartRemote) {
postCommand(_("-exec-interrupt"));
return;
}
const qint64 attachedPID = q->inferiorPid();
if (attachedPID <= 0) {
debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"));
return;
}
if (!interruptProcess(attachedPID))
debugMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
m_gdbAdapter->interruptInferior();
}
void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
@@ -699,7 +706,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
debugMessage(_("Cannot parse PID from %1").arg(pid0));
return;
}
if (pid == q->inferiorPid())
if (pid == inferiorPid())
return;
debugMessage(_("FOUND PID %1").arg(pid));
@@ -739,12 +746,12 @@ void GdbEngine::postCommand(const QString &command, GdbCommandFlags flags,
cmd.callbackName = callbackName;
cmd.cookie = cookie;
if ((flags & NeedsStop) && q->status() != DebuggerInferiorStopped
&& q->status() != DebuggerProcessStartingUp) {
if ((flags & NeedsStop) && status() != DebuggerInferiorStopped
&& status() != DebuggerProcessStartingUp) {
// queue the commands that we cannot send at once
QTC_ASSERT(q->status() == DebuggerInferiorRunning,
qDebug() << "STATUS:" << q->status());
q->showStatusMessage(tr("Stopping temporarily."));
QTC_ASSERT(status() == DebuggerInferiorRunning,
qDebug() << "STATUS:" << status());
showStatusMessage(tr("Stopping temporarily."));
debugMessage(_("QUEUING COMMAND ") + cmd.command);
m_commandsToRunOnTemporaryBreak.append(cmd);
interruptInferior();
@@ -786,9 +793,9 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
// msg="Cannot find new threads: generic error"
if (record.resultClass == GdbResultError) {
QByteArray msg = record.data.findChild("msg").data();
QMessageBox::critical(q->mainWindow(), tr("Error"),
QMessageBox::critical(mainWindow(), tr("Error"),
tr("Executable failed:\n") + QString::fromLocal8Bit(msg));
q->showStatusMessage(tr("Process failed to start."));
showStatusMessage(tr("Process failed to start."));
exitDebugger();
//qq->notifyInferiorStopped();
//qq->notifyInferiorExited();
@@ -805,7 +812,7 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
if (record.token < m_oldestAcceptableToken && (cmd.flags & Discardable)) {
//qDebug() << "### SKIPPING OLD RESULT" << record.toString();
//QMessageBox::information(q->mainWindow(), tr("Skipped"), "xxx");
//QMessageBox::information(mainWindow(), tr("Skipped"), "xxx");
return;
}
@@ -841,7 +848,7 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
if (m_cookieForToken.isEmpty() && m_autoContinue) {
m_autoContinue = false;
continueInferior();
q->showStatusMessage(tr("Continuing after temporary stop."));
showStatusMessage(tr("Continuing after temporary stop."));
}
}
@@ -858,8 +865,8 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
void GdbEngine::handleTargetCore(const GdbResultRecord &, const QVariant &)
{
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Core file loaded."));
q->resetLocation();
showStatusMessage(tr("Core file loaded."));
m_manager->resetLocation();
tryLoadDebuggingHelpers();
qq->stackHandler()->setCurrentIndex(0);
updateLocals(); // Quick shot
@@ -958,7 +965,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record)
// ~"242\t x *= 2;"
//109^done"
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Jumped. Stopped."));
showStatusMessage(tr("Jumped. Stopped."));
QByteArray output = record.data.findChild("logstreamoutput").data();
if (output.isEmpty())
return;
@@ -968,7 +975,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record)
if (idx2 > 0) {
QString file = QString::fromLocal8Bit(output.mid(idx1, idx2 - idx1));
int line = output.mid(idx2 + 1).toInt();
q->gotoLocation(file, line, true);
m_manager->gotoLocation(file, line, true);
}
}
}
@@ -983,13 +990,13 @@ void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record, const QVa
// func="foo",args=[{name="str",value="@0x7fff0f450460"}],
// file="main.cpp",fullname="/tmp/g/main.cpp",line="37"}
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Run to Function finished. Stopped."));
showStatusMessage(tr("Run to Function finished. Stopped."));
GdbMi frame = record.data.findChild("frame");
StackFrame f;
f.file = QString::fromLocal8Bit(frame.findChild("fullname").data());
f.line = frame.findChild("line").data().toInt();
f.address = _(frame.findChild("addr").data());
q->gotoLocation(f, true);
m_manager->gotoLocation(f, true);
}
static bool isExitedReason(const QByteArray &reason)
@@ -1074,7 +1081,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
} else {
msg = tr("Program exited normally");
}
q->showStatusMessage(msg);
showStatusMessage(msg);
postCommand(_("-gdb-exit"), CB(handleExit));
return;
}
@@ -1095,8 +1102,8 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
}
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
QTC_ASSERT(q->status() == DebuggerInferiorStopRequested,
qDebug() << "STATUS:" << q->status())
QTC_ASSERT(status() == DebuggerInferiorStopRequested,
qDebug() << "STATUS:" << status())
qq->notifyInferiorStopped();
// FIXME: racy
while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
@@ -1105,7 +1112,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
.arg(cmd.command).arg(_(cmd.callbackName)));
flushCommand(cmd);
}
q->showStatusMessage(tr("Processing queued commands."));
showStatusMessage(tr("Processing queued commands."));
m_autoContinue = true;
return;
}
@@ -1119,7 +1126,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
debugMessage(_("PATTERN: ") + pat);
postCommand(_("sharedlibrary ") + pat);
continueInferior();
q->showStatusMessage(tr("Loading %1...").arg(dataStr));
showStatusMessage(tr("Loading %1...").arg(dataStr));
return;
}
m_modulesListOutdated = true;
@@ -1151,14 +1158,14 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
if (isLeavableFunction(funcName, fileName)) {
//debugMessage(_("LEAVING ") + funcName);
++stepCounter;
q->stepOutExec();
m_manager->stepOutExec();
//stepExec();
return;
}
if (isSkippableFunction(funcName, fileName)) {
//debugMessage(_("SKIPPING ") + funcName);
++stepCounter;
q->stepExec();
m_manager->stepExec();
return;
}
//if (stepCounter)
@@ -1174,7 +1181,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
}
// Need another round trip
if (reason == "breakpoint-hit") {
q->showStatusMessage(tr("Stopped at breakpoint."));
showStatusMessage(tr("Stopped at breakpoint."));
GdbMi frame = data.findChild("frame");
//debugMessage(_("HIT BREAKPOINT: " + frame.toString()));
m_currentFrame = _(frame.findChild("addr").data() + '%' +
@@ -1215,16 +1222,16 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
.arg(meaning.isEmpty() ? tr(" <Unknown> ") : _(meaning));
QMessageBox *mb = new QMessageBox(QMessageBox::Information,
tr("Signal received"), msg, QMessageBox::NoButton,
q->mainWindow());
mainWindow());
mb->setAttribute(Qt::WA_DeleteOnClose);
mb->show();
}
}
if (reason.isEmpty())
q->showStatusMessage(tr("Stopped."));
showStatusMessage(tr("Stopped."));
else
q->showStatusMessage(tr("Stopped: \"%1\"").arg(_(reason)));
showStatusMessage(tr("Stopped: \"%1\"").arg(_(reason)));
handleAsyncOutput2(data);
}
return;
@@ -1244,15 +1251,15 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
// MAC yields sometimes:
// >3661*stopped,time={wallclock="0.00658",user="0.00142",
// system="0.00136",start="1218810678.805432",end="1218810678.812011"}
q->resetLocation();
m_manager->resetLocation();
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Run to Function finished. Stopped."));
showStatusMessage(tr("Run to Function finished. Stopped."));
GdbMi frame = data.findChild("frame");
StackFrame f;
f.file = QString::fromLocal8Bit(frame.findChild("fullname").data());
f.line = frame.findChild("line").data().toInt();
f.address = _(frame.findChild("addr").data());
q->gotoLocation(f, true);
m_manager->gotoLocation(f, true);
#endif
}
@@ -1299,7 +1306,7 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
f.file = QString::fromLocal8Bit(fullName.data());
f.line = frame.findChild("line").data().toInt();
f.address = _(frame.findChild("addr").data());
q->gotoLocation(f, true);
m_manager->gotoLocation(f, true);
}
//
@@ -1342,11 +1349,11 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response, const QVarian
"Using gdb 6.7 or later is strongly recommended.");
#if 0
// ugly, but 'Show again' check box...
static QErrorMessage *err = new QErrorMessage(q->mainWindow());
static QErrorMessage *err = new QErrorMessage(mainWindow());
err->setMinimumSize(400, 300);
err->showMessage(msg);
#else
//QMessageBox::information(q->mainWindow(), tr("Warning"), msg);
//QMessageBox::information(mainWindow(), tr("Warning"), msg);
#endif
} else {
m_gdbVersion = 10000 * supported.cap(2).toInt()
@@ -1366,9 +1373,9 @@ void GdbEngine::handleFileExecAndSymbols(const GdbResultRecord &response, const
//m_breakHandler->clearBreakMarkers();
} else if (response.resultClass == GdbResultError) {
QString msg = __(response.data.findChild("msg").data());
QMessageBox::critical(q->mainWindow(), tr("Error"),
QMessageBox::critical(mainWindow(), tr("Error"),
tr("Starting executable failed:\n") + msg);
QTC_ASSERT(q->status() == DebuggerInferiorRunning, /**/);
QTC_ASSERT(status() == DebuggerInferiorRunning, /**/);
//interruptInferior();
qq->notifyInferiorExited();
}
@@ -1381,9 +1388,9 @@ void GdbEngine::handleExecRun(const GdbResultRecord &response, const QVariant &)
} else {
QTC_ASSERT(response.resultClass == GdbResultError, /**/);
const QByteArray &msg = response.data.findChild("msg").data();
QMessageBox::critical(q->mainWindow(), tr("Error"),
QMessageBox::critical(mainWindow(), tr("Error"),
tr("Starting executable failed:\n") + QString::fromLocal8Bit(msg));
QTC_ASSERT(q->status() == DebuggerInferiorRunning, /**/);
QTC_ASSERT(status() == DebuggerInferiorRunning, /**/);
//interruptInferior();
qq->notifyInferiorExited();
}
@@ -1398,13 +1405,13 @@ void GdbEngine::handleExecContinue(const GdbResultRecord &response, const QVaria
const QByteArray &msg = response.data.findChild("msg").data();
if (msg == "Cannot find bounds of current function") {
qq->notifyInferiorStopped();
//q->showStatusMessage(tr("No debug information available. "
//showStatusMessage(tr("No debug information available. "
// "Leaving function..."));
//stepOutExec();
} else {
QMessageBox::critical(q->mainWindow(), tr("Error"),
QMessageBox::critical(mainWindow(), tr("Error"),
tr("Starting executable failed:\n") + QString::fromLocal8Bit(msg));
QTC_ASSERT(q->status() == DebuggerInferiorRunning, /**/);
QTC_ASSERT(status() == DebuggerInferiorRunning, /**/);
//interruptInferior();
qq->notifyInferiorExited();
}
@@ -1471,13 +1478,13 @@ void GdbEngine::exitDebugger()
if (m_gdbAdapter->state() == QProcess::Running) {
debugMessage(_("WAITING FOR RUNNING GDB TO SHUTDOWN: %1")
.arg(m_gdbAdapter->state()));
if (q->status() != DebuggerInferiorStopped
&& q->status() != DebuggerProcessStartingUp) {
QTC_ASSERT(q->status() == DebuggerInferiorRunning,
qDebug() << "STATUS ON EXITDEBUGGER:" << q->status());
if (status() != DebuggerInferiorStopped
&& status() != DebuggerProcessStartingUp) {
QTC_ASSERT(status() == DebuggerInferiorRunning,
qDebug() << "STATUS ON EXITDEBUGGER:" << status());
interruptInferior();
}
if (q->startMode() == AttachExternal || q->startMode() == AttachCrashedExternal)
if (startMode() == AttachExternal || startMode() == AttachCrashedExternal)
postCommand(_("detach"));
else
postCommand(_("kill"));
@@ -1498,7 +1505,7 @@ void GdbEngine::exitDebugger()
m_outputCollector.shutdown();
initializeVariables();
//q->settings()->m_debugDebuggingHelpers = false;
//m_manager->settings()->m_debugDebuggingHelpers = false;
}
@@ -1527,12 +1534,13 @@ void GdbEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
gdbArgs.prepend(_("mi"));
gdbArgs.prepend(_("-i"));
if (q->startMode() == AttachCore || q->startMode() == AttachExternal || q->startMode() == AttachCrashedExternal) {
if (startMode() == AttachCore || startMode() == AttachExternal ||
startMode() == AttachCrashedExternal) {
// nothing to do
} else if (q->startMode() == StartRemote) {
} else if (startMode() == StartRemote) {
// Start the remote server
if (m_startParameters.serverStartScript.isEmpty()) {
q->showStatusMessage(_("No server start script given. "
showStatusMessage(_("No server start script given. "
"Assuming server runs already."));
} else {
if (!m_startParameters.workingDir.isEmpty())
@@ -1555,7 +1563,7 @@ void GdbEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
}
} else {
if (!m_outputCollector.listen()) {
QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"),
QMessageBox::critical(mainWindow(), tr("Debugger Startup Failure"),
tr("Cannot set up communication with child process: %1")
.arg(m_outputCollector.errorString()));
emitStartFailed();
@@ -1570,9 +1578,9 @@ void GdbEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
}
#if 0
qDebug() << "Command:" << q->settings()->m_gdbCmd;
qDebug() << "Command:" << m_manager->settings()->m_gdbCmd;
qDebug() << "WorkingDirectory:" << m_gdbAdapter->workingDirectory();
qDebug() << "ScriptFile:" << q->settings()->m_scriptFile;
qDebug() << "ScriptFile:" << m_manager->settings()->m_scriptFile;
qDebug() << "Environment:" << m_gdbAdapter->environment();
qDebug() << "Arguments:" << gdbArgs;
qDebug() << "BuildDir:" << m_startParameters.buildDir;
@@ -1580,13 +1588,13 @@ void GdbEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
#endif
QString loc = theDebuggerStringSetting(GdbLocation);
q->showStatusMessage(tr("Starting Debugger: ") + loc + _c(' ') + gdbArgs.join(_(" ")));
showStatusMessage(tr("Starting Debugger: ") + loc + _c(' ') + gdbArgs.join(_(" ")));
m_gdbAdapter->start(loc, gdbArgs);
}
void GdbEngine::emitStartFailed()
{
// QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"),
// QMessageBox::critical(mainWindow(), tr("Debugger Startup Failure"),
// tr("Cannot start debugger: %1").arg(m_gdbAdapter->errorString()));
m_outputCollector.shutdown();
m_stubProc.blockSignals(true);
@@ -1598,7 +1606,7 @@ void GdbEngine::emitStartFailed()
void GdbEngine::startDebugger2()
{
debugMessage(_("STARTUP, PHASE 2"));
q->showStatusMessage(tr("Gdb Running..."));
showStatusMessage(tr("Gdb Running..."));
postCommand(_("show version"), CB(handleShowVersion));
//postCommand(_("-enable-timings");
@@ -1668,7 +1676,7 @@ void GdbEngine::startDebugger2()
if (QFileInfo(scriptFileName).isReadable()) {
postCommand(_("source ") + scriptFileName);
} else {
QMessageBox::warning(q->mainWindow(),
QMessageBox::warning(mainWindow(),
tr("Cannot find debugger initialization script"),
tr("The debugger settings point to a script file at '%1' "
"which is not accessible. If a script file is not needed, "
@@ -1677,11 +1685,11 @@ void GdbEngine::startDebugger2()
}
}
if (q->startMode() == AttachExternal || q->startMode() == AttachCrashedExternal) {
if (startMode() == AttachExternal || startMode() == AttachCrashedExternal) {
postCommand(_("attach %1").arg(m_startParameters.attachPID), CB(handleAttach));
// Task 254674 does not want to remove them
//qq->breakHandler()->removeAllBreakpoints();
} else if (q->startMode() == AttachCore) {
} else if (startMode() == AttachCore) {
QFileInfo fi(m_startParameters.executable);
QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
QFileInfo fi2(m_startParameters.coreFile);
@@ -1690,7 +1698,7 @@ void GdbEngine::startDebugger2()
postCommand(_("-file-exec-and-symbols ") + fileName, CB(handleFileExecAndSymbols));
postCommand(_("target core ") + coreName, CB(handleTargetCore));
qq->breakHandler()->removeAllBreakpoints();
} else if (q->startMode() == StartRemote) {
} else if (startMode() == StartRemote) {
postCommand(_("set architecture %1").arg(m_startParameters.remoteArchitecture));
qq->breakHandler()->setAllPending();
//QFileInfo fi(m_startParameters.executable);
@@ -1701,8 +1709,8 @@ void GdbEngine::startDebugger2()
postCommand(_("set target-async on"), CB(handleSetTargetAsync));
} else if (m_startParameters.useTerminal) {
qq->breakHandler()->setAllPending();
} else if (q->startMode() == StartInternal || q->startMode() == StartExternal) {
m_gdbAdapter->attach(this);
} else if (startMode() == StartInternal || startMode() == StartExternal) {
m_gdbAdapter->attach();
if (m_gdbAdapter->isAdapter()) {
qq->notifyInferiorRunningRequested();
postCommand(_("-exec-continue"), CB(handleExecContinue));
@@ -1732,7 +1740,7 @@ void GdbEngine::startDebugger2()
void GdbEngine::continueInferior()
{
q->resetLocation();
m_manager->resetLocation();
setTokenBarrier();
qq->notifyInferiorRunningRequested();
postCommand(_("-exec-continue"), CB(handleExecContinue));
@@ -1767,10 +1775,10 @@ void GdbEngine::handleStart(const GdbResultRecord &response, const QVariant &)
void GdbEngine::handleAttach(const GdbResultRecord &, const QVariant &)
{
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Attached to running process. Stopped."));
showStatusMessage(tr("Attached to running process. Stopped."));
handleAqcuiredInferior();
q->resetLocation();
m_manager->resetLocation();
recheckDebuggingHelperAvailability();
//
@@ -1793,7 +1801,7 @@ void GdbEngine::handleSetTargetAsync(const GdbResultRecord &record, const QVaria
{
if (record.resultClass == GdbResultDone) {
qq->notifyInferiorRunningRequested();
postCommand(_("target remote %1").arg(q->startParameters()->remoteChannel),
postCommand(_("target remote %1").arg(m_manager->startParameters()->remoteChannel),
CB(handleTargetRemote));
} else if (record.resultClass == GdbResultError) {
// a typical response on "old" gdb is:
@@ -1815,15 +1823,15 @@ void GdbEngine::handleTargetRemote(const GdbResultRecord &record, const QVariant
// 16^error,msg="hd:5555: Connection timed out."
QString msg = __(record.data.findChild("msg").data());
QString msg1 = tr("Connecting to remote server failed:");
q->showStatusMessage(msg1 + _c(' ') + msg);
QMessageBox::critical(q->mainWindow(), tr("Error"), msg1 + _c('\n') + msg);
showStatusMessage(msg1 + _c(' ') + msg);
QMessageBox::critical(mainWindow(), tr("Error"), msg1 + _c('\n') + msg);
postCommand(_("-gdb-exit"), CB(handleExit));
}
}
void GdbEngine::handleExit(const GdbResultRecord &, const QVariant &)
{
q->showStatusMessage(tr("Debugger exited."));
showStatusMessage(tr("Debugger exited."));
}
void GdbEngine::stepExec()
@@ -1907,11 +1915,11 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
// ~"run1 (argc=1, argv=0x7fffbf1f5538) at test1.cpp:242"
// ~"242\t x *= 2;"
// 23^done"
q->gotoLocation(frame, true);
m_manager->gotoLocation(frame, true);
//setBreakpoint();
//postCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
#else
q->gotoLocation(frame, true);
m_manager->gotoLocation(frame, true);
setBreakpoint(fileName, lineNumber);
postCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
#endif
@@ -1945,7 +1953,7 @@ void GdbEngine::setDebugDebuggingHelpers(const QVariant &on)
if (on.toBool()) {
debugMessage(_("SWITCHING ON DUMPER DEBUGGING"));
postCommand(_("set unwindonsignal off"));
q->breakByFunction(_("qDumpObjectData440"));
m_manager->breakByFunction(_("qDumpObjectData440"));
//updateLocals();
} else {
debugMessage(_("SWITCHING OFF DUMPER DEBUGGING"));
@@ -2067,7 +2075,7 @@ void GdbEngine::sendInsertBreakpoint(int index)
// cmd += _("-c ") + data->condition + ' ';
#endif
cmd += where;
emit gdbOutputAvailable(LogStatus, _("Current state: %1").arg(q->status()));
emit gdbOutputAvailable(LogStatus, _("Current state: %1").arg(status()));
postCommand(cmd, NeedsStop, CB(handleBreakInsert), index);
}
@@ -2487,7 +2495,7 @@ void GdbEngine::reloadSourceFiles()
void GdbEngine::handleStackSelectThread(const GdbResultRecord &, const QVariant &)
{
//qDebug("FIXME: StackHandler::handleOutput: SelectThread");
q->showStatusMessage(tr("Retrieving data for stack view..."), 3000);
showStatusMessage(tr("Retrieving data for stack view..."), 3000);
reloadStack();
}
@@ -2550,7 +2558,7 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVari
if (topFrame != -1 || theDebuggerBoolSetting(StepByInstruction)) {
const StackFrame &frame = qq->stackHandler()->currentFrame();
q->gotoLocation(frame, true);
m_manager->gotoLocation(frame, true);
}
} else if (record.resultClass == GdbResultError) {
qDebug() << "STACK FAILED: " << record.toString();
@@ -2560,7 +2568,7 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVari
void GdbEngine::selectThread(int index)
{
//reset location arrow
q->resetLocation();
m_manager->resetLocation();
ThreadsHandler *threadsHandler = qq->threadsHandler();
threadsHandler->setCurrentThread(index);
@@ -2568,13 +2576,13 @@ void GdbEngine::selectThread(int index)
QList<ThreadData> threads = threadsHandler->threads();
QTC_ASSERT(index < threads.size(), return);
int id = threads.at(index).id;
q->showStatusMessage(tr("Retrieving data for stack view..."), 10000);
showStatusMessage(tr("Retrieving data for stack view..."), 10000);
postCommand(_("-thread-select %1").arg(id), CB(handleStackSelectThread));
}
void GdbEngine::activateFrame(int frameIndex)
{
if (q->status() != DebuggerInferiorStopped)
if (status() != DebuggerInferiorStopped)
return;
StackHandler *stackHandler = qq->stackHandler();
@@ -2603,7 +2611,7 @@ void GdbEngine::activateFrame(int frameIndex)
const StackFrame &frame = stackHandler->currentFrame();
if (frame.isUsable())
q->gotoLocation(frame, true);
m_manager->gotoLocation(frame, true);
else
qDebug() << "FULL NAME NOT USABLE:" << frame.file;
}
@@ -2743,7 +2751,7 @@ bool GdbEngine::showToolTip()
void GdbEngine::setToolTipExpression(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos)
{
if (q->status() != DebuggerInferiorStopped || !isCppEditor(editor)) {
if (status() != DebuggerInferiorStopped || !isCppEditor(editor)) {
//qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED/Non Cpp editor";
return;
}
@@ -2951,7 +2959,7 @@ void GdbEngine::runDirectDebuggingHelper(const WatchData &data, bool dumpChildre
var.setValue(data);
postCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue3), var);
q->showStatusMessage(msgRetrievingWatchData(m_pendingRequests + 1), 10000);
showStatusMessage(msgRetrievingWatchData(m_pendingRequests + 1), 10000);
}
void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
@@ -3005,7 +3013,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
var.setValue(data);
postCommand(cmd, WatchUpdate | EmbedToken, CB(handleDebuggingHelperValue1), var);
q->showStatusMessage(msgRetrievingWatchData(m_pendingRequests + 1), 10000);
showStatusMessage(msgRetrievingWatchData(m_pendingRequests + 1), 10000);
// retrieve response
postCommand(_("p (char*)&qDumpOutBuffer"), WatchUpdate,
@@ -3220,7 +3228,7 @@ void GdbEngine::rebuildModel()
m_processedNames.clear();
PENDING_DEBUG("REBUILDING MODEL" << count);
emit gdbInputAvailable(LogStatus, _("<Rebuild Watchmodel %1>").arg(count));
q->showStatusMessage(tr("Finished retrieving data."), 400);
showStatusMessage(tr("Finished retrieving data."), 400);
qq->watchHandler()->endCycle();
showToolTip();
}
@@ -3280,7 +3288,7 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const
if (availableSimpleDebuggingHelpers.isEmpty()) {
if (!m_dumperInjectionLoad) // Retry if thread has not terminated yet.
m_debuggingHelperState = DebuggingHelperUnavailable;
q->showStatusMessage(tr("Debugging helpers not found."));
showStatusMessage(tr("Debugging helpers not found."));
} else {
// Get version and sizes from dumpers. Expression cache
// currently causes errors.
@@ -3293,7 +3301,7 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const
parseSizeCache(contents, &m_dumperHelper);
m_debuggingHelperState = DebuggingHelperAvailable;
const QString successMsg = tr("Dumper version %1, %n custom dumpers found.", 0, m_dumperHelper.typeCount()).arg(dumperVersion);
q->showStatusMessage(successMsg);
showStatusMessage(successMsg);
}
//qDebug() << m_dumperHelper.toString(true);
//qDebug() << m_availableSimpleDebuggingHelpers << "DATA DUMPERS AVAILABLE";
@@ -3426,7 +3434,7 @@ void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record, const
} else if (record.resultClass == GdbResultError) {
QString msg = QString::fromLocal8Bit(record.data.findChild("msg").data());
//qDebug() << "CUSTOM DUMPER SETUP ERROR MESSAGE:" << msg;
q->showStatusMessage(tr("Custom dumper setup: %1").arg(msg), 10000);
showStatusMessage(tr("Custom dumper setup: %1").arg(msg), 10000);
}
}
@@ -3623,7 +3631,7 @@ void GdbEngine::updateLocals()
// Asynchronous load of injected library, initialize in first stop
if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried
&& m_dumperHelper.typeCount() == 0
&& q->inferiorPid() > 0)
&& inferiorPid() > 0)
tryQueryDebuggingHelpers();
m_pendingRequests = 0;
@@ -3935,7 +3943,7 @@ void GdbEngine::tryLoadDebuggingHelpers()
postCommand(_(contents));
return;
}
if (m_dumperInjectionLoad && q->inferiorPid() <= 0) // Need PID to inject
if (m_dumperInjectionLoad && inferiorPid() <= 0) // Need PID to inject
return;
PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
@@ -3959,7 +3967,7 @@ void GdbEngine::tryLoadDebuggingHelpers()
#if defined(Q_OS_WIN)
if (m_dumperInjectionLoad) {
/// Launch asynchronous remote thread to load.
SharedLibraryInjector injector(q->inferiorPid());
SharedLibraryInjector injector(inferiorPid());
QString errorMessage;
if (injector.remoteInject(lib, false, &errorMessage)) {
debugMessage(tr("Dumper injection loading triggered (%1)...").arg(lib));
@@ -4020,9 +4028,9 @@ void GdbEngine::recheckDebuggingHelperAvailability()
bool GdbEngine::startModeAllowsDumpers() const
{
return q->startMode() == StartInternal
|| q->startMode() == StartExternal
|| q->startMode() == AttachExternal;
return startMode() == StartInternal
|| startMode() == StartExternal
|| startMode() == AttachExternal;
}
void GdbEngine::watchPoint(const QPoint &pnt)

View File

@@ -107,7 +107,8 @@ public:
void setWorkingDirectory(const QString &dir) { m_proc.setWorkingDirectory(dir); }
void setEnvironment(const QStringList &env) { m_proc.setEnvironment(env); }
bool isAdapter() const { return false; }
void attach(GdbEngine *engine) const;
void attach();
void interruptInferior();
private:
QProcess m_proc;
@@ -289,6 +290,15 @@ private:
void debugMessage(const QString &msg);
bool showToolTip();
// Convenience
DebuggerManager *manager() { return m_manager; }
void showStatusMessage(const QString &msg, int timeout = -1)
{ m_manager->showStatusMessage(msg, timeout); }
int status() const { return m_manager->status(); }
QMainWindow *mainWindow() const { return m_manager->mainWindow(); }
DebuggerStartMode startMode() const { return m_manager->startMode(); }
qint64 inferiorPid() const { return m_manager->inferiorPid(); }
void handleChildren(const WatchData &parent, const GdbMi &child,
QList<WatchData> *insertions);
const bool m_dumperInjectionLoad;
@@ -441,7 +451,7 @@ private:
QList<GdbCommand> m_commandsToRunOnTemporaryBreak;
DebuggerManager * const q;
DebuggerManager * const m_manager;
IDebuggerManagerAccessForEngines * const qq;
DebuggerStartParameters m_startParameters;
// make sure to re-initialize new members in initializeVariables();

View File

@@ -1416,16 +1416,16 @@ void TrkGdbAdapter::setEnvironment(const QStringList &env)
m_gdbProc.setEnvironment(env);
}
void TrkGdbAdapter::attach(GdbEngine *engine) const
void TrkGdbAdapter::attach()
{
#ifdef STANDALONE_RUNNER
#else
QString fileName = engine->startParameters().executable;
engine->postCommand(_("add-symbol-file \"%1\" %2").arg(fileName)
QString fileName = m_engine->startParameters().executable;
m_engine->postCommand(_("add-symbol-file \"%1\" %2").arg(fileName)
.arg(m_session.codeseg));
engine->postCommand(_("symbol-file \"%1\"").arg(fileName));
engine->postCommand(_("target remote ") + gdbServerName());
engine->attemptBreakpointSynchronization();
m_engine->postCommand(_("symbol-file \"%1\"").arg(fileName));
m_engine->postCommand(_("target remote ") + gdbServerName());
m_engine->attemptBreakpointSynchronization();
#endif
}

View File

@@ -132,7 +132,8 @@ public:
void setWorkingDirectory(const QString &dir);
void setEnvironment(const QStringList &env);
bool isAdapter() const { return true; }
void attach(GdbEngine *engine) const;
void attach();
void interruptInferior();
//
// TRK
@@ -177,7 +178,6 @@ public:
void reportToGdb(const TrkResult &result);
void readMemory(uint addr, uint len);
void interruptInferior();
trk::TrkDevice m_trkDevice;