diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 95f9c3b1104213ec36739c3b68d3de30d142595e..fc963d0798f25e5bc64c48ea03db538c27417f2e 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -314,6 +314,10 @@ DebuggerSettings *theDebuggerSettings() item->setDefaultValue(20); instance->insertItem(MaximalStackDepth, item); + item = new SavedAction(instance); + item->setText(QObject::tr("Reload full stack")); + instance->insertItem(ExpandStack, item); + item = new SavedAction(instance); item->setText(QObject::tr("Execute line")); instance->insertItem(ExecuteCommand, item); diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 31e04199f534c7195af11e9cd560bbc54ae27f55..cb51e551aa0315ad23dc7fad4dc7df606691d2d4 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -79,6 +79,7 @@ enum DebuggerActionCode // Stack MaximalStackDepth, + ExpandStack, // Watchers & Locals WatchExpression, diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 97e639f097ce0d9de706fde4f25ef6581744bf1c..a2d54fb4cf6cb942cf3cb8548b708341c036d2bc 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -1372,7 +1372,7 @@ void DebuggerManager::disassemblerDockToggled(bool on) ////////////////////////////////////////////////////////////////////// // -// Sourec files specific stuff +// Source files specific stuff // ////////////////////////////////////////////////////////////////////// diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index aaa53804a60dc3d3eda58dd9221389973dd8f602..491572ecd6db571ae3f028bb9404fbefdd2d5d39 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -797,7 +797,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess void DebuggerPlugin::extensionsInitialized() { // time gdb -i mi -ex 'debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin - qDebug() << "EXTENSIONS INITIALIZED"; + //qDebug() << "EXTENSIONS INITIALIZED"; QByteArray env = qgetenv("QTC_DEBUGGER_TEST"); if (!env.isEmpty()) m_manager->runTest(QString::fromLocal8Bit(env)); diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index f1fea3104eb3075b79871d6b331e85ec8490a8c6..72d2e6137913f3c5ea9b93a8efd51d0135bf1ecc 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -230,6 +230,9 @@ void GdbEngine::initializeConnections() this, SLOT(reloadRegisters())); connect(theDebuggerAction(FormatNatural), SIGNAL(triggered()), this, SLOT(reloadRegisters())); + + connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()), + this, SLOT(reloadFullStack())); } void GdbEngine::initializeVariables() @@ -803,7 +806,7 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type, break; case StackListFrames: - handleStackListFrames(record); + handleStackListFrames(record, cookie.toBool()); break; case StackListThreads: handleStackListThreads(record, cookie.toInt()); @@ -1301,12 +1304,18 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) #endif } +void GdbEngine::reloadFullStack() +{ + QString cmd = "-stack-list-frames"; + sendSynchronizedCommand(cmd, StackListFrames, true); +} + void GdbEngine::reloadStack() { QString cmd = "-stack-list-frames"; if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt()) cmd += " 0 " + QString::number(stackDepth); - sendSynchronizedCommand(cmd, StackListFrames); + sendSynchronizedCommand(cmd, StackListFrames, false); } void GdbEngine::handleAsyncOutput2(const GdbMi &data) @@ -2450,7 +2459,7 @@ void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int) } -void GdbEngine::handleStackListFrames(const GdbResultRecord &record) +void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull) { QList<StackFrame> stackFrames; @@ -2501,30 +2510,11 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record) topFrame = i; } - if (n >= theDebuggerAction(MaximalStackDepth)->value().toInt()) { - StackFrame frame(n); - frame.file = "..."; - frame.function = "..."; - frame.from = "..."; - frame.line = 0; - frame.address = "..."; - stackFrames.append(frame); - } - - qq->stackHandler()->setFrames(stackFrames); + bool canExpand = !isFull + && (n >= theDebuggerAction(MaximalStackDepth)->value().toInt()); + theDebuggerAction(ExpandStack)->setEnabled(canExpand); + qq->stackHandler()->setFrames(stackFrames, canExpand); -#if 0 - if (0 && topFrame != -1) { - // updates of locals already triggered early - const StackFrame &frame = qq->stackHandler()->currentFrame(); - if (frame.isUsable()) - q->gotoLocation(frame.file, frame.line, true); - else - qDebug() << "FULL NAME NOT USABLE 0: " << frame.file; - } else { - activateFrame(topFrame); - } -#else if (topFrame != -1) { // updates of locals already triggered early const StackFrame &frame = qq->stackHandler()->currentFrame(); @@ -2533,7 +2523,6 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record) else qDebug() << "FULL NAME NOT USABLE 0: " << frame.file << topFrame; } -#endif } void GdbEngine::selectThread(int index) @@ -2562,6 +2551,10 @@ void GdbEngine::activateFrame(int frameIndex) //qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex // << stackHandler->currentIndex(); + if (frameIndex == stackHandler->stackSize()) { + reloadFullStack(); + return; + } QTC_ASSERT(frameIndex < stackHandler->stackSize(), return); if (oldIndex != frameIndex) { diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index 0ea15012e982dfca77c71a00fbf939d594130bcc..79d95f34fcabf90c7fda1160d89a63409f56613f 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -277,10 +277,11 @@ private: // // Stack specific stuff // - void handleStackListFrames(const GdbResultRecord &record); + void handleStackListFrames(const GdbResultRecord &record, bool isFull); void handleStackSelectThread(const GdbResultRecord &record, int cookie); void handleStackListThreads(const GdbResultRecord &record, int cookie); - void reloadStack(); + Q_SLOT void reloadStack(); + Q_SLOT void reloadFullStack(); // diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index 17c8168c7c3c3f156053f69ffc42af2d4a969da2..d8beb63a3e66631f04f50e81e2dfe3d0ee7f0c3d 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -57,12 +57,13 @@ StackHandler::StackHandler(QObject *parent) { m_emptyIcon = QIcon(":/gdbdebugger/images/empty.svg"); m_positionIcon = QIcon(":/gdbdebugger/images/location.svg"); + m_canExpand = false; } int StackHandler::rowCount(const QModelIndex &parent) const { // Since the stack is not a tree, row count is 0 for any valid parent - return parent.isValid() ? 0 : m_stackFrames.size(); + return parent.isValid() ? 0 : (m_stackFrames.size() + m_canExpand); } int StackHandler::columnCount(const QModelIndex &parent) const @@ -72,9 +73,15 @@ int StackHandler::columnCount(const QModelIndex &parent) const QVariant StackHandler::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= m_stackFrames.size()) + if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand) return QVariant(); + if (index.row() == m_stackFrames.size()) { + if (role == Qt::DisplayRole && index.column() == 0) + return "<...>"; + return QVariant(); + } + const StackFrame &frame = m_stackFrames.at(index.row()); if (role == Qt::DisplayRole) { @@ -123,10 +130,12 @@ QVariant StackHandler::headerData(int section, Qt::Orientation orientation, int Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const { - if (index.row() >= m_stackFrames.size()) + if (index.row() >= m_stackFrames.size() + m_canExpand) return 0; + if (index.row() == m_stackFrames.size()) + return QAbstractTableModel::flags(index); const StackFrame &frame = m_stackFrames.at(index.row()); - const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty(); + const bool isValid = (!frame.file.isEmpty() && !frame.function.isEmpty()); return isValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0); } @@ -160,8 +169,9 @@ void StackHandler::removeAll() reset(); } -void StackHandler::setFrames(const QList<StackFrame> &frames) +void StackHandler::setFrames(const QList<StackFrame> &frames, bool canExpand) { + m_canExpand = canExpand; m_stackFrames = frames; if (m_currentIndex >= m_stackFrames.size()) m_currentIndex = m_stackFrames.size() - 1; diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h index ae073e3d1369f74a42ba6eeb9b5df0580c545205..c928a6fed92913351031f1e9072ecf65a8a6639d 100644 --- a/src/plugins/debugger/stackhandler.h +++ b/src/plugins/debugger/stackhandler.h @@ -64,7 +64,7 @@ class StackHandler : public QAbstractTableModel public: StackHandler(QObject *parent = 0); - void setFrames(const QList<StackFrame> &frames); + void setFrames(const QList<StackFrame> &frames, bool canExpand = false); QList<StackFrame> frames() const; void setCurrentIndex(int index); int currentIndex() const { return m_currentIndex; } @@ -88,6 +88,7 @@ private: int m_currentIndex; QIcon m_positionIcon; QIcon m_emptyIcon; + bool m_canExpand; }; diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp index e0340ce0ae8e3908276a0a37c22b1228056c8e24..cac2a40bed9ce194a5728519008779b7459425a3 100644 --- a/src/plugins/debugger/stackwindow.cpp +++ b/src/plugins/debugger/stackwindow.cpp @@ -98,6 +98,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev) act2->setCheckable(true); act2->setChecked(m_alwaysResizeColumnsToContents); + menu.addAction(theDebuggerAction(ExpandStack)); menu.addAction(act0); menu.addSeparator(); menu.addAction(act1); diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index b2af8278d94ba1a6818ea2d3d1d007695d500fd7..76d27768e19acad7f750ae8f60095593e2f0fcc8 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -871,10 +871,11 @@ void WatchHandler::watchExpression(const QString &exp) { // FIXME: 'exp' can contain illegal characters //MODEL_DEBUG("WATCH: " << exp); + static int counter = 0; WatchData data; data.exp = exp; data.name = exp; - data.iname = QLatin1String("watch.") + exp; + data.iname = QLatin1String("watch.") + QString::number(counter++); insertData(data); m_watchers.append(exp); saveWatchers(); @@ -993,7 +994,6 @@ void WatchHandler::reinitializeWatchersHelper() data.variable.clear(); data.setAllNeeded(); data.valuedisabled = false; - data.iname = QLatin1String("watch.") + QString::number(i); data.name = exp; data.exp = exp; insertData(data); diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp index 5673704b10613a0ccf82894c3c54ee1eef85ce8e..f0f30d6d144a5e31169a5c4860429d65487f5394 100644 --- a/tests/auto/debugger/main.cpp +++ b/tests/auto/debugger/main.cpp @@ -85,7 +85,6 @@ private slots: void tst_Debugger::runQtc() { QString test = QFileInfo(qApp->arguments().at(0)).absoluteFilePath(); - //QString qtc = QFileInfo(test + "../../bin/qtcreator.bin").absoluteFilePath(); QString qtc = QFileInfo(test).absolutePath() + "/../../../bin/qtcreator.bin"; qtc = QFileInfo(qtc).absoluteFilePath(); QProcess proc;