forked from qt-creator/qt-creator
Fixes: debugger: try accessing compiled-in dumpers when attaching to an
external application
This commit is contained in:
@@ -296,6 +296,8 @@ void DebuggerManager::init()
|
||||
this, SLOT(watchExpression(QString)));
|
||||
connect(localsView, SIGNAL(settingsDialogRequested()),
|
||||
this, SIGNAL(settingsDialogRequested()));
|
||||
connect(localsView, SIGNAL(requestRecheckCustomDumperAvailability()),
|
||||
this, SLOT(recheckCustomDumperAvailability()));
|
||||
|
||||
// Watchers
|
||||
QTreeView *watchersView = qobject_cast<QTreeView *>(m_watchersWindow);
|
||||
@@ -316,6 +318,8 @@ void DebuggerManager::init()
|
||||
this, SIGNAL(setSessionValueRequested(QString,QVariant)));
|
||||
connect(watchersView, SIGNAL(settingsDialogRequested()),
|
||||
this, SIGNAL(settingsDialogRequested()));
|
||||
connect(watchersView, SIGNAL(requestRecheckCustomDumperAvailability()),
|
||||
this, SLOT(recheckCustomDumperAvailability()));
|
||||
|
||||
// Tooltip
|
||||
QTreeView *tooltipView = qobject_cast<QTreeView *>(m_tooltipWindow);
|
||||
@@ -993,13 +997,13 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
|
||||
qDebug() << m_executable << type;
|
||||
|
||||
setDebuggerType(type);
|
||||
setBusyCursor(false);
|
||||
setStatus(DebuggerProcessStartingUp);
|
||||
if (!m_engine->startDebugger()) {
|
||||
setStatus(DebuggerProcessNotReady);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_busy = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1199,6 +1203,18 @@ void DebuggerManager::breakAtMain()
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool isAllowedTransition(int from, int to)
|
||||
{
|
||||
return (from == -1)
|
||||
|| (from == DebuggerProcessNotReady && to == DebuggerProcessStartingUp)
|
||||
|| (from == DebuggerProcessStartingUp && to == DebuggerInferiorStopped)
|
||||
|| (from == DebuggerInferiorStopped && to == DebuggerInferiorRunningRequested)
|
||||
|| (from == DebuggerInferiorRunningRequested && to == DebuggerInferiorRunning)
|
||||
|| (from == DebuggerInferiorRunning && to == DebuggerInferiorStopRequested)
|
||||
|| (from == DebuggerInferiorStopRequested && to == DebuggerInferiorStopped)
|
||||
|| (to == DebuggerProcessNotReady);
|
||||
}
|
||||
|
||||
void DebuggerManager::setStatus(int status)
|
||||
{
|
||||
if (Debugger::Constants::Internal::debug)
|
||||
@@ -1207,6 +1223,10 @@ void DebuggerManager::setStatus(int status)
|
||||
if (status == m_status)
|
||||
return;
|
||||
|
||||
if (!isAllowedTransition(m_status, status))
|
||||
qDebug() << "UNEXPECTED TRANSITION: " << m_status << status;
|
||||
|
||||
|
||||
m_status = status;
|
||||
|
||||
const bool started = status == DebuggerInferiorRunning
|
||||
@@ -1255,9 +1275,9 @@ void DebuggerManager::setStatus(int status)
|
||||
|
||||
void DebuggerManager::setBusyCursor(bool busy)
|
||||
{
|
||||
//qDebug() << "BUSY FROM: " << m_busy << " TO: " << m_busy;
|
||||
if (busy == m_busy)
|
||||
return;
|
||||
//qDebug() << "BUSY: " << busy;
|
||||
m_busy = busy;
|
||||
|
||||
QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
|
||||
@@ -1413,6 +1433,16 @@ void DebuggerManager::fileOpen(const QString &fileName)
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Watch specific stuff
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DebuggerManager::recheckCustomDumperAvailability()
|
||||
{
|
||||
m_engine->recheckCustomDumperAvailability();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -311,6 +311,7 @@ private slots:
|
||||
void setStatus(int status);
|
||||
void clearStatusMessage();
|
||||
void attemptBreakpointSynchronization();
|
||||
void recheckCustomDumperAvailability();
|
||||
|
||||
private:
|
||||
//
|
||||
|
||||
@@ -112,8 +112,7 @@ enum GdbCommandType
|
||||
GdbInfoShared,
|
||||
GdbInfoProc,
|
||||
GdbInfoThreads,
|
||||
GdbQueryDataDumper1,
|
||||
GdbQueryDataDumper2,
|
||||
GdbQueryDataDumper,
|
||||
GdbTemporaryContinue,
|
||||
GdbTargetCore,
|
||||
|
||||
@@ -799,11 +798,8 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
case GdbInfoShared:
|
||||
handleInfoShared(record);
|
||||
break;
|
||||
case GdbQueryDataDumper1:
|
||||
handleQueryDataDumper1(record);
|
||||
break;
|
||||
case GdbQueryDataDumper2:
|
||||
handleQueryDataDumper2(record);
|
||||
case GdbQueryDataDumper:
|
||||
handleQueryDataDumper(record);
|
||||
break;
|
||||
case GdbTemporaryContinue:
|
||||
continueInferior();
|
||||
@@ -1570,7 +1566,7 @@ bool GdbEngine::startDebugger()
|
||||
gdbArgs.prepend(QLatin1String("mi"));
|
||||
gdbArgs.prepend(QLatin1String("-i"));
|
||||
|
||||
if (q->startMode() == AttachCore) {
|
||||
if (q->startMode() == AttachCore || q->startMode() == AttachExternal) {
|
||||
// nothing to do
|
||||
} else if (q->m_useTerminal) {
|
||||
m_stubProc.stop(); // We leave the console open, so recycle it now.
|
||||
@@ -1778,6 +1774,7 @@ void GdbEngine::handleAttach()
|
||||
handleAqcuiredInferior();
|
||||
|
||||
q->resetLocation();
|
||||
recheckCustomDumperAvailability();
|
||||
|
||||
//
|
||||
// Stack
|
||||
@@ -3520,14 +3517,9 @@ void GdbEngine::updateWatchModel2()
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::handleQueryDataDumper1(const GdbResultRecord &record)
|
||||
void GdbEngine::handleQueryDataDumper(const GdbResultRecord &record)
|
||||
{
|
||||
Q_UNUSED(record);
|
||||
}
|
||||
|
||||
void GdbEngine::handleQueryDataDumper2(const GdbResultRecord &record)
|
||||
{
|
||||
//qDebug() << "DATA DUMPER TRIAL:" << record.toString();
|
||||
qDebug() << "DATA DUMPER TRIAL:" << record.toString();
|
||||
GdbMi output = record.data.findChild("consolestreamoutput");
|
||||
QByteArray out = output.data();
|
||||
out = out.mid(out.indexOf('"') + 2); // + 1 is success marker
|
||||
@@ -3568,6 +3560,8 @@ void GdbEngine::handleQueryDataDumper2(const GdbResultRecord &record)
|
||||
);
|
||||
} else {
|
||||
m_dataDumperState = DataDumperAvailable;
|
||||
q->showStatusMessage(tr("%1 custom dumpers found")
|
||||
.arg(m_availableSimpleDumpers.size()));
|
||||
}
|
||||
//qDebug() << "DATA DUMPERS AVAILABLE" << m_availableSimpleDumpers;
|
||||
}
|
||||
@@ -4274,9 +4268,8 @@ void GdbEngine::tryLoadCustomDumpers()
|
||||
|
||||
if (m_dataDumperState == DataDumperLoadTried) {
|
||||
// retreive list of dumpable classes
|
||||
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)",
|
||||
GdbQueryDataDumper1);
|
||||
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper2);
|
||||
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
||||
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper);
|
||||
} else {
|
||||
debugMessage(QString("DEBUG HELPER LIBRARY IS NOT USABLE: "
|
||||
" %1 EXISTS: %2, EXECUTABLE: %3").arg(lib)
|
||||
@@ -4285,6 +4278,12 @@ void GdbEngine::tryLoadCustomDumpers()
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::recheckCustomDumperAvailability()
|
||||
{
|
||||
// retreive list of dumpable classes
|
||||
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)");
|
||||
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper);
|
||||
}
|
||||
|
||||
IDebuggerEngine *createGdbEngine(DebuggerManager *parent)
|
||||
{
|
||||
|
||||
@@ -304,6 +304,7 @@ private:
|
||||
void maybeHandleInferiorPidChanged(const QString &pid);
|
||||
|
||||
void tryLoadCustomDumpers();
|
||||
Q_SLOT void recheckCustomDumperAvailability();
|
||||
void runCustomDumper(const WatchData &data, bool dumpChildren);
|
||||
void runDirectDumper(const WatchData &data, bool dumpChildren);
|
||||
bool isCustomValueDumperAvailable(const QString &type) const;
|
||||
@@ -317,8 +318,7 @@ private:
|
||||
const WatchData &cookie);
|
||||
void handleToolTip(const GdbResultRecord &record,
|
||||
const QString &cookie);
|
||||
void handleQueryDataDumper1(const GdbResultRecord &record);
|
||||
void handleQueryDataDumper2(const GdbResultRecord &record);
|
||||
void handleQueryDataDumper(const GdbResultRecord &record);
|
||||
void handleDumpCustomValue1(const GdbResultRecord &record,
|
||||
const WatchData &cookie);
|
||||
void handleDumpCustomValue2(const GdbResultRecord &record,
|
||||
|
||||
@@ -83,6 +83,7 @@ public:
|
||||
virtual void reloadRegisters() = 0;
|
||||
virtual void setDebugDumpers(bool on) = 0;
|
||||
virtual void setUseCustomDumpers(bool on) = 0;
|
||||
virtual void recheckCustomDumperAvailability() = 0;
|
||||
|
||||
virtual void reloadSourceFiles() = 0;
|
||||
};
|
||||
|
||||
@@ -99,6 +99,7 @@ private:
|
||||
|
||||
void setDebugDumpers(bool) {}
|
||||
void setUseCustomDumpers(bool) {}
|
||||
void recheckCustomDumperAvailability() {}
|
||||
|
||||
void assignValueInDebugger(const QString &expr, const QString &value);
|
||||
void executeDebuggerCommand(const QString & command);
|
||||
|
||||
@@ -105,6 +105,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||
QAction *act3 = 0;
|
||||
QAction *act4 = 0;
|
||||
QAction *act5 = new QAction("Debugger properties...", &menu);
|
||||
QAction *act6 = new QAction("Re-check availability of custom dumpers", &menu);
|
||||
|
||||
menu.addAction(act1);
|
||||
menu.addAction(act2);
|
||||
@@ -130,6 +131,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||
// FIXME: menu.addAction(act4);
|
||||
}
|
||||
menu.addSeparator();
|
||||
menu.addAction(act6);
|
||||
menu.addAction(act5);
|
||||
|
||||
QAction *act = menu.exec(ev->globalPos());
|
||||
@@ -149,6 +151,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||
model()->setData(mi0, !visual, VisualRole);
|
||||
else if (act == act5)
|
||||
emit settingsDialogRequested();
|
||||
else if (act == act6)
|
||||
emit requestRecheckCustomDumperAvailability();
|
||||
}
|
||||
|
||||
void WatchWindow::resizeColumnsToContents()
|
||||
|
||||
@@ -63,6 +63,7 @@ signals:
|
||||
void requestAssignValue(const QString &exp, const QString &value);
|
||||
void requestExpandChildren(const QModelIndex &idx);
|
||||
void requestCollapseChildren(const QModelIndex &idx);
|
||||
void requestRecheckCustomDumperAvailability();
|
||||
void settingsDialogRequested();
|
||||
|
||||
private slots:
|
||||
|
||||
Reference in New Issue
Block a user