From f2042616412af89cd0060cb066be009e3588f3d7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 Sep 2009 14:00:18 +0200 Subject: [PATCH 1/6] Debugger: Compile Windows, check only .exe files for PE sections. --- src/plugins/debugger/cdb/cdbdebugengine.h | 1 - src/plugins/debugger/debuggermanager.cpp | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index 6b57235fa34..18b66041652 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -99,7 +99,6 @@ public: virtual void reloadRegisters(); virtual void reloadSourceFiles(); virtual void reloadFullStack() {} - virtual void addOptionPages(QList *) const; public slots: void syncDebuggerPaths(); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index bc97bcdd84a..903407750c0 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -769,6 +769,9 @@ static IDebuggerEngine *determineDebuggerEngine(const QString &executable, return gdbEngine; #else + // A remote executable? + if (!executable.endsWith(_(".exe"))) + return gdbEngine; // If a file has PDB files, it has been compiled by VS. QStringList pdbFiles; if (!getPDBFiles(executable, &pdbFiles, errorMessage)) From c71e3e958ef87e85528fa4f3e0b7b38515af973c Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 23 Sep 2009 13:52:14 +0200 Subject: [PATCH 2/6] debugger: clean up old commented code --- src/plugins/debugger/gdb/gdbengine.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index de6556e693a..12fb509fca4 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -812,7 +812,6 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) { //qDebug() << "TOKEN:" << record.token // << " ACCEPTABLE:" << m_oldestAcceptableToken; - //qDebug() << ""; //qDebug() << "\nRESULT" << record.token << record.toString(); int token = record.token; @@ -823,7 +822,7 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) // In theory this should not happen, in practice it does. debugMessage(_("COOKIE FOR TOKEN %1 ALREADY EATEN. " "TWO RESPONSES FOR ONE COMMAND?").arg(token)); - // handle a case known to occur on Linux/gdb 6.8 when debugging moc + // Handle a case known to occur on Linux/gdb 6.8 when debugging moc // with helpers enabled. In this case we get a second response with // msg="Cannot find new threads: generic error" if (record.resultClass == GdbResultError) { @@ -832,8 +831,6 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) tr("Executable failed"), QString::fromLocal8Bit(msg)); showStatusMessage(tr("Process failed to start.")); exitDebugger(); - //qq->notifyInferiorStopped(); - //qq->notifyInferiorExited(); } return; } @@ -858,8 +855,6 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) << "\n record: " << record.toString(); #endif - // << "\n data: " << record.data.toString(true); - if (cmd.callback) (this->*cmd.callback)(record, cmd.cookie); if (cmd.adapterCallback) @@ -911,7 +906,7 @@ void GdbEngine::handleTargetCore() m_manager->resetLocation(); tryLoadDebuggingHelpers(); qq->stackHandler()->setCurrentIndex(0); - updateLocals(); // Quick shot + updateLocals(); reloadStack(); if (supportsThreads()) postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0); @@ -935,7 +930,6 @@ void GdbEngine::handleQuerySources(const GdbResultRecord &record, const QVariant full = QDir::cleanPath(full); #endif if (fullName.isValid() && QFileInfo(full).isReadable()) { - //qDebug() << "STORING 2:" << fileName << full; m_shortToFullName[fileName] = full; m_fullToShortName[full] = fileName; } From d24752a765cca7cd439337c2a9ed0d1345652699 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 23 Sep 2009 13:59:55 +0200 Subject: [PATCH 3/6] debugger: remove more dead code --- src/plugins/debugger/gdb/gdbengine.cpp | 51 +++----------------------- src/plugins/debugger/gdb/gdbengine.h | 3 -- 2 files changed, 6 insertions(+), 48 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 12fb509fca4..1fbd98e7798 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -324,7 +324,6 @@ void GdbEngine::initializeVariables() m_outputCodec = QTextCodec::codecForLocale(); m_pendingRequests = 0; m_continuationAfterDone = 0; - m_waitingForFirstBreakpointToBeHit = false; m_commandsToRunOnTemporaryBreak.clear(); m_cookieForToken.clear(); m_customOutputForToken.clear(); @@ -1122,21 +1121,6 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) return; } - //MAC: bool isFirstStop = data.findChild("bkptno").data() == "1"; - //!MAC: startSymbolName == data.findChild("frame").findChild("func") - if (m_waitingForFirstBreakpointToBeHit) { - m_waitingForFirstBreakpointToBeHit = false; - - // If the executable dies already that early we might get something - // like >49*stopped,reason="exited",exit-code="0177" - // This is handled now above. - - qq->notifyInferiorStopped(); - handleAqcuiredInferior(); -// FIXME: m_continuationAfterDone = true; - return; - } - if (!m_commandsToRunOnTemporaryBreak.isEmpty()) { QTC_ASSERT(status() == DebuggerInferiorStopRequested, qDebug() << "STATUS:" << status()) @@ -1369,11 +1353,13 @@ void GdbEngine::handleStop2(const GdbMi &data) qq->stackHandler()->setCurrentIndex(0); updateLocals(); // Quick shot - int currentId = data.findChild("thread-id").data().toInt(); - reloadStack(); - if (supportsThreads()) - postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), currentId); + + if (supportsThreads()) { + int currentId = data.findChild("thread-id").data().toInt(); + postCommand(_("-thread-list-ids"), WatchUpdate, + CB(handleStackListThreads), currentId); + } // // Registers @@ -1616,31 +1602,6 @@ void GdbEngine::continueInferior() } #if 0 -void GdbEngine::handleAttach(const GdbResultRecord &, const QVariant &) -{ - qq->notifyInferiorStopped(); - showStatusMessage(tr("Attached to running process. Stopped.")); - handleAqcuiredInferior(); - - m_manager->resetLocation(); - recheckDebuggingHelperAvailability(); - - // - // Stack - // - qq->stackHandler()->setCurrentIndex(0); - updateLocals(); // Quick shot - - reloadStack(); - if (supportsThreads()) - postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0); - - // - // Registers - // - qq->reloadRegisters(); -} - void GdbEngine::handleSetTargetAsync(const GdbResultRecord &record, const QVariant &) { if (record.resultClass == GdbResultDone) { diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index eb97e06c6a5..4ab56fb4e87 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -251,7 +251,6 @@ private: int terminationIndex(const QByteArray &buffer, int &length); void handleResponse(const QByteArray &buff); void handleStart(const GdbResultRecord &response, const QVariant &); - //void handleAttach(const GdbResultRecord &, const QVariant &); void handleAqcuiredInferior(); void handleAsyncOutput(const GdbMi &data); void handleStop1(const GdbResultRecord &, const QVariant &cookie); @@ -260,7 +259,6 @@ private: void handleResultRecord(const GdbResultRecord &response); void handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &); void handleExecContinue(const GdbResultRecord &response, const QVariant &); - //void handleExecRun(const GdbResultRecord &response, const QVariant &); void handleExecJumpToLine(const GdbResultRecord &response, const QVariant &); void handleExecRunToFunction(const GdbResultRecord &response, const QVariant &); void handleInfoShared(const GdbResultRecord &response, const QVariant &); @@ -432,7 +430,6 @@ private: Continuation m_continuationAfterDone; void handleInitialBreakpointsSet(); - bool m_waitingForFirstBreakpointToBeHit; bool m_modulesListOutdated; QList m_commandsToRunOnTemporaryBreak; From 378036c9161e2e60bb4d7126b4c39fb7f5b8f553 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 23 Sep 2009 15:28:50 +0200 Subject: [PATCH 4/6] debugger: make attaching to running process work again --- src/plugins/debugger/debuggerdialogs.cpp | 1 + src/plugins/debugger/debuggermanager.h | 22 +- src/plugins/debugger/debuggerplugin.cpp | 2 +- src/plugins/debugger/gdb/attachgdbadapter.cpp | 205 ++++++++++++++++++ src/plugins/debugger/gdb/attachgdbadapter.h | 84 +++++++ src/plugins/debugger/gdb/coregdbadapter.cpp | 5 +- src/plugins/debugger/gdb/gdb.pri | 22 +- src/plugins/debugger/gdb/gdbengine.cpp | 26 ++- src/plugins/debugger/gdb/gdbengine.h | 26 ++- src/plugins/debugger/gdb/plaingdbadapter.cpp | 5 - src/plugins/debugger/gdb/remotegdbadapter.cpp | 17 +- 11 files changed, 341 insertions(+), 74 deletions(-) create mode 100644 src/plugins/debugger/gdb/attachgdbadapter.cpp create mode 100644 src/plugins/debugger/gdb/attachgdbadapter.h diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 36128020850..4796a9b0f19 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -248,6 +248,7 @@ AttachExternalDialog::AttachExternalDialog(QWidget *parent) QPushButton *refreshButton = new QPushButton(tr("Refresh")); connect(refreshButton, SIGNAL(clicked()), this, SLOT(rebuildProcessList())); m_ui->buttonBox->addButton(refreshButton, QDialogButtonBox::ActionRole); + m_ui->filterLineEdit->setFocus(Qt::TabFocusReason); // Do not use activated, will be single click in Oxygen connect(m_ui->procView, SIGNAL(doubleClicked(QModelIndex)), diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 29052449c9e..bf51de7822d 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -366,6 +366,7 @@ private: ThreadsHandler *threadsHandler() { return m_threadsHandler; } WatchHandler *watchHandler() { return m_watchHandler; } SourceFilesWindow *sourceFileWindow() { return m_sourceFilesWindow; } + QWidget *threadsWindow() const { return m_threadsWindow; } void notifyInferiorStopped(); void notifyInferiorRunningRequested(); @@ -376,20 +377,16 @@ private: void cleanupViews(); - // - // Implementation of IDebuggerManagerAccessForDebugMode - // - QWidget *threadsWindow() const { return m_threadsWindow; } - - virtual bool qtDumperLibraryEnabled() const; - virtual QString qtDumperLibraryName() const; - virtual QStringList qtDumperLibraryLocations() const; - virtual void showQtDumperLibraryWarning(const QString &details = QString()); - virtual bool isReverseDebugging() const; - // // internal implementation // + bool qtDumperLibraryEnabled() const; + QString qtDumperLibraryName() const; + QStringList qtDumperLibraryLocations() const; + void showQtDumperLibraryWarning(const QString &details = QString()); + bool isReverseDebugging() const; + QAbstractItemModel *threadsModel(); + Q_SLOT void loadSessionData(); Q_SLOT void saveSessionData(); Q_SLOT void dumpLog(); @@ -397,7 +394,6 @@ private: public: // stuff in this block should be made private by moving it to // one of the interfaces - QAbstractItemModel *threadsModel(); int status() const { return m_status; } // FIXME: hide this in the engines? //DebuggerStartMode startMode() const; @@ -471,14 +467,12 @@ private: QAction *m_watchAction; QAction *m_breakAction; QAction *m_sepAction; - //QActio *m_stepByInstructionAction; QAction *m_reverseDirectionAction; QWidget *m_breakWindow; QWidget *m_localsWindow; QWidget *m_registerWindow; QWidget *m_modulesWindow; - //QWidget *m_tooltipWindow; QWidget *m_stackWindow; QWidget *m_threadsWindow; QWidget *m_watchersWindow; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 24e06712b96..37c4a3b04a0 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1229,7 +1229,7 @@ void DebuggerPlugin::attachExternalApplication(qint64 pid, const QString &crashP const DebuggerStartParametersPtr sp(new DebuggerStartParameters); sp->attachPID = pid; sp->crashParameter = crashParameter; - sp->startMode = crashParameter.isEmpty() ? AttachExternal : AttachCrashedExternal; + sp->startMode = crashParameter.isEmpty() ? AttachExternal : AttachCrashedExternal; RunConfigurationPtr rc = activeRunConfiguration(); if (rc.isNull()) rc = DebuggerRunner::createDefaultRunConfiguration(); diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp new file mode 100644 index 00000000000..6b0e702e14b --- /dev/null +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -0,0 +1,205 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "attachgdbadapter.h" + +#include "debuggeractions.h" +#include "gdbengine.h" +#include "procinterrupt.h" + +#include + + +namespace Debugger { +namespace Internal { + +#define STRINGIFY_INTERNAL(x) #x +#define STRINGIFY(x) STRINGIFY_INTERNAL(x) +#define CB(callback) \ + static_cast(&AttachGdbAdapter::callback), \ + STRINGIFY(callback) + +/////////////////////////////////////////////////////////////////////// +// +// AttachGdbAdapter +// +/////////////////////////////////////////////////////////////////////// + +AttachGdbAdapter::AttachGdbAdapter(GdbEngine *engine, QObject *parent) + : AbstractGdbAdapter(engine, parent) +{ + QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state()); + connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)), + this, SIGNAL(error(QProcess::ProcessError))); + connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()), + this, SIGNAL(readyReadStandardOutput())); + connect(&m_gdbProc, SIGNAL(readyReadStandardError()), + this, SIGNAL(readyReadStandardError())); + connect(&m_gdbProc, SIGNAL(started()), + this, SLOT(handleGdbStarted())); + connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(handleGdbFinished(int, QProcess::ExitStatus))); +} + +void AttachGdbAdapter::startAdapter() +{ + QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state()); + setState(AdapterStarting); + debugMessage(_("TRYING TO START ADAPTER")); + + QStringList gdbArgs; + gdbArgs.prepend(_("mi")); + gdbArgs.prepend(_("-i")); + + if (!m_engine->m_outputCollector.listen()) { + emit adapterStartFailed(tr("Cannot set up communication with child process: %1") + .arg(m_engine->m_outputCollector.errorString())); + return; + } + gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName()); + + if (!startParameters().workingDir.isEmpty()) + setWorkingDirectory(startParameters().workingDir); + if (!startParameters().environment.isEmpty()) + setEnvironment(startParameters().environment); + + QString location = theDebuggerStringSetting(GdbLocation); + m_gdbProc.start(location, gdbArgs); +} + +void AttachGdbAdapter::handleGdbStarted() +{ + QTC_ASSERT(state() == AdapterStarting, qDebug() << state()); + setState(AdapterStarted); + emit adapterStarted(); +} + +void AttachGdbAdapter::prepareInferior() +{ + const qint64 pid = startParameters().attachPID; + QTC_ASSERT(state() == AdapterStarted, qDebug() << state()); + setState(InferiorPreparing); + qDebug() << "USING " << pid; + m_engine->postCommand(_("attach %1").arg(pid), CB(handleAttach)); + // Task 254674 does not want to remove them + //qq->breakHandler()->removeAllBreakpoints(); +} + +void AttachGdbAdapter::handleAttach(const GdbResultRecord &response, const QVariant &) +{ + QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); + if (response.resultClass == GdbResultDone) { + setState(InferiorPrepared); + emit inferiorPrepared(); + } else if (response.resultClass == GdbResultError) { + QString msg = __(response.data.findChild("msg").data()); + setState(InferiorPreparationFailed); + emit inferiorPreparationFailed(msg); + } +} + +void AttachGdbAdapter::startInferior() +{ + QTC_ASSERT(state() == InferiorPrepared, qDebug() << state()); + setState(InferiorStarting); + m_engine->postCommand(_("-exec-continue"), CB(handleContinue)); +} + +void AttachGdbAdapter::handleContinue(const GdbResultRecord &response, const QVariant &) +{ + QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); + if (response.resultClass == GdbResultRunning) { + setState(InferiorStarted); + emit inferiorStarted(); + } else { + QTC_ASSERT(response.resultClass == GdbResultError, /**/); + const QByteArray &msg = response.data.findChild("msg").data(); + setState(InferiorStartFailed); + emit inferiorStartFailed(msg); + } +} + +void AttachGdbAdapter::interruptInferior() +{ + debugMessage(_("TRYING TO INTERUPT INFERIOR")); + const qint64 pid = startParameters().attachPID; + if (!interruptProcess(pid)) + debugMessage(_("CANNOT INTERRUPT %1").arg(pid)); +} + +void AttachGdbAdapter::shutdown() +{ + if (state() == InferiorStarted) { + setState(InferiorShuttingDown); + m_engine->postCommand(_("detach"), CB(handleDetach)); + return; + } + + if (state() == InferiorShutDown) { + setState(AdapterShuttingDown); + m_engine->postCommand(_("-gdb-exit"), CB(handleExit)); + return; + } + QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state()); +} + +void AttachGdbAdapter::handleDetach(const GdbResultRecord &response, const QVariant &) +{ + if (response.resultClass == GdbResultDone) { + setState(InferiorShutDown); + emit inferiorShutDown(); + shutdown(); // re-iterate... + } else if (response.resultClass == GdbResultError) { + QString msg = tr("Inferior process could not be stopped:\n") + + __(response.data.findChild("msg").data()); + setState(InferiorShutdownFailed); + emit inferiorShutdownFailed(msg); + } +} + +void AttachGdbAdapter::handleExit(const GdbResultRecord &response, const QVariant &) +{ + if (response.resultClass == GdbResultDone) { + // don't set state here, this will be handled in handleGdbFinished() + } else if (response.resultClass == GdbResultError) { + QString msg = tr("Gdb process could not be stopped:\n") + + __(response.data.findChild("msg").data()); + emit adapterShutdownFailed(msg); + } +} + +void AttachGdbAdapter::handleGdbFinished(int, QProcess::ExitStatus) +{ + debugMessage(_("GDB PROESS FINISHED")); + setState(AdapterNotRunning); + emit adapterShutDown(); +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/gdb/attachgdbadapter.h b/src/plugins/debugger/gdb/attachgdbadapter.h new file mode 100644 index 00000000000..6bedcbfc002 --- /dev/null +++ b/src/plugins/debugger/gdb/attachgdbadapter.h @@ -0,0 +1,84 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef DEBUGGER_ATTACHGDBADAPTER_H +#define DEBUGGER_ATTACHGDBADAPTER_H + +#include "abstractgdbadapter.h" +#include "gdbengine.h" + +#include +#include + +namespace Debugger { +namespace Internal { + +/////////////////////////////////////////////////////////////////////// +// +// AttachGdbAdapter +// +/////////////////////////////////////////////////////////////////////// + +class AttachGdbAdapter : public AbstractGdbAdapter +{ + Q_OBJECT + +public: + AttachGdbAdapter(GdbEngine *engine, QObject *parent = 0); + +private: + QByteArray readAllStandardError() { return m_gdbProc.readAllStandardError(); } + QByteArray readAllStandardOutput() { return m_gdbProc.readAllStandardOutput(); } + qint64 write(const char *data) { return m_gdbProc.write(data); } + void setWorkingDirectory(const QString &dir) { m_gdbProc.setWorkingDirectory(dir); } + void setEnvironment(const QStringList &env) { m_gdbProc.setEnvironment(env); } + bool isTrkAdapter() const { return false; } + + void startAdapter(); + void prepareInferior(); + void startInferior(); + void interruptInferior(); + void shutdown(); + + void handleAttach(const GdbResultRecord &, const QVariant &); + void handleContinue(const GdbResultRecord &, const QVariant &); + void handleDetach(const GdbResultRecord &, const QVariant &); + void handleExit(const GdbResultRecord &, const QVariant &); + + void debugMessage(const QString &msg) { m_engine->debugMessage(msg); } + Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus); + Q_SLOT void handleGdbStarted(); + + QProcess m_gdbProc; +}; + +} // namespace Internal +} // namespace Debugger + +#endif // DEBUGGER_ATTACHDBADAPTER_H diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index 820d158d105..d5817633572 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -31,13 +31,10 @@ #include "debuggeractions.h" #include "gdbengine.h" -#include "procinterrupt.h" #include -#include #include -#include namespace Debugger { namespace Internal { @@ -148,7 +145,7 @@ void CoreGdbAdapter::handleTargetCore(const GdbResultRecord &response, const QVa if (response.resultClass == GdbResultDone) { setState(InferiorStarted); emit inferiorStarted(); - m_engine->handleTargetCore(); + m_engine->updateAll(); } else { QTC_ASSERT(response.resultClass == GdbResultError, /**/); const QByteArray &msg = response.data.findChild("msg").data(); diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri index 08a45315a94..344f724eebd 100644 --- a/src/plugins/debugger/gdb/gdb.pri +++ b/src/plugins/debugger/gdb/gdb.pri @@ -1,29 +1,31 @@ include(../../../shared/trk/trk.pri) HEADERS += \ - $$PWD/abstractgdbadapter.h \ - $$PWD/plaingdbadapter.h \ $$PWD/gdbmi.h \ $$PWD/gdbengine.h \ $$PWD/gdboptionspage.h \ - $$PWD/remotegdbadapter.h \ - $$PWD/coregdbadapter.h \ - $$PWD/trkgdbadapter.h \ $$PWD/trkoptions.h \ $$PWD/trkoptionswidget.h \ - $$PWD/trkoptionspage.h + $$PWD/trkoptionspage.h \ + $$PWD/abstractgdbadapter.h \ + $$PWD/attachgdbadapter.h \ + $$PWD/coregdbadapter.h \ + $$PWD/plaingdbadapter.h \ + $$PWD/remotegdbadapter.h \ + $$PWD/trkgdbadapter.h \ SOURCES += \ $$PWD/gdbmi.cpp \ $$PWD/gdbengine.cpp \ $$PWD/gdboptionspage.cpp \ - $$PWD/plaingdbadapter.cpp \ - $$PWD/remotegdbadapter.cpp \ - $$PWD/coregdbadapter.cpp \ $$PWD/trkoptions.cpp \ $$PWD/trkoptionswidget.cpp \ $$PWD/trkoptionspage.cpp \ - $$PWD/trkgdbadapter.cpp + $$PWD/attachgdbadapter.cpp \ + $$PWD/coregdbadapter.cpp \ + $$PWD/plaingdbadapter.cpp \ + $$PWD/remotegdbadapter.cpp \ + $$PWD/trkgdbadapter.cpp \ FORMS += $$PWD/gdboptionspage.ui \ $$PWD/trkoptionswidget.ui diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 1fbd98e7798..0b4b671acfe 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -34,10 +34,11 @@ #include "trkoptions.h" #include "trkoptionspage.h" -#include "plaingdbadapter.h" -#include "trkgdbadapter.h" -#include "remotegdbadapter.h" +#include "attachgdbadapter.h" #include "coregdbadapter.h" +#include "plaingdbadapter.h" +#include "remotegdbadapter.h" +#include "trkgdbadapter.h" #include "watchutils.h" #include "debuggeractions.h" @@ -46,7 +47,6 @@ #include "debuggermanager.h" #include "debuggertooltip.h" #include "gdbmi.h" -#include "procinterrupt.h" #include "breakhandler.h" #include "moduleshandler.h" @@ -182,6 +182,7 @@ GdbEngine::GdbEngine(DebuggerManager *parent) : m_trkAdapter = new TrkGdbAdapter(this, options); m_remoteAdapter = new RemoteGdbAdapter(this); m_coreAdapter = new CoreGdbAdapter(this); + m_attachAdapter = new AttachGdbAdapter(this); // Output connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)), @@ -232,6 +233,7 @@ GdbEngine::~GdbEngine() delete m_trkAdapter; delete m_remoteAdapter; delete m_coreAdapter; + delete m_attachAdapter; } void GdbEngine::connectAdapter() @@ -697,6 +699,7 @@ void GdbEngine::interruptInferior() return; } + debugMessage(_("TRYING TO INTERUPT INFERIOR")); m_gdbAdapter->interruptInferior(); } @@ -898,7 +901,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command) m_gdbAdapter->write(command.toLatin1() + "\r\n"); } -void GdbEngine::handleTargetCore() +void GdbEngine::updateAll() { qq->notifyInferiorStopped(); showStatusMessage(tr("Core file loaded.")); @@ -1505,7 +1508,9 @@ void GdbEngine::shutdown() void GdbEngine::detachDebugger() { - postCommand(_("detach"), CB(handleDetach)); + //postCommand(_("detach"), CB(handleDetach)); + QTC_ASSERT(startMode() == AttachExternal, /**/); + shutdown(); } void GdbEngine::exitDebugger() @@ -1516,11 +1521,6 @@ void GdbEngine::exitDebugger() m_gdbAdapter->shutdown(); } -void GdbEngine::handleDetach(const GdbResultRecord &, const QVariant &) -{ - exitDebugger(); -} - int GdbEngine::currentFrame() const { return qq->stackHandler()->currentIndex(); @@ -1547,6 +1547,8 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp) m_gdbAdapter = m_coreAdapter; else if (sp->startMode == StartRemote) m_gdbAdapter = m_remoteAdapter; + else if (sp->startMode == AttachExternal) + m_gdbAdapter = m_attachAdapter; else m_gdbAdapter = m_plainAdapter; @@ -4081,7 +4083,7 @@ void GdbEngine::handleAdapterStarted() void GdbEngine::handleInferiorPreparationFailed(const QString &msg) { - debugMessage(_("INFERIOR PREPARATION FAILD")); + debugMessage(_("INFERIOR PREPARATION FAILED")); showMessageBox(QMessageBox::Critical, tr("Inferior start preparation failed"), msg); shutdown(); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 4ab56fb4e87..765a958add3 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -62,13 +62,14 @@ class IDebuggerManagerAccessForEngines; class GdbResultRecord; class GdbMi; -class WatchData; class BreakpointData; +class WatchData; -class PlainGdbAdapter; -class TrkGdbAdapter; -class RemoteGdbAdapter; +class AttachGdbAdapter; class CoreGdbAdapter; +class PlainGdbAdapter; +class RemoteGdbAdapter; +class TrkGdbAdapter; enum DebuggingHelperState { @@ -92,10 +93,11 @@ signals: void applicationOutputAvailable(const QString &output); private: - friend class PlainGdbAdapter; - friend class TrkGdbAdapter; - friend class RemoteGdbAdapter; + friend class AttachGdbAdapter; friend class CoreGdbAdapter; + friend class PlainGdbAdapter; + friend class RemoteGdbAdapter; + friend class TrkGdbAdapter; // // IDebuggerEngine implementation @@ -226,6 +228,7 @@ private: void postCommandHelper(const GdbCommand &cmd); void setTokenBarrier(); + void updateAll(); void updateLocals(); private slots: @@ -268,11 +271,9 @@ private: void handleQueryPwd(const GdbResultRecord &response, const QVariant &); void handleQuerySources(const GdbResultRecord &response, const QVariant &); void handleExit(const GdbResultRecord &, const QVariant &); - void handleDetach(const GdbResultRecord &, const QVariant &); //void handleSetTargetAsync(const GdbResultRecord &, const QVariant &); //void handleTargetRemote(const GdbResultRecord &, const QVariant &); void handleWatchPoint(const GdbResultRecord &, const QVariant &); - void handleTargetCore(); bool showToolTip(); // Convenience @@ -441,10 +442,11 @@ private: // only one of those is active at a given time, available in m_gdbAdapter AbstractGdbAdapter *m_gdbAdapter; // pointer to one listed below - PlainGdbAdapter *m_plainAdapter; // owned - TrkGdbAdapter *m_trkAdapter; // owned - RemoteGdbAdapter *m_remoteAdapter; // owned + AttachGdbAdapter *m_attachAdapter; // owned CoreGdbAdapter *m_coreAdapter; // owned + PlainGdbAdapter *m_plainAdapter; // owned + RemoteGdbAdapter *m_remoteAdapter; // owned + TrkGdbAdapter *m_trkAdapter; // owned public: void showMessageBox(int icon, const QString &title, const QString &text); diff --git a/src/plugins/debugger/gdb/plaingdbadapter.cpp b/src/plugins/debugger/gdb/plaingdbadapter.cpp index 68630fff7a7..fee4c3974c9 100644 --- a/src/plugins/debugger/gdb/plaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/plaingdbadapter.cpp @@ -225,11 +225,6 @@ void PlainGdbAdapter::startInferior() void PlainGdbAdapter::interruptInferior() { debugMessage(_("TRYING TO INTERUPT INFERIOR")); - if (m_engine->startMode() == StartRemote) { - m_engine->postCommand(_("-exec-interrupt")); - return; - } - const qint64 attachedPID = m_engine->inferiorPid(); if (attachedPID <= 0) { debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED")); diff --git a/src/plugins/debugger/gdb/remotegdbadapter.cpp b/src/plugins/debugger/gdb/remotegdbadapter.cpp index 0a4a9f92b61..beed13ac931 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbadapter.cpp @@ -31,10 +31,8 @@ #include "debuggeractions.h" #include "gdbengine.h" -#include "procinterrupt.h" #include -#include #include #include @@ -229,20 +227,7 @@ void RemoteGdbAdapter::handleExecRun(const GdbResultRecord &response, const QVar void RemoteGdbAdapter::interruptInferior() { - debugMessage(_("TRYING TO INTERUPT INFERIOR")); - if (m_engine->startMode() == StartRemote) { - m_engine->postCommand(_("-exec-interrupt")); - return; - } - - const qint64 attachedPID = m_engine->inferiorPid(); - if (attachedPID <= 0) { - debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED")); - return; - } - - if (!interruptProcess(attachedPID)) - debugMessage(_("CANNOT INTERRUPT %1").arg(attachedPID)); + m_engine->postCommand(_("-exec-interrupt")); } void RemoteGdbAdapter::shutdown() From b65bbff491a80ad835885aed2606a3099c4701ba Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 23 Sep 2009 15:32:22 +0200 Subject: [PATCH 5/6] debugger: split connectDebuggingHelperActions(bool) into connect* and disconnect* --- src/plugins/debugger/gdb/gdbengine.cpp | 31 +++++++++++++------------- src/plugins/debugger/gdb/gdbengine.h | 3 ++- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 0b4b671acfe..cabd1310259 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -199,22 +199,23 @@ GdbEngine::GdbEngine(DebuggerManager *parent) : Qt::QueuedConnection); } -void GdbEngine::connectDebuggingHelperActions(bool on) +void GdbEngine::connectDebuggingHelperActions() { - if (on) { - connect(theDebuggerAction(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)), - this, SLOT(setUseDebuggingHelpers(QVariant))); - connect(theDebuggerAction(DebugDebuggingHelpers), SIGNAL(valueChanged(QVariant)), - this, SLOT(setDebugDebuggingHelpers(QVariant))); - connect(theDebuggerAction(RecheckDebuggingHelpers), SIGNAL(triggered()), - this, SLOT(recheckDebuggingHelperAvailability())); - } else { - disconnect(theDebuggerAction(UseDebuggingHelpers), 0, this, 0); - disconnect(theDebuggerAction(DebugDebuggingHelpers), 0, this, 0); - disconnect(theDebuggerAction(RecheckDebuggingHelpers), 0, this, 0); - } + connect(theDebuggerAction(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)), + this, SLOT(setUseDebuggingHelpers(QVariant))); + connect(theDebuggerAction(DebugDebuggingHelpers), SIGNAL(valueChanged(QVariant)), + this, SLOT(setDebugDebuggingHelpers(QVariant))); + connect(theDebuggerAction(RecheckDebuggingHelpers), SIGNAL(triggered()), + this, SLOT(recheckDebuggingHelperAvailability())); } +void GdbEngine::disconnectDebuggingHelperActions() +{ + disconnect(theDebuggerAction(UseDebuggingHelpers), 0, this, 0); + disconnect(theDebuggerAction(DebugDebuggingHelpers), 0, this, 0); + disconnect(theDebuggerAction(RecheckDebuggingHelpers), 0, this, 0); +} + DebuggerStartMode GdbEngine::startMode() const { QTC_ASSERT(!m_startParameters.isNull(), return NoStartMode); @@ -1515,7 +1516,7 @@ void GdbEngine::detachDebugger() void GdbEngine::exitDebugger() { - connectDebuggingHelperActions(false); + disconnectDebuggingHelperActions(); m_outputCollector.shutdown(); initializeVariables(); m_gdbAdapter->shutdown(); @@ -1536,7 +1537,7 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp) m_startParameters = sp; if (startModeAllowsDumpers()) - connectDebuggingHelperActions(true); + connectDebuggingHelperActions(); if (m_gdbAdapter) disconnectAdapter(); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 765a958add3..d39546f9b81 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -411,7 +411,8 @@ private: void setWatchDataType(WatchData &data, const GdbMi &mi); void setWatchDataDisplayedType(WatchData &data, const GdbMi &mi); void setLocals(const QList &locals); - void connectDebuggingHelperActions(bool on); + void connectDebuggingHelperActions(); + void disconnectDebuggingHelperActions(); bool startModeAllowsDumpers() const; QString parseDisassembler(const GdbMi &lines); From 46952c04eb5fca2cd33bb80402e1bf2626c96668 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 23 Sep 2009 16:11:25 +0200 Subject: [PATCH 6/6] act on http://bugreports.qt.nokia.com/browse/QTCREATORBUG-123 --- src/plugins/debugger/breakhandler.cpp | 4 +++- src/plugins/debugger/commonoptionspage.ui | 14 ++++++++++++-- src/plugins/debugger/debuggeractions.cpp | 11 +++++++++-- src/plugins/debugger/debuggeractions.h | 3 ++- src/plugins/debugger/debuggerplugin.cpp | 9 ++++++--- src/plugins/debugger/watchhandler.cpp | 3 ++- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index af0af291173..a24f53f8e7d 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -29,6 +29,7 @@ #include "breakhandler.h" +#include "debuggeractions.h" #include "debuggermanager.h" #include "stackframe.h" @@ -507,7 +508,8 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const break; } if (role == Qt::ToolTipRole) - return data->toToolTip(); + return theDebuggerBoolSetting(UseToolTipsInLocalsView) + ? data->toToolTip() : QVariant(); return QVariant(); } diff --git a/src/plugins/debugger/commonoptionspage.ui b/src/plugins/debugger/commonoptionspage.ui index 249ccaca917..24551580597 100644 --- a/src/plugins/debugger/commonoptionspage.ui +++ b/src/plugins/debugger/commonoptionspage.ui @@ -53,12 +53,22 @@ - + Checking this will enable tooltips for variable values during debugging. Since this can slow down debugging and does not provide reliable information as it does not use scope information, it is switched off by default. - Use tooltips while debugging + Use tooltips in locals view while debugging + + + + + + + Checking this will enable tooltips for in the locals view during debugging. + + + Use tooltips in main editor while debugging diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index d13e3559af8..2c98c9f7c9e 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -254,10 +254,17 @@ DebuggerSettings *DebuggerSettings::instance() item = new SavedAction(instance); item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTips")); - item->setText(tr("Use tooltips when debugging")); + item->setText(tr("Use tooltips in main editor when debugging")); item->setCheckable(true); item->setDefaultValue(false); - instance->insertItem(UseToolTips, item); + instance->insertItem(UseToolTipsInMainEditor, item); + + item = new SavedAction(instance); + item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInLocalsView")); + item->setText(tr("Use tooltips in locals view when debugging")); + item->setCheckable(true); + item->setDefaultValue(false); + instance->insertItem(UseToolTipsInLocalsView, item); item = new SavedAction(instance); item->setSettingsKey(debugModeGroup, QLatin1String("ListSourceFiles")); diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 6d9656ffce0..07cac69e80b 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -100,7 +100,8 @@ enum DebuggerActionCode WatchExpressionInWindow, RemoveWatchExpression, WatchPoint, - UseToolTips, + UseToolTipsInMainEditor, + UseToolTipsInLocalsView, AssignValue, AssignType, diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 37c4a3b04a0..f01d9b569d0 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -292,8 +292,10 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent) m_ui.checkBoxUseMessageBoxForSignals); m_group.insert(theDebuggerAction(SkipKnownFrames), m_ui.checkBoxSkipKnownFrames); - m_group.insert(theDebuggerAction(UseToolTips), - m_ui.checkBoxUseToolTips); + m_group.insert(theDebuggerAction(UseToolTipsInMainEditor), + m_ui.checkBoxUseToolTipsInMainEditor); + m_group.insert(theDebuggerAction(UseToolTipsInLocalsView), + m_ui.checkBoxUseToolTipsInLocalsView); m_group.insert(theDebuggerAction(EnableReverseDebugging), m_ui.checkBoxEnableReverseDebugging); m_group.insert(theDebuggerAction(MaximalStackDepth), @@ -1036,7 +1038,8 @@ void DebuggerPlugin::requestMark(TextEditor::ITextEditor *editor, int lineNumber void DebuggerPlugin::showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos) { - if (!theDebuggerBoolSetting(UseToolTips) || m_manager->status() == DebuggerProcessNotReady) + if (!theDebuggerBoolSetting(UseToolTipsInMainEditor) + || m_manager->status() == DebuggerProcessNotReady) return; m_manager->setToolTipExpression(point, editor, pos); diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index ac52e47baa3..8f6bba03ac1 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -702,7 +702,8 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const } case Qt::ToolTipRole: - return data.toToolTip(); + return theDebuggerBoolSetting(UseToolTipsInLocalsView) + ? data.toToolTip() : QVariant(); case Qt::ForegroundRole: { static const QVariant red(QColor(200, 0, 0));