forked from qt-creator/qt-creator
Debugger: Fix a state transition regression
Task-number: QTCREATORBUG-14028 Change-Id: I426baf1549d138f4a35d23d5ab814def2125dfbe Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -98,6 +98,15 @@ enum { debugPending = 0 };
|
|||||||
|
|
||||||
#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
|
#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
|
||||||
|
|
||||||
|
#define CHECK_STATE(s) \
|
||||||
|
do { \
|
||||||
|
if (state() != s) { \
|
||||||
|
showMessage(QString::fromLatin1("UNEXPECTED STATE: %1 WANTED: %2 IN %3:%4") \
|
||||||
|
.arg(state()).arg(s).arg(QLatin1String(__FILE__)).arg(__LINE__), LogError); \
|
||||||
|
QTC_ASSERT(false, qDebug() << state() << s); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
QByteArray GdbEngine::tooltipIName(const QString &exp)
|
QByteArray GdbEngine::tooltipIName(const QString &exp)
|
||||||
{
|
{
|
||||||
return "tooltip." + exp.toLatin1().toHex();
|
return "tooltip." + exp.toLatin1().toHex();
|
||||||
@@ -788,8 +797,7 @@ void GdbEngine::readGdbStandardOutput()
|
|||||||
|
|
||||||
void GdbEngine::interruptInferior()
|
void GdbEngine::interruptInferior()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopRequested,
|
CHECK_STATE(InferiorStopRequested);
|
||||||
qDebug() << "INTERRUPT INFERIOR: " << state(); return);
|
|
||||||
|
|
||||||
if (terminal()->sendInterrupt())
|
if (terminal()->sendInterrupt())
|
||||||
return;
|
return;
|
||||||
@@ -1323,10 +1331,6 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
showMessage(_("IGNORING TERMINAL SIGTRAP"), LogMisc);
|
showMessage(_("IGNORING TERMINAL SIGTRAP"), LogMisc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// This is gdb 7+'s initial *stopped in response to attach.
|
|
||||||
// For consistency, we just discard it.
|
|
||||||
if (state() == InferiorSetupRequested)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (isDying()) {
|
if (isDying()) {
|
||||||
notifyInferiorStopOk();
|
notifyInferiorStopOk();
|
||||||
@@ -1337,6 +1341,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
threadsHandler()->notifyStopped(threads.data());
|
threadsHandler()->notifyStopped(threads.data());
|
||||||
|
|
||||||
const QByteArray reason = data["reason"].data();
|
const QByteArray reason = data["reason"].data();
|
||||||
|
const GdbMi frame = data["frame"];
|
||||||
|
const QByteArray func = frame["from"].data();
|
||||||
|
|
||||||
if (isExitedReason(reason)) {
|
if (isExitedReason(reason)) {
|
||||||
// // The user triggered a stop, but meanwhile the app simply exited ...
|
// // The user triggered a stop, but meanwhile the app simply exited ...
|
||||||
@@ -1358,6 +1364,19 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ignore signals from the process stub.
|
||||||
|
if (startParameters().useTerminal
|
||||||
|
&& data["reason"].data() == "signal-received"
|
||||||
|
&& data["signal-name"].data() == "SIGSTOP"
|
||||||
|
&& (func.endsWith("/ld-linux.so.2")
|
||||||
|
|| func.endsWith("/ld-linux-x86-64.so.2")))
|
||||||
|
{
|
||||||
|
showMessage(_("INTERNAL CONTINUE AFTER SIGSTOP FROM STUB"), LogMisc);
|
||||||
|
notifyInferiorSpontaneousStop();
|
||||||
|
continueInferiorInternal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool gotoHandleStop1 = true;
|
bool gotoHandleStop1 = true;
|
||||||
if (!m_fullStartDone) {
|
if (!m_fullStartDone) {
|
||||||
m_fullStartDone = true;
|
m_fullStartDone = true;
|
||||||
@@ -1367,8 +1386,6 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BreakpointResponseId rid(data["bkptno"].data());
|
BreakpointResponseId rid(data["bkptno"].data());
|
||||||
const GdbMi frame = data["frame"];
|
|
||||||
|
|
||||||
int lineNumber = 0;
|
int lineNumber = 0;
|
||||||
QString fullName;
|
QString fullName;
|
||||||
QByteArray function;
|
QByteArray function;
|
||||||
@@ -1410,14 +1427,14 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
gotoLocation(Location(fullName, lineNumber));
|
gotoLocation(Location(fullName, lineNumber));
|
||||||
|
|
||||||
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
|
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
|
||||||
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
|
CHECK_STATE(InferiorStopRequested);
|
||||||
notifyInferiorStopOk();
|
notifyInferiorStopOk();
|
||||||
flushQueuedCommands();
|
flushQueuedCommands();
|
||||||
if (state() == InferiorStopOk) {
|
if (state() == InferiorStopOk) {
|
||||||
QTC_CHECK(m_commandsDoneCallback == 0);
|
QTC_CHECK(m_commandsDoneCallback == 0);
|
||||||
m_commandsDoneCallback = &GdbEngine::autoContinueInferior;
|
m_commandsDoneCallback = &GdbEngine::autoContinueInferior;
|
||||||
} else {
|
} else {
|
||||||
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
|
CHECK_STATE(InferiorShutdownRequested);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1441,12 +1458,18 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
notifyInferiorSpontaneousStop();
|
notifyInferiorSpontaneousStop();
|
||||||
} else if (state() == InferiorStopOk) {
|
} else if (state() == InferiorStopOk) {
|
||||||
// That's expected.
|
// That's expected.
|
||||||
} else {
|
} else if (state() == InferiorStopRequested) {
|
||||||
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
|
|
||||||
notifyInferiorStopOk();
|
notifyInferiorStopOk();
|
||||||
|
} else if (state() == EngineRunRequested) {
|
||||||
|
// This is gdb 7+'s initial *stopped in response to attach that
|
||||||
|
// appears before the ^done is seen.
|
||||||
|
notifyEngineRunAndInferiorStopOk();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
QTC_CHECK(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
|
|
||||||
if (gotoHandleStop1)
|
if (gotoHandleStop1)
|
||||||
handleStop1(data);
|
handleStop1(data);
|
||||||
@@ -1459,7 +1482,7 @@ static QByteArray stopSignal(const Abi &abi)
|
|||||||
|
|
||||||
void GdbEngine::handleStop1(const GdbMi &data)
|
void GdbEngine::handleStop1(const GdbMi &data)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
QTC_ASSERT(!isDying(), return);
|
QTC_ASSERT(!isDying(), return);
|
||||||
const GdbMi frame = data["frame"];
|
const GdbMi frame = data["frame"];
|
||||||
const QByteArray reason = data["reason"].data();
|
const QByteArray reason = data["reason"].data();
|
||||||
@@ -1531,7 +1554,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
|
|||||||
|
|
||||||
void GdbEngine::handleStop2(const GdbMi &data)
|
void GdbEngine::handleStop2(const GdbMi &data)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
QTC_ASSERT(!isDying(), return);
|
QTC_ASSERT(!isDying(), return);
|
||||||
|
|
||||||
// A user initiated stop looks like the following. Note that there is
|
// A user initiated stop looks like the following. Note that there is
|
||||||
@@ -1560,23 +1583,10 @@ void GdbEngine::handleStop2(const GdbMi &data)
|
|||||||
// dState changed from InferiorStopRequested(13) to InferiorStopOk(14).
|
// dState changed from InferiorStopRequested(13) to InferiorStopOk(14).
|
||||||
|
|
||||||
const QByteArray reason = data["reason"].data();
|
const QByteArray reason = data["reason"].data();
|
||||||
const QByteArray func = data["frame"]["from"].data();
|
|
||||||
const DebuggerStartParameters &sp = startParameters();
|
const DebuggerStartParameters &sp = startParameters();
|
||||||
|
|
||||||
bool isStopperThread = false;
|
bool isStopperThread = false;
|
||||||
|
|
||||||
if (sp.useTerminal
|
|
||||||
&& reason == "signal-received"
|
|
||||||
&& data["signal-name"].data() == "SIGSTOP"
|
|
||||||
&& (func.endsWith("/ld-linux.so.2")
|
|
||||||
|| func.endsWith("/ld-linux-x86-64.so.2")))
|
|
||||||
{
|
|
||||||
// Ignore signals from the process stub.
|
|
||||||
showMessage(_("INTERNAL CONTINUE AFTER SIGSTOP FROM STUB"), LogMisc);
|
|
||||||
continueInferiorInternal();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sp.toolChainAbi.os() == Abi::WindowsOS
|
if (sp.toolChainAbi.os() == Abi::WindowsOS
|
||||||
&& sp.useTerminal
|
&& sp.useTerminal
|
||||||
&& reason == "signal-received"
|
&& reason == "signal-received"
|
||||||
@@ -1711,13 +1721,13 @@ void GdbEngine::handleListFeatures(const DebuggerResponse &response)
|
|||||||
|
|
||||||
void GdbEngine::handlePythonSetup(const DebuggerResponse &response)
|
void GdbEngine::handlePythonSetup(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
CHECK_STATE(EngineSetupRequested);
|
||||||
if (response.resultClass == ResultDone) {
|
if (response.resultClass == ResultDone) {
|
||||||
GdbMi data;
|
GdbMi data;
|
||||||
data.fromStringMultiple(response.consoleStreamOutput);
|
data.fromStringMultiple(response.consoleStreamOutput);
|
||||||
watchHandler()->addDumpers(data["dumpers"]);
|
watchHandler()->addDumpers(data["dumpers"]);
|
||||||
loadInitScript();
|
loadInitScript();
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
CHECK_STATE(EngineSetupRequested);
|
||||||
showMessage(_("ENGINE SUCCESSFULLY STARTED"));
|
showMessage(_("ENGINE SUCCESSFULLY STARTED"));
|
||||||
notifyEngineSetupOk();
|
notifyEngineSetupOk();
|
||||||
} else {
|
} else {
|
||||||
@@ -1740,7 +1750,7 @@ void GdbEngine::showExecutionError(const QString &message)
|
|||||||
|
|
||||||
void GdbEngine::handleExecuteContinue(const DebuggerResponse &response)
|
void GdbEngine::handleExecuteContinue(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
|
CHECK_STATE(InferiorRunRequested);
|
||||||
if (response.resultClass == ResultRunning) {
|
if (response.resultClass == ResultRunning) {
|
||||||
// All is fine. Waiting for a *running.
|
// All is fine. Waiting for a *running.
|
||||||
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
|
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
|
||||||
@@ -1753,7 +1763,7 @@ void GdbEngine::handleExecuteContinue(const DebuggerResponse &response)
|
|||||||
return;
|
return;
|
||||||
if (!m_commandsToRunOnTemporaryBreak.isEmpty())
|
if (!m_commandsToRunOnTemporaryBreak.isEmpty())
|
||||||
flushQueuedCommands();
|
flushQueuedCommands();
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
showStatusMessage(tr("Stopped."), 5000);
|
showStatusMessage(tr("Stopped."), 5000);
|
||||||
reloadStack();
|
reloadStack();
|
||||||
} else if (msg.startsWith("Cannot access memory at address")) {
|
} else if (msg.startsWith("Cannot access memory at address")) {
|
||||||
@@ -1762,7 +1772,7 @@ void GdbEngine::handleExecuteContinue(const DebuggerResponse &response)
|
|||||||
notifyInferiorRunFailed();
|
notifyInferiorRunFailed();
|
||||||
if (isDying())
|
if (isDying())
|
||||||
return;
|
return;
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
// FIXME: Fix translation in master.
|
// FIXME: Fix translation in master.
|
||||||
showStatusMessage(QString::fromLocal8Bit(msg), 5000);
|
showStatusMessage(QString::fromLocal8Bit(msg), 5000);
|
||||||
gotoLocation(stackHandler()->currentFrame());
|
gotoLocation(stackHandler()->currentFrame());
|
||||||
@@ -1837,7 +1847,7 @@ QString GdbEngine::cleanupFullName(const QString &fileName)
|
|||||||
|
|
||||||
void GdbEngine::shutdownInferior()
|
void GdbEngine::shutdownInferior()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
|
CHECK_STATE(InferiorShutdownRequested);
|
||||||
m_commandsToRunOnTemporaryBreak.clear();
|
m_commandsToRunOnTemporaryBreak.clear();
|
||||||
switch (startParameters().closeMode) {
|
switch (startParameters().closeMode) {
|
||||||
case KillAtClose:
|
case KillAtClose:
|
||||||
@@ -1853,7 +1863,7 @@ void GdbEngine::shutdownInferior()
|
|||||||
|
|
||||||
void GdbEngine::handleInferiorShutdown(const DebuggerResponse &response)
|
void GdbEngine::handleInferiorShutdown(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
|
CHECK_STATE(InferiorShutdownRequested);
|
||||||
if (response.resultClass == ResultDone) {
|
if (response.resultClass == ResultDone) {
|
||||||
notifyInferiorShutdownOk();
|
notifyInferiorShutdownOk();
|
||||||
return;
|
return;
|
||||||
@@ -1875,13 +1885,13 @@ void GdbEngine::handleInferiorShutdown(const DebuggerResponse &response)
|
|||||||
void GdbEngine::notifyAdapterShutdownFailed()
|
void GdbEngine::notifyAdapterShutdownFailed()
|
||||||
{
|
{
|
||||||
showMessage(_("ADAPTER SHUTDOWN FAILED"));
|
showMessage(_("ADAPTER SHUTDOWN FAILED"));
|
||||||
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
CHECK_STATE(EngineShutdownRequested);
|
||||||
notifyEngineShutdownFailed();
|
notifyEngineShutdownFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::notifyAdapterShutdownOk()
|
void GdbEngine::notifyAdapterShutdownOk()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
CHECK_STATE(EngineShutdownRequested);
|
||||||
showMessage(_("INITIATE GDBENGINE SHUTDOWN IN STATE %1, PROC: %2")
|
showMessage(_("INITIATE GDBENGINE SHUTDOWN IN STATE %1, PROC: %2")
|
||||||
.arg(lastGoodState()).arg(m_gdbProc->state()));
|
.arg(lastGoodState()).arg(m_gdbProc->state()));
|
||||||
m_commandsDoneCallback = 0;
|
m_commandsDoneCallback = 0;
|
||||||
@@ -1925,7 +1935,7 @@ void GdbEngine::handleGdbExit(const DebuggerResponse &response)
|
|||||||
|
|
||||||
void GdbEngine::detachDebugger()
|
void GdbEngine::detachDebugger()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
QTC_ASSERT(startMode() != AttachCore, qDebug() << startMode());
|
QTC_ASSERT(startMode() != AttachCore, qDebug() << startMode());
|
||||||
postCommand("detach", GdbEngine::ExitRequest, CB(handleDetach));
|
postCommand("detach", GdbEngine::ExitRequest, CB(handleDetach));
|
||||||
}
|
}
|
||||||
@@ -1933,7 +1943,7 @@ void GdbEngine::detachDebugger()
|
|||||||
void GdbEngine::handleDetach(const DebuggerResponse &response)
|
void GdbEngine::handleDetach(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
Q_UNUSED(response);
|
Q_UNUSED(response);
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
notifyInferiorExited();
|
notifyInferiorExited();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2008,10 +2018,10 @@ bool GdbEngine::hasCapability(unsigned cap) const
|
|||||||
|
|
||||||
void GdbEngine::continueInferiorInternal()
|
void GdbEngine::continueInferiorInternal()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
showStatusMessage(tr("Running requested..."), 5000);
|
showStatusMessage(tr("Running requested..."), 5000);
|
||||||
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
|
CHECK_STATE(InferiorRunRequested);
|
||||||
postCommand("-exec-continue", RunRequest, CB(handleExecuteContinue));
|
postCommand("-exec-continue", RunRequest, CB(handleExecuteContinue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2024,14 +2034,14 @@ void GdbEngine::autoContinueInferior()
|
|||||||
|
|
||||||
void GdbEngine::continueInferior()
|
void GdbEngine::continueInferior()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
continueInferiorInternal();
|
continueInferiorInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::executeStep()
|
void GdbEngine::executeStep()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
showStatusMessage(tr("Step requested..."), 5000);
|
showStatusMessage(tr("Step requested..."), 5000);
|
||||||
@@ -2054,7 +2064,7 @@ void GdbEngine::handleExecuteStep(const DebuggerResponse &response)
|
|||||||
QTC_CHECK(state() == InferiorStopOk);
|
QTC_CHECK(state() == InferiorStopOk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
|
CHECK_STATE(InferiorRunRequested);
|
||||||
if (response.resultClass == ResultRunning) {
|
if (response.resultClass == ResultRunning) {
|
||||||
// All is fine. Waiting for a *running.
|
// All is fine. Waiting for a *running.
|
||||||
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
|
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
|
||||||
@@ -2086,7 +2096,7 @@ void GdbEngine::handleExecuteStep(const DebuggerResponse &response)
|
|||||||
|
|
||||||
void GdbEngine::executeStepI()
|
void GdbEngine::executeStepI()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
showStatusMessage(tr("Step by instruction requested..."), 5000);
|
showStatusMessage(tr("Step by instruction requested..."), 5000);
|
||||||
@@ -2098,7 +2108,7 @@ void GdbEngine::executeStepI()
|
|||||||
|
|
||||||
void GdbEngine::executeStepOut()
|
void GdbEngine::executeStepOut()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
postCommand("-stack-select-frame 0", Discardable);
|
postCommand("-stack-select-frame 0", Discardable);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
@@ -2108,7 +2118,7 @@ void GdbEngine::executeStepOut()
|
|||||||
|
|
||||||
void GdbEngine::executeNext()
|
void GdbEngine::executeNext()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
showStatusMessage(tr("Step next requested..."), 5000);
|
showStatusMessage(tr("Step next requested..."), 5000);
|
||||||
@@ -2132,16 +2142,16 @@ void GdbEngine::handleExecuteNext(const DebuggerResponse &response)
|
|||||||
if (response.resultClass == ResultDone) {
|
if (response.resultClass == ResultDone) {
|
||||||
// Step was finishing too quick, and a '*stopped' messages should
|
// Step was finishing too quick, and a '*stopped' messages should
|
||||||
// have preceded it, so just ignore this result.
|
// have preceded it, so just ignore this result.
|
||||||
QTC_CHECK(state() == InferiorStopOk);
|
CHECK_STATE(InferiorStopOk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
|
CHECK_STATE(InferiorRunRequested);
|
||||||
if (response.resultClass == ResultRunning) {
|
if (response.resultClass == ResultRunning) {
|
||||||
// All is fine. Waiting for a *running.
|
// All is fine. Waiting for a *running.
|
||||||
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
|
notifyInferiorRunOk(); // Only needed for gdb < 7.0.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
QByteArray msg = response.data["msg"].data();
|
QByteArray msg = response.data["msg"].data();
|
||||||
if (msg.startsWith("Cannot find bounds of current function")
|
if (msg.startsWith("Cannot find bounds of current function")
|
||||||
|| msg.contains("Error accessing memory address ")) {
|
|| msg.contains("Error accessing memory address ")) {
|
||||||
@@ -2162,7 +2172,7 @@ void GdbEngine::handleExecuteNext(const DebuggerResponse &response)
|
|||||||
|
|
||||||
void GdbEngine::executeNextI()
|
void GdbEngine::executeNextI()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
showStatusMessage(tr("Step next instruction requested..."), 5000);
|
showStatusMessage(tr("Step next instruction requested..."), 5000);
|
||||||
@@ -2179,7 +2189,7 @@ static QByteArray addressSpec(quint64 address)
|
|||||||
|
|
||||||
void GdbEngine::executeRunToLine(const ContextData &data)
|
void GdbEngine::executeRunToLine(const ContextData &data)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
resetLocation();
|
resetLocation();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
@@ -2204,7 +2214,7 @@ void GdbEngine::executeRunToLine(const ContextData &data)
|
|||||||
|
|
||||||
void GdbEngine::executeRunToFunction(const QString &functionName)
|
void GdbEngine::executeRunToFunction(const QString &functionName)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
resetLocation();
|
resetLocation();
|
||||||
postCommand("-break-insert -t " + functionName.toLatin1());
|
postCommand("-break-insert -t " + functionName.toLatin1());
|
||||||
@@ -2214,7 +2224,7 @@ void GdbEngine::executeRunToFunction(const QString &functionName)
|
|||||||
|
|
||||||
void GdbEngine::executeJumpToLine(const ContextData &data)
|
void GdbEngine::executeJumpToLine(const ContextData &data)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
QByteArray loc;
|
QByteArray loc;
|
||||||
if (data.address)
|
if (data.address)
|
||||||
loc = addressSpec(data.address);
|
loc = addressSpec(data.address);
|
||||||
@@ -2234,7 +2244,7 @@ void GdbEngine::executeJumpToLine(const ContextData &data)
|
|||||||
|
|
||||||
void GdbEngine::executeReturn()
|
void GdbEngine::executeReturn()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
CHECK_STATE(InferiorStopOk);
|
||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
showStatusMessage(tr("Immediate return from function requested..."), 5000);
|
showStatusMessage(tr("Immediate return from function requested..."), 5000);
|
||||||
@@ -4417,7 +4427,7 @@ void GdbEngine::resetInferior()
|
|||||||
|
|
||||||
void GdbEngine::handleAdapterStartFailed(const QString &msg, Id settingsIdHint)
|
void GdbEngine::handleAdapterStartFailed(const QString &msg, Id settingsIdHint)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
CHECK_STATE(EngineSetupOk);
|
||||||
showMessage(_("ADAPTER START FAILED"));
|
showMessage(_("ADAPTER START FAILED"));
|
||||||
if (!msg.isEmpty()) {
|
if (!msg.isEmpty()) {
|
||||||
const QString title = tr("Adapter start failed");
|
const QString title = tr("Adapter start failed");
|
||||||
@@ -4442,7 +4452,7 @@ void GdbEngine::handleInferiorPrepared()
|
|||||||
{
|
{
|
||||||
const DebuggerStartParameters &sp = startParameters();
|
const DebuggerStartParameters &sp = startParameters();
|
||||||
|
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
CHECK_STATE(InferiorSetupRequested);
|
||||||
|
|
||||||
if (!sp.commandsAfterConnect.isEmpty()) {
|
if (!sp.commandsAfterConnect.isEmpty()) {
|
||||||
QByteArray commands = globalMacroExpander()->expand(sp.commandsAfterConnect);
|
QByteArray commands = globalMacroExpander()->expand(sp.commandsAfterConnect);
|
||||||
@@ -4475,7 +4485,7 @@ void GdbEngine::handleInferiorPrepared()
|
|||||||
|
|
||||||
void GdbEngine::finishInferiorSetup()
|
void GdbEngine::finishInferiorSetup()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
CHECK_STATE(InferiorSetupRequested);
|
||||||
|
|
||||||
if (startParameters().startMode == AttachCore) {
|
if (startParameters().startMode == AttachCore) {
|
||||||
notifyInferiorSetupOk(); // No breakpoints in core files.
|
notifyInferiorSetupOk(); // No breakpoints in core files.
|
||||||
|
@@ -140,11 +140,13 @@ void GdbTermEngine::runEngine()
|
|||||||
|
|
||||||
void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)
|
void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
// InferiorStopOk can happen if the "*stopped" in response to the
|
||||||
|
// 'attach' comes in before its '^done'
|
||||||
|
QTC_ASSERT(state() == EngineRunRequested || state() == InferiorStopOk,
|
||||||
|
qDebug() << state());
|
||||||
|
|
||||||
switch (response.resultClass) {
|
switch (response.resultClass) {
|
||||||
case ResultDone:
|
case ResultDone:
|
||||||
case ResultRunning:
|
|
||||||
if (startParameters().toolChainAbi.os() != ProjectExplorer::Abi::WindowsOS) {
|
if (startParameters().toolChainAbi.os() != ProjectExplorer::Abi::WindowsOS) {
|
||||||
showMessage(_("INFERIOR ATTACHED"));
|
showMessage(_("INFERIOR ATTACHED"));
|
||||||
} else {
|
} else {
|
||||||
@@ -160,8 +162,19 @@ void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)
|
|||||||
LogWarning);
|
LogWarning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifyEngineRunAndInferiorStopOk();
|
if (state() == EngineRunRequested) {
|
||||||
continueInferiorInternal();
|
// We will get a '*stopped' later that we'll interpret as 'spontaneous'
|
||||||
|
// So acknowledge the current state and put a delayed 'continue' in the pipe.
|
||||||
|
notifyEngineRunAndInferiorRunOk();
|
||||||
|
} else {
|
||||||
|
//postCommand("print 43", NoFlags, [this](const DebuggerResponse &) { continueInferiorInternal(); });
|
||||||
|
continueInferiorInternal();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ResultRunning:
|
||||||
|
// Has anyone seen such a result lately?
|
||||||
|
showMessage(_("INFERIOR ATTACHED AND RUNNING"));
|
||||||
|
notifyEngineRunAndInferiorRunOk();
|
||||||
break;
|
break;
|
||||||
case ResultError:
|
case ResultError:
|
||||||
if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
|
if (response.data["msg"].data() == "ptrace: Operation not permitted.") {
|
||||||
@@ -170,11 +183,11 @@ void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
showMessage(QString::fromLocal8Bit(response.data["msg"].data()));
|
showMessage(QString::fromLocal8Bit(response.data["msg"].data()));
|
||||||
notifyEngineRunFailed();
|
notifyEngineIll();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
showMessage(QString::fromLatin1("Invalid response %1").arg(response.resultClass));
|
showMessage(QString::fromLatin1("Invalid response %1").arg(response.resultClass));
|
||||||
notifyEngineRunFailed();
|
notifyEngineIll();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user