diff options
Diffstat (limited to 'src/plugins/debugger/gdb/gdbengine.cpp')
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 90 |
1 files changed, 68 insertions, 22 deletions
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 5eac84b1169..5af199ff156 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -241,6 +241,7 @@ GdbEngine::GdbEngine(const DebuggerRunParameters &startParameters) m_fullStartDone = false; m_systemDumpersLoaded = false; m_rerunPending = false; + m_inUpdateLocals = false; m_debugInfoTaskHandler = new DebugInfoTaskHandler(this); //ExtensionSystem::PluginManager::addObject(m_debugInfoTaskHandler); @@ -442,23 +443,31 @@ void GdbEngine::handleResponse(const QByteArray &buff) } } if (asyncClass == "stopped") { - handleStopResponse(result); - m_pendingLogStreamOutput.clear(); - m_pendingConsoleStreamOutput.clear(); + if (m_inUpdateLocals) { + showMessage(_("UNEXPECTED *stopped NOTIFICATION IGNORED"), LogWarning); + } else { + handleStopResponse(result); + m_pendingLogStreamOutput.clear(); + m_pendingConsoleStreamOutput.clear(); + } } else if (asyncClass == "running") { - GdbMi threads = result["thread-id"]; - threadsHandler()->notifyRunning(threads.data()); - if (state() == InferiorRunOk || state() == InferiorSetupRequested) { - // We get multiple *running after thread creation and in Windows terminals. - showMessage(QString::fromLatin1("NOTE: INFERIOR STILL RUNNING IN STATE %1."). - arg(QLatin1String(DebuggerEngine::stateName(state())))); - } else if (HostOsInfo::isWindowsHost() && (state() == InferiorStopRequested - || state() == InferiorShutdownRequested)) { - // FIXME: Breakpoints on Windows are exceptions which are thrown in newly - // created threads so we have to filter out the running threads messages when - // we request a stop. + if (m_inUpdateLocals) { + showMessage(_("UNEXPECTED *running NOTIFICATION IGNORED"), LogWarning); } else { - notifyInferiorRunOk(); + GdbMi threads = result["thread-id"]; + threadsHandler()->notifyRunning(threads.data()); + if (state() == InferiorRunOk || state() == InferiorSetupRequested) { + // We get multiple *running after thread creation and in Windows terminals. + showMessage(QString::fromLatin1("NOTE: INFERIOR STILL RUNNING IN STATE %1."). + arg(QLatin1String(DebuggerEngine::stateName(state())))); + } else if (HostOsInfo::isWindowsHost() && (state() == InferiorStopRequested + || state() == InferiorShutdownRequested)) { + // FIXME: Breakpoints on Windows are exceptions which are thrown in newly + // created threads so we have to filter out the running threads messages when + // we request a stop. + } else { + notifyInferiorRunOk(); + } } } else if (asyncClass == "library-loaded") { // Archer has 'id="/usr/lib/libdrm.so.2", @@ -1187,6 +1196,8 @@ void GdbEngine::handleResultRecord(DebuggerResponse *response) if (!(cmd.flags & Discardable)) --m_nonDiscardableCount; + m_inUpdateLocals = (cmd.flags & InUpdateLocals); + if (cmd.callback) cmd.callback(*response); @@ -3557,7 +3568,9 @@ void GdbEngine::reloadRegisters() if (true) { if (!m_registerNamesListed) { - postCommand("-data-list-register-names", NoFlags, CB(handleRegisterListNames)); + // The MI version does not give register size. + // postCommand("-data-list-register-names", NoFlags, CB(handleRegisterListNames)); + postCommand("maintenance print raw-registers", NoFlags, CB(handleRegisterListing)); m_registerNamesListed = true; } // Can cause i386-linux-nat.c:571: internal-error: Got request @@ -3638,15 +3651,47 @@ void GdbEngine::handleRegisterListNames(const DebuggerResponse &response) } GdbMi names = response.data["register-names"]; - m_registerNames.clear(); + m_registers.clear(); int gdbRegisterNumber = 0; foreach (const GdbMi &item, names.children()) { - if (!item.data().isEmpty()) - m_registerNames[gdbRegisterNumber] = item.data(); + if (!item.data().isEmpty()) { + Register reg; + reg.name = item.data(); + m_registers[gdbRegisterNumber] = reg; + } ++gdbRegisterNumber; } } +void GdbEngine::handleRegisterListing(const DebuggerResponse &response) +{ + if (response.resultClass != ResultDone) { + m_registerNamesListed = false; + return; + } + + // &"maintenance print raw-registers\n" + // >~" Name Nr Rel Offset Size Type Raw value\n" + // >~" rax 0 0 0 8 int64_t 0x0000000000000005\n" + // >~" rip 16 16 128 8 *1 0x000000000040232a\n" + // >~" '' 145 145 536 0 int0_t <invalid>\n" + + m_registers.clear(); + QList<QByteArray> lines = response.consoleStreamOutput.split('\n'); + for (int i = 1; i < lines.size(); ++i) { + QStringList parts = QString::fromLatin1(lines.at(i)) + .split(QLatin1Char(' '), QString::SkipEmptyParts); + if (parts.size() < 7) + continue; + int gdbRegisterNumber = parts.at(1).toInt(); + Register reg; + reg.name = parts.at(0).toLatin1(); + reg.size = parts.at(4).toInt(); + reg.reportedType = parts.at(5).toLatin1(); + m_registers[gdbRegisterNumber] = reg; + } +} + void GdbEngine::handleRegisterListValues(const DebuggerResponse &response) { if (response.resultClass != ResultDone) @@ -3656,9 +3701,8 @@ void GdbEngine::handleRegisterListValues(const DebuggerResponse &response) // 24^done,register-values=[{number="0",value="0xf423f"},...] const GdbMi values = response.data["register-values"]; foreach (const GdbMi &item, values.children()) { - Register reg; const int number = item["number"].toInt(); - reg.name = m_registerNames[number]; + Register reg = m_registers[number]; QByteArray data = item["value"].data(); if (data.startsWith("0x")) { reg.value = data; @@ -4725,7 +4769,7 @@ void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms) cmd.arg("resultvarname", m_resultVarName); cmd.arg("partialVariable", params.partialVariable); cmd.arg("sortStructMembers", boolSetting(SortStructMembers)); - cmd.flags = Discardable; + cmd.flags = Discardable | InUpdateLocals; cmd.callback = [this](const DebuggerResponse &r) { handleStackFrame(r); }; runCommand(cmd); @@ -4735,6 +4779,8 @@ void GdbEngine::doUpdateLocals(const UpdateParameters ¶ms) void GdbEngine::handleStackFrame(const DebuggerResponse &response) { + m_inUpdateLocals = false; + if (response.resultClass == ResultDone) { QByteArray out = response.consoleStreamOutput; while (out.endsWith(' ') || out.endsWith('\n')) |