Commit b3aff6b9 authored by hjk's avatar hjk

debugger: more of the RunControl refactoring

Pass output through the RunControl instead of the DebuggerManager.
parent 6ed98309
......@@ -121,7 +121,7 @@ static QString msgFunctionFailed(const char *func, const QString &why)
CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *manager,
const QSharedPointer<CdbOptions> &options,
CdbDebugEngine* engine) :
CdbDebugEngine *engine) :
m_options(options),
m_hDebuggeeProcess(0),
m_hDebuggeeThread(0),
......@@ -149,16 +149,12 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
if (!CdbCore::CoreEngine::init(m_options->path, errorMessage))
return false;
CdbDebugOutput *output = new CdbDebugOutput;
CdbDebugOutput *output = new CdbDebugOutput(m_engine);
setDebugOutput(DebugOutputBasePtr(output));
connect(output, SIGNAL(debuggerOutput(int,QString)),
manager(), SLOT(showDebuggerOutput(int,QString)));
connect(output, SIGNAL(debuggerInputPrompt(int,QString)),
manager(), SLOT(showDebuggerInput(int,QString)));
connect(output, SIGNAL(debuggeeOutput(QString,bool)),
manager(), SLOT(showApplicationOutput(QString,bool)));
connect(output, SIGNAL(debuggeeInputPrompt(QString,bool)),
manager(), SLOT(showApplicationOutput(QString,bool)));
setDebugEventCallback(DebugEventCallbackBasePtr(new CdbDebugEventCallback(m_engine)));
updateCodeLevel();
......
......@@ -31,6 +31,7 @@
#include "cdbdebugengine.h"
#include "cdbdebugengine_p.h"
#include "cdbcom.h"
#include "debuggerrunner.h"
namespace Debugger {
namespace Internal {
......@@ -62,27 +63,30 @@ static inline OutputKind outputKind(ULONG mask)
return DebuggerOutput;
}
CdbDebugOutput::CdbDebugOutput()
CdbDebugOutput::CdbDebugOutput(CdbDebugEngine *engine)
: m_engine(engine)
{
}
void CdbDebugOutput::output(ULONG mask, const QString &msg)
{
DebuggerRunControl *runControl = m_engine->runControl();
QTC_ASSER(runControl, return);
if (debugCDB > 1)
qDebug() << Q_FUNC_INFO << "\n " << msg;
switch (outputKind(mask)) {
case DebuggerOutput:
debuggerOutput(logChannel(mask), msg);
runControl->showDebuggerOutput(msg, logChannel(mask));
break;
case DebuggerPromptOutput:
emit debuggerInputPrompt(logChannel(mask), msg);
runControl->showDebuggerInput(msg, logChannel(mask));
break;
case DebuggeeOutput:
emit debuggeeOutput(msg, true);
runControl->showApplicationOutput(msg, true);
break;
case DebuggeePromptOutput:
emit debuggeeInputPrompt(msg, false);
runControl->showApplicationOutput(msg, false);
break;
}
}
......
......@@ -38,20 +38,16 @@ namespace Debugger {
namespace Internal {
// Standard CDB output handler
class CdbDebugOutput : public QObject, public CdbCore::DebugOutputBase
class CdbDebugOutput : public CdbCore::DebugOutputBase
{
Q_OBJECT
public:
CdbDebugOutput();
explicit CdbDebugOutput(CdbDebugEngine *engine);
protected:
virtual void output(ULONG mask, const QString &message);
signals:
void debuggerOutput(int channel, const QString &message);
void debuggerInputPrompt(int channel, const QString &message);
void debuggeeOutput(const QString &message, bool onStderr);
void debuggeeInputPrompt(const QString &message, bool onStderr);
private:
CdbDebugEngine *m_engine;
};
} // namespace Internal
......
......@@ -261,7 +261,9 @@ void DisassemblerViewAgent::setFrame(const StackFrame &frame, bool tryMixed)
if (it != d->cache.end()) {
QString msg = _("Use cache disassembler for '%1' in '%2'")
.arg(frame.function).arg(frame.file);
d->manager->showDebuggerOutput(msg);
QTC_ASSERT(d->manager->runControl(), /**/);
if (d->manager->runControl())
d->manager->runControl()->showDebuggerOutput(msg);
setContents(*it);
return;
}
......
......@@ -107,7 +107,7 @@
// use Q_FUNC_INFO?
# define STATE_DEBUG(s) \
do { QString msg; QTextStream ts(&msg); ts << s; \
showDebuggerOutput(LogDebug, msg); } while (0)
showDebuggerOutput(msg, LogDebug); } while (0)
#else
# define STATE_DEBUG(s)
#endif
......@@ -504,12 +504,6 @@ void DebuggerManager::init()
connect(localsView->header(), SIGNAL(sectionResized(int,int,int)),
this, SLOT(updateWatchersHeader(int,int,int)), Qt::QueuedConnection);
// Log
connect(this, SIGNAL(emitShowInput(int, QString)),
d->m_outputWindow, SLOT(showInput(int, QString)), Qt::QueuedConnection);
connect(this, SIGNAL(emitShowOutput(int, QString)),
d->m_outputWindow, SLOT(showOutput(int, QString)), Qt::QueuedConnection);
// Tooltip
qRegisterMetaType<WatchData>("WatchData");
qRegisterMetaType<StackCookie>("StackCookie");
......@@ -836,7 +830,7 @@ void DebuggerManager::clearStatusMessage()
void DebuggerManager::showStatusMessage(const QString &msg0, int timeout)
{
Q_UNUSED(timeout)
showDebuggerOutput(LogStatus, msg0);
showDebuggerOutput(msg0, LogStatus);
QString msg = msg0;
msg.replace(QLatin1Char('\n'), QString());
d->m_statusLabel->setText(msg);
......@@ -877,11 +871,6 @@ void DebuggerManager::notifyInferiorPidChanged(qint64 pid)
}
}
void DebuggerManager::showApplicationOutput(const QString &str, bool onStdErr)
{
emit applicationOutputAvailable(str, onStdErr);
}
void DebuggerManager::aboutToShutdown()
{
STATE_DEBUG(d->m_engine);
......@@ -1071,9 +1060,8 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
ProjectExplorer::ToolChain::ToolChainType(sp->toolChainType));
d->m_plugin->activateDebugMode();
showDebuggerOutput(LogStatus,
tr("Starting debugger for tool chain '%1'...").arg(toolChainName));
showDebuggerOutput(LogDebug, DebuggerSettings::instance()->dump());
showDebuggerOutput(tr("Starting debugger for tool chain '%1'...").arg(toolChainName), LogStatus);
showDebuggerOutput(DebuggerSettings::instance()->dump(), LogDebug);
QString errorMessage;
QString settingsIdHint;
......@@ -1583,31 +1571,12 @@ void DebuggerManager::modulesDockToggled(bool on)
reloadModules();
}
//////////////////////////////////////////////////////////////////////
//
// Output specific stuff
//
//////////////////////////////////////////////////////////////////////
void DebuggerManager::showDebuggerOutput(int channel, const QString &msg)
void DebuggerManager::showDebuggerOutput(const QString &msg, int channel)
{
if (d->m_outputWindow) {
emit emitShowOutput(channel, msg);
if (channel == LogError)
ensureLogVisible();
} else {
if (runControl())
runControl()->showDebuggerOutput(msg, channel);
else
qDebug() << "OUTPUT: " << channel << msg;
}
}
void DebuggerManager::showDebuggerInput(int channel, const QString &msg)
{
if (d->m_outputWindow)
emit emitShowInput(channel, msg);
else
qDebug() << "INPUT: " << channel << msg;
}
......@@ -1807,7 +1776,7 @@ void DebuggerManager::setState(DebuggerState state, bool forced)
if (!forced && !isAllowedTransition(d->m_state, state))
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
showDebuggerOutput(LogDebug, msg);
showDebuggerOutput(msg, LogDebug);
//resetLocation();
if (state == d->m_state)
......@@ -2034,6 +2003,12 @@ DebuggerRunControl *DebuggerManager::runControl() const
return const_cast<DebuggerRunControl *>(d->m_runControl);
}
DebuggerOutputWindow *DebuggerManager::debuggerOutputWindow() const
{
return d->m_outputWindow;
}
//////////////////////////////////////////////////////////////////////
//
// AbstractDebuggerEngine
......@@ -2055,6 +2030,7 @@ void IDebuggerEngine::setState(DebuggerState state, bool forced)
m_manager->setState(state, forced);
}
//////////////////////////////////////////////////////////////////////
//
// Testing
......
......@@ -235,18 +235,12 @@ public slots:
static const char *stateName(int s);
public slots: // FIXME
void showDebuggerOutput(const QString &msg)
{ showDebuggerOutput(LogDebug, msg); }
void ensureLogVisible();
void updateWatchersWindow();
void updateWatchersHeader(int section, int oldSize, int newSize);
void activateBreakpoint(int index);
//private slots: // FIXME
void showDebuggerOutput(int channel, const QString &msg);
void showDebuggerInput(int channel, const QString &msg);
void showApplicationOutput(const QString &data, bool onStdErr);
void reloadSourceFiles();
void sourceFilesDockToggled(bool on);
......@@ -271,6 +265,7 @@ public:
Internal::ThreadsHandler *threadsHandler() const;
Internal::WatchHandler *watchHandler() const;
Internal::SnapshotHandler *snapshotHandler() const;
Internal::DebuggerOutputWindow *debuggerOutputWindow() const;
private:
Internal::SourceFilesWindow *sourceFileWindow() const;
......@@ -316,12 +311,11 @@ signals:
void statusMessageRequested(const QString &msg, int timeout); // -1 for 'forever'
void applicationOutputAvailable(const QString &output, bool onStdErr);
void messageAvailable(const QString &output, bool isError);
void emitShowOutput(int channel, const QString &output);
void emitShowInput(int channel, const QString &input);
private:
void init();
// void runTest(const QString &fileName);
void showDebuggerOutput(const QString &msg, int channel);
Q_SLOT void createNewDock(QWidget *widget);
void aboutToShutdown();
......
......@@ -29,6 +29,7 @@
#include "debuggerrunner.h"
#include "debuggermanager.h"
#include "debuggeroutputwindow.h"
#include <projectexplorer/debugginghelper.h>
#include <projectexplorer/environment.h>
......@@ -48,6 +49,8 @@
#include <QtGui/QTextDocument>
using namespace ProjectExplorer;
using namespace Debugger::Internal;
namespace Debugger {
......@@ -147,9 +150,6 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
connect(m_manager, SIGNAL(debuggingFinished()),
this, SLOT(debuggingFinished()),
Qt::QueuedConnection);
connect(m_manager, SIGNAL(applicationOutputAvailable(QString, bool)),
this, SLOT(slotAddToOutputWindowInline(QString, bool)),
Qt::QueuedConnection);
connect(m_manager, SIGNAL(messageAvailable(QString, bool)),
this, SLOT(slotMessageAvailable(QString, bool)));
connect(m_manager, SIGNAL(inferiorPidChanged(qint64)),
......@@ -161,6 +161,7 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
if (m_startParameters.environment.empty())
m_startParameters.environment = ProjectExplorer::Environment().toStringList();
m_startParameters.useTerminal = false;
}
QString DebuggerRunControl::displayName() const
......@@ -183,21 +184,19 @@ void DebuggerRunControl::start()
QString errorMessage;
QString settingsCategory;
QString settingsPage;
if (m_manager->checkDebugConfiguration(m_startParameters.toolChainType, &errorMessage,
&settingsCategory, &settingsPage)) {
if (m_manager->checkDebugConfiguration(m_startParameters.toolChainType,
&errorMessage, &settingsCategory, &settingsPage)) {
m_manager->startNewDebugger(this);
emit started();
} else {
appendMessage(this, errorMessage, true);
emit finished();
Core::ICore::instance()->showWarningWithOptions(tr("Debugger"), errorMessage,
QString(),
settingsCategory, settingsPage);
Core::ICore::instance()->showWarningWithOptions(tr("Debugger"),
errorMessage, QString(), settingsCategory, settingsPage);
}
}
void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data,
bool onStdErr)
void DebuggerRunControl::showApplicationOutput(const QString &data, bool onStdErr)
{
emit addToOutputWindowInline(this, data, onStdErr);
}
......@@ -207,6 +206,20 @@ void DebuggerRunControl::slotMessageAvailable(const QString &data, bool isError)
emit appendMessage(this, data, isError);
}
void DebuggerRunControl::showDebuggerOutput(const QString &output, int channel)
{
DebuggerOutputWindow *ow = m_manager->debuggerOutputWindow();
QTC_ASSERT(ow, return);
ow->showOutput(channel, output);
}
void DebuggerRunControl::showDebuggerInput(const QString &input, int channel)
{
DebuggerOutputWindow *ow = m_manager->debuggerOutputWindow();
QTC_ASSERT(ow, return);
ow->showInput(channel, input);
}
void DebuggerRunControl::stop()
{
m_running = false;
......
......@@ -129,14 +129,20 @@ public:
signals:
void stopRequested();
public slots:
void showDebuggerOutput(const QString &msg)
{ showDebuggerOutput(msg, LogDebug); }
void showApplicationOutput(const QString &output, bool onStdErr);
void showDebuggerOutput(const QString &output, int channel);
void showDebuggerInput(const QString &input, int channel);
private slots:
void slotAddToOutputWindowInline(const QString &output, bool onStdErr);
void slotMessageAvailable(const QString &data, bool isError);
private:
void init();
DebuggerManager *m_manager;
DebuggerStartParameters m_startParameters;
DebuggerManager *m_manager;
bool m_running;
};
......
......@@ -107,7 +107,7 @@ protected:
{ m_engine->setState(state); }
const DebuggerStartParameters &startParameters() const
{ return m_engine->startParameters(); }
const DebuggerRunControl *runControl() const
DebuggerRunControl *runControl() const
{ return m_engine->runControl(); }
void debugMessage(const QString &msg) const
{ m_engine->debugMessage(msg); }
......
......@@ -160,8 +160,8 @@ void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChild
// Avoid endless loops created by faulty dumpers.
QByteArray processedName = QByteArray::number(dumpChildren) + '-' + data.iname;
if (m_processedNames.contains(processedName)) {
showDebuggerInput(LogStatus,
_("<Breaking endless loop for " + data.iname + '>'));
showDebuggerInput(
_("<Breaking endless loop for " + data.iname + '>'), LogStatus);
data.setAllUnneeded();
data.setValue(_("<unavailable>"));
data.setHasChildren(false);
......
......@@ -343,7 +343,7 @@ void GdbEngine::readDebugeeOutput(const QByteArray &data)
void GdbEngine::debugMessage(const QString &msg)
{
showDebuggerOutput(LogDebug, msg);
showDebuggerOutput(msg, LogDebug);
}
void GdbEngine::handleResponse(const QByteArray &buff)
......@@ -351,8 +351,8 @@ void GdbEngine::handleResponse(const QByteArray &buff)
static QTime lastTime;
if (theDebuggerBoolSetting(LogTimeStamps))
showDebuggerOutput(LogTime, currentTime());
showDebuggerOutput(LogOutput, QString::fromLocal8Bit(buff, buff.length()));
showDebuggerOutput(currentTime(), LogTime);
showDebuggerOutput(QString::fromLocal8Bit(buff, buff.length()), LogOutput);
#if 0
qDebug() // << "#### start response handling #### "
......@@ -824,7 +824,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
{
GdbCommand cmd = cmd0;
if (state() == DebuggerNotReady) {
showDebuggerInput(LogInput, _(cmd.command));
showDebuggerInput(_(cmd.command), LogInput);
debugMessage(_("GDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: " + cmd.command));
return;
}
......@@ -833,7 +833,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
cmd.postTime = QTime::currentTime();
m_cookieForToken[currentToken()] = cmd;
cmd.command = QByteArray::number(currentToken()) + cmd.command;
showDebuggerInput(LogInput, _(cmd.command));
showDebuggerInput(_(cmd.command), LogInput);
m_gdbAdapter->write(cmd.command + "\r\n");
......@@ -958,9 +958,10 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
GdbCommand cmd = m_cookieForToken.take(token);
if (theDebuggerBoolSetting(LogTimeStamps)) {
showDebuggerOutput(LogTime, _("Response time: %1: %2 s")
showDebuggerOutput(_("Response time: %1: %2 s")
.arg(_(cmd.command))
.arg(cmd.postTime.msecsTo(QTime::currentTime()) / 1000.));
.arg(cmd.postTime.msecsTo(QTime::currentTime()) / 1000.),
LogTime);
}
if (response->token < m_oldestAcceptableToken && (cmd.flags & Discardable)) {
......@@ -2049,9 +2050,9 @@ void GdbEngine::setTokenBarrier()
);
}
PENDING_DEBUG("\n--- token barrier ---\n");
showDebuggerInput(LogMisc, _("--- token barrier ---"));
showDebuggerInput(_("--- token barrier ---"), LogMisc);
if (theDebuggerBoolSetting(LogTimeStamps))
showDebuggerInput(LogMisc, currentTime());
showDebuggerInput(currentTime(), LogMisc);
m_oldestAcceptableToken = currentToken();
}
......@@ -3375,8 +3376,8 @@ void GdbEngine::updateWatchData(const WatchData &data)
//qDebug() << "PROCESSED NAMES: " << processedName << m_processedNames;
if (m_processedNames.contains(processedName)) {
WatchData data1 = data;
showDebuggerInput(LogStatus,
_("<Breaking endless loop for " + data.iname + '>'));
showDebuggerInput(_("<Breaking endless loop for " + data.iname + '>'),
LogStatus);
data1.setAllUnneeded();
data1.setValue(_("<unavailable>"));
data1.setHasChildren(false);
......@@ -3427,8 +3428,8 @@ void GdbEngine::rebuildWatchModel()
m_processedNames.clear();
PENDING_DEBUG("REBUILDING MODEL" << count);
if (theDebuggerBoolSetting(LogTimeStamps))
showDebuggerInput(LogMisc, currentTime());
showDebuggerInput(LogStatus, _("<Rebuild Watchmodel %1>").arg(count));
showDebuggerInput(currentTime(), LogMisc);
showDebuggerInput(_("<Rebuild Watchmodel %1>").arg(count), LogStatus);
showStatusMessage(tr("Finished retrieving data"), 400);
manager()->watchHandler()->endCycle();
showToolTip();
......@@ -3456,7 +3457,7 @@ void GdbEngine::sendWatchParameters(const QByteArray &params0)
const QByteArray inBufferCmd = arrayFillCommand("qDumpInBuffer", params);
params.replace('\0','!');
showDebuggerInput(LogMisc, QString::fromUtf8(params));
showDebuggerInput(QString::fromUtf8(params), LogMisc);
params.clear();
params.append('\0');
......@@ -4033,14 +4034,13 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QStr
// Check for existing values.
if (environment.contains(pythonPathVariable)) {
const QString oldPythonPath = environment.value(pythonPathVariable);
manager()->showDebuggerOutput(LogMisc,
_("Using existing python path: %1").arg(oldPythonPath));
showDebuggerOutput(_("Using existing python path: %1")
.arg(oldPythonPath), LogMisc);
} else {
const QString pythonPath =
QDir::toNativeSeparators(dir.absoluteFilePath(winPythonVersion));
environment.insert(pythonPathVariable, pythonPath);
manager()->showDebuggerOutput(LogMisc,
_("Python path: %1").arg(pythonPath));
showDebuggerOutput(_("Python path: %1").arg(pythonPath), LogMisc);
gdbProc()->setProcessEnvironment(environment);
}
foundPython = true;
......
......@@ -142,13 +142,13 @@ void RemoteGdbServerAdapter::uploadProcError(QProcess::ProcessError error)
void RemoteGdbServerAdapter::readUploadStandardOutput()
{
QByteArray ba = m_uploadProc.readAllStandardOutput();
m_engine->showDebuggerOutput(LogOutput, QString::fromLocal8Bit(ba, ba.length()));
runControl()->showDebuggerOutput(QString::fromLocal8Bit(ba, ba.length()), LogOutput);
}
void RemoteGdbServerAdapter::readUploadStandardError()
{
QByteArray ba = m_uploadProc.readAllStandardError();
m_engine->showDebuggerOutput(LogError, QString::fromLocal8Bit(ba, ba.length()));
runControl()->showDebuggerOutput(QString::fromLocal8Bit(ba, ba.length()), LogError);
}
void RemoteGdbServerAdapter::startInferior()
......
......@@ -86,7 +86,8 @@ QString RemotePlainGdbAdapter::fromLocalEncoding(const QByteArray &b) const
void RemotePlainGdbAdapter::handleApplicationOutput(const QByteArray &output)
{
m_engine->manager()->showApplicationOutput(output, false);
QTC_ASSERT(m_engine->runControl(), return);
m_engine->runControl()->showApplicationOutput(output, false);
}
} // namespace Internal
......
......@@ -1139,7 +1139,7 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result)
trk::Launcher::parseNotifyStopped(result.data, &pid, &tid, &addr, &reason);
const QString msg = trk::Launcher::msgStopped(pid, tid, addr, reason);
logMessage(prefix + msg);
m_engine->manager()->showDebuggerOutput(LogMisc, msg);
runControl()->showDebuggerOutput(msg, LogMisc);
sendTrkAck(result.token);
if (addr) {
// Todo: Do not send off GdbMessages if a synced gdb
......
......@@ -30,6 +30,8 @@
#include "idebuggerengine.h"
#include "debuggermanager.h"
#include <utils/qtcassert.h>
namespace Debugger {
namespace Internal {
......@@ -56,14 +58,16 @@ bool IDebuggerEngine::checkConfiguration(int toolChain,
return true;
}
void IDebuggerEngine::showDebuggerInput(int channel, const QString &msg)
void IDebuggerEngine::showDebuggerInput(const QString &msg, int channel) const
{
m_manager->showDebuggerInput(channel, msg);
QTC_ASSERT(runControl(), return);
runControl()->showDebuggerInput(msg, channel);
}
void IDebuggerEngine::showDebuggerOutput(int channel, const QString &msg)
void IDebuggerEngine::showDebuggerOutput(const QString &msg, int channel) const
{
m_manager->showDebuggerOutput(channel, msg);
QTC_ASSERT(runControl(), return);
runControl()->showDebuggerOutput(msg, channel);
}
} // namespace Internal
......
......@@ -133,8 +133,8 @@ public:
virtual QString qtNamespace() const { return QString(); }
// Convenience
void showDebuggerInput(int channel, const QString &msg);
void showDebuggerOutput(int channel, const QString &msg);
void showDebuggerInput(const QString &msg, int channel = LogDebug) const;
void showDebuggerOutput(const QString &msg, int channel = LogDebug) const;
protected:
void showStatusMessage(const QString &msg, int timeout = -1);
......
......@@ -94,7 +94,7 @@ void PdbEngine::executeDebuggerCommand(const QString &command)
{
XSDEBUG("PdbEngine::executeDebuggerCommand:" << command);
if (state() == DebuggerNotReady) {
debugMessage(_("PDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command);
showDebuggerOutput(_("PDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command);
return;