Commit 9f7e9dc0 authored by hjk's avatar hjk

debugger: refactoring of output channeling

parent 254a51bf
......@@ -33,6 +33,8 @@
#include "cdbcom.h"
#include "debuggerrunner.h"
#include <utils/qtcassert.h>
namespace Debugger {
namespace Internal {
......@@ -47,20 +49,16 @@ static int logChannel(ULONG mask)
return LogWarning;
if (mask & (DEBUG_OUTPUT_ERROR))
return LogError;
return LogMisc;
}
enum OutputKind { DebuggerOutput, DebuggerPromptOutput, DebuggeeOutput, DebuggeePromptOutput };
static inline OutputKind outputKind(ULONG mask)
{
if (mask & DEBUG_OUTPUT_DEBUGGEE)
return DebuggeeOutput;
//return DebuggeeOutput;
return AppOut;
if (mask & DEBUG_OUTPUT_DEBUGGEE_PROMPT)
return DebuggeePromptOutput;
//return DebuggeePromptOutput;
return AppErr;
if (mask & DEBUG_OUTPUT_PROMPT)
return DebuggerPromptOutput;
return DebuggerOutput;
//return DebuggerPromptOutput;
return AppErr;
return LogMisc;
}
CdbDebugOutput::CdbDebugOutput(CdbDebugEngine *engine)
......@@ -71,24 +69,10 @@ CdbDebugOutput::CdbDebugOutput(CdbDebugEngine *engine)
void CdbDebugOutput::output(ULONG mask, const QString &msg)
{
DebuggerRunControl *runControl = m_engine->runControl();
QTC_ASSER(runControl, return);
QTC_ASSERT(runControl, return);
if (debugCDB > 1)
qDebug() << Q_FUNC_INFO << "\n " << msg;
switch (outputKind(mask)) {
case DebuggerOutput:
runControl->showDebuggerOutput(msg, logChannel(mask));
break;
case DebuggerPromptOutput:
runControl->showDebuggerInput(msg, logChannel(mask));
break;
case DebuggeeOutput:
runControl->showApplicationOutput(msg, true);
break;
case DebuggeePromptOutput:
runControl->showApplicationOutput(msg, false);
break;
}
runControl->showMessage(msg, logChannel(mask));
}
} // namespace Internal
......
......@@ -37,6 +37,8 @@
namespace Debugger {
namespace Internal {
class CdbDebugEngine;
// Standard CDB output handler
class CdbDebugOutput : public CdbCore::DebugOutputBase
{
......
......@@ -263,7 +263,7 @@ void DisassemblerViewAgent::setFrame(const StackFrame &frame, bool tryMixed)
.arg(frame.function).arg(frame.file);
QTC_ASSERT(d->manager->runControl(), /**/);
if (d->manager->runControl())
d->manager->runControl()->showDebuggerOutput(msg);
d->manager->runControl()->showMessage(msg);
setContents(*it);
return;
}
......
......@@ -139,13 +139,17 @@ enum DebuggerCapabilities
enum LogChannel
{
LogInput, // Used for user input
LogMiscInput, // Used for misc stuff in the input pane
LogOutput,
LogWarning,
LogError,
LogStatus, // Used for status changed messages
LogTime, // Used for time stamp messages
LogDebug,
LogMisc
LogMisc,
AppOutput,
AppError,
StatusBar // LogStatus and also put to the status bar
};
} // namespace Debugger
......
......@@ -107,7 +107,7 @@
// use Q_FUNC_INFO?
# define STATE_DEBUG(s) \
do { QString msg; QTextStream ts(&msg); ts << s; \
showDebuggerOutput(msg, LogDebug); } while (0)
showMessage(msg, LogDebug); } while (0)
#else
# define STATE_DEBUG(s)
#endif
......@@ -830,7 +830,7 @@ void DebuggerManager::clearStatusMessage()
void DebuggerManager::showStatusMessage(const QString &msg0, int timeout)
{
Q_UNUSED(timeout)
showDebuggerOutput(msg0, LogStatus);
showMessage(msg0, LogStatus);
QString msg = msg0;
msg.replace(QLatin1Char('\n'), QString());
d->m_statusLabel->setText(msg);
......@@ -1060,8 +1060,9 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
ProjectExplorer::ToolChain::ToolChainType(sp->toolChainType));
d->m_plugin->activateDebugMode();
showDebuggerOutput(tr("Starting debugger for tool chain '%1'...").arg(toolChainName), LogStatus);
showDebuggerOutput(DebuggerSettings::instance()->dump(), LogDebug);
showMessage(tr("Starting debugger for tool chain '%1'...").arg(toolChainName),
LogStatus);
showMessage(DebuggerSettings::instance()->dump(), LogDebug);
QString errorMessage;
QString settingsIdHint;
......@@ -1571,10 +1572,10 @@ void DebuggerManager::modulesDockToggled(bool on)
reloadModules();
}
void DebuggerManager::showDebuggerOutput(const QString &msg, int channel)
void DebuggerManager::showMessage(const QString &msg, int channel)
{
if (runControl())
runControl()->showDebuggerOutput(msg, channel);
runControl()->showMessage(msg, channel);
else
qDebug() << "OUTPUT: " << channel << msg;
}
......@@ -1776,7 +1777,7 @@ void DebuggerManager::setState(DebuggerState state, bool forced)
if (!forced && !isAllowedTransition(d->m_state, state))
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
showDebuggerOutput(msg, LogDebug);
showMessage(msg, LogDebug);
//resetLocation();
if (state == d->m_state)
......@@ -2015,10 +2016,12 @@ DebuggerOutputWindow *DebuggerManager::debuggerOutputWindow() const
//
//////////////////////////////////////////////////////////////////////
/*
void IDebuggerEngine::showStatusMessage(const QString &msg, int timeout)
{
m_manager->showStatusMessage(msg, timeout);
}
*/
DebuggerState IDebuggerEngine::state() const
{
......
......@@ -315,7 +315,7 @@ signals:
private:
void init();
// void runTest(const QString &fileName);
void showDebuggerOutput(const QString &msg, int channel);
void showMessage(const QString &msg, int channel);
Q_SLOT void createNewDock(QWidget *widget);
void aboutToShutdown();
......
......@@ -196,9 +196,34 @@ void DebuggerRunControl::start()
}
}
void DebuggerRunControl::showApplicationOutput(const QString &data, bool onStdErr)
void DebuggerRunControl::showMessage(const QString &msg, int channel,
int timeout)
{
emit addToOutputWindowInline(this, data, onStdErr);
DebuggerOutputWindow *ow = m_manager->debuggerOutputWindow();
QTC_ASSERT(ow, return);
switch (channel) {
case StatusBar:
m_manager->showStatusMessage(msg, timeout);
ow->showOutput(LogStatus, msg);
break;
case AppOutput:
emit addToOutputWindowInline(this, msg, false);
break;
case AppError:
emit addToOutputWindowInline(this, msg, true);
break;
case LogMiscInput:
ow->showInput(LogMisc, msg);
ow->showOutput(LogMisc, msg);
break;
case LogInput:
ow->showInput(channel, msg);
ow->showOutput(channel, msg);
break;
default:
ow->showOutput(channel, msg);
break;
}
}
void DebuggerRunControl::slotMessageAvailable(const QString &data, bool isError)
......@@ -206,19 +231,6 @@ 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()
{
......
......@@ -130,11 +130,7 @@ 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);
void showMessage(const QString &output, int channel = LogDebug, int timeout = -1);
private slots:
void slotMessageAvailable(const QString &data, bool isError);
......
......@@ -109,10 +109,8 @@ protected:
{ return m_engine->startParameters(); }
DebuggerRunControl *runControl() const
{ return m_engine->runControl(); }
void debugMessage(const QString &msg) const
{ m_engine->debugMessage(msg); }
void showStatusMessage(const QString &msg) const
{ m_engine->showStatusMessage(msg); }
void showMessage(const QString &msg, int channel = LogDebug, int timeout = 1)
{ runControl()->showMessage(msg, channel, timeout); }
void showMessageBox(int icon, const QString &title, const QString &text) const
{ m_engine->showMessageBox(icon, title, text); }
......
......@@ -91,8 +91,8 @@ void AbstractPlainGdbAdapter::handleExecRun(const GdbResponse &response)
{
if (response.resultClass == GdbResultRunning) {
QTC_ASSERT(state() == InferiorRunning, qDebug() << state());
debugMessage(_("INFERIOR STARTED"));
showStatusMessage(msgInferiorStarted());
showMessage(_("INFERIOR STARTED"));
showMessage(msgInferiorStarted(), StatusBar);
// FIXME: That's the wrong place for it.
if (theDebuggerBoolSetting(EnableReverseDebugging))
m_engine->postCommand("target record");
......
......@@ -58,7 +58,7 @@ void AttachGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
showMessage(_("TRYING TO START ADAPTER"));
if (!m_engine->startGdb())
return;
......@@ -80,8 +80,8 @@ void AttachGdbAdapter::handleAttach(const GdbResponse &response)
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
if (response.resultClass == GdbResultDone) {
setState(InferiorStopped);
debugMessage(_("INFERIOR ATTACHED"));
showStatusMessage(msgAttachedToStoppedInferior());
showMessage(_("INFERIOR ATTACHED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
emit inferiorPrepared();
m_engine->updateAll();
} else {
......@@ -95,7 +95,7 @@ void AttachGdbAdapter::interruptInferior()
const qint64 pid = startParameters().attachPID;
QTC_ASSERT(pid > 0, return);
if (!interruptProcess(pid))
debugMessage(_("CANNOT INTERRUPT %1").arg(pid));
showMessage(_("CANNOT INTERRUPT %1").arg(pid));
}
} // namespace Internal
......
......@@ -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(
_("<Breaking endless loop for " + data.iname + '>'), LogStatus);
showMessage(
_("<Breaking endless loop for " + data.iname + '>'), LogMiscInput);
data.setAllUnneeded();
data.setValue(_("<unavailable>"));
data.setHasChildren(false);
......@@ -395,7 +395,7 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
// Remove traces of the question, too.
if (m_cookieForToken.contains(response.token - 1)) {
m_cookieForToken.remove(response.token - 1);
debugMessage(_("DETECTING LOST COMMAND %1").arg(response.token - 1));
showMessage(_("DETECTING LOST COMMAND %1").arg(response.token - 1));
--m_pendingWatchRequests;
data.setError(WatchData::msgNotInScope());
insertData(data);
......@@ -591,12 +591,12 @@ void GdbEngine::setDebugDebuggingHelpersClassic(const QVariant &on)
{
PRECONDITION;
if (on.toBool()) {
debugMessage(_("SWITCHING ON DUMPER DEBUGGING"));
showMessage(_("SWITCHING ON DUMPER DEBUGGING"));
postCommand("set unwindonsignal off");
m_manager->breakByFunction(_("qDumpObjectData440"));
//updateLocals();
} else {
debugMessage(_("SWITCHING OFF DUMPER DEBUGGING"));
showMessage(_("SWITCHING OFF DUMPER DEBUGGING"));
postCommand("set unwindonsignal on");
}
}
......@@ -641,7 +641,7 @@ void GdbEngine::handleStackListArgumentsClassic(const GdbResponse &response)
} else {
// Seems to occur on "RedHat 4 based Linux" gdb 7.0.1:
// ^error,msg="Cannot access memory at address 0x0"
debugMessage(_("UNEXPECTED RESPONSE: ") + response.toString());
showMessage(_("UNEXPECTED RESPONSE: ") + response.toString());
}
}
......@@ -698,7 +698,7 @@ bool GdbEngine::checkDebuggingHelpersClassic()
const QStringList &locations = manager()->qtDumperLibraryLocations();
const QString loc = locations.join(QLatin1String(", "));
const QString msg = tr("The debugging helper library was not found at %1.").arg(loc);
debugMessage(msg);
showMessage(msg);
manager()->showQtDumperLibraryWarning(msg);
return false;
}
......@@ -757,11 +757,11 @@ void GdbEngine::handleDebuggingHelperVersionCheckClassic(const GdbResponse &resp
"application (%2).\nThis might yield incorrect results.")
.arg(dumperQtVersion).arg(debuggeeQtVersion));
} else {
debugMessage(_("DUMPER VERSION CHECK SUCCESSFUL: ")
showMessage(_("DUMPER VERSION CHECK SUCCESSFUL: ")
+ dumperQtVersion);
}
} else {
debugMessage("DUMPER VERSION CHECK NOT COMPLETED");
showMessage("DUMPER VERSION CHECK NOT COMPLETED");
}
}
......
......@@ -61,7 +61,7 @@ void CoreGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
showMessage(_("TRYING TO START ADAPTER"));
if (!m_engine->startGdb())
return;
......@@ -106,7 +106,7 @@ void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
if (response.resultClass == GdbResultDone) {
showStatusMessage(tr("Symbols found."));
showMessage(tr("Symbols found."), StatusBar);
} else {
QString msg = tr("Loading symbols from \"%1\" failed:\n").arg(m_executable)
+ QString::fromLocal8Bit(response.data.findChild("msg").data());
......@@ -144,7 +144,7 @@ void CoreGdbAdapter::handleTargetCore(const GdbResponse &response)
.absoluteFilePath(m_executable);
if (QFile::exists(m_executable)) {
// Finish extra round ...
showStatusMessage(tr("Attached to core temporarily."));
showMessage(tr("Attached to core temporarily."), StatusBar);
m_engine->postCommand("detach");
// ... and retry.
loadExeAndSyms();
......@@ -156,7 +156,7 @@ void CoreGdbAdapter::handleTargetCore(const GdbResponse &response)
tr("Unable to determine executable from core file."));
}
#endif
showStatusMessage(tr("Attached to core."));
showMessage(tr("Attached to core."), StatusBar);
setState(InferiorUnrunnable);
m_engine->updateAll();
} else {
......
This diff is collapsed.
......@@ -527,7 +527,6 @@ private: ////////// Convenience Functions //////////
QString errorMessage(QProcess::ProcessError error);
QMessageBox *showMessageBox(int icon, const QString &title, const QString &text,
int buttons = 0);
void debugMessage(const QString &msg);
QMainWindow *mainWindow() const;
AbstractGdbProcess *gdbProc() const;
......
......@@ -70,7 +70,7 @@ void LocalPlainGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
showMessage(_("TRYING TO START ADAPTER"));
QStringList gdbArgs;
......@@ -125,17 +125,17 @@ void LocalPlainGdbAdapter::interruptInferior()
{
const qint64 attachedPID = m_engine->inferiorPid();
if (attachedPID <= 0) {
debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"));
showMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"));
return;
}
if (!interruptProcess(attachedPID))
debugMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
showMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
}
void LocalPlainGdbAdapter::shutdown()
{
debugMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
showMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
m_outputCollector.shutdown();
}
......
......@@ -120,7 +120,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
//qDebug() << "SECOND CHUNK: " << out;
int pos = out.indexOf("data=");
if (pos != 0) {
debugMessage(_("DISCARDING JUNK AT BEGIN OF RESPONSE: "
showMessage(_("DISCARDING JUNK AT BEGIN OF RESPONSE: "
+ out.left(pos)));
out = out.mid(pos);
}
......@@ -186,7 +186,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
rebuildWatchModel();
}
} else {
debugMessage(_("DUMPER FAILED: " + response.toString()));
showMessage(_("DUMPER FAILED: " + response.toString()));
}
}
......
......@@ -86,13 +86,13 @@ void RemoteGdbServerAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
showMessage(_("TRYING TO START ADAPTER"));
// FIXME: make asynchroneous
// Start the remote server
if (startParameters().serverStartScript.isEmpty()) {
m_engine->showStatusMessage(_("No server start script given. "
"Assuming server runs already."));
showMessage(_("No server start script given. "
"Assuming server runs already."), StatusBar);
} else {
m_uploadProc.start(_("/bin/sh ") + startParameters().serverStartScript);
m_uploadProc.waitForStarted();
......@@ -135,20 +135,24 @@ void RemoteGdbServerAdapter::uploadProcError(QProcess::ProcessError error)
"This is the default return value of error().");
}
m_engine->showStatusMessage(msg);
showMessage(msg, StatusBar);
showMessageBox(QMessageBox::Critical, tr("Error"), msg);
}
void RemoteGdbServerAdapter::readUploadStandardOutput()
{
QByteArray ba = m_uploadProc.readAllStandardOutput();
runControl()->showDebuggerOutput(QString::fromLocal8Bit(ba, ba.length()), LogOutput);
const QByteArray ba = m_uploadProc.readAllStandardOutput();
const QString msg = QString::fromLocal8Bit(ba, ba.length());
showMessage(msg, LogOutput);
showMessage(msg, AppOutput);
}
void RemoteGdbServerAdapter::readUploadStandardError()
{
QByteArray ba = m_uploadProc.readAllStandardError();
runControl()->showDebuggerOutput(QString::fromLocal8Bit(ba, ba.length()), LogError);
const QByteArray ba = m_uploadProc.readAllStandardError();
const QString msg = QString::fromLocal8Bit(ba, ba.length());
showMessage(msg, LogOutput);
showMessage(msg, AppError);
}
void RemoteGdbServerAdapter::startInferior()
......@@ -209,8 +213,8 @@ void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
if (record.resultClass == GdbResultDone) {
setState(InferiorStopped);
// gdb server will stop the remote application itself.
debugMessage(_("INFERIOR STARTED"));
showStatusMessage(msgAttachedToStoppedInferior());
showMessage(_("INFERIOR STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
emit inferiorPrepared();
} else {
// 16^error,msg="hd:5555: Connection timed out."
......
......@@ -48,7 +48,7 @@ void RemotePlainGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
setState(AdapterStarting);
debugMessage(QLatin1String("TRYING TO START ADAPTER"));
showMessage(QLatin1String("TRYING TO START ADAPTER"));
if (!startParameters().workingDirectory.isEmpty())
m_gdbProc.setWorkingDirectory(startParameters().workingDirectory);
......@@ -86,8 +86,8 @@ QString RemotePlainGdbAdapter::fromLocalEncoding(const QByteArray &b) const
void RemotePlainGdbAdapter::handleApplicationOutput(const QByteArray &output)
{
QTC_ASSERT(m_engine->runControl(), return);
m_engine->runControl()->showApplicationOutput(output, false);
// FIXME: Remote encoding?
showMessage(QString::fromLatin1(output), AppOutput);
}
} // namespace Internal
......
......@@ -83,7 +83,7 @@ void TermGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
showMessage(_("TRYING TO START ADAPTER"));
// Currently, adapters are not re-used
// // We leave the console open, so recycle it now.
......@@ -130,7 +130,7 @@ void TermGdbAdapter::handleStubAttached(const GdbResponse &response)
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
if (response.resultClass == GdbResultDone) {
setState(InferiorStopped);
debugMessage(_("INFERIOR ATTACHED"));
showMessage(_("INFERIOR ATTACHED"));
emit inferiorPrepared();
#ifdef Q_OS_LINUX
m_engine->postCommand("-stack-list-frames 0 0", CB(handleEntryPoint));
......@@ -162,7 +162,7 @@ void TermGdbAdapter::interruptInferior()
const qint64 attachedPID = m_engine->inferiorPid();
QTC_ASSERT(attachedPID > 0, return);
if (!interruptProcess(attachedPID))
debugMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
showMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
}
void TermGdbAdapter::stubMessage(const QString &msg, bool)
......@@ -172,7 +172,7 @@ void TermGdbAdapter::stubMessage(const QString &msg, bool)
void TermGdbAdapter::stubExited()
{
debugMessage(_("STUB EXITED"));
showMessage(_("STUB EXITED"));
if (state() != AdapterStarting // From previous instance
&& state() != EngineShuttingDown && state() != DebuggerNotReady)
emit adapterCrashed(QString());
......
......@@ -379,7 +379,7 @@ QByteArray TrkGdbAdapter::trkStepRangeMessage()
if (from <= pc && pc <= to) {
//to = qMax(to - 4, from);
//to = qMax(to - 4, from);
debugMessage("STEP IN " + hexxNumber(from) + " " + hexxNumber(to)
showMessage("STEP IN " + hexxNumber(from) + " " + hexxNumber(to)
+ " INSTEAD OF " + hexxNumber(pc));
} else {
from = pc;
......@@ -434,7 +434,7 @@ void TrkGdbAdapter::slotEmitDelayedInferiorStartFailed()
void TrkGdbAdapter::logMessage(const QString &msg)
{
if (m_verbose)
debugMessage("TRK LOG: " + msg);
showMessage("TRK LOG: " + msg);
}