S60/Debugger: Add Bluetooth starter to Debugger

- Remove old rfcomm process handler from TrkGdbAdapter, use
  Bluetooth starter instead
- Synchronous connection, remove waitForTrkConnect()
- Move gdb start into Trk version answer, pass on
  settings id hint
- Prevent exit crash triggered by signal gdbProcessFinished()
- Set DebuggerNotReady correctly on AdapterStartFailed when no
  gdb is started yet
This commit is contained in:
Friedemann Kleint
2009-10-26 11:55:02 +01:00
parent dc9e019a1d
commit 93759263d0
4 changed files with 79 additions and 156 deletions

View File

@@ -225,7 +225,9 @@ QMainWindow *GdbEngine::mainWindow() const
GdbEngine::~GdbEngine() GdbEngine::~GdbEngine()
{ {
// prevent sending error messages afterwards // prevent sending error messages afterwards
disconnect(&m_gdbProc);
delete m_gdbAdapter; delete m_gdbAdapter;
m_gdbAdapter = 0;
} }
void GdbEngine::connectAdapter() void GdbEngine::connectAdapter()
@@ -1325,7 +1327,11 @@ void GdbEngine::shutdown()
// fall-through // fall-through
case AdapterStartFailed: // Adapter "did something", but it did not help case AdapterStartFailed: // Adapter "did something", but it did not help
// FIXME set some timeout? // FIXME set some timeout?
if (m_gdbProc.state() == QProcess::Running) {
postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleGdbExit)); postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleGdbExit));
} else {
setState(DebuggerNotReady);
}
break; break;
case InferiorRunningRequested: case InferiorRunningRequested:
case InferiorRunning: case InferiorRunning:
@@ -4099,7 +4105,7 @@ void GdbEngine::gotoLocation(const StackFrame &frame, bool setMarker)
// Starting up & shutting down // Starting up & shutting down
// //
bool GdbEngine::startGdb(const QStringList &args, const QString &gdb) bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QString &settingsIdHint)
{ {
debugMessage(_("STARTING GDB ") + gdb); debugMessage(_("STARTING GDB ") + gdb);
@@ -4115,7 +4121,8 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb)
m_gdbProc.start(location, gdbArgs); m_gdbProc.start(location, gdbArgs);
if (!m_gdbProc.waitForStarted()) { if (!m_gdbProc.waitForStarted()) {
handleAdapterStartFailed(m_gdbProc.errorString()); const QString msg = tr("Unable to start gdb '%1': %2").arg(gdb, m_gdbProc.errorString());
handleAdapterStartFailed(msg, settingsIdHint);
return false; return false;
} }
@@ -4166,7 +4173,6 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb)
// /build/buildd/gdb-6.8/gdb/valops.c:2069: internal-error: // /build/buildd/gdb-6.8/gdb/valops.c:2069: internal-error:
postCommand(_("set overload-resolution off")); postCommand(_("set overload-resolution off"));
//postCommand(_("set demangle-style none")); //postCommand(_("set demangle-style none"));
// From the docs: // From the docs:
// Stop means reenter debugger if this signal happens (implies print). // Stop means reenter debugger if this signal happens (implies print).
// Print means print a message if this signal happens. // Print means print a message if this signal happens.
@@ -4238,6 +4244,8 @@ void GdbEngine::handleGdbError(QProcess::ProcessError error)
void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type) void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
{ {
debugMessage(_("GDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code)); debugMessage(_("GDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code));
if (!m_gdbAdapter)
return;
if (state() == EngineShuttingDown) { if (state() == EngineShuttingDown) {
m_gdbAdapter->shutdown(); m_gdbAdapter->shutdown();
} else if (state() != AdapterStartFailed) { } else if (state() != AdapterStartFailed) {
@@ -4255,9 +4263,14 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &sett
{ {
setState(AdapterStartFailed); setState(AdapterStartFailed);
debugMessage(_("ADAPTER START FAILED")); debugMessage(_("ADAPTER START FAILED"));
Core::ICore::instance()->showWarningWithOptions( const QString title = tr("Adapter start failed");
tr("Adapter start failed"), msg, QString(), if (settingsIdHint.isEmpty()) {
_(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint); Core::ICore::instance()->showWarningWithOptions(title, msg);
} else {
Core::ICore::instance()->showWarningWithOptions(title, msg, QString(),
_(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY),
settingsIdHint);
}
shutdown(); shutdown();
} }

View File

@@ -126,7 +126,9 @@ private: ////////// Gdb Process Management //////////
AbstractGdbAdapter *createAdapter(const DebuggerStartParametersPtr &dp); AbstractGdbAdapter *createAdapter(const DebuggerStartParametersPtr &dp);
void connectAdapter(); void connectAdapter();
bool startGdb(const QStringList &args = QStringList(), const QString &gdb = QString()); bool startGdb(const QStringList &args = QStringList(),
const QString &gdb = QString(),
const QString &settingsIdHint = QString());
void startInferiorPhase2(); void startInferiorPhase2();
void handleInferiorShutdown(const GdbResponse &response); void handleInferiorShutdown(const GdbResponse &response);

View File

@@ -30,6 +30,8 @@
#include "trkgdbadapter.h" #include "trkgdbadapter.h"
#include "trkoptions.h" #include "trkoptions.h"
#include "trkoptionspage.h" #include "trkoptionspage.h"
#include "s60debuggerbluetoothstarter.h"
#include "bluetoothlistener_gui.h"
#include "debuggerstringutils.h" #include "debuggerstringutils.h"
#ifndef STANDALONE_RUNNER #ifndef STANDALONE_RUNNER
@@ -193,10 +195,10 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
m_options(options), m_options(options),
m_overrideTrkDeviceType(-1), m_overrideTrkDeviceType(-1),
m_running(false), m_running(false),
m_trkDevice(new trk::TrkDevice),
m_gdbAckMode(true), m_gdbAckMode(true),
m_verbose(2), m_verbose(2),
m_bufferedMemoryRead(true), m_bufferedMemoryRead(true)
m_waitCount(0)
{ {
m_gdbServer = 0; m_gdbServer = 0;
m_gdbConnection = 0; m_gdbConnection = 0;
@@ -207,28 +209,15 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
#endif #endif
m_gdbServerName = _("127.0.0.1:%1").arg(2222 + portOffset); m_gdbServerName = _("127.0.0.1:%1").arg(2222 + portOffset);
connect(&m_rfcommProc, SIGNAL(readyReadStandardError()), connect(m_trkDevice.data(), SIGNAL(messageReceived(trk::TrkResult)),
this, SLOT(handleRfcommReadyReadStandardError()));
connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()),
this, SLOT(handleRfcommReadyReadStandardOutput()));
connect(&m_rfcommProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(handleRfcommError(QProcess::ProcessError)));
connect(&m_rfcommProc, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(handleRfcommFinished(int, QProcess::ExitStatus)));
connect(&m_rfcommProc, SIGNAL(started()),
this, SLOT(handleRfcommStarted()));
connect(&m_rfcommProc, SIGNAL(stateChanged(QProcess::ProcessState)),
this, SLOT(handleRfcommStateChanged(QProcess::ProcessState)));
connect(&m_trkDevice, SIGNAL(messageReceived(trk::TrkResult)),
this, SLOT(handleTrkResult(trk::TrkResult))); this, SLOT(handleTrkResult(trk::TrkResult)));
connect(&m_trkDevice, SIGNAL(error(QString)), connect(m_trkDevice.data(), SIGNAL(error(QString)),
this, SLOT(handleTrkError(QString))); this, SLOT(handleTrkError(QString)));
m_trkDevice.setVerbose(m_verbose); m_trkDevice->setVerbose(m_verbose);
m_trkDevice.setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth); m_trkDevice->setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth);
connect(&m_trkDevice, SIGNAL(logMessage(QString)), connect(m_trkDevice.data(), SIGNAL(logMessage(QString)),
this, SLOT(trkLogMessage(QString))); this, SLOT(trkLogMessage(QString)));
} }
@@ -387,44 +376,6 @@ void TrkGdbAdapter::slotEmitDelayedInferiorStartFailed()
emit inferiorStartFailed(m_adapterFailMessage); emit inferiorStartFailed(m_adapterFailMessage);
} }
void TrkGdbAdapter::waitForTrkConnect()
{
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
QString errorMessage;
const QString device = effectiveTrkDevice();
if (!m_trkDevice.open(device, &errorMessage)) {
logMessage(_("Waiting on %1 (%2)").arg(device, errorMessage));
if (errorMessage.contains(_("ermission denied"))) {
static int direction = 0;
direction = (direction + 1) % 4;
showStatusMessage(_("Please start TRK on your device! %1")
.arg(QChar("/-\\|"[direction])));
}
// Do not loop forever
if (m_waitCount++ < (effectiveTrkDeviceType() == TrkOptions::BlueTooth ? 60 : 5)) {
QTimer::singleShot(1000, this, SLOT(waitForTrkConnect()));
} else {
QString msg = _("Failed to connect to %1 after "
"%2 attempts").arg(device).arg(m_waitCount);
logMessage(msg);
emit adapterStartFailed(msg, TrkOptionsPage::settingsId());
}
return;
}
m_trkDevice.sendTrkInitialPing();
sendTrkMessage(0x02); // Disconnect, as trk might be still connected
sendTrkMessage(0x01); // Connect
sendTrkMessage(0x05, TrkCB(handleSupportMask));
sendTrkMessage(0x06, TrkCB(handleCpuType));
sendTrkMessage(0x04, TrkCB(handleTrkVersions)); // Versions
//sendTrkMessage(0x09); // Unrecognized command
//sendTrkMessage(0x4a, 0,
// "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File
//sendTrkMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File
emit adapterStarted();
}
void TrkGdbAdapter::logMessage(const QString &msg) void TrkGdbAdapter::logMessage(const QString &msg)
{ {
@@ -981,13 +932,13 @@ i */
void TrkGdbAdapter::sendTrkMessage(byte code, TrkCallback callback, void TrkGdbAdapter::sendTrkMessage(byte code, TrkCallback callback,
const QByteArray &data, const QVariant &cookie) const QByteArray &data, const QVariant &cookie)
{ {
m_trkDevice.sendTrkMessage(code, callback, data, cookie); m_trkDevice->sendTrkMessage(code, callback, data, cookie);
} }
void TrkGdbAdapter::sendTrkAck(byte token) void TrkGdbAdapter::sendTrkAck(byte token)
{ {
//logMessage(QString("SENDING ACKNOWLEDGEMENT FOR TOKEN %1").arg(int(token))); //logMessage(QString("SENDING ACKNOWLEDGEMENT FOR TOKEN %1").arg(int(token)));
m_trkDevice.sendTrkAck(token); m_trkDevice->sendTrkAck(token);
} }
void TrkGdbAdapter::handleTrkError(const QString &msg) void TrkGdbAdapter::handleTrkError(const QString &msg)
@@ -1495,7 +1446,7 @@ void TrkGdbAdapter::handleSupportMask(const TrkResult &result)
logMessage("SUPPORTED: " + str); logMessage("SUPPORTED: " + str);
} }
void TrkGdbAdapter::handleTrkVersions(const TrkResult &result) void TrkGdbAdapter::handleTrkVersionsStartGdb(const TrkResult &result)
{ {
QString logMsg; QString logMsg;
QTextStream str(&logMsg); QTextStream str(&logMsg);
@@ -1507,6 +1458,13 @@ void TrkGdbAdapter::handleTrkVersions(const TrkResult &result)
<< '.' << int(result.data.at(4)); << '.' << int(result.data.at(4));
} }
logMessage(logMsg); logMessage(logMsg);
QStringList gdbArgs;
gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file
if (!m_engine->startGdb(gdbArgs, m_options->gdb, TrkOptionsPage::settingsId())) {
cleanup();
return;
}
emit adapterStarted();
} }
void TrkGdbAdapter::handleDisconnect(const TrkResult & /*result*/) void TrkGdbAdapter::handleDisconnect(const TrkResult & /*result*/)
@@ -1553,30 +1511,32 @@ void TrkGdbAdapter::startAdapter()
setState(AdapterStarting); setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER")); debugMessage(_("TRYING TO START ADAPTER"));
logMessage(QLatin1String("### Starting TrkGdbAdapter")); logMessage(QLatin1String("### Starting TrkGdbAdapter"));
m_trkDevice.setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth); m_trkDevice->setSerialFrame(effectiveTrkDeviceType() != TrkOptions::BlueTooth);
if (effectiveTrkDeviceType() == TrkOptions::BlueTooth) { // Prompt the user for a bluetooth connection
const QString device = effectiveTrkDevice(); const QString device = effectiveTrkDevice();
const QString blueToothListener = QLatin1String("rfcomm"); QString message;
QStringList blueToothListenerArguments; if (effectiveTrkDeviceType() == TrkOptions::BlueTooth) {
blueToothListenerArguments.append(_("-r")); S60DebuggerBluetoothStarter starter(m_trkDevice);
blueToothListenerArguments.append(_("listen")); starter.setDevice(device);
blueToothListenerArguments.append(m_options->blueToothDevice); const trk::StartBluetoothGuiResult src = trk::startBluetoothGui(starter, 0, &message);
blueToothListenerArguments.append(_("1")); switch (src) {
logMessage(_("### Starting BlueTooth listener %1 on %2: %3 %4") case trk::BluetoothGuiConnected:
.arg(blueToothListener).arg(device).arg(blueToothListener) break;
.arg(blueToothListenerArguments.join(" "))); case trk::BluetoothGuiCanceled:
m_rfcommProc.start(blueToothListener, blueToothListenerArguments); emit adapterStartFailed(message, QString());
m_rfcommProc.waitForStarted(); return;
if (m_rfcommProc.state() != QProcess::Running) { case trk::BluetoothGuiError:
QString msg = _("Failed to start BlueTooth " emit adapterStartFailed(message, TrkOptionsPage::settingsId());
"listener %1 on %2: %3\n"); return;
msg = msg.arg(blueToothListener, device, m_rfcommProc.errorString()); };
msg += QString::fromLocal8Bit(m_rfcommProc.readAllStandardError()); } else {
emit adapterStartFailed(msg, TrkOptionsPage::settingsId()); if (!m_trkDevice->isOpen() && !m_trkDevice->open(device, &message)) {
message = tr("Failed to connect to %1: %2\nCheck whether TRK is running.").arg(device).arg(message);
logMessage(message);
emit adapterStartFailed(message, TrkOptionsPage::settingsId());
return; return;
} }
} }
m_waitCount = 0;
QTC_ASSERT(m_gdbServer == 0, delete m_gdbServer); QTC_ASSERT(m_gdbServer == 0, delete m_gdbServer);
QTC_ASSERT(m_gdbConnection == 0, m_gdbConnection = 0); QTC_ASSERT(m_gdbConnection == 0, m_gdbConnection = 0);
@@ -1596,14 +1556,12 @@ void TrkGdbAdapter::startAdapter()
connect(m_gdbServer, SIGNAL(newConnection()), connect(m_gdbServer, SIGNAL(newConnection()),
this, SLOT(handleGdbConnection())); this, SLOT(handleGdbConnection()));
QStringList gdbArgs; m_trkDevice->sendTrkInitialPing();
gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file sendTrkMessage(0x02); // Disconnect, as trk might be still connected
if (!m_engine->startGdb(gdbArgs, m_options->gdb)) { sendTrkMessage(0x01); // Connect
cleanup(); sendTrkMessage(0x05, TrkCB(handleSupportMask));
return; sendTrkMessage(0x06, TrkCB(handleCpuType));
} sendTrkMessage(0x04, TrkCB(handleTrkVersionsStartGdb)); // Versions
waitForTrkConnect();
} }
void TrkGdbAdapter::startInferior() void TrkGdbAdapter::startInferior()
@@ -1640,11 +1598,11 @@ void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
m_session.tid = extractInt(data + 5); m_session.tid = extractInt(data + 5);
m_session.codeseg = extractInt(data + 9); m_session.codeseg = extractInt(data + 9);
m_session.dataseg = extractInt(data + 13); m_session.dataseg = extractInt(data + 13);
const QString startMsg = tr("Process started, PID: 0x%1, thread id: 0x%2, code segment: 0x%3, data segment: 0x%4.")
.arg(m_session.pid, 0, 16).arg(m_session.tid, 0, 16)
.arg(m_session.codeseg, 0, 16).arg(m_session.dataseg, 0, 16);
logMessage("PID: " + hexxNumber(m_session.pid)); logMessage(startMsg);
logMessage("TID: " + hexxNumber(m_session.tid));
logMessage("COD: " + hexxNumber(m_session.codeseg));
logMessage("DAT: " + hexxNumber(m_session.dataseg));
const QString fileName = m_symbolFile; const QString fileName = m_symbolFile;
if (m_symbolFile.isEmpty()) { if (m_symbolFile.isEmpty()) {
@@ -1675,45 +1633,6 @@ void TrkGdbAdapter::startInferiorPhase2()
m_engine->continueInferiorInternal(); m_engine->continueInferiorInternal();
} }
//
// Rfcomm process handling
//
void TrkGdbAdapter::handleRfcommReadyReadStandardError()
{
QByteArray ba = m_rfcommProc.readAllStandardError();
logMessage(QString("RFCONN stderr: %1").arg(_(ba)));
}
void TrkGdbAdapter::handleRfcommReadyReadStandardOutput()
{
QByteArray ba = m_rfcommProc.readAllStandardOutput();
logMessage(QString("RFCONN stdout: %1").arg(_(ba)));
}
void TrkGdbAdapter::handleRfcommError(QProcess::ProcessError error)
{
logMessage(QString("RFCOMM: Process Error %1: %2")
.arg(error).arg(m_rfcommProc.errorString()));
}
void TrkGdbAdapter::handleRfcommFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
logMessage(QString("RFCOMM: ProcessFinished %1 %2")
.arg(exitCode).arg(exitStatus));
}
void TrkGdbAdapter::handleRfcommStarted()
{
logMessage(QString("RFCOMM: Process Started"));
}
void TrkGdbAdapter::handleRfcommStateChanged(QProcess::ProcessState newState)
{
logMessage(QString("RFCOMM: Process State %1").arg(newState));
}
// //
// AbstractGdbAdapter interface implementation // AbstractGdbAdapter interface implementation
// //
@@ -1939,7 +1858,7 @@ void TrkGdbAdapter::handleDirectStep3(const TrkResult &result)
void TrkGdbAdapter::cleanup() void TrkGdbAdapter::cleanup()
{ {
m_trkDevice.close(); m_trkDevice->close();
delete m_gdbServer; delete m_gdbServer;
m_gdbServer = 0; m_gdbServer = 0;
} }

