Debugger[CODA/TRK]: Emergency shutdown if gdb crashes.

Kill the debuggee when gdb crashes in stopped state to prevent
the phone from locking up.

Task-number: QTCREATORBUG-3099
This commit is contained in:
Friedemann Kleint
2010-12-02 15:16:53 +01:00
parent 179d77fa33
commit 52d18e7e6f
4 changed files with 68 additions and 16 deletions

View File

@@ -639,11 +639,7 @@ void TcfTrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
else if (cmd == "k" || cmd.startsWith("vKill")) { else if (cmd == "k" || cmd.startsWith("vKill")) {
// Kill inferior process // Kill inferior process
logMessage(msgGdbPacket(QLatin1String("kill"))); logMessage(msgGdbPacket(QLatin1String("kill")));
// Requires id of main thread to terminate. sendRunControlTerminateCommand();
// Note that calling 'Settings|set|removeExecutable' crashes TCF TRK,
// so, it is apparently not required.
m_trkDevice->sendRunControlTerminateCommand(TcfTrkCallback(),
mainThreadContextId());
} }
else if (cmd.startsWith('m')) { else if (cmd.startsWith('m')) {
@@ -952,6 +948,28 @@ void TcfTrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
} }
} }
void TcfTrkGdbAdapter::sendRunControlTerminateCommand()
{
// Requires id of main thread to terminate.
// Note that calling 'Settings|set|removeExecutable' crashes TCF TRK,
// so, it is apparently not required.
m_trkDevice->sendRunControlTerminateCommand(TcfTrkCallback(this, &TcfTrkGdbAdapter::handleRunControlTerminate),
mainThreadContextId());
}
void TcfTrkGdbAdapter::handleRunControlTerminate(const tcftrk::TcfTrkCommandResult &)
{
QString msg = QString::fromLatin1("CODA disconnected");
const bool emergencyShutdown = m_gdbProc.state() != QProcess::Running;
if (emergencyShutdown)
msg += QString::fromLatin1(" (emergency shutdown");
logMessage(msg);
if (emergencyShutdown) {
cleanup();
m_engine->notifyAdapterShutdownOk();
}
}
void TcfTrkGdbAdapter::gdbSetCurrentThread(const QByteArray &cmd, const char *why) void TcfTrkGdbAdapter::gdbSetCurrentThread(const QByteArray &cmd, const char *why)
{ {
// Thread ID from Hg/Hc commands: '-1': All, '0': arbitrary, else hex thread id. // Thread ID from Hg/Hc commands: '-1': All, '0': arbitrary, else hex thread id.
@@ -1168,8 +1186,16 @@ void TcfTrkGdbAdapter::shutdownInferior()
void TcfTrkGdbAdapter::shutdownAdapter() void TcfTrkGdbAdapter::shutdownAdapter()
{ {
cleanup(); if (m_gdbProc.state() == QProcess::Running) {
m_engine->notifyAdapterShutdownOk(); cleanup();
m_engine->notifyAdapterShutdownOk();
} else {
// Something is wrong, gdb crashed. Kill debuggee (see handleDeleteProcess2)
if (m_trkDevice->device()->isOpen()) {
logMessage("Emergency shutdown of CODA", LogError);
sendRunControlTerminateCommand();
}
}
} }
void TcfTrkGdbAdapter::trkReloadRegisters() void TcfTrkGdbAdapter::trkReloadRegisters()

View File

@@ -108,6 +108,8 @@ private:
void interruptInferior(); void interruptInferior();
void shutdownInferior(); void shutdownInferior();
void shutdownAdapter(); void shutdownAdapter();
void sendRunControlTerminateCommand();
void handleRunControlTerminate(const tcftrk::TcfTrkCommandResult &);
void sendRegistersGetMCommand(); void sendRegistersGetMCommand();
void handleWriteRegister(const tcftrk::TcfTrkCommandResult &result); void handleWriteRegister(const tcftrk::TcfTrkCommandResult &result);
void reportRegisters(); void reportRegisters();

View File

@@ -558,10 +558,7 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
} }
else if (cmd == "k" || cmd.startsWith("vKill")) { else if (cmd == "k" || cmd.startsWith("vKill")) {
// Kill inferior process trkKill();
logMessage(msgGdbPacket(QLatin1String("kill")));
sendTrkMessage(0x41, TrkCB(handleDeleteProcess),
trkDeleteProcessMessage(), "Delete process");
} }
else if (cmd.startsWith('m')) { else if (cmd.startsWith('m')) {
@@ -864,6 +861,14 @@ void TrkGdbAdapter::gdbSetCurrentThread(const QByteArray &cmd, const char *why)
sendGdbServerMessage("OK", message); sendGdbServerMessage("OK", message);
} }
void TrkGdbAdapter::trkKill()
{
// Kill inferior process
logMessage(msgGdbPacket(QLatin1String("kill")));
sendTrkMessage(0x41, TrkCB(handleDeleteProcess),
trkDeleteProcessMessage(), "Delete process");
}
void TrkGdbAdapter::trkContinueAll(const char *why) void TrkGdbAdapter::trkContinueAll(const char *why)
{ {
if (why) if (why)
@@ -1148,9 +1153,19 @@ void TrkGdbAdapter::handleDeleteProcess(const TrkResult &result)
void TrkGdbAdapter::handleDeleteProcess2(const TrkResult &result) void TrkGdbAdapter::handleDeleteProcess2(const TrkResult &result)
{ {
Q_UNUSED(result); Q_UNUSED(result);
logMessage("App TRK disconnected"); QString msg = QString::fromLatin1("App TRK disconnected");
sendGdbServerAck();
sendGdbServerMessage("", "process killed"); const bool emergencyShutdown = m_gdbProc.state() != QProcess::Running;
if (emergencyShutdown)
msg += QString::fromLatin1(" (emergency shutdown");
logMessage(msg);
if (emergencyShutdown) {
cleanup();
m_engine->notifyAdapterShutdownOk();
} else {
sendGdbServerAck();
sendGdbServerMessage("", "process killed");
}
} }
void TrkGdbAdapter::handleReadRegisters(const TrkResult &result) void TrkGdbAdapter::handleReadRegisters(const TrkResult &result)
@@ -1945,8 +1960,16 @@ void TrkGdbAdapter::shutdownInferior()
void TrkGdbAdapter::shutdownAdapter() void TrkGdbAdapter::shutdownAdapter()
{ {
cleanup(); if (m_gdbProc.state() == QProcess::Running) {
m_engine->notifyAdapterShutdownOk(); cleanup();
m_engine->notifyAdapterShutdownOk();
} else {
// Something is wrong, gdb crashed. Kill debuggee (see handleDeleteProcess2)
if (m_trkDevice->isOpen()) {
logMessage("Emergency shutdown of TRK", LogError);
trkKill();
}
}
} }
void TrkGdbAdapter::trkReloadRegisters() void TrkGdbAdapter::trkReloadRegisters()

View File

@@ -135,6 +135,7 @@ private:
Q_SLOT void handleTrkResult(const trk::TrkResult &data); Q_SLOT void handleTrkResult(const trk::TrkResult &data);
Q_SLOT void handleTrkError(const QString &msg); Q_SLOT void handleTrkError(const QString &msg);
void trkContinueAll(const char *why); void trkContinueAll(const char *why);
void trkKill();
void handleTrkContinueNext(const TrkResult &result); void handleTrkContinueNext(const TrkResult &result);
void trkContinueNext(int threadIndex); void trkContinueNext(int threadIndex);