debugger: reorganize trk startup

This commit is contained in:
hjk
2009-09-22 09:27:19 +02:00
parent efb02a30a0
commit 41caca2763
3 changed files with 144 additions and 45 deletions

View File

@@ -83,12 +83,12 @@
#endif #endif
#include <ctype.h> #include <ctype.h>
// FIXME: temporary hack to evalute tbreak based step-over behaviour
static QString lastFile; static QString lastFile;
static int lastLine; static int lastLine;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
using namespace Debugger::Constants;
//#define DEBUG_PENDING 1 //#define DEBUG_PENDING 1
//#define DEBUG_SUBITEM 1 //#define DEBUG_SUBITEM 1
@@ -103,6 +103,18 @@ using namespace Debugger::Constants;
#define STRINGIFY(x) STRINGIFY_INTERNAL(x) #define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define CB(callback) &GdbEngine::callback, STRINGIFY(callback) #define CB(callback) &GdbEngine::callback, STRINGIFY(callback)
static bool stateAcceptsGdbCommands(GdbAdapterState state)
{
return state == AdapterStarted
|| state == InferiorPreparing
|| state == InferiorPrepared
|| state == InferiorStarting
|| state == InferiorStarted
|| state == InferiorShuttingDown
|| state == InferiorShutDown
|| state == AdapterShuttingDown;
};
static int &currentToken() static int &currentToken()
{ {
static int token = 0; static int token = 0;
@@ -729,7 +741,8 @@ void GdbEngine::postCommand(const QString &command, GdbCommandFlags flags,
void GdbEngine::postCommandHelper(const GdbCommand &cmd) void GdbEngine::postCommandHelper(const GdbCommand &cmd)
{ {
if (m_gdbAdapter->state() == AdapterNotRunning) { if (!stateAcceptsGdbCommands(m_gdbAdapter->state())) {
PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + cmd.command);
debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + cmd.command); debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + cmd.command);
return; return;
} }
@@ -737,10 +750,12 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
if (cmd.flags & RebuildModel) { if (cmd.flags & RebuildModel) {
++m_pendingRequests; ++m_pendingRequests;
PENDING_DEBUG(" CALLBACK" << cmd.callbackName PENDING_DEBUG(" CALLBACK" << cmd.callbackName
<< "INCREMENTS PENDING TO:" << m_pendingRequests << cmd.command); << "INCREMENTS PENDING TO:" << m_pendingRequests << cmd.command
<< m_gdbAdapter->state());
} else { } else {
PENDING_DEBUG(" UNKNOWN CALLBACK" << cmd.callbackName PENDING_DEBUG(" UNKNOWN CALLBACK" << cmd.callbackName
<< "LEAVES PENDING AT:" << m_pendingRequests << cmd.command); << "LEAVES PENDING AT:" << m_pendingRequests << cmd.command
<< m_gdbAdapter->state());
} }
if ((cmd.flags & NeedsStop) && status() != DebuggerInferiorStopped if ((cmd.flags & NeedsStop) && status() != DebuggerInferiorStopped

View File

@@ -37,9 +37,17 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <utils/qtcassert.h>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtCore/QDir> #include <QtCore/QDir>
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define CB(callback) \
static_cast<GdbEngine::AdapterCallback>(&TrkGdbAdapter::callback), \
STRINGIFY(callback)
#define TrkCB(s) TrkCallback(this, &TrkGdbAdapter::s) #define TrkCB(s) TrkCallback(this, &TrkGdbAdapter::s)
@@ -84,7 +92,7 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
m_bufferedMemoryRead(true), m_bufferedMemoryRead(true),
m_waitCount(0) m_waitCount(0)
{ {
setState(AdapterNotRunning);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
const DWORD portOffset = GetCurrentProcessId() % 100; const DWORD portOffset = GetCurrentProcessId() % 100;
#else #else
@@ -117,6 +125,11 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
connect(&m_rfcommProc, SIGNAL(stateChanged(QProcess::ProcessState)), connect(&m_rfcommProc, SIGNAL(stateChanged(QProcess::ProcessState)),
this, SLOT(handleRfcommStateChanged(QProcess::ProcessState))); this, SLOT(handleRfcommStateChanged(QProcess::ProcessState)));
connect(&m_trkDevice, SIGNAL(messageReceived(trk::TrkResult)),
this, SLOT(handleTrkResult(trk::TrkResult)));
connect(&m_trkDevice, SIGNAL(error(QString)),
this, SLOT(handleTrkError(QString)));
if (m_verbose > 1) if (m_verbose > 1)
m_trkDevice.setVerbose(true); m_trkDevice.setVerbose(true);
m_trkDevice.setSerialFrame(m_options->mode != TrkOptions::BlueTooth); m_trkDevice.setSerialFrame(m_options->mode != TrkOptions::BlueTooth);
@@ -219,6 +232,7 @@ QByteArray TrkGdbAdapter::trkStepRangeMessage(byte option)
void TrkGdbAdapter::startInferiorEarly() void TrkGdbAdapter::startInferiorEarly()
{ {
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
QString errorMessage; QString errorMessage;
const QString device = effectiveTrkDevice(); const QString device = effectiveTrkDevice();
if (!m_trkDevice.open(device, &errorMessage)) { if (!m_trkDevice.open(device, &errorMessage)) {
@@ -230,9 +244,9 @@ void TrkGdbAdapter::startInferiorEarly()
QString msg = QString::fromLatin1("Failed to connect to %1 after " QString msg = QString::fromLatin1("Failed to connect to %1 after "
"%2 attempts").arg(device).arg(m_waitCount); "%2 attempts").arg(device).arg(m_waitCount);
logMessage(msg); logMessage(msg);
setState(AdapterNotRunning);
emit adapterStartFailed(msg); emit adapterStartFailed(msg);
} }
QTimer::singleShot(1000, this, SLOT(startInferiorEarly()));
return; return;
} }
@@ -947,6 +961,7 @@ void TrkGdbAdapter::handleCpuType(const TrkResult &result)
void TrkGdbAdapter::handleCreateProcess(const TrkResult &result) void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
{ {
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
// 40 00 00] // 40 00 00]
//logMessage(" RESULT: " + result.toString()); //logMessage(" RESULT: " + result.toString());
// [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00]
@@ -1284,6 +1299,7 @@ void TrkGdbAdapter::readMemory(uint addr, uint len)
void TrkGdbAdapter::interruptInferior() void TrkGdbAdapter::interruptInferior()
{ {
QTC_ASSERT(state() == AdapterStarted, qDebug() << state());
qDebug() << "TRYING TO INTERRUPT INFERIOR"; qDebug() << "TRYING TO INTERRUPT INFERIOR";
QByteArray ba; QByteArray ba;
// stop the thread (2) or the process (1) or the whole system (0) // stop the thread (2) or the process (1) or the whole system (0)
@@ -1302,30 +1318,42 @@ void TrkGdbAdapter::handleGdbError(QProcess::ProcessError error)
void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus) void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus)
{ {
logMessage(QString("GDB: ProcessFinished %1 %2").arg(exitCode).arg(exitStatus)); logMessage(QString("GDB: ProcessFinished %1 %2").arg(exitCode).arg(exitStatus));
//setState(AdapterNotRunning);
//emit adapterShutDown();
} }
void TrkGdbAdapter::handleGdbStarted() void TrkGdbAdapter::handleGdbStarted()
{ {
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
logMessage(QString("GDB: Process Started")); logMessage(QString("GDB: Process Started"));
setState(AdapterStarted);
emit adapterStarted(); emit adapterStarted();
} }
void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState) void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState)
{ {
logMessage(QString("GDB: Process State %1").arg(newState)); logMessage(_("GDB: Process State %1").arg(newState));
} }
void TrkGdbAdapter::startAdapter(const DebuggerStartParametersPtr &sp) void TrkGdbAdapter::startAdapter(const DebuggerStartParametersPtr &sp)
{ {
QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
m_startParameters = sp; m_startParameters = sp;
logMessage(QLatin1String("### Starting TrkGdbAdapter")); logMessage(QLatin1String("### Starting TrkGdbAdapter"));
if (m_options->mode == TrkOptions::BlueTooth) { if (m_options->mode == TrkOptions::BlueTooth) {
const QString device = effectiveTrkDevice(); const QString device = effectiveTrkDevice();
const QString blueToothListener = QLatin1String("rfcomm"); const QString blueToothListener = QLatin1String("rfcomm");
logMessage(QString::fromLatin1("### Starting BlueTooth listener %1 on %2") QStringList blueToothListenerArguments;
.arg(blueToothListener, device)); blueToothListenerArguments.append(_("-r"));
m_rfcommProc.start(blueToothListener + QLatin1String(" -r listen ") blueToothListenerArguments.append(_("listen"));
+ m_options->blueToothDevice + QLatin1String(" 1")); blueToothListenerArguments.append(m_options->blueToothDevice);
blueToothListenerArguments.append(_("1"));
logMessage(_("### Starting BlueTooth listener %1 on %2: %3 %4")
.arg(blueToothListener).arg(device).arg(blueToothListener)
.arg(blueToothListenerArguments.join(" ")));
m_rfcommProc.start(blueToothListener, blueToothListenerArguments);
m_rfcommProc.waitForStarted(); m_rfcommProc.waitForStarted();
if (m_rfcommProc.state() != QProcess::Running) { if (m_rfcommProc.state() != QProcess::Running) {
QString msg = QString::fromLatin1("Failed to start BlueTooth " QString msg = QString::fromLatin1("Failed to start BlueTooth "
@@ -1338,24 +1366,56 @@ void TrkGdbAdapter::startAdapter(const DebuggerStartParametersPtr &sp)
} }
m_waitCount = 0; m_waitCount = 0;
connect(&m_trkDevice, SIGNAL(messageReceived(trk::TrkResult)),
this, SLOT(handleTrkResult(trk::TrkResult)));
connect(&m_trkDevice, SIGNAL(error(QString)),
this, SLOT(handleTrkError(QString)));
startInferiorEarly(); startInferiorEarly();
} }
void TrkGdbAdapter::prepareInferior() void TrkGdbAdapter::prepareInferior()
{ {
// we already prepared the inferior during the adapter start QTC_ASSERT(state() == AdapterStarted, qDebug() << state());
// We already started the inferior process during the adapter start.
// Now make gdb aware of it.
setState(InferiorPreparing);
QString fileName = m_engine->startParameters().executable;
m_engine->postCommand(_("add-symbol-file \"%1\" %2").arg(fileName)
.arg(m_session.codeseg));
m_engine->postCommand(_("symbol-file \"%1\"").arg(fileName));
m_engine->postCommand(_("target remote ") + gdbServerName(),
CB(handleTargetRemote));
}
void TrkGdbAdapter::handleTargetRemote(const GdbResultRecord &record, const QVariant &)
{
QTC_ASSERT(state() == InferiorPreparing, qDebug() << state());
if (record.resultClass == GdbResultDone) {
//postCommand(_("-exec-continue"), CB(handleExecContinue));
setState(InferiorPrepared);
emit inferiorPrepared(); emit inferiorPrepared();
} else if (record.resultClass == GdbResultError) {
// 16^error,msg="hd:5555: Connection timed out."
QString msg = __(record.data.findChild("msg").data());
QString msg1 = tr("Connecting to remote server failed:");
emit inferiorPreparationFailed(msg1 + _c(' ') + msg);
}
} }
void TrkGdbAdapter::startInferior() void TrkGdbAdapter::startInferior()
{ {
// we already started the inferior during the adapter start QTC_ASSERT(state() == InferiorPrepared, qDebug() << state());
setState(InferiorStarting);
m_engine->postCommand(_("-exec-continue"), CB(handleFirstContinue));
}
void TrkGdbAdapter::handleFirstContinue(const GdbResultRecord &record, const QVariant &)
{
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
if (record.resultClass == GdbResultDone) {
setState(InferiorStarted);
emit inferiorStarted(); emit inferiorStarted();
} else if (record.resultClass == GdbResultError) {
//QString msg = __(record.data.findChild("msg").data());
QString msg1 = tr("Connecting to remote server failed:");
emit inferiorStartFailed(msg1 + record.toString());
}
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@@ -1383,10 +1443,12 @@ static void setGdbCygwinEnvironment(const QString &cygwin, QProcess *process)
void TrkGdbAdapter::startGdb() void TrkGdbAdapter::startGdb()
{ {
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
if (!m_gdbServer.listen(QHostAddress(gdbServerIP()), gdbServerPort())) { if (!m_gdbServer.listen(QHostAddress(gdbServerIP()), gdbServerPort())) {
QString msg = QString("Unable to start the gdb server at %1: %2.") QString msg = QString("Unable to start the gdb server at %1: %2.")
.arg(m_gdbServerName).arg(m_gdbServer.errorString()); .arg(m_gdbServerName).arg(m_gdbServer.errorString());
logMessage(msg); logMessage(msg);
setState(AdapterNotRunning);
emit adapterStartFailed(msg); emit adapterStartFailed(msg);
return; return;
} }
@@ -1458,7 +1520,7 @@ void TrkGdbAdapter::handleRfcommStateChanged(QProcess::ProcessState newState)
} }
// //
// GdbProcessBase // AbstractGdbAdapter interface implementation
// //
void TrkGdbAdapter::kill() void TrkGdbAdapter::kill()
@@ -1475,6 +1537,7 @@ void TrkGdbAdapter::terminate()
m_gdbProc.terminate(); m_gdbProc.terminate();
} }
/*
bool TrkGdbAdapter::waitForFinished(int msecs) bool TrkGdbAdapter::waitForFinished(int msecs)
{ {
QByteArray ba; QByteArray ba;
@@ -1487,12 +1550,7 @@ bool TrkGdbAdapter::waitForFinished(int msecs)
proc.waitForFinished(); proc.waitForFinished();
return m_gdbProc.waitForFinished(msecs); return m_gdbProc.waitForFinished(msecs);
} }
*/
GdbAdapterState TrkGdbAdapter::state() const
{
//return m_gdbProc.state();
return AdapterNotRunning; // FIXME
}
QString TrkGdbAdapter::errorString() const QString TrkGdbAdapter::errorString() const
{ {
@@ -1524,31 +1582,53 @@ void TrkGdbAdapter::setEnvironment(const QStringList &env)
m_gdbProc.setEnvironment(env); m_gdbProc.setEnvironment(env);
} }
void TrkGdbAdapter::shutdownInferior()
{
m_engine->postCommand(_("kill"), CB(handleKill));
}
void TrkGdbAdapter::shutdownAdapter() void TrkGdbAdapter::shutdownAdapter()
{ {
if (state() == InferiorStarted) {
setState(InferiorShuttingDown);
m_engine->postCommand(_("kill"), CB(handleKill));
return;
}
if (state() == InferiorShutDown) {
setState(AdapterShuttingDown);
m_engine->postCommand(_("-gdb-exit"), CB(handleExit));
return;
}
QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state());
emit adapterShutDown(); emit adapterShutDown();
} }
void TrkGdbAdapter::shutdownInferior() void TrkGdbAdapter::handleKill(const GdbResultRecord &response, const QVariant &)
{ {
if (response.resultClass == GdbResultDone) {
setState(InferiorShutDown);
emit inferiorShutDown(); emit inferiorShutDown();
shutdownAdapter(); // re-iterate...
} else if (response.resultClass == GdbResultError) {
QString msg = tr("Inferior process could not be stopped:\n") +
__(response.data.findChild("msg").data());
setState(InferiorShutdownFailed);
emit inferiorShutdownFailed(msg);
}
} }
/* void TrkGdbAdapter::handleExit(const GdbResultRecord &response, const QVariant &)
void TrkGdbAdapter::attach()
{ {
#ifdef STANDALONE_RUNNER if (response.resultClass == GdbResultDone) {
#else // don't set state here, this will be handled in handleGdbFinished()
QString fileName = m_engine->startParameters().executable; } else if (response.resultClass == GdbResultError) {
m_engine->postCommand(_("add-symbol-file \"%1\" %2").arg(fileName) QString msg = tr("Gdb process could not be stopped:\n") +
.arg(m_session.codeseg)); __(response.data.findChild("msg").data());
m_engine->postCommand(_("symbol-file \"%1\"").arg(fileName)); emit adapterShutdownFailed(msg);
//m_engine->postCommand(_("target remote ") + gdbServerName(), }
// &GdbEngine::handleTargetRemote, "handleTargetRemote");
m_engine->postCommand(_("target remote ") + gdbServerName());
#endif
} }
*/
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger

View File

@@ -101,6 +101,7 @@ private:
QProcess m_rfcommProc; QProcess m_rfcommProc;
bool m_running; bool m_running;
DebuggerStartParametersPtr m_startParameters; DebuggerStartParametersPtr m_startParameters;
void debugMessage(const QString &msg) { m_engine->debugMessage(msg); }
public: public:
// //
@@ -110,8 +111,6 @@ public:
QIODevice::OpenMode mode = QIODevice::ReadWrite); QIODevice::OpenMode mode = QIODevice::ReadWrite);
void kill(); void kill();
void terminate(); void terminate();
bool waitForFinished(int msecs = 30000);
GdbAdapterState state() const;
QString errorString() const; QString errorString() const;
QByteArray readAllStandardError(); QByteArray readAllStandardError();
QByteArray readAllStandardOutput(); QByteArray readAllStandardOutput();
@@ -121,7 +120,7 @@ public:
bool isAdapter() const { return true; } bool isAdapter() const { return true; }
//void attach(); //void attach();
void interruptInferior(); void interruptInferior();
void startInferiorEarly(); Q_SLOT void startInferiorEarly();
void startAdapter(const DebuggerStartParametersPtr &sp); void startAdapter(const DebuggerStartParametersPtr &sp);
void prepareInferior(); void prepareInferior();
@@ -129,6 +128,11 @@ public:
void shutdownInferior(); void shutdownInferior();
void shutdownAdapter(); void shutdownAdapter();
void handleKill(const GdbResultRecord &, const QVariant &);
void handleExit(const GdbResultRecord &, const QVariant &);
void handleTargetRemote(const GdbResultRecord &, const QVariant &);
void handleFirstContinue(const GdbResultRecord &, const QVariant &);
// //
// TRK // TRK
// //