View File

@@ -43,10 +43,12 @@
#include <QtCore/QQueue> #include <QtCore/QQueue>
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QSharedPointer>
#include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket> #include <QtNetwork/QTcpSocket>
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -152,7 +154,6 @@ private:
QString m_gdbServerName; // 127.0.0.1:(2222+uid) QString m_gdbServerName; // 127.0.0.1:(2222+uid)
QProcess m_rfcommProc;
bool m_running; bool m_running;
public: public:
@@ -176,7 +177,6 @@ private:
void emitDelayedInferiorStartFailed(const QString &msg); void emitDelayedInferiorStartFailed(const QString &msg);
Q_SLOT void slotEmitDelayedInferiorStartFailed(); Q_SLOT void slotEmitDelayedInferiorStartFailed();
Q_SLOT void waitForTrkConnect();
void handleTargetRemote(const GdbResponse &response); void handleTargetRemote(const GdbResponse &response);
// //
@@ -198,7 +198,7 @@ private:
void handleSignalContinue(const TrkResult &result); void handleSignalContinue(const TrkResult &result);
void handleStop(const TrkResult &result); void handleStop(const TrkResult &result);
void handleSupportMask(const TrkResult &result); void handleSupportMask(const TrkResult &result);
void handleTrkVersions(const TrkResult &result); void handleTrkVersionsStartGdb(const TrkResult &result);
void handleDisconnect(const TrkResult &result); void handleDisconnect(const TrkResult &result);
void handleDeleteProcess(const TrkResult &result); void handleDeleteProcess(const TrkResult &result);
void handleDeleteProcess2(const TrkResult &result); void handleDeleteProcess2(const TrkResult &result);
@@ -248,7 +248,7 @@ private:
QByteArray trkDeleteProcessMessage(); QByteArray trkDeleteProcessMessage();
QByteArray trkInterruptMessage(); QByteArray trkInterruptMessage();
trk::TrkDevice m_trkDevice; QSharedPointer<trk::TrkDevice> m_trkDevice;
QString m_adapterFailMessage; QString m_adapterFailMessage;
// //
@@ -288,16 +288,6 @@ private:
QHash<int, GdbCommand> m_gdbCookieForToken; QHash<int, GdbCommand> m_gdbCookieForToken;
//
// Rfcomm
//
Q_SLOT void handleRfcommReadyReadStandardError();
Q_SLOT void handleRfcommReadyReadStandardOutput();
Q_SLOT void handleRfcommError(QProcess::ProcessError error);
Q_SLOT void handleRfcommFinished(int exitCode, QProcess::ExitStatus exitStatus);
Q_SLOT void handleRfcommStarted();
Q_SLOT void handleRfcommStateChanged(QProcess::ProcessState newState);
QString effectiveTrkDevice() const; QString effectiveTrkDevice() const;
int effectiveTrkDeviceType() const; int effectiveTrkDeviceType() const;
@@ -308,7 +298,6 @@ private:
QString m_symbolFile; QString m_symbolFile;
int m_verbose; int m_verbose;
bool m_bufferedMemoryRead; bool m_bufferedMemoryRead;
int m_waitCount;
}; };
} // namespace Internal } // namespace Internal