From 52d18e7e6fa623706758c59efab2a0be83ea3ae0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 2 Dec 2010 15:16:53 +0100 Subject: [PATCH] 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 --- src/plugins/debugger/gdb/tcftrkgdbadapter.cpp | 40 ++++++++++++++---- src/plugins/debugger/gdb/tcftrkgdbadapter.h | 2 + src/plugins/debugger/gdb/trkgdbadapter.cpp | 41 +++++++++++++++---- src/plugins/debugger/gdb/trkgdbadapter.h | 1 + 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp index a59a6051621..bea408f7e1c 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp @@ -639,11 +639,7 @@ void TcfTrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) else if (cmd == "k" || cmd.startsWith("vKill")) { // Kill inferior process logMessage(msgGdbPacket(QLatin1String("kill"))); - // 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(), - mainThreadContextId()); + sendRunControlTerminateCommand(); } 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) { // Thread ID from Hg/Hc commands: '-1': All, '0': arbitrary, else hex thread id. @@ -1168,8 +1186,16 @@ void TcfTrkGdbAdapter::shutdownInferior() void TcfTrkGdbAdapter::shutdownAdapter() { - cleanup(); - m_engine->notifyAdapterShutdownOk(); + if (m_gdbProc.state() == QProcess::Running) { + 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() diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.h b/src/plugins/debugger/gdb/tcftrkgdbadapter.h index e597cc09820..f583d316519 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.h +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.h @@ -108,6 +108,8 @@ private: void interruptInferior(); void shutdownInferior(); void shutdownAdapter(); + void sendRunControlTerminateCommand(); + void handleRunControlTerminate(const tcftrk::TcfTrkCommandResult &); void sendRegistersGetMCommand(); void handleWriteRegister(const tcftrk::TcfTrkCommandResult &result); void reportRegisters(); diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 34d44d99186..9eb44532ef1 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -558,10 +558,7 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) } else if (cmd == "k" || cmd.startsWith("vKill")) { - // Kill inferior process - logMessage(msgGdbPacket(QLatin1String("kill"))); - sendTrkMessage(0x41, TrkCB(handleDeleteProcess), - trkDeleteProcessMessage(), "Delete process"); + trkKill(); } else if (cmd.startsWith('m')) { @@ -864,6 +861,14 @@ void TrkGdbAdapter::gdbSetCurrentThread(const QByteArray &cmd, const char *why) 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) { if (why) @@ -1148,9 +1153,19 @@ void TrkGdbAdapter::handleDeleteProcess(const TrkResult &result) void TrkGdbAdapter::handleDeleteProcess2(const TrkResult &result) { Q_UNUSED(result); - logMessage("App TRK disconnected"); - sendGdbServerAck(); - sendGdbServerMessage("", "process killed"); + QString msg = QString::fromLatin1("App TRK disconnected"); + + 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) @@ -1945,8 +1960,16 @@ void TrkGdbAdapter::shutdownInferior() void TrkGdbAdapter::shutdownAdapter() { - cleanup(); - m_engine->notifyAdapterShutdownOk(); + if (m_gdbProc.state() == QProcess::Running) { + 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() diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index 699c5199766..6c25aa0334c 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -135,6 +135,7 @@ private: Q_SLOT void handleTrkResult(const trk::TrkResult &data); Q_SLOT void handleTrkError(const QString &msg); void trkContinueAll(const char *why); + void trkKill(); void handleTrkContinueNext(const TrkResult &result); void trkContinueNext(int threadIndex);