2010-06-16 11:08:54 +02:00
|
|
|
/**************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
|
|
|
|
** Copyright (c) 2010 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 "debuggerengine.h"
|
|
|
|
|
|
|
|
|
|
#include "debuggeractions.h"
|
2010-11-10 11:39:01 +01:00
|
|
|
#include "debuggercore.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "debuggerplugin.h"
|
2010-11-10 11:39:01 +01:00
|
|
|
#include "debuggerrunner.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "debuggerstringutils.h"
|
2010-09-15 19:02:12 +02:00
|
|
|
#include "debuggertooltip.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-12-08 12:43:11 +01:00
|
|
|
#include "memoryagent.h"
|
|
|
|
|
#include "disassembleragent.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "breakhandler.h"
|
|
|
|
|
#include "moduleshandler.h"
|
|
|
|
|
#include "registerhandler.h"
|
|
|
|
|
#include "snapshothandler.h"
|
|
|
|
|
#include "sourcefileshandler.h"
|
|
|
|
|
#include "stackhandler.h"
|
|
|
|
|
#include "threadshandler.h"
|
|
|
|
|
#include "watchhandler.h"
|
|
|
|
|
|
2010-06-22 17:18:29 +02:00
|
|
|
#include <coreplugin/icore.h>
|
2010-11-02 16:14:00 +01:00
|
|
|
#include <coreplugin/ifile.h>
|
2010-07-21 11:02:51 +02:00
|
|
|
#include <coreplugin/progressmanager/progressmanager.h>
|
|
|
|
|
#include <coreplugin/progressmanager/futureprogress.h>
|
2010-06-22 17:18:29 +02:00
|
|
|
|
2010-12-10 09:37:31 +01:00
|
|
|
#include <projectexplorer/toolchain.h>
|
2010-11-01 14:14:17 +01:00
|
|
|
#include <projectexplorer/toolchaintype.h>
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-06-22 17:18:29 +02:00
|
|
|
#include <texteditor/itexteditor.h>
|
|
|
|
|
|
2010-09-23 10:35:23 +02:00
|
|
|
#include <utils/environment.h>
|
2010-06-16 11:08:54 +02:00
|
|
|
#include <utils/savedaction.h>
|
|
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
|
|
|
|
#include <QtCore/QDebug>
|
|
|
|
|
#include <QtCore/QTimer>
|
2010-07-21 11:02:51 +02:00
|
|
|
#include <QtCore/QFutureInterface>
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-11-17 17:16:34 +01:00
|
|
|
#include <QtGui/QMessageBox>
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-06-22 17:18:29 +02:00
|
|
|
using namespace Core;
|
2010-06-16 11:08:54 +02:00
|
|
|
using namespace Debugger::Internal;
|
2010-06-22 17:18:29 +02:00
|
|
|
using namespace ProjectExplorer;
|
|
|
|
|
using namespace TextEditor;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
//#define DEBUG_STATE 1
|
|
|
|
|
#if DEBUG_STATE
|
|
|
|
|
# define SDEBUG(s) qDebug() << s
|
|
|
|
|
#else
|
|
|
|
|
# define SDEBUG(s)
|
|
|
|
|
#endif
|
|
|
|
|
# define XSDEBUG(s) qDebug() << s
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-11-08 15:41:44 +01:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebuggerStartParameters
|
|
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2010-11-10 11:39:01 +01:00
|
|
|
namespace Debugger {
|
|
|
|
|
|
2010-09-07 14:34:38 +02:00
|
|
|
DebuggerStartParameters::DebuggerStartParameters() :
|
2010-09-07 14:19:44 +02:00
|
|
|
isSnapshot(false),
|
2010-09-07 14:34:38 +02:00
|
|
|
attachPID(-1),
|
|
|
|
|
useTerminal(false),
|
2010-08-24 17:17:54 +02:00
|
|
|
breakAtMain(false),
|
|
|
|
|
qmlServerAddress("127.0.0.1"),
|
2010-09-02 17:17:35 +02:00
|
|
|
qmlServerPort(0),
|
2010-09-06 11:33:07 +02:00
|
|
|
useServerStartScript(false),
|
2010-09-27 17:28:38 +02:00
|
|
|
connParams(SshConnectionParameters::NoProxy),
|
2010-11-01 14:14:17 +01:00
|
|
|
toolChainType(ToolChain_UNKNOWN),
|
2010-08-24 17:17:54 +02:00
|
|
|
startMode(NoStartMode),
|
|
|
|
|
executableUid(0)
|
2010-06-16 11:08:54 +02:00
|
|
|
{}
|
|
|
|
|
|
2010-12-10 09:37:31 +01:00
|
|
|
QString DebuggerStartParameters::toolChainName() const
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2010-12-10 09:37:31 +01:00
|
|
|
return ToolChain::toolChainName(ProjectExplorer::ToolChainType(toolChainType));
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDebug operator<<(QDebug d, DebuggerState state)
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
//return d << DebuggerEngine::stateName(state) << '(' << int(state) << ')';
|
|
|
|
|
return d << DebuggerEngine::stateName(state);
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QDebug operator<<(QDebug str, const DebuggerStartParameters &sp)
|
|
|
|
|
{
|
|
|
|
|
QDebug nospace = str.nospace();
|
|
|
|
|
nospace << "executable=" << sp.executable
|
|
|
|
|
<< " coreFile=" << sp.coreFile
|
2010-10-19 11:14:03 +02:00
|
|
|
<< " processArgs=" << sp.processArgs
|
2010-06-16 11:08:54 +02:00
|
|
|
<< " environment=<" << sp.environment.size() << " variables>"
|
|
|
|
|
<< " workingDir=" << sp.workingDirectory
|
|
|
|
|
<< " attachPID=" << sp.attachPID
|
|
|
|
|
<< " useTerminal=" << sp.useTerminal
|
|
|
|
|
<< " remoteChannel=" << sp.remoteChannel
|
|
|
|
|
<< " remoteArchitecture=" << sp.remoteArchitecture
|
|
|
|
|
<< " symbolFileName=" << sp.symbolFileName
|
2010-09-06 11:33:07 +02:00
|
|
|
<< " useServerStartScript=" << sp.useServerStartScript
|
2010-06-16 11:08:54 +02:00
|
|
|
<< " serverStartScript=" << sp.serverStartScript
|
|
|
|
|
<< " toolchain=" << sp.toolChainType << '\n';
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *DebuggerEngine::stateName(int s)
|
|
|
|
|
{
|
|
|
|
|
# define SN(x) case x: return #x;
|
|
|
|
|
switch (s) {
|
|
|
|
|
SN(DebuggerNotReady)
|
2010-07-09 17:07:59 +02:00
|
|
|
SN(EngineSetupRequested)
|
2010-07-09 08:48:33 +02:00
|
|
|
SN(EngineSetupOk)
|
|
|
|
|
SN(EngineSetupFailed)
|
2010-07-09 17:07:59 +02:00
|
|
|
SN(EngineRunFailed)
|
|
|
|
|
SN(InferiorSetupRequested)
|
2010-07-08 18:10:50 +02:00
|
|
|
SN(InferiorSetupFailed)
|
2010-07-09 17:07:59 +02:00
|
|
|
SN(EngineRunRequested)
|
|
|
|
|
SN(InferiorRunRequested)
|
|
|
|
|
SN(InferiorRunOk)
|
|
|
|
|
SN(InferiorRunFailed)
|
2010-06-16 11:08:54 +02:00
|
|
|
SN(InferiorUnrunnable)
|
2010-07-09 17:07:59 +02:00
|
|
|
SN(InferiorStopRequested)
|
|
|
|
|
SN(InferiorStopOk)
|
2010-06-16 11:08:54 +02:00
|
|
|
SN(InferiorStopFailed)
|
2010-07-09 17:07:59 +02:00
|
|
|
SN(InferiorShutdownRequested)
|
|
|
|
|
SN(InferiorShutdownOk)
|
2010-06-16 11:08:54 +02:00
|
|
|
SN(InferiorShutdownFailed)
|
2010-07-09 17:07:59 +02:00
|
|
|
SN(EngineShutdownRequested)
|
|
|
|
|
SN(EngineShutdownOk)
|
|
|
|
|
SN(EngineShutdownFailed)
|
|
|
|
|
SN(DebuggerFinished)
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
return "<unknown>";
|
|
|
|
|
# undef SN
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-22 15:37:27 +02:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebuggerEnginePrivate
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2010-06-25 16:06:48 +02:00
|
|
|
class DebuggerEnginePrivate : public QObject
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2010-06-25 16:06:48 +02:00
|
|
|
Q_OBJECT
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
public:
|
|
|
|
|
DebuggerEnginePrivate(DebuggerEngine *engine, const DebuggerStartParameters &sp)
|
|
|
|
|
: m_engine(engine),
|
|
|
|
|
m_runControl(0),
|
|
|
|
|
m_startParameters(sp),
|
|
|
|
|
m_state(DebuggerNotReady),
|
2010-07-09 17:07:59 +02:00
|
|
|
m_lastGoodState(DebuggerNotReady),
|
2010-10-21 12:36:19 +02:00
|
|
|
m_targetState(DebuggerNotReady),
|
2010-11-05 19:38:40 +01:00
|
|
|
m_modulesHandler(),
|
2010-11-05 13:35:31 +01:00
|
|
|
m_registerHandler(),
|
2010-11-05 19:38:40 +01:00
|
|
|
m_sourceFilesHandler(),
|
|
|
|
|
m_stackHandler(),
|
2010-11-05 17:02:27 +01:00
|
|
|
m_threadsHandler(),
|
2010-06-16 11:08:54 +02:00
|
|
|
m_watchHandler(engine),
|
2010-08-18 13:54:12 +02:00
|
|
|
m_disassemblerViewAgent(engine),
|
2010-10-27 14:25:36 +02:00
|
|
|
m_isSlaveEngine(false)
|
2010-07-21 14:06:42 +02:00
|
|
|
{}
|
2010-07-21 11:02:51 +02:00
|
|
|
|
|
|
|
|
~DebuggerEnginePrivate() {}
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-06-25 16:06:48 +02:00
|
|
|
public slots:
|
2010-07-08 18:10:50 +02:00
|
|
|
void doSetupInferior();
|
|
|
|
|
void doRunEngine();
|
2010-07-09 17:07:59 +02:00
|
|
|
void doShutdownEngine();
|
|
|
|
|
void doShutdownInferior();
|
2010-07-09 08:48:33 +02:00
|
|
|
void doInterruptInferior();
|
2010-07-09 17:07:59 +02:00
|
|
|
void doFinishDebugger();
|
2010-07-08 18:10:50 +02:00
|
|
|
|
2010-11-05 19:38:40 +01:00
|
|
|
void queueRunEngine()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->setState(EngineRunRequested);
|
|
|
|
|
m_engine->showMessage(_("QUEUE: RUN ENGINE"));
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(doRunEngine()));
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-05 19:38:40 +01:00
|
|
|
void queueShutdownEngine()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->setState(EngineShutdownRequested);
|
|
|
|
|
m_engine->showMessage(_("QUEUE: SHUTDOWN ENGINE"));
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(doShutdownEngine()));
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-05 19:38:40 +01:00
|
|
|
void queueShutdownInferior()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->setState(InferiorShutdownRequested);
|
|
|
|
|
m_engine->showMessage(_("QUEUE: SHUTDOWN INFERIOR"));
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(doShutdownInferior()));
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-05 19:38:40 +01:00
|
|
|
void queueFinishDebugger()
|
|
|
|
|
{
|
2010-07-20 18:54:06 +02:00
|
|
|
QTC_ASSERT(state() == EngineShutdownOk
|
|
|
|
|
|| state() == EngineShutdownFailed, qDebug() << state());
|
|
|
|
|
m_engine->setState(DebuggerFinished);
|
|
|
|
|
m_engine->showMessage(_("QUEUE: FINISH DEBUGGER"));
|
2010-07-13 08:41:27 +02:00
|
|
|
QTimer::singleShot(0, this, SLOT(doFinishDebugger()));
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-05 19:38:40 +01:00
|
|
|
void raiseApplication()
|
|
|
|
|
{
|
2010-07-22 17:00:24 +02:00
|
|
|
QTC_ASSERT(m_runControl, return);
|
2010-07-20 10:07:42 +02:00
|
|
|
m_runControl->bringApplicationToForeground(m_inferiorPid);
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
public:
|
2010-07-09 17:07:59 +02:00
|
|
|
DebuggerState state() const { return m_state; }
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
DebuggerEngine *m_engine; // Not owned.
|
|
|
|
|
DebuggerRunControl *m_runControl; // Not owned.
|
|
|
|
|
|
|
|
|
|
DebuggerStartParameters m_startParameters;
|
2010-07-09 17:07:59 +02:00
|
|
|
|
|
|
|
|
// The current state.
|
2010-06-16 11:08:54 +02:00
|
|
|
DebuggerState m_state;
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
// The state we had before something unexpected happend.
|
|
|
|
|
DebuggerState m_lastGoodState;
|
|
|
|
|
|
|
|
|
|
// The state we are aiming for.
|
|
|
|
|
DebuggerState m_targetState;
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
qint64 m_inferiorPid;
|
|
|
|
|
|
|
|
|
|
ModulesHandler m_modulesHandler;
|
|
|
|
|
RegisterHandler m_registerHandler;
|
|
|
|
|
SourceFilesHandler m_sourceFilesHandler;
|
|
|
|
|
StackHandler m_stackHandler;
|
|
|
|
|
ThreadsHandler m_threadsHandler;
|
|
|
|
|
WatchHandler m_watchHandler;
|
|
|
|
|
DisassemblerViewAgent m_disassemblerViewAgent;
|
2010-07-21 11:02:51 +02:00
|
|
|
QFutureInterface<void> m_progress;
|
2010-08-18 13:54:12 +02:00
|
|
|
|
2010-10-27 14:25:36 +02:00
|
|
|
bool m_isSlaveEngine;
|
2010-06-16 11:08:54 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebuggerEngine
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
DebuggerEngine::DebuggerEngine(const DebuggerStartParameters &startParameters)
|
|
|
|
|
: d(new DebuggerEnginePrivate(this, startParameters))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DebuggerEngine::~DebuggerEngine()
|
|
|
|
|
{
|
2010-07-20 10:04:08 +02:00
|
|
|
disconnect();
|
|
|
|
|
delete d;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-06-22 15:37:27 +02:00
|
|
|
void DebuggerEngine::showStatusMessage(const QString &msg, int timeout) const
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2010-06-22 15:37:27 +02:00
|
|
|
showMessage(msg, StatusBar, timeout);
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
2010-06-22 15:37:27 +02:00
|
|
|
|
2010-09-15 19:02:12 +02:00
|
|
|
void DebuggerEngine::removeTooltip()
|
|
|
|
|
{
|
|
|
|
|
watchHandler()->removeTooltip();
|
|
|
|
|
hideDebuggerToolTip();
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
void DebuggerEngine::frameUp()
|
|
|
|
|
{
|
|
|
|
|
int currentIndex = stackHandler()->currentIndex();
|
|
|
|
|
activateFrame(qMin(currentIndex + 1, stackHandler()->stackSize() - 1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::frameDown()
|
|
|
|
|
{
|
|
|
|
|
int currentIndex = stackHandler()->currentIndex();
|
|
|
|
|
activateFrame(qMax(currentIndex - 1, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ModulesHandler *DebuggerEngine::modulesHandler() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_modulesHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegisterHandler *DebuggerEngine::registerHandler() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_registerHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StackHandler *DebuggerEngine::stackHandler() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_stackHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ThreadsHandler *DebuggerEngine::threadsHandler() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_threadsHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WatchHandler *DebuggerEngine::watchHandler() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_watchHandler;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-13 15:57:34 +02:00
|
|
|
//SnapshotHandler *DebuggerEngine::snapshotHandler() const
|
|
|
|
|
//{
|
|
|
|
|
// return &d->m_snapshotHandler;
|
|
|
|
|
//}
|
2010-06-16 11:08:54 +02:00
|
|
|
|
|
|
|
|
SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_sourceFilesHandler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::modulesModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_modulesHandler.model();
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("ModulesModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::registerModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_registerHandler.model();
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("RegisterModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::stackModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_stackHandler.model();
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("StackModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::threadsModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_threadsHandler.model();
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("ThreadsModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::localsModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_watchHandler.model(LocalsWatch);
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("LocalsModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::watchersModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_watchHandler.model(WatchersWatch);
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("WatchersModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::returnModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_watchHandler.model(ReturnWatch);
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("ReturnModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
|
|
|
|
|
{
|
2010-08-24 16:22:21 +02:00
|
|
|
QAbstractItemModel *model = d->m_sourceFilesHandler.model();
|
|
|
|
|
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
|
|
|
model->setObjectName(objectName() + QLatin1String("SourceFilesModel"));
|
|
|
|
|
return model;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::fetchMemory(MemoryViewAgent *, QObject *,
|
|
|
|
|
quint64 addr, quint64 length)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(addr);
|
|
|
|
|
Q_UNUSED(length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::setRegisterValue(int regnr, const QString &value)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(regnr);
|
|
|
|
|
Q_UNUSED(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) const
|
|
|
|
|
{
|
2010-07-14 17:54:19 +02:00
|
|
|
//if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper())
|
|
|
|
|
// qDebug() << qPrintable(msg) << "IN STATE" << state();
|
2010-11-10 11:39:01 +01:00
|
|
|
debuggerCore()->showMessage(msg, channel, timeout);
|
2010-08-10 14:50:29 +02:00
|
|
|
if (d->m_runControl) {
|
|
|
|
|
d->m_runControl->showMessage(msg, channel);
|
|
|
|
|
} else {
|
|
|
|
|
qWarning("Warning: %s (no active run control)", qPrintable(msg));
|
|
|
|
|
}
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
|
|
|
|
|
{
|
2010-11-04 18:11:09 +01:00
|
|
|
if (!isSlaveEngine()) {
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressRange(0, 1000);
|
2010-07-21 14:06:42 +02:00
|
|
|
Core::FutureProgress *fp = Core::ICore::instance()->progressManager()
|
|
|
|
|
->addTask(d->m_progress.future(),
|
|
|
|
|
tr("Launching"), _("Debugger.Launcher"));
|
2010-10-15 17:22:45 +02:00
|
|
|
fp->setKeepOnFinish(Core::FutureProgress::DontKeepOnFinish);
|
2010-07-21 14:06:42 +02:00
|
|
|
d->m_progress.reportStarted();
|
|
|
|
|
}
|
2010-07-09 08:48:33 +02:00
|
|
|
QTC_ASSERT(runControl, notifyEngineSetupFailed(); return);
|
|
|
|
|
QTC_ASSERT(!d->m_runControl, notifyEngineSetupFailed(); return);
|
2010-06-16 11:08:54 +02:00
|
|
|
|
|
|
|
|
d->m_runControl = runControl;
|
|
|
|
|
|
|
|
|
|
d->m_inferiorPid = d->m_startParameters.attachPID > 0
|
|
|
|
|
? d->m_startParameters.attachPID : 0;
|
|
|
|
|
|
2010-10-19 11:14:03 +02:00
|
|
|
if (!d->m_startParameters.environment.size())
|
|
|
|
|
d->m_startParameters.environment = Utils::Environment();
|
2010-06-16 11:08:54 +02:00
|
|
|
|
|
|
|
|
if (d->m_startParameters.breakAtMain)
|
|
|
|
|
breakByFunctionMain();
|
|
|
|
|
|
|
|
|
|
const unsigned engineCapabilities = debuggerCapabilities();
|
2010-11-10 16:33:11 +01:00
|
|
|
debuggerCore()->action(OperateByInstruction)
|
2010-06-16 11:08:54 +02:00
|
|
|
->setEnabled(engineCapabilities & DisassemblerCapability);
|
|
|
|
|
|
2010-07-20 18:31:35 +02:00
|
|
|
QTC_ASSERT(state() == DebuggerNotReady || state() == DebuggerFinished,
|
|
|
|
|
qDebug() << state());
|
2010-11-25 17:16:58 +01:00
|
|
|
d->m_lastGoodState = DebuggerNotReady;
|
|
|
|
|
d->m_targetState = DebuggerNotReady;
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(EngineSetupRequested);
|
2010-07-20 18:31:35 +02:00
|
|
|
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(200);
|
2010-07-08 18:10:50 +02:00
|
|
|
setupEngine();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::breakByFunctionMain()
|
|
|
|
|
{
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
// FIXME: wrong on non-Qt based binaries
|
|
|
|
|
emit breakByFunction("qMain");
|
|
|
|
|
#else
|
|
|
|
|
emit breakByFunction("main");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::breakByFunction(const QString &functionName)
|
|
|
|
|
{
|
2010-11-04 09:54:23 +01:00
|
|
|
breakHandler()->breakByFunction(functionName);
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::resetLocation()
|
|
|
|
|
{
|
|
|
|
|
d->m_disassemblerViewAgent.resetLocation();
|
2010-11-10 12:38:29 +01:00
|
|
|
debuggerCore()->removeLocationMark();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMarker)
|
|
|
|
|
{
|
2010-11-24 11:44:43 +01:00
|
|
|
debuggerCore()->gotoLocation(fileName, lineNumber, setMarker);
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::gotoLocation(const StackFrame &frame, bool setMarker)
|
|
|
|
|
{
|
2010-11-24 11:44:43 +01:00
|
|
|
if (debuggerCore()->boolSetting(OperateByInstruction) || !frame.isUsable())
|
|
|
|
|
d->m_disassemblerViewAgent.setFrame(frame, true, setMarker);
|
|
|
|
|
else
|
2010-11-10 11:39:01 +01:00
|
|
|
debuggerCore()->gotoLocation(frame.file, frame.line, setMarker);
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-20 18:31:35 +02:00
|
|
|
// Called from RunControl.
|
|
|
|
|
void DebuggerEngine::handleStartFailed()
|
|
|
|
|
{
|
2010-07-22 12:02:09 +02:00
|
|
|
showMessage("HANDLE RUNCONTROL START FAILED");
|
2010-07-20 18:31:35 +02:00
|
|
|
d->m_runControl = 0;
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(900);
|
2010-07-21 11:02:51 +02:00
|
|
|
d->m_progress.reportCanceled();
|
|
|
|
|
d->m_progress.reportFinished();
|
2010-07-20 18:31:35 +02:00
|
|
|
}
|
|
|
|
|
|
2010-06-22 15:14:44 +02:00
|
|
|
// Called from RunControl.
|
|
|
|
|
void DebuggerEngine::handleFinished()
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2010-07-22 12:02:09 +02:00
|
|
|
showMessage("HANDLE RUNCONTROL FINISHED");
|
2010-07-20 18:31:35 +02:00
|
|
|
d->m_runControl = 0;
|
2010-06-16 11:08:54 +02:00
|
|
|
modulesHandler()->removeAll();
|
|
|
|
|
stackHandler()->removeAll();
|
|
|
|
|
threadsHandler()->removeAll();
|
|
|
|
|
watchHandler()->cleanup();
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(1000);
|
2010-07-21 11:02:51 +02:00
|
|
|
d->m_progress.reportFinished();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DebuggerStartParameters &DebuggerEngine::startParameters() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_startParameters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DebuggerStartParameters &DebuggerEngine::startParameters()
|
|
|
|
|
{
|
|
|
|
|
return d->m_startParameters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Dumpers. "Custom dumpers" are a library compiled against the current
|
|
|
|
|
// Qt containing functions to evaluate values of Qt classes
|
|
|
|
|
// (such as QString, taking pointers to their addresses).
|
|
|
|
|
// The library must be loaded into the debuggee.
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::qtDumperLibraryEnabled() const
|
|
|
|
|
{
|
2010-11-10 16:33:11 +01:00
|
|
|
return debuggerCore()->boolSetting(UseDebuggingHelpers);
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList DebuggerEngine::qtDumperLibraryLocations() const
|
|
|
|
|
{
|
2010-11-10 16:33:11 +01:00
|
|
|
if (debuggerCore()->action(UseCustomDebuggingHelperLocation)->value().toBool()) {
|
2010-06-16 11:08:54 +02:00
|
|
|
const QString customLocation =
|
2010-11-10 16:33:11 +01:00
|
|
|
debuggerCore()->action(CustomDebuggingHelperLocation)->value().toString();
|
2010-06-16 11:08:54 +02:00
|
|
|
const QString location =
|
|
|
|
|
tr("%1 (explicitly set in the Debugger Options)").arg(customLocation);
|
|
|
|
|
return QStringList(location);
|
|
|
|
|
}
|
|
|
|
|
return d->m_startParameters.dumperLibraryLocations;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::showQtDumperLibraryWarning(const QString &details)
|
|
|
|
|
{
|
2010-11-10 11:39:01 +01:00
|
|
|
debuggerCore()->showQtDumperLibraryWarning(details);
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString DebuggerEngine::qtDumperLibraryName() const
|
|
|
|
|
{
|
2010-11-10 16:33:11 +01:00
|
|
|
if (debuggerCore()->action(UseCustomDebuggingHelperLocation)->value().toBool())
|
|
|
|
|
return debuggerCore()->action(CustomDebuggingHelperLocation)->value().toString();
|
2010-06-16 11:08:54 +02:00
|
|
|
return startParameters().dumperLibrary;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DebuggerState DebuggerEngine::state() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_state;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
DebuggerState DebuggerEngine::lastGoodState() const
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2010-07-09 17:07:59 +02:00
|
|
|
return d->m_lastGoodState;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DebuggerState DebuggerEngine::targetState() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_targetState;
|
|
|
|
|
}
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
static bool isAllowedTransition(DebuggerState from, DebuggerState to)
|
|
|
|
|
{
|
|
|
|
|
switch (from) {
|
2010-06-16 11:08:54 +02:00
|
|
|
case DebuggerNotReady:
|
2010-07-12 15:34:05 +02:00
|
|
|
return to == EngineSetupRequested;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
case EngineSetupRequested:
|
2010-07-09 08:48:33 +02:00
|
|
|
return to == EngineSetupOk || to == EngineSetupFailed;
|
|
|
|
|
case EngineSetupFailed:
|
2010-11-10 12:53:33 +01:00
|
|
|
// In is the engine's task to go into a proper "Shutdown"
|
|
|
|
|
// state before calling notifyEngineSetupFailed
|
|
|
|
|
return to == DebuggerFinished;
|
2010-07-09 08:48:33 +02:00
|
|
|
case EngineSetupOk:
|
2010-07-09 17:07:59 +02:00
|
|
|
return to == InferiorSetupRequested || to == EngineShutdownRequested;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
case InferiorSetupRequested:
|
|
|
|
|
return to == EngineRunRequested || to == InferiorSetupFailed;
|
2010-07-08 18:10:50 +02:00
|
|
|
case InferiorSetupFailed:
|
2010-07-09 17:07:59 +02:00
|
|
|
return to == EngineShutdownRequested;
|
|
|
|
|
|
|
|
|
|
case EngineRunRequested:
|
|
|
|
|
return to == InferiorRunRequested || to == InferiorStopRequested
|
|
|
|
|
|| to == InferiorUnrunnable || to == EngineRunFailed;
|
|
|
|
|
|
|
|
|
|
case EngineRunFailed:
|
2010-11-29 17:12:43 +01:00
|
|
|
return to == EngineShutdownRequested;
|
2010-07-09 17:07:59 +02:00
|
|
|
|
|
|
|
|
case InferiorRunRequested:
|
|
|
|
|
return to == InferiorRunOk || to == InferiorRunFailed;
|
|
|
|
|
case InferiorRunFailed:
|
|
|
|
|
return to == InferiorStopOk;
|
|
|
|
|
case InferiorRunOk:
|
|
|
|
|
return to == InferiorStopRequested || to == InferiorStopOk;
|
|
|
|
|
|
|
|
|
|
case InferiorStopRequested:
|
|
|
|
|
return to == InferiorStopOk || to == InferiorStopFailed;
|
|
|
|
|
case InferiorStopOk:
|
|
|
|
|
return to == InferiorRunRequested || to == InferiorShutdownRequested
|
|
|
|
|
|| to == InferiorStopOk;
|
2010-06-16 11:08:54 +02:00
|
|
|
case InferiorStopFailed:
|
2010-07-09 17:07:59 +02:00
|
|
|
return to == EngineShutdownRequested;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
|
|
|
|
case InferiorUnrunnable:
|
2010-07-09 17:07:59 +02:00
|
|
|
return to == InferiorShutdownRequested;
|
|
|
|
|
case InferiorShutdownRequested:
|
|
|
|
|
return to == InferiorShutdownOk || to == InferiorShutdownFailed;
|
|
|
|
|
case InferiorShutdownOk:
|
|
|
|
|
return to == EngineShutdownRequested;
|
2010-06-16 11:08:54 +02:00
|
|
|
case InferiorShutdownFailed:
|
2010-07-09 17:07:59 +02:00
|
|
|
return to == EngineShutdownRequested;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
case EngineShutdownRequested:
|
2010-09-07 13:22:12 +02:00
|
|
|
return to == EngineShutdownOk || to == EngineShutdownFailed;
|
2010-07-09 17:07:59 +02:00
|
|
|
case EngineShutdownOk:
|
|
|
|
|
return to == DebuggerFinished;
|
|
|
|
|
case EngineShutdownFailed:
|
|
|
|
|
return to == DebuggerFinished;
|
|
|
|
|
|
|
|
|
|
case DebuggerFinished:
|
2010-07-20 18:31:35 +02:00
|
|
|
return to == EngineSetupRequested; // Happens on restart.
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-11-16 13:52:21 +01:00
|
|
|
qDebug() << "UNKNOWN DEBUGGER STATE:" << from;
|
2010-06-16 11:08:54 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-09 08:48:33 +02:00
|
|
|
void DebuggerEngine::notifyEngineSetupFailed()
|
2010-07-08 18:10:50 +02:00
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE SETUP FAILED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
2010-07-09 08:48:33 +02:00
|
|
|
setState(EngineSetupFailed);
|
2010-07-22 17:00:24 +02:00
|
|
|
QTC_ASSERT(d->m_runControl, return);
|
|
|
|
|
d->m_runControl->startFailed();
|
2010-10-26 17:08:12 +02:00
|
|
|
setState(DebuggerFinished);
|
2010-07-08 18:10:50 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-09 08:48:33 +02:00
|
|
|
void DebuggerEngine::notifyEngineSetupOk()
|
2010-07-08 14:26:35 +02:00
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE SETUP OK"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
2010-07-09 08:48:33 +02:00
|
|
|
setState(EngineSetupOk);
|
2010-07-22 17:00:24 +02:00
|
|
|
QTC_ASSERT(d->m_runControl, return);
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("QUEUE: SETUP INFERIOR"));
|
2010-07-08 18:10:50 +02:00
|
|
|
QTimer::singleShot(0, d, SLOT(doSetupInferior()));
|
2010-07-08 14:26:35 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-08 18:10:50 +02:00
|
|
|
void DebuggerEnginePrivate::doSetupInferior()
|
2010-07-08 14:26:35 +02:00
|
|
|
{
|
2010-07-21 11:02:51 +02:00
|
|
|
m_engine->showMessage(_("CALL: SETUP INFERIOR"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineSetupOk, qDebug() << state());
|
2010-07-22 12:02:09 +02:00
|
|
|
m_progress.setProgressValue(250);
|
2010-07-09 17:07:59 +02:00
|
|
|
m_engine->setState(InferiorSetupRequested);
|
2010-07-08 18:10:50 +02:00
|
|
|
m_engine->setupInferior();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorSetupFailed()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR SETUP FAILED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
2010-07-08 18:10:50 +02:00
|
|
|
setState(InferiorSetupFailed);
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueShutdownEngine();
|
2010-07-08 18:10:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorSetupOk()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR SETUP OK"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueRunEngine();
|
2010-07-08 18:10:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEnginePrivate::doRunEngine()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->showMessage(_("CALL: RUN ENGINE"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
2010-07-22 12:02:09 +02:00
|
|
|
m_progress.setProgressValue(300);
|
2010-07-08 18:10:50 +02:00
|
|
|
m_engine->runEngine();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEngine::notifyInferiorUnrunnable()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR UNRUNNABLE"));
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(1000);
|
|
|
|
|
d->m_progress.reportFinished();
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
|
|
|
|
setState(InferiorUnrunnable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineRunFailed()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE RUN FAILED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(900);
|
|
|
|
|
d->m_progress.reportCanceled();
|
|
|
|
|
d->m_progress.reportFinished();
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(EngineRunFailed);
|
2010-11-29 16:53:40 +01:00
|
|
|
d->queueShutdownEngine();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineRunAndInferiorRunOk()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE RUN AND INFERIOR RUN OK"));
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(1000);
|
|
|
|
|
d->m_progress.reportFinished();
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
|
|
|
|
setState(InferiorRunRequested);
|
|
|
|
|
notifyInferiorRunOk();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineRunAndInferiorStopOk()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE RUN AND INFERIOR STOP OK"));
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(1000);
|
|
|
|
|
d->m_progress.reportFinished();
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
|
|
|
|
|
setState(InferiorStopRequested);
|
|
|
|
|
notifyInferiorStopOk();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorRunRequested()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR RUN REQUESTED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
|
|
|
|
|
setState(InferiorRunRequested);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorRunOk()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR RUN OK"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
|
|
|
|
|
setState(InferiorRunOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorRunFailed()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR RUN FAILED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
|
|
|
|
|
setState(InferiorRunFailed);
|
|
|
|
|
setState(InferiorStopOk);
|
2010-07-13 08:41:27 +02:00
|
|
|
if (isDying())
|
|
|
|
|
d->queueShutdownInferior();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorStopOk()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR STOP OK"));
|
|
|
|
|
// Ignore spurious notifications after we are set to die.
|
2010-07-09 17:07:59 +02:00
|
|
|
if (isDying()) {
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ... WHILE DYING. "));
|
|
|
|
|
// Forward state to "StopOk" if needed.
|
|
|
|
|
if (state() == InferiorStopRequested
|
|
|
|
|
|| state() == InferiorRunRequested
|
|
|
|
|
|| state() == InferiorRunOk) {
|
|
|
|
|
showMessage(_("NOTE: ... FORWARDING TO 'STOP OK'. "));
|
|
|
|
|
setState(InferiorStopOk);
|
|
|
|
|
}
|
|
|
|
|
if (state() == InferiorStopOk || state() == InferiorStopFailed) {
|
|
|
|
|
d->queueShutdownInferior();
|
|
|
|
|
}
|
|
|
|
|
showMessage(_("NOTE: ... IGNORING STOP MESSAGE"));
|
|
|
|
|
return;
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
2010-07-13 08:41:27 +02:00
|
|
|
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
|
|
|
|
|
setState(InferiorStopOk);
|
2010-07-08 18:10:50 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEngine::notifyInferiorSpontaneousStop()
|
2010-07-09 08:48:33 +02:00
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR SPONTANEOUES STOP"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorRunOk, qDebug() << state());
|
|
|
|
|
setState(InferiorStopOk);
|
2010-07-09 08:48:33 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEngine::notifyInferiorStopFailed()
|
2010-07-09 08:48:33 +02:00
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR STOP FAILED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
|
|
|
|
|
setState(InferiorStopFailed);
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueShutdownEngine();
|
2010-07-09 08:48:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEnginePrivate::doInterruptInferior()
|
|
|
|
|
{
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == InferiorRunOk, qDebug() << state());
|
|
|
|
|
m_engine->setState(InferiorStopRequested);
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->showMessage(_("CALL: INTERRUPT INFERIOR"));
|
2010-07-09 08:48:33 +02:00
|
|
|
m_engine->interruptInferior();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEnginePrivate::doShutdownInferior()
|
|
|
|
|
{
|
2010-07-20 18:14:41 +02:00
|
|
|
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
m_engine->resetLocation();
|
|
|
|
|
m_targetState = DebuggerFinished;
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->showMessage(_("CALL: SHUTDOWN INFERIOR"));
|
2010-07-09 17:07:59 +02:00
|
|
|
m_engine->shutdownInferior();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorShutdownOk()
|
|
|
|
|
{
|
|
|
|
|
showMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN"));
|
2010-07-13 08:41:27 +02:00
|
|
|
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
d->m_lastGoodState = DebuggerNotReady; // A "neutral" value.
|
|
|
|
|
setState(InferiorShutdownOk);
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueShutdownEngine();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorShutdownFailed()
|
|
|
|
|
{
|
|
|
|
|
showMessage(_("INFERIOR SHUTDOWN FAILED"));
|
2010-07-14 16:01:53 +02:00
|
|
|
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << this << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(InferiorShutdownFailed);
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueShutdownEngine();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorIll()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR ILL"));
|
2010-07-09 17:07:59 +02:00
|
|
|
// This can be issued in almost any state. The inferior could still be
|
|
|
|
|
// alive as some previous notifications might have been bogus.
|
|
|
|
|
d->m_targetState = DebuggerFinished;
|
|
|
|
|
d->m_lastGoodState = d->m_state;
|
|
|
|
|
if (state() == InferiorRunRequested) {
|
|
|
|
|
// We asked for running, but did not see a response.
|
|
|
|
|
// Assume the inferior is dead.
|
|
|
|
|
// FIXME: Use timeout?
|
|
|
|
|
setState(InferiorRunFailed);
|
|
|
|
|
setState(InferiorStopOk);
|
|
|
|
|
}
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueShutdownInferior();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEnginePrivate::doShutdownEngine()
|
|
|
|
|
{
|
2010-07-20 18:54:06 +02:00
|
|
|
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
m_targetState = DebuggerFinished;
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->showMessage(_("CALL: SHUTDOWN ENGINE"));
|
2010-07-09 17:07:59 +02:00
|
|
|
m_engine->shutdownEngine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineShutdownOk()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE SHUTDOWN OK"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
|
|
|
|
setState(EngineShutdownOk);
|
2010-10-27 15:05:56 +02:00
|
|
|
d->queueFinishDebugger();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineShutdownFailed()
|
2010-07-08 18:10:50 +02:00
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE SHUTDOWN FAILED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
|
|
|
|
|
setState(EngineShutdownFailed);
|
2010-10-27 15:05:56 +02:00
|
|
|
d->queueFinishDebugger();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEnginePrivate::doFinishDebugger()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->showMessage(_("NOTE: FINISH DEBUGGER"));
|
2010-07-20 18:54:06 +02:00
|
|
|
QTC_ASSERT(state() == DebuggerFinished, qDebug() << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
m_engine->resetLocation();
|
2010-11-25 11:34:46 +01:00
|
|
|
if (!m_engine->isSlaveEngine()) {
|
|
|
|
|
QTC_ASSERT(m_runControl, return);
|
|
|
|
|
m_runControl->debuggingFinished();
|
|
|
|
|
}
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineIll()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE ILL ******"));
|
2010-07-09 17:07:59 +02:00
|
|
|
d->m_targetState = DebuggerFinished;
|
|
|
|
|
d->m_lastGoodState = d->m_state;
|
2010-07-13 08:41:27 +02:00
|
|
|
switch (state()) {
|
|
|
|
|
case InferiorRunRequested:
|
|
|
|
|
case InferiorRunOk:
|
2010-10-11 14:39:16 +02:00
|
|
|
// The engine does not look overly ill right now, so attempt to
|
|
|
|
|
// properly interrupt at least once. If that fails, we are on the
|
|
|
|
|
// shutdown path due to d->m_targetState anyways.
|
|
|
|
|
setState(InferiorStopRequested, true);
|
|
|
|
|
showMessage(_("ATTEMPT TO INTERRUPT INFERIOR"));
|
|
|
|
|
interruptInferior();
|
|
|
|
|
break;
|
2010-07-13 08:41:27 +02:00
|
|
|
case InferiorStopRequested:
|
|
|
|
|
case InferiorStopOk:
|
2010-10-11 14:39:16 +02:00
|
|
|
showMessage(_("FORWARDING STATE TO InferiorShutdownFailed"));
|
2010-07-13 08:41:27 +02:00
|
|
|
setState(InferiorShutdownFailed, true);
|
2010-10-11 14:39:16 +02:00
|
|
|
d->queueShutdownEngine();
|
2010-07-13 08:41:27 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
2010-10-11 14:39:16 +02:00
|
|
|
d->queueShutdownEngine();
|
2010-07-13 08:41:27 +02:00
|
|
|
break;
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineSpontaneousShutdown()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE SPONTANEOUS SHUTDOWN"));
|
2010-07-20 18:54:06 +02:00
|
|
|
setState(EngineShutdownOk, true);
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueFinishDebugger();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorExited()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR EXITED"));
|
2010-07-09 17:07:59 +02:00
|
|
|
resetLocation();
|
|
|
|
|
|
|
|
|
|
// This can be issued in almost any state. We assume, though,
|
|
|
|
|
// that at this point of time the inferior is not running anymore,
|
|
|
|
|
// even if stop notification were not issued or got lost.
|
|
|
|
|
if (state() == InferiorRunOk) {
|
|
|
|
|
setState(InferiorStopRequested);
|
|
|
|
|
setState(InferiorStopOk);
|
|
|
|
|
}
|
|
|
|
|
setState(InferiorShutdownRequested);
|
|
|
|
|
setState(InferiorShutdownOk);
|
2010-07-14 11:32:25 +02:00
|
|
|
d->queueShutdownEngine();
|
2010-07-08 14:26:35 +02:00
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
void DebuggerEngine::setState(DebuggerState state, bool forced)
|
|
|
|
|
{
|
2010-11-18 17:32:41 +01:00
|
|
|
//qDebug() << "STATUS CHANGE: FROM " << stateName(d->m_state)
|
|
|
|
|
// << " TO " << stateName(state);
|
2010-11-15 17:36:00 +01:00
|
|
|
|
2010-06-23 14:11:52 +02:00
|
|
|
DebuggerState oldState = d->m_state;
|
|
|
|
|
d->m_state = state;
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
QString msg = _("State changed%5 from %1(%2) to %3(%4).")
|
|
|
|
|
.arg(stateName(oldState)).arg(oldState).arg(stateName(state)).arg(state)
|
|
|
|
|
.arg(forced ? " BY FORCE" : "");
|
2010-06-23 14:11:52 +02:00
|
|
|
if (!forced && !isAllowedTransition(oldState, state))
|
2010-06-16 11:08:54 +02:00
|
|
|
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
|
|
|
|
|
|
2010-11-10 16:33:11 +01:00
|
|
|
if (state == DebuggerFinished) {
|
|
|
|
|
// Give up ownership on claimed breakpoints.
|
|
|
|
|
BreakHandler *handler = breakHandler();
|
|
|
|
|
foreach (BreakpointId id, handler->engineBreakpointIds(this))
|
|
|
|
|
handler->notifyBreakpointReleased(id);
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-21 13:11:03 +02:00
|
|
|
const bool running = d->m_state == InferiorRunOk;
|
|
|
|
|
if (running)
|
|
|
|
|
threadsHandler()->notifyRunning();
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
showMessage(msg, LogDebug);
|
2010-10-27 14:21:33 +02:00
|
|
|
updateViews();
|
2010-08-18 13:54:12 +02:00
|
|
|
|
|
|
|
|
emit stateChanged(d->m_state);
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-27 14:21:33 +02:00
|
|
|
void DebuggerEngine::updateViews()
|
|
|
|
|
{
|
2010-10-27 15:05:56 +02:00
|
|
|
// The slave engines are not entitled to change the view. Their wishes
|
|
|
|
|
// should be coordinated by their master engine.
|
|
|
|
|
if (isSlaveEngine())
|
2010-10-28 08:55:50 +02:00
|
|
|
return;
|
2010-11-10 11:39:01 +01:00
|
|
|
debuggerCore()->updateState(this);
|
2010-10-27 14:21:33 +02:00
|
|
|
}
|
|
|
|
|
|
2010-10-27 14:25:36 +02:00
|
|
|
bool DebuggerEngine::isSlaveEngine() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_isSlaveEngine;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::setSlaveEngine(bool value)
|
2010-08-18 13:54:12 +02:00
|
|
|
{
|
2010-10-27 14:25:36 +02:00
|
|
|
d->m_isSlaveEngine = value;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::debuggerActionsEnabled() const
|
|
|
|
|
{
|
|
|
|
|
return debuggerActionsEnabled(d->m_state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state)
|
|
|
|
|
{
|
|
|
|
|
switch (state) {
|
2010-07-09 17:07:59 +02:00
|
|
|
case InferiorSetupRequested:
|
|
|
|
|
case InferiorRunOk:
|
2010-06-16 11:08:54 +02:00
|
|
|
case InferiorUnrunnable:
|
2010-07-09 17:07:59 +02:00
|
|
|
case InferiorStopOk:
|
2010-06-16 11:08:54 +02:00
|
|
|
return true;
|
2010-07-09 17:07:59 +02:00
|
|
|
case InferiorStopRequested:
|
|
|
|
|
case InferiorRunRequested:
|
|
|
|
|
case InferiorRunFailed:
|
2010-06-16 11:08:54 +02:00
|
|
|
case DebuggerNotReady:
|
2010-07-09 17:07:59 +02:00
|
|
|
case EngineSetupRequested:
|
2010-07-09 08:48:33 +02:00
|
|
|
case EngineSetupOk:
|
|
|
|
|
case EngineSetupFailed:
|
2010-07-09 17:07:59 +02:00
|
|
|
case EngineRunRequested:
|
|
|
|
|
case EngineRunFailed:
|
2010-07-08 18:10:50 +02:00
|
|
|
case InferiorSetupFailed:
|
2010-06-16 11:08:54 +02:00
|
|
|
case InferiorStopFailed:
|
2010-07-09 17:07:59 +02:00
|
|
|
case InferiorShutdownRequested:
|
|
|
|
|
case InferiorShutdownOk:
|
2010-06-16 11:08:54 +02:00
|
|
|
case InferiorShutdownFailed:
|
2010-07-09 17:07:59 +02:00
|
|
|
case EngineShutdownRequested:
|
|
|
|
|
case EngineShutdownOk:
|
|
|
|
|
case EngineShutdownFailed:
|
|
|
|
|
case DebuggerFinished:
|
2010-07-08 18:10:50 +02:00
|
|
|
return false;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorPid(qint64 pid)
|
|
|
|
|
{
|
2010-07-15 14:54:17 +02:00
|
|
|
showMessage(tr("Taking notice of pid %1").arg(pid));
|
2010-06-16 11:08:54 +02:00
|
|
|
if (d->m_inferiorPid == pid)
|
|
|
|
|
return;
|
|
|
|
|
d->m_inferiorPid = pid;
|
2010-07-20 10:07:42 +02:00
|
|
|
QTimer::singleShot(0, d, SLOT(raiseApplication()));
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qint64 DebuggerEngine::inferiorPid() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_inferiorPid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::isReverseDebugging() const
|
|
|
|
|
{
|
2010-11-10 11:39:01 +01:00
|
|
|
return debuggerCore()->isReverseDebugging();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-11-18 17:32:41 +01:00
|
|
|
// Called by DebuggerRunControl.
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEngine::quitDebugger()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage("QUIT DEBUGGER REQUESTED");
|
2010-07-20 15:12:29 +02:00
|
|
|
d->m_targetState = DebuggerFinished;
|
2010-08-18 11:08:50 +02:00
|
|
|
switch (state()) {
|
|
|
|
|
case InferiorStopOk:
|
|
|
|
|
case InferiorStopFailed:
|
2010-07-20 18:06:34 +02:00
|
|
|
d->queueShutdownInferior();
|
2010-08-18 11:08:50 +02:00
|
|
|
break;
|
|
|
|
|
case InferiorRunOk:
|
2010-07-20 15:12:29 +02:00
|
|
|
d->doInterruptInferior();
|
2010-08-18 11:08:50 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
2010-11-18 17:32:41 +01:00
|
|
|
// FIXME: We should disable the actions connected to that.
|
2010-07-20 15:12:29 +02:00
|
|
|
notifyInferiorIll();
|
2010-08-18 11:08:50 +02:00
|
|
|
break;
|
2010-07-20 15:12:29 +02:00
|
|
|
}
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-20 12:14:59 +02:00
|
|
|
void DebuggerEngine::requestInterruptInferior()
|
|
|
|
|
{
|
|
|
|
|
d->doInterruptInferior();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-21 11:02:51 +02:00
|
|
|
void DebuggerEngine::progressPing()
|
|
|
|
|
{
|
2010-07-22 12:02:09 +02:00
|
|
|
int progress = qMin(d->m_progress.progressValue() + 2, 800);
|
|
|
|
|
d->m_progress.setProgressValue(progress);
|
2010-07-21 11:02:51 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-18 13:54:12 +02:00
|
|
|
DebuggerRunControl *DebuggerEngine::runControl() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_runControl;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-08 15:19:13 +01:00
|
|
|
void DebuggerEngine::setToolTipExpression
|
|
|
|
|
(const QPoint &, TextEditor::ITextEditor *, int)
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-08 15:19:13 +01:00
|
|
|
void DebuggerEngine::updateWatchData
|
|
|
|
|
(const Internal::WatchData &, const Internal::WatchUpdateFlags &)
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::watchPoint(const QPoint &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::fetchDisassembler(Internal::DisassemblerViewAgent *)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::activateFrame(int)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::reloadModules()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::examineModules()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::loadSymbols(const QString &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::loadAllSymbols()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::requestModuleSymbols(const QString &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::reloadRegisters()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::reloadSourceFiles()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::reloadFullStack()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::addOptionPages(QList<Core::IOptionsPage*> *) const
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned DebuggerEngine::debuggerCapabilities() const
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::isSynchronous() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray DebuggerEngine::qtNamespace() const
|
|
|
|
|
{
|
|
|
|
|
return QByteArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::createSnapshot()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::updateAll()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-10 16:33:11 +01:00
|
|
|
#if 0
|
|
|
|
|
// FIXME: Remove explicit use of BreakpointData
|
|
|
|
|
if (!bp->engine && acceptsBreakpoint(id)) {
|
|
|
|
|
QTC_ASSERT(state == BreakpointNew, /**/);
|
|
|
|
|
// Take ownership of the breakpoint.
|
|
|
|
|
bp->engine = this;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::attemptBreakpointSynchronization()
|
|
|
|
|
{
|
2010-11-10 16:33:11 +01:00
|
|
|
if (!stateAcceptsBreakpointChanges()) {
|
|
|
|
|
showMessage(_("BREAKPOINT SYNCHRONIZATION NOT POSSIBLE IN CURRENT STATE"));
|
|
|
|
|
return;
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-10 16:33:11 +01:00
|
|
|
BreakHandler *handler = breakHandler();
|
|
|
|
|
|
|
|
|
|
foreach (BreakpointId id, handler->unclaimedBreakpointIds()) {
|
|
|
|
|
// Take ownership of the breakpoint. Requests insertion.
|
|
|
|
|
if (acceptsBreakpoint(id))
|
|
|
|
|
handler->setEngine(id, this);
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-25 11:51:09 +01:00
|
|
|
bool done = true;
|
2010-11-10 16:33:11 +01:00
|
|
|
foreach (BreakpointId id, handler->engineBreakpointIds(this)) {
|
|
|
|
|
switch (handler->state(id)) {
|
|
|
|
|
case BreakpointNew:
|
|
|
|
|
// Should not happen once claimed.
|
|
|
|
|
QTC_ASSERT(false, /**/);
|
|
|
|
|
continue;
|
|
|
|
|
case BreakpointInsertRequested:
|
2010-11-25 11:51:09 +01:00
|
|
|
done = false;
|
2010-11-10 16:33:11 +01:00
|
|
|
insertBreakpoint(id);
|
|
|
|
|
continue;
|
|
|
|
|
case BreakpointChangeRequested:
|
2010-11-25 11:51:09 +01:00
|
|
|
done = false;
|
2010-11-10 16:33:11 +01:00
|
|
|
changeBreakpoint(id);
|
|
|
|
|
continue;
|
|
|
|
|
case BreakpointRemoveRequested:
|
2010-11-25 11:51:09 +01:00
|
|
|
done = false;
|
2010-11-10 16:33:11 +01:00
|
|
|
removeBreakpoint(id);
|
|
|
|
|
continue;
|
|
|
|
|
case BreakpointChangeProceeding:
|
|
|
|
|
case BreakpointInsertProceeding:
|
|
|
|
|
case BreakpointRemoveProceeding:
|
2010-11-25 11:51:09 +01:00
|
|
|
done = false;
|
2010-11-10 16:33:11 +01:00
|
|
|
//qDebug() << "BREAKPOINT " << id << " STILL IN PROGRESS, STATE"
|
|
|
|
|
// << handler->state(id);
|
|
|
|
|
continue;
|
|
|
|
|
case BreakpointInserted:
|
2010-11-16 17:53:08 +01:00
|
|
|
//qDebug() << "BREAKPOINT " << id << " IS GOOD";
|
2010-11-10 16:33:11 +01:00
|
|
|
continue;
|
|
|
|
|
case BreakpointDead:
|
|
|
|
|
// Should not only be visible inside BreakpointHandler.
|
|
|
|
|
QTC_ASSERT(false, /**/);
|
|
|
|
|
continue;
|
2010-11-09 12:50:46 +01:00
|
|
|
}
|
2010-11-10 16:33:11 +01:00
|
|
|
QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
2010-11-10 16:33:11 +01:00
|
|
|
|
2010-11-25 11:51:09 +01:00
|
|
|
if (done)
|
|
|
|
|
d->m_disassemblerViewAgent.updateBreakpointMarkers();
|
2010-09-13 13:30:35 +02:00
|
|
|
}
|
|
|
|
|
|
2010-11-30 10:00:33 +01:00
|
|
|
void DebuggerEngine::insertBreakpoint(BreakpointId id)
|
2010-11-08 18:55:32 +01:00
|
|
|
{
|
2010-11-30 10:00:33 +01:00
|
|
|
BreakpointState state = breakHandler()->state(id);
|
|
|
|
|
QTC_ASSERT(state == BreakpointInsertRequested, qDebug() << state);
|
2010-11-10 16:33:11 +01:00
|
|
|
QTC_ASSERT(false, /**/);
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-30 10:00:33 +01:00
|
|
|
void DebuggerEngine::removeBreakpoint(BreakpointId id)
|
2010-11-08 18:55:32 +01:00
|
|
|
{
|
2010-11-30 10:00:33 +01:00
|
|
|
BreakpointState state = breakHandler()->state(id);
|
|
|
|
|
QTC_ASSERT(state == BreakpointRemoveRequested, qDebug() << state);
|
2010-11-10 16:33:11 +01:00
|
|
|
QTC_ASSERT(false, /**/);
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-30 10:00:33 +01:00
|
|
|
void DebuggerEngine::changeBreakpoint(BreakpointId id)
|
2010-11-08 18:55:32 +01:00
|
|
|
{
|
2010-11-30 10:00:33 +01:00
|
|
|
BreakpointState state = breakHandler()->state(id);
|
|
|
|
|
QTC_ASSERT(state == BreakpointChangeRequested, qDebug() << state);
|
2010-11-10 16:33:11 +01:00
|
|
|
QTC_ASSERT(false, /**/);
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::selectThread(int)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-08 15:19:13 +01:00
|
|
|
void DebuggerEngine::assignValueInDebugger
|
|
|
|
|
(const Internal::WatchData *, const QString &, const QVariant &)
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::detachDebugger()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-08 17:43:31 +01:00
|
|
|
void DebuggerEngine::exitDebugger()
|
2010-11-08 15:19:13 +01:00
|
|
|
{
|
2010-11-08 17:43:31 +01:00
|
|
|
QTC_ASSERT(d->m_state == InferiorStopOk, qDebug() << d->m_state);
|
2010-11-08 15:19:13 +01:00
|
|
|
d->queueShutdownInferior();
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::executeStep()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeStepOut()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeNext()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeStepI()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeNextI()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeReturn()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::continueInferior()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::interruptInferior()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeRunToLine(const QString &, int)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeRunToFunction(const QString &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeJumpToLine(const QString &, int)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeDebuggerCommand(const QString &)
|
|
|
|
|
{
|
2010-11-04 09:54:23 +01:00
|
|
|
}
|
2010-09-13 13:30:35 +02:00
|
|
|
|
2010-11-04 09:54:23 +01:00
|
|
|
Internal::BreakHandler *DebuggerEngine::breakHandler() const
|
|
|
|
|
{
|
2010-11-10 11:39:01 +01:00
|
|
|
return debuggerCore()->breakHandler();
|
2010-09-13 13:30:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::isDying() const
|
|
|
|
|
{
|
|
|
|
|
return targetState() == DebuggerFinished;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-18 17:32:41 +01:00
|
|
|
QString DebuggerEngine::msgWatchpointTriggered(BreakpointId id,
|
|
|
|
|
const int number, quint64 address)
|
2010-11-17 17:16:34 +01:00
|
|
|
{
|
2010-12-01 11:52:18 +01:00
|
|
|
return id
|
2010-11-18 17:32:41 +01:00
|
|
|
? tr("Watchpoint %1 (%2) at 0x%3 triggered.")
|
|
|
|
|
.arg(id).arg(number).arg(address, 0, 16)
|
|
|
|
|
: tr("Internal watchpoint %1 at 0x%2 triggered.")
|
|
|
|
|
.arg(number).arg(address, 0, 16);
|
2010-11-17 17:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-18 17:32:41 +01:00
|
|
|
QString DebuggerEngine::msgWatchpointTriggered(BreakpointId id,
|
|
|
|
|
const int number, quint64 address, const QString &threadId)
|
2010-11-17 17:16:34 +01:00
|
|
|
{
|
2010-12-01 11:52:18 +01:00
|
|
|
return id
|
2010-11-18 17:32:41 +01:00
|
|
|
? tr("Watchpoint %1 (%2) at 0x%3 in thread %4 triggered.")
|
|
|
|
|
.arg(id).arg(number).arg(address, 0, 16).arg(threadId)
|
|
|
|
|
: tr("Internal watchpoint %1 at 0x%2 in thread %3 triggered.")
|
|
|
|
|
.arg(id).arg(number).arg(address, 0, 16).arg(threadId);
|
2010-11-17 17:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-18 17:32:41 +01:00
|
|
|
QString DebuggerEngine::msgBreakpointTriggered(BreakpointId id,
|
|
|
|
|
const int number, const QString &threadId)
|
2010-11-17 17:16:34 +01:00
|
|
|
{
|
2010-12-01 11:52:18 +01:00
|
|
|
return id
|
2010-11-18 17:32:41 +01:00
|
|
|
? tr("Stopped at breakpoint %1 (%2) in thread %3.")
|
|
|
|
|
.arg(id).arg(number).arg(threadId)
|
|
|
|
|
: tr("Stopped at internal breakpoint %1 in thread %2.")
|
|
|
|
|
.arg(number).arg(threadId);
|
2010-11-17 17:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString DebuggerEngine::msgStopped(const QString &reason)
|
|
|
|
|
{
|
|
|
|
|
return reason.isEmpty() ? tr("Stopped.") : tr("Stopped: \"%1\"").arg(reason);
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-18 17:32:41 +01:00
|
|
|
QString DebuggerEngine::msgStoppedBySignal(const QString &meaning,
|
|
|
|
|
const QString &name)
|
2010-11-17 17:16:34 +01:00
|
|
|
{
|
|
|
|
|
return tr("Stopped: %1 by signal %2.").arg(meaning, name);
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-18 17:32:41 +01:00
|
|
|
QString DebuggerEngine::msgStoppedByException(const QString &description,
|
|
|
|
|
const QString &threadId)
|
2010-11-17 17:16:34 +01:00
|
|
|
{
|
|
|
|
|
return tr("Stopped in thread %1 by: %2.").arg(threadId, description);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString DebuggerEngine::msgInterrupted()
|
|
|
|
|
{
|
|
|
|
|
return tr("Interrupted.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::showStoppedBySignalMessageBox(QString meaning, QString name)
|
|
|
|
|
{
|
|
|
|
|
if (name.isEmpty())
|
|
|
|
|
name = tr(" <Unknown> ", "name");
|
|
|
|
|
if (meaning.isEmpty())
|
|
|
|
|
meaning = tr(" <Unknown> ", "meaning");
|
|
|
|
|
const QString msg = tr("<p>The inferior stopped because it received a "
|
|
|
|
|
"signal from the Operating System.<p>"
|
|
|
|
|
"<table><tr><td>Signal name : </td><td>%1</td></tr>"
|
|
|
|
|
"<tr><td>Signal meaning : </td><td>%2</td></tr></table>")
|
|
|
|
|
.arg(name, meaning);
|
|
|
|
|
showMessageBox(QMessageBox::Information, tr("Signal received"), msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::showStoppedByExceptionMessageBox(const QString &description)
|
|
|
|
|
{
|
2010-11-18 17:32:41 +01:00
|
|
|
const QString msg =
|
|
|
|
|
tr("<p>The inferior stopped because it triggered an exception.<p>%1").
|
2010-11-17 17:16:34 +01:00
|
|
|
arg(description);
|
|
|
|
|
showMessageBox(QMessageBox::Information, tr("Exception Triggered"), msg);
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-26 13:06:03 +01:00
|
|
|
bool DebuggerEngine::isCppBreakpoint(const BreakpointParameters &p)
|
|
|
|
|
{
|
|
|
|
|
// Qml is currently only file
|
|
|
|
|
if (p.type != BreakpointByFileAndLine)
|
|
|
|
|
return true;
|
|
|
|
|
return !p.fileName.endsWith(QLatin1String(".qml"), Qt::CaseInsensitive)
|
|
|
|
|
&& !p.fileName.endsWith(QLatin1String(".js"), Qt::CaseInsensitive);
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-08 12:43:11 +01:00
|
|
|
void DebuggerEngine::openMemoryView(quint64 address)
|
|
|
|
|
{
|
|
|
|
|
(void) new MemoryViewAgent(this, address);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::openDisassemblerView(const StackFrame &frame)
|
|
|
|
|
{
|
|
|
|
|
DisassemblerViewAgent *agent = new DisassemblerViewAgent(this);
|
|
|
|
|
agent->setFrame(frame, true, false);
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
} // namespace Debugger
|
2010-06-25 16:06:48 +02:00
|
|
|
|
|
|
|
|
#include "debuggerengine.moc"
|