2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2010-06-16 11:08:54 +02:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2010-06-16 11:08:54 +02:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2010-06-16 11:08:54 +02:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2010-06-16 11:08:54 +02:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2010-12-17 16:01:08 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2010-06-16 11:08:54 +02:00
|
|
|
|
|
|
|
|
#include "debuggerengine.h"
|
|
|
|
|
|
2011-04-21 15:52:51 +02:00
|
|
|
#include "debuggerinternalconstants.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "debuggeractions.h"
|
2010-11-10 11:39:01 +01:00
|
|
|
#include "debuggercore.h"
|
2014-10-17 13:40:04 +02:00
|
|
|
#include "debuggerruncontrol.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "debuggerstringutils.h"
|
2011-01-10 10:14:23 +01:00
|
|
|
#include "debuggerstartparameters.h"
|
2014-07-10 18:10:56 +02:00
|
|
|
#include "debuggertooltipmanager.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
|
|
|
|
|
#include "breakhandler.h"
|
2013-03-04 00:42:36 -08:00
|
|
|
#include "disassembleragent.h"
|
2015-03-26 13:03:38 +01:00
|
|
|
#include "logwindow.h"
|
2013-03-04 00:42:36 -08:00
|
|
|
#include "memoryagent.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "moduleshandler.h"
|
2015-03-26 13:03:38 +01:00
|
|
|
#include "gdb/gdbengine.h" // REMOVE
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "registerhandler.h"
|
|
|
|
|
#include "sourcefileshandler.h"
|
2015-07-17 16:33:25 +02:00
|
|
|
#include "sourceutils.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "stackhandler.h"
|
2015-01-14 16:58:10 +01:00
|
|
|
#include "terminal.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
#include "threadshandler.h"
|
|
|
|
|
#include "watchhandler.h"
|
2015-11-10 16:59:02 +01:00
|
|
|
#include "debugger/shared/peutils.h"
|
|
|
|
|
#include "console/console.h"
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2010-12-14 16:10:19 +01:00
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
2013-03-26 11:32:14 +01:00
|
|
|
#include <coreplugin/editormanager/ieditor.h>
|
2014-05-22 17:56:14 +02:00
|
|
|
#include <coreplugin/icore.h>
|
2015-02-26 13:38:54 +01:00
|
|
|
#include <coreplugin/idocument.h>
|
2014-11-25 13:08:18 +01:00
|
|
|
#include <coreplugin/messagebox.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
|
|
|
|
2012-03-07 16:40:03 +01:00
|
|
|
#include <projectexplorer/projectexplorer.h>
|
2011-11-25 17:45:07 +01:00
|
|
|
#include <projectexplorer/taskhub.h>
|
|
|
|
|
|
2014-09-26 09:14:03 +02:00
|
|
|
#include <texteditor/texteditor.h>
|
2013-03-26 11:32:14 +01:00
|
|
|
|
2012-02-22 11:50:05 +01:00
|
|
|
#include <utils/fileinprojectfinder.h>
|
2014-10-13 18:49:44 +02:00
|
|
|
#include <utils/macroexpander.h>
|
|
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
#include <utils/savedaction.h>
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QFileInfo>
|
2013-10-17 17:25:05 +02:00
|
|
|
#include <QDir>
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2015-10-08 16:19:57 +02:00
|
|
|
#include <QJsonArray>
|
|
|
|
|
#include <QJsonDocument>
|
|
|
|
|
#include <QJsonObject>
|
|
|
|
|
#include <QJsonValue>
|
|
|
|
|
|
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
|
|
|
|
2012-05-08 16:50:03 +02:00
|
|
|
//#define WITH_BENCHMARK
|
|
|
|
|
#ifdef WITH_BENCHMARK
|
|
|
|
|
#include <valgrind/callgrind.h>
|
|
|
|
|
#endif
|
2010-11-08 15:41:44 +01:00
|
|
|
|
2014-06-05 14:55:50 +02:00
|
|
|
// VariableManager Prefix
|
|
|
|
|
const char PrefixDebugExecutable[] = "DebuggedExecutable";
|
|
|
|
|
|
2010-11-10 11:39:01 +01:00
|
|
|
namespace Debugger {
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2015-05-27 13:59:56 +02:00
|
|
|
QDebug operator<<(QDebug str, const DebuggerRunParameters &sp)
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
|
|
|
|
QDebug nospace = str.nospace();
|
|
|
|
|
nospace << "executable=" << sp.executable
|
|
|
|
|
<< " coreFile=" << sp.coreFile
|
2010-10-19 11:14:03 +02:00
|
|
|
<< " processArgs=" << sp.processArgs
|
2015-12-08 12:39:10 +01:00
|
|
|
<< " inferior environment=<" << sp.inferiorEnvironment.size() << " variables>"
|
|
|
|
|
<< " debugger environment=<" << sp.debuggerEnvironment.size() << " variables>"
|
2010-06-16 11:08:54 +02:00
|
|
|
<< " workingDir=" << sp.workingDirectory
|
|
|
|
|
<< " attachPID=" << sp.attachPID
|
|
|
|
|
<< " useTerminal=" << sp.useTerminal
|
|
|
|
|
<< " remoteChannel=" << sp.remoteChannel
|
|
|
|
|
<< " serverStartScript=" << sp.serverStartScript
|
2011-02-01 18:36:00 +01:00
|
|
|
<< " abi=" << sp.toolChainAbi.toString() << '\n';
|
2010-06-16 11:08:54 +02:00
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-12 15:33:16 +01:00
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
|
|
Location::Location(const StackFrame &frame, bool marker)
|
|
|
|
|
{
|
|
|
|
|
init();
|
|
|
|
|
m_fileName = frame.file;
|
|
|
|
|
m_lineNumber = frame.line;
|
|
|
|
|
m_needsMarker = marker;
|
|
|
|
|
m_functionName = frame.function;
|
|
|
|
|
m_hasDebugInfo = frame.isUsable();
|
|
|
|
|
m_address = frame.address;
|
2015-10-08 16:19:57 +02:00
|
|
|
m_from = frame.module;
|
2014-12-12 15:33:16 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-22 15:37:27 +02:00
|
|
|
|
2015-07-17 16:33:25 +02:00
|
|
|
LocationMark::LocationMark(DebuggerEngine *engine, const QString &file, int line)
|
|
|
|
|
: TextMark(file, line, Constants::TEXT_MARK_CATEGORY_LOCATION), m_engine(engine)
|
2015-07-16 08:14:17 +02:00
|
|
|
{
|
2015-07-17 16:33:25 +02:00
|
|
|
setIcon(Internal::locationMarkIcon());
|
|
|
|
|
setPriority(TextMark::HighPriority);
|
|
|
|
|
}
|
2015-07-16 08:14:17 +02:00
|
|
|
|
2015-07-17 16:33:25 +02:00
|
|
|
bool LocationMark::isDraggable() const
|
|
|
|
|
{
|
|
|
|
|
return m_engine->hasCapability(JumpToLineCapability);
|
|
|
|
|
}
|
2015-07-16 08:14:17 +02:00
|
|
|
|
2015-07-17 16:33:25 +02:00
|
|
|
void LocationMark::dragToLine(int line)
|
|
|
|
|
{
|
|
|
|
|
if (m_engine) {
|
2015-07-20 09:37:54 +02:00
|
|
|
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor()) {
|
|
|
|
|
ContextData location = getLocationContext(textEditor->textDocument(), line);
|
|
|
|
|
if (location.isValid())
|
|
|
|
|
m_engine->executeJumpToLine(location);
|
|
|
|
|
}
|
2015-07-16 08:14:17 +02:00
|
|
|
}
|
2015-07-17 16:33:25 +02:00
|
|
|
}
|
2015-07-16 08:14:17 +02:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebuggerEnginePrivate
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2012-01-31 13:23:05 +01:00
|
|
|
// transitions:
|
|
|
|
|
// None->Requested
|
|
|
|
|
// Requested->Succeeded
|
|
|
|
|
// Requested->Failed
|
|
|
|
|
// Requested->Cancelled
|
|
|
|
|
enum RemoteSetupState { RemoteSetupNone, RemoteSetupRequested,
|
|
|
|
|
RemoteSetupSucceeded, RemoteSetupFailed,
|
|
|
|
|
RemoteSetupCancelled };
|
|
|
|
|
|
2015-03-26 13:03:38 +01:00
|
|
|
struct TypeInfo
|
|
|
|
|
{
|
|
|
|
|
TypeInfo(uint s = 0) : size(s) {}
|
|
|
|
|
uint size;
|
|
|
|
|
};
|
|
|
|
|
|
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:
|
2015-05-27 13:59:56 +02:00
|
|
|
DebuggerEnginePrivate(DebuggerEngine *engine, const DebuggerRunParameters &sp)
|
2010-06-16 11:08:54 +02:00
|
|
|
: m_engine(engine),
|
2012-08-15 14:33:39 +02:00
|
|
|
m_masterEngine(0),
|
2010-06-16 11:08:54 +02:00
|
|
|
m_runControl(0),
|
2015-05-27 13:59:56 +02:00
|
|
|
m_runParameters(sp),
|
2010-06-16 11:08:54 +02:00
|
|
|
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),
|
2012-01-31 13:23:05 +01:00
|
|
|
m_remoteSetupState(RemoteSetupNone),
|
2011-04-28 09:04:49 +02:00
|
|
|
m_inferiorPid(0),
|
2012-08-28 10:53:33 +02:00
|
|
|
m_modulesHandler(engine),
|
2015-08-25 13:48:55 +02:00
|
|
|
m_registerHandler(engine),
|
2010-11-05 19:38:40 +01:00
|
|
|
m_sourceFilesHandler(),
|
2015-10-08 16:19:57 +02:00
|
|
|
m_stackHandler(engine),
|
2010-11-05 17:02:27 +01:00
|
|
|
m_threadsHandler(),
|
2010-06-16 11:08:54 +02:00
|
|
|
m_watchHandler(engine),
|
2010-12-14 12:29:32 +01:00
|
|
|
m_disassemblerAgent(engine),
|
2011-01-14 14:25:02 +01:00
|
|
|
m_memoryAgent(engine),
|
2013-08-15 12:14:46 +02:00
|
|
|
m_isStateDebugging(false)
|
2010-12-14 12:21:29 +01:00
|
|
|
{
|
2015-02-12 13:50:54 +01:00
|
|
|
connect(&m_locationTimer, &QTimer::timeout,
|
|
|
|
|
this, &DebuggerEnginePrivate::resetLocation);
|
|
|
|
|
connect(action(IntelFlavor), &Utils::SavedAction::valueChanged,
|
|
|
|
|
this, &DebuggerEnginePrivate::reloadDisassembly);
|
2015-02-05 14:19:32 +01:00
|
|
|
|
2014-10-13 18:49:44 +02:00
|
|
|
Utils::globalMacroExpander()->registerFileVariables(PrefixDebugExecutable,
|
2014-06-23 16:57:56 +02:00
|
|
|
tr("Debugged executable"),
|
2015-05-27 13:59:56 +02:00
|
|
|
[this]() { return m_runParameters.executable; });
|
2010-12-14 12:21:29 +01:00
|
|
|
}
|
2010-07-21 11:02:51 +02:00
|
|
|
|
2010-06-25 16:06:48 +02:00
|
|
|
public slots:
|
2011-01-14 18:16:40 +01:00
|
|
|
void doSetupEngine();
|
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
|
|
|
|
2014-05-26 15:24:27 +02:00
|
|
|
void reloadDisassembly()
|
|
|
|
|
{
|
|
|
|
|
m_disassemblerAgent.reload();
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-14 18:16:40 +01:00
|
|
|
void queueSetupEngine()
|
|
|
|
|
{
|
|
|
|
|
m_engine->setState(EngineSetupRequested);
|
|
|
|
|
m_engine->showMessage(_("QUEUE: SETUP ENGINE"));
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(doSetupEngine()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void queueSetupInferior()
|
|
|
|
|
{
|
|
|
|
|
m_engine->setState(InferiorSetupRequested);
|
|
|
|
|
m_engine->showMessage(_("QUEUE: SETUP INFERIOR"));
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(doSetupInferior()));
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
2011-04-18 16:49:41 +02:00
|
|
|
resetLocation();
|
|
|
|
|
if (isMasterEngine()) {
|
|
|
|
|
m_engine->showMessage(_("QUEUE: FINISH DEBUGGER"));
|
|
|
|
|
QTimer::singleShot(0, this, SLOT(doFinishDebugger()));
|
|
|
|
|
}
|
2010-07-13 08:41:27 +02:00
|
|
|
}
|
|
|
|
|
|
2010-11-05 19:38:40 +01:00
|
|
|
void raiseApplication()
|
|
|
|
|
{
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(runControl(), return);
|
|
|
|
|
runControl()->bringApplicationToForeground(m_inferiorPid);
|
2010-07-20 10:07:42 +02:00
|
|
|
}
|
|
|
|
|
|
2010-12-17 11:30:32 +01:00
|
|
|
void scheduleResetLocation()
|
2010-12-14 12:21:29 +01:00
|
|
|
{
|
2010-12-17 11:30:32 +01:00
|
|
|
m_stackHandler.scheduleResetLocation();
|
2012-01-17 18:44:02 +01:00
|
|
|
m_watchHandler.scheduleResetLocation();
|
2011-04-18 16:40:59 +02:00
|
|
|
m_threadsHandler.scheduleResetLocation();
|
2011-03-18 18:33:20 +01:00
|
|
|
m_disassemblerAgent.scheduleResetLocation();
|
2010-12-14 12:21:29 +01:00
|
|
|
m_locationTimer.setSingleShot(true);
|
|
|
|
|
m_locationTimer.start(80);
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-17 11:30:32 +01:00
|
|
|
void resetLocation()
|
2010-12-14 12:21:29 +01:00
|
|
|
{
|
|
|
|
|
m_locationTimer.stop();
|
|
|
|
|
m_locationMark.reset();
|
2010-12-17 11:30:32 +01:00
|
|
|
m_stackHandler.resetLocation();
|
2012-01-17 18:44:02 +01:00
|
|
|
m_watchHandler.resetLocation();
|
2011-04-18 16:40:59 +02:00
|
|
|
m_threadsHandler.resetLocation();
|
2010-12-17 11:30:32 +01:00
|
|
|
m_disassemblerAgent.resetLocation();
|
2014-11-11 11:00:32 +01:00
|
|
|
DebuggerToolTipManager::resetLocation();
|
2010-12-14 12:21:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
public:
|
2010-07-09 17:07:59 +02:00
|
|
|
DebuggerState state() const { return m_state; }
|
2012-01-31 13:23:05 +01:00
|
|
|
RemoteSetupState remoteSetupState() const { return m_remoteSetupState; }
|
2011-01-14 14:25:02 +01:00
|
|
|
bool isMasterEngine() const { return m_engine->isMasterEngine(); }
|
|
|
|
|
DebuggerRunControl *runControl() const
|
|
|
|
|
{ return m_masterEngine ? m_masterEngine->runControl() : m_runControl; }
|
2012-01-31 13:23:05 +01:00
|
|
|
void setRemoteSetupState(RemoteSetupState state);
|
2010-07-09 17:07:59 +02:00
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
DebuggerEngine *m_engine; // Not owned.
|
2011-01-12 12:10:12 +01:00
|
|
|
DebuggerEngine *m_masterEngine; // Not owned
|
2010-06-16 11:08:54 +02:00
|
|
|
DebuggerRunControl *m_runControl; // Not owned.
|
|
|
|
|
|
2015-05-27 13:59:56 +02:00
|
|
|
DebuggerRunParameters m_runParameters;
|
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;
|
|
|
|
|
|
2012-01-31 13:23:05 +01:00
|
|
|
// State of RemoteSetup signal/slots.
|
|
|
|
|
RemoteSetupState m_remoteSetupState;
|
|
|
|
|
|
2015-01-14 16:58:10 +01:00
|
|
|
Terminal m_terminal;
|
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;
|
2010-07-21 11:02:51 +02:00
|
|
|
QFutureInterface<void> m_progress;
|
2010-08-18 13:54:12 +02:00
|
|
|
|
2010-12-14 12:29:32 +01:00
|
|
|
DisassemblerAgent m_disassemblerAgent;
|
|
|
|
|
MemoryAgent m_memoryAgent;
|
2015-07-16 08:14:17 +02:00
|
|
|
QScopedPointer<LocationMark> m_locationMark;
|
2010-12-14 12:21:29 +01:00
|
|
|
QTimer m_locationTimer;
|
2011-01-14 14:25:02 +01:00
|
|
|
|
|
|
|
|
bool m_isStateDebugging;
|
2011-11-25 16:29:25 +01:00
|
|
|
|
2012-02-22 11:50:05 +01:00
|
|
|
Utils::FileInProjectFinder m_fileFinder;
|
2015-03-26 13:03:38 +01:00
|
|
|
QHash<QByteArray, TypeInfo> m_typeInfoCache;
|
|
|
|
|
QByteArray m_qtNamespace;
|
2010-06-16 11:08:54 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebuggerEngine
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2015-05-27 13:59:56 +02:00
|
|
|
DebuggerEngine::DebuggerEngine(const DebuggerRunParameters &startParameters)
|
2012-08-15 14:33:39 +02:00
|
|
|
: d(new DebuggerEnginePrivate(this, startParameters))
|
2012-08-14 17:54:01 +02:00
|
|
|
{}
|
2010-06-16 11:08:54 +02:00
|
|
|
|
|
|
|
|
DebuggerEngine::~DebuggerEngine()
|
|
|
|
|
{
|
2010-07-20 10:04:08 +02:00
|
|
|
disconnect();
|
|
|
|
|
delete d;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2011-01-07 09:44:23 +01:00
|
|
|
const char *DebuggerEngine::stateName(int s)
|
|
|
|
|
{
|
|
|
|
|
# define SN(x) case x: return #x;
|
|
|
|
|
switch (s) {
|
|
|
|
|
SN(DebuggerNotReady)
|
|
|
|
|
SN(EngineSetupRequested)
|
|
|
|
|
SN(EngineSetupOk)
|
|
|
|
|
SN(EngineSetupFailed)
|
|
|
|
|
SN(EngineRunFailed)
|
|
|
|
|
SN(InferiorSetupRequested)
|
|
|
|
|
SN(InferiorSetupFailed)
|
2011-01-14 14:25:02 +01:00
|
|
|
SN(InferiorSetupOk)
|
2011-01-07 09:44:23 +01:00
|
|
|
SN(EngineRunRequested)
|
|
|
|
|
SN(InferiorRunRequested)
|
|
|
|
|
SN(InferiorRunOk)
|
|
|
|
|
SN(InferiorRunFailed)
|
|
|
|
|
SN(InferiorUnrunnable)
|
|
|
|
|
SN(InferiorStopRequested)
|
|
|
|
|
SN(InferiorStopOk)
|
|
|
|
|
SN(InferiorStopFailed)
|
|
|
|
|
SN(InferiorShutdownRequested)
|
|
|
|
|
SN(InferiorShutdownOk)
|
|
|
|
|
SN(InferiorShutdownFailed)
|
|
|
|
|
SN(EngineShutdownRequested)
|
|
|
|
|
SN(EngineShutdownOk)
|
|
|
|
|
SN(EngineShutdownFailed)
|
|
|
|
|
SN(DebuggerFinished)
|
|
|
|
|
}
|
|
|
|
|
return "<unknown>";
|
|
|
|
|
# undef SN
|
|
|
|
|
}
|
|
|
|
|
|
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-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));
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-08 18:07:11 +02:00
|
|
|
void DebuggerEngine::doUpdateLocals(const UpdateParameters &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-19 14:42:16 +01:00
|
|
|
void DebuggerEngine::setTargetState(DebuggerState state)
|
|
|
|
|
{
|
|
|
|
|
d->m_targetState = state;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
ModulesHandler *DebuggerEngine::modulesHandler() const
|
|
|
|
|
{
|
2011-01-12 12:10:12 +01:00
|
|
|
return d->m_masterEngine
|
|
|
|
|
? d->m_masterEngine->modulesHandler()
|
|
|
|
|
: &d->m_modulesHandler;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegisterHandler *DebuggerEngine::registerHandler() const
|
|
|
|
|
{
|
2011-01-12 12:10:12 +01:00
|
|
|
return d->m_masterEngine
|
|
|
|
|
? d->m_masterEngine->registerHandler()
|
|
|
|
|
: &d->m_registerHandler;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StackHandler *DebuggerEngine::stackHandler() const
|
|
|
|
|
{
|
2012-02-23 17:14:46 +01:00
|
|
|
return d->m_masterEngine
|
|
|
|
|
? d->m_masterEngine->stackHandler()
|
|
|
|
|
: &d->m_stackHandler;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ThreadsHandler *DebuggerEngine::threadsHandler() const
|
|
|
|
|
{
|
2011-01-12 12:10:12 +01:00
|
|
|
return d->m_masterEngine
|
|
|
|
|
? d->m_masterEngine->threadsHandler()
|
|
|
|
|
: &d->m_threadsHandler;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WatchHandler *DebuggerEngine::watchHandler() const
|
|
|
|
|
{
|
2011-01-12 12:10:12 +01:00
|
|
|
return d->m_masterEngine
|
|
|
|
|
? d->m_masterEngine->watchHandler()
|
|
|
|
|
: &d->m_watchHandler;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const
|
|
|
|
|
{
|
2011-01-12 12:10:12 +01:00
|
|
|
return d->m_masterEngine
|
|
|
|
|
? d->m_masterEngine->sourceFilesHandler()
|
|
|
|
|
: &d->m_sourceFilesHandler;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::modulesModel() const
|
|
|
|
|
{
|
2013-08-19 13:30:10 +02:00
|
|
|
return modulesHandler()->model();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::registerModel() const
|
|
|
|
|
{
|
2013-08-19 13:30:10 +02:00
|
|
|
return registerHandler()->model();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::stackModel() const
|
|
|
|
|
{
|
2013-08-19 13:30:10 +02:00
|
|
|
return stackHandler()->model();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerEngine::threadsModel() const
|
|
|
|
|
{
|
2013-08-19 13:30:10 +02:00
|
|
|
return threadsHandler()->model();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2012-05-18 02:28:41 +02:00
|
|
|
QAbstractItemModel *DebuggerEngine::watchModel() const
|
|
|
|
|
{
|
|
|
|
|
return watchHandler()->model();
|
2011-02-11 15:00:13 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
|
|
|
|
|
{
|
2013-08-19 13:30:10 +02:00
|
|
|
return sourceFilesHandler()->model();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-12-14 12:29:32 +01:00
|
|
|
void DebuggerEngine::fetchMemory(MemoryAgent *, QObject *,
|
2010-06-16 11:08:54 +02:00
|
|
|
quint64 addr, quint64 length)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(addr);
|
|
|
|
|
Q_UNUSED(length);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-25 13:21:54 +01:00
|
|
|
void DebuggerEngine::changeMemory(MemoryAgent *, QObject *,
|
|
|
|
|
quint64 addr, const QByteArray &data)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(addr);
|
|
|
|
|
Q_UNUSED(data);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-17 13:14:29 +01:00
|
|
|
void DebuggerEngine::setRegisterValue(const QByteArray &name, const QString &value)
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2014-12-17 13:14:29 +01:00
|
|
|
Q_UNUSED(name);
|
2010-06-16 11:08:54 +02:00
|
|
|
Q_UNUSED(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) const
|
|
|
|
|
{
|
2011-01-14 14:25:02 +01:00
|
|
|
if (d->m_masterEngine) {
|
|
|
|
|
d->m_masterEngine->showMessage(msg, channel, timeout);
|
|
|
|
|
return;
|
|
|
|
|
}
|
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();
|
2015-11-10 16:59:02 +01:00
|
|
|
if (channel == ConsoleOutput)
|
|
|
|
|
debuggerConsole()->printItem(ConsoleItem::DefaultType, msg);
|
2012-02-15 12:35:43 +01:00
|
|
|
|
2014-10-22 13:04:47 +02:00
|
|
|
Internal::showMessage(msg, channel, timeout);
|
2014-10-17 13:06:37 +02:00
|
|
|
if (d->m_runControl) {
|
|
|
|
|
switch (channel) {
|
|
|
|
|
case AppOutput:
|
|
|
|
|
d->m_runControl->appendMessage(msg, Utils::StdOutFormatSameLine);
|
|
|
|
|
break;
|
|
|
|
|
case AppError:
|
|
|
|
|
d->m_runControl->appendMessage(msg, Utils::StdErrFormatSameLine);
|
|
|
|
|
break;
|
|
|
|
|
case AppStuff:
|
|
|
|
|
d->m_runControl->appendMessage(msg, Utils::DebugFormat);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2010-08-10 14:50:29 +02:00
|
|
|
qWarning("Warning: %s (no active run control)", qPrintable(msg));
|
2014-10-17 13:06:37 +02:00
|
|
|
}
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
|
|
|
|
|
{
|
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
|
|
|
|
2011-01-14 14:25:02 +01:00
|
|
|
d->m_progress.setProgressRange(0, 1000);
|
2013-08-30 09:22:42 +02:00
|
|
|
FutureProgress *fp = ProgressManager::addTask(d->m_progress.future(),
|
2014-04-17 15:14:14 +02:00
|
|
|
tr("Launching Debugger"), "Debugger.Launcher");
|
2015-02-12 13:50:54 +01:00
|
|
|
connect(fp, &FutureProgress::canceled, this, &DebuggerEngine::quitDebugger);
|
2013-08-30 09:22:42 +02:00
|
|
|
fp->setKeepOnFinish(FutureProgress::HideOnFinish);
|
2011-01-14 14:25:02 +01:00
|
|
|
d->m_progress.reportStarted();
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
d->m_runControl = runControl;
|
|
|
|
|
|
2015-05-27 13:59:56 +02:00
|
|
|
d->m_inferiorPid = d->m_runParameters.attachPID > 0
|
|
|
|
|
? d->m_runParameters.attachPID : 0;
|
2011-05-31 09:48:00 +02:00
|
|
|
if (d->m_inferiorPid)
|
|
|
|
|
d->m_runControl->setApplicationProcessHandle(ProcessHandle(d->m_inferiorPid));
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2015-06-08 12:10:11 +02:00
|
|
|
if (isNativeMixedActive())
|
2015-12-08 12:39:10 +01:00
|
|
|
d->m_runParameters.inferiorEnvironment.set(QLatin1String("QV4_FORCE_INTERPRETER"), QLatin1String("1"));
|
2015-06-08 12:10:11 +02:00
|
|
|
|
2014-07-28 14:23:52 +02:00
|
|
|
action(OperateByInstruction)->setEnabled(hasCapability(DisassemblerCapability));
|
2010-06-16 11:08:54 +02:00
|
|
|
|
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-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(200);
|
2015-01-14 16:58:10 +01:00
|
|
|
|
|
|
|
|
d->m_terminal.setup();
|
|
|
|
|
if (d->m_terminal.isUsable()) {
|
|
|
|
|
connect(&d->m_terminal, &Terminal::stdOutReady, [this, runControl](const QString &msg) {
|
|
|
|
|
runControl->appendMessage(msg, Utils::StdOutFormatSameLine);
|
|
|
|
|
});
|
|
|
|
|
connect(&d->m_terminal, &Terminal::stdErrReady, [this, runControl](const QString &msg) {
|
|
|
|
|
runControl->appendMessage(msg, Utils::StdErrFormatSameLine);
|
|
|
|
|
});
|
|
|
|
|
connect(&d->m_terminal, &Terminal::error, [this, runControl](const QString &msg) {
|
|
|
|
|
runControl->appendMessage(msg, Utils::ErrorMessageFormat);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-14 18:16:40 +01:00
|
|
|
d->queueSetupEngine();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::resetLocation()
|
|
|
|
|
{
|
2010-12-17 11:30:32 +01:00
|
|
|
// Do it after some delay to avoid flicker.
|
|
|
|
|
d->scheduleResetLocation();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-12-16 19:06:33 +01:00
|
|
|
void DebuggerEngine::gotoLocation(const Location &loc)
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2011-12-28 13:20:27 +01:00
|
|
|
d->resetLocation();
|
|
|
|
|
|
2015-02-27 11:56:03 +01:00
|
|
|
if (loc.canBeDisassembled()
|
|
|
|
|
&& ((hasCapability(OperateByInstructionCapability) && boolSetting(OperateByInstruction))
|
|
|
|
|
|| !loc.hasDebugInfo()) )
|
|
|
|
|
{
|
2010-12-16 19:06:33 +01:00
|
|
|
d->m_disassemblerAgent.setLocation(loc);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-12-14 12:21:29 +01:00
|
|
|
|
2015-02-27 11:56:03 +01:00
|
|
|
if (loc.fileName().isEmpty()) {
|
|
|
|
|
showMessage(QLatin1String("CANNOT GO TO THIS LOCATION"));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2013-10-17 17:25:05 +02:00
|
|
|
const QString file = QDir::cleanPath(loc.fileName());
|
2010-12-16 19:06:33 +01:00
|
|
|
const int line = loc.lineNumber();
|
2013-07-09 12:14:33 +02:00
|
|
|
bool newEditor = false;
|
2013-08-30 09:22:42 +02:00
|
|
|
IEditor *editor = EditorManager::openEditor(file, Id(),
|
2013-07-09 12:14:33 +02:00
|
|
|
EditorManager::IgnoreNavigationHistory, &newEditor);
|
|
|
|
|
QTC_ASSERT(editor, return); // Unreadable file?
|
2014-05-02 12:08:44 +02:00
|
|
|
|
2014-07-28 14:23:52 +02:00
|
|
|
editor->gotoLine(line, 0, !boolSetting(StationaryEditorWhileStepping));
|
2014-05-02 12:08:44 +02:00
|
|
|
|
2013-07-09 12:14:33 +02:00
|
|
|
if (newEditor)
|
|
|
|
|
editor->document()->setProperty(Constants::OPENED_BY_DEBUGGER, true);
|
2010-12-14 16:01:02 +01:00
|
|
|
|
2015-07-17 16:33:25 +02:00
|
|
|
if (loc.needsMarker())
|
2015-07-16 08:14:17 +02:00
|
|
|
d->m_locationMark.reset(new LocationMark(this, file, line));
|
2010-12-16 10:44:21 +01:00
|
|
|
|
|
|
|
|
//qDebug() << "MEMORY: " << d->m_memoryAgent.hasVisibleEditor();
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-20 18:31:35 +02:00
|
|
|
// Called from RunControl.
|
|
|
|
|
void DebuggerEngine::handleStartFailed()
|
|
|
|
|
{
|
2011-12-21 14:02:52 +01:00
|
|
|
showMessage(QLatin1String("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
|
|
|
{
|
2011-12-21 14:02:52 +01:00
|
|
|
showMessage(QLatin1String("HANDLE RUNCONTROL FINISHED"));
|
2010-07-20 18:31:35 +02:00
|
|
|
d->m_runControl = 0;
|
2011-02-22 18:45:52 +01:00
|
|
|
d->m_progress.setProgressValue(1000);
|
|
|
|
|
d->m_progress.reportFinished();
|
2010-06-16 11:08:54 +02:00
|
|
|
modulesHandler()->removeAll();
|
|
|
|
|
stackHandler()->removeAll();
|
|
|
|
|
threadsHandler()->removeAll();
|
|
|
|
|
watchHandler()->cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-27 13:59:56 +02:00
|
|
|
const DebuggerRunParameters &DebuggerEngine::runParameters() const
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2015-05-27 13:59:56 +02:00
|
|
|
return d->m_runParameters;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2015-05-27 13:59:56 +02:00
|
|
|
DebuggerRunParameters &DebuggerEngine::runParameters()
|
2010-06-16 11:08:54 +02:00
|
|
|
{
|
2015-05-27 13:59:56 +02:00
|
|
|
return d->m_runParameters;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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:
|
2011-01-14 14:25:02 +01:00
|
|
|
return to == InferiorSetupOk || to == InferiorSetupFailed;
|
2010-07-08 18:10:50 +02:00
|
|
|
case InferiorSetupFailed:
|
2010-07-09 17:07:59 +02:00
|
|
|
return to == EngineShutdownRequested;
|
2011-01-14 14:25:02 +01:00
|
|
|
case InferiorSetupOk:
|
|
|
|
|
return to == EngineRunRequested;
|
2010-07-09 17:07:59 +02:00
|
|
|
|
|
|
|
|
case EngineRunRequested:
|
2011-01-14 18:47:44 +01:00
|
|
|
return to == EngineRunFailed
|
2012-08-21 11:30:59 +02:00
|
|
|
|| to == InferiorRunRequested
|
2011-01-14 18:47:44 +01:00
|
|
|
|| to == InferiorRunOk
|
|
|
|
|
|| to == InferiorStopOk
|
|
|
|
|
|| to == InferiorUnrunnable;
|
2010-07-09 17:07:59 +02:00
|
|
|
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:
|
2011-01-14 19:04:16 +01:00
|
|
|
return to == InferiorStopRequested
|
2015-06-16 15:01:46 +02:00
|
|
|
|| to == InferiorStopOk // A spontaneous stop.
|
|
|
|
|
|| to == InferiorShutdownOk; // A spontaneous exit.
|
2010-07-09 17:07:59 +02:00
|
|
|
|
|
|
|
|
case InferiorStopRequested:
|
|
|
|
|
return to == InferiorStopOk || to == InferiorStopFailed;
|
|
|
|
|
case InferiorStopOk:
|
|
|
|
|
return to == InferiorRunRequested || to == InferiorShutdownRequested
|
2015-06-16 15:01:46 +02:00
|
|
|
|| to == InferiorStopOk || to == InferiorShutdownOk;
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-14 18:16:40 +01:00
|
|
|
void DebuggerEngine::setupSlaveEngine()
|
|
|
|
|
{
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(state() == DebuggerNotReady);
|
2011-01-14 18:16:40 +01:00
|
|
|
d->queueSetupEngine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEnginePrivate::doSetupEngine()
|
|
|
|
|
{
|
|
|
|
|
m_engine->showMessage(_("CALL: SETUP ENGINE"));
|
|
|
|
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << m_engine << state());
|
2015-05-27 13:59:56 +02:00
|
|
|
m_engine->validateExecutable(&m_runParameters);
|
2011-01-14 18:16:40 +01:00
|
|
|
m_engine->setupEngine();
|
|
|
|
|
}
|
|
|
|
|
|
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"));
|
2012-01-31 13:23:05 +01:00
|
|
|
QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
|
|
|
|
|
|| d->remoteSetupState() == RemoteSetupRequested
|
|
|
|
|
|| d->remoteSetupState() == RemoteSetupSucceeded,
|
|
|
|
|
qDebug() << this << "remoteSetupState" << d->remoteSetupState());
|
|
|
|
|
if (d->remoteSetupState() == RemoteSetupRequested)
|
|
|
|
|
d->setRemoteSetupState(RemoteSetupCancelled);
|
|
|
|
|
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
2010-07-09 08:48:33 +02:00
|
|
|
setState(EngineSetupFailed);
|
2011-02-09 16:40:08 +01:00
|
|
|
if (isMasterEngine() && runControl())
|
2011-01-14 14:25:02 +01:00
|
|
|
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"));
|
2012-01-31 13:23:05 +01:00
|
|
|
QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone
|
|
|
|
|
|| d->remoteSetupState() == RemoteSetupSucceeded,
|
|
|
|
|
qDebug() << this << "remoteSetupState" << d->remoteSetupState());
|
|
|
|
|
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
2010-07-09 08:48:33 +02:00
|
|
|
setState(EngineSetupOk);
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("QUEUE: SETUP INFERIOR"));
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
2011-01-14 18:16:40 +01:00
|
|
|
d->queueSetupInferior();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::setupSlaveInferior()
|
|
|
|
|
{
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(state() == EngineSetupOk);
|
2011-01-14 18:16:40 +01:00
|
|
|
d->queueSetupInferior();
|
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"));
|
2011-01-14 18:16:40 +01:00
|
|
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << m_engine << state());
|
2010-07-22 12:02:09 +02:00
|
|
|
m_progress.setProgressValue(250);
|
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"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Setup failed."));
|
2010-07-08 18:10:50 +02:00
|
|
|
setState(InferiorSetupFailed);
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
d->queueShutdownEngine();
|
2010-07-08 18:10:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorSetupOk()
|
|
|
|
|
{
|
2012-05-08 16:50:03 +02:00
|
|
|
#ifdef WITH_BENCHMARK
|
|
|
|
|
CALLGRIND_START_INSTRUMENTATION;
|
|
|
|
|
#endif
|
2014-12-12 15:33:16 +01:00
|
|
|
aboutToNotifyInferiorSetupOk();
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR SETUP OK"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
|
|
|
|
|
setState(InferiorSetupOk);
|
|
|
|
|
if (isMasterEngine())
|
|
|
|
|
d->queueRunEngine();
|
2010-07-08 18:10:50 +02:00
|
|
|
}
|
|
|
|
|
|
2011-01-14 18:16:40 +01:00
|
|
|
void DebuggerEngine::runSlaveEngine()
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(isSlaveEngine(), return);
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(state() == InferiorSetupOk);
|
2011-01-14 18:16:40 +01: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"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << m_engine << state());
|
2010-07-22 12:02:09 +02:00
|
|
|
m_progress.setProgressValue(300);
|
2010-07-08 18:10:50 +02:00
|
|
|
m_engine->runEngine();
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-26 15:21:43 +01:00
|
|
|
void DebuggerEngine::notifyEngineRunOkAndInferiorUnrunnable()
|
2010-07-09 17:07:59 +02:00
|
|
|
{
|
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();
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Loading finished."));
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(InferiorUnrunnable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineRunFailed()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE RUN FAILED"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
|
2010-07-22 12:02:09 +02:00
|
|
|
d->m_progress.setProgressValue(900);
|
|
|
|
|
d->m_progress.reportCanceled();
|
|
|
|
|
d->m_progress.reportFinished();
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Run failed."));
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(EngineRunFailed);
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
d->queueShutdownEngine();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
2012-01-31 13:23:05 +01:00
|
|
|
void DebuggerEngine::notifyEngineRequestRemoteSetup()
|
|
|
|
|
{
|
|
|
|
|
showMessage(_("NOTE: REQUEST REMOTE SETUP"));
|
|
|
|
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
|
|
|
|
QTC_ASSERT(d->remoteSetupState() == RemoteSetupNone, qDebug() << this
|
|
|
|
|
<< "remoteSetupState" << d->remoteSetupState());
|
|
|
|
|
|
|
|
|
|
d->setRemoteSetupState(RemoteSetupRequested);
|
|
|
|
|
emit requestRemoteSetup();
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-27 15:12:36 +01:00
|
|
|
void DebuggerEngine::notifyEngineRemoteServerRunning(const QByteArray &, int /*pid*/)
|
|
|
|
|
{
|
|
|
|
|
showMessage(_("NOTE: REMOTE SERVER RUNNING IN MULTIMODE"));
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-18 19:21:27 +02:00
|
|
|
void DebuggerEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &result)
|
2012-01-31 13:23:05 +01:00
|
|
|
{
|
|
|
|
|
QTC_ASSERT(state() == EngineSetupRequested
|
|
|
|
|
|| state() == EngineSetupFailed
|
|
|
|
|
|| state() == DebuggerFinished, qDebug() << this << state());
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(d->remoteSetupState() == RemoteSetupRequested
|
|
|
|
|
|| d->remoteSetupState() == RemoteSetupCancelled,
|
|
|
|
|
qDebug() << this << "remoteSetupState" << d->remoteSetupState());
|
|
|
|
|
|
2014-09-18 19:21:27 +02:00
|
|
|
if (result.success) {
|
|
|
|
|
showMessage(_("NOTE: REMOTE SETUP DONE: GDB SERVER PORT: %1 QML PORT %2")
|
|
|
|
|
.arg(result.gdbServerPort).arg(result.qmlServerPort));
|
2012-01-31 13:23:05 +01:00
|
|
|
|
2014-09-18 19:21:27 +02:00
|
|
|
if (d->remoteSetupState() != RemoteSetupCancelled)
|
|
|
|
|
d->setRemoteSetupState(RemoteSetupSucceeded);
|
2014-09-18 20:01:19 +02:00
|
|
|
|
|
|
|
|
if (result.gdbServerPort != InvalidPid) {
|
2015-05-27 13:59:56 +02:00
|
|
|
QString &rc = d->m_runParameters.remoteChannel;
|
2014-09-18 20:01:19 +02:00
|
|
|
const int sepIndex = rc.lastIndexOf(QLatin1Char(':'));
|
|
|
|
|
if (sepIndex != -1) {
|
|
|
|
|
rc.replace(sepIndex + 1, rc.count() - sepIndex - 1,
|
|
|
|
|
QString::number(result.gdbServerPort));
|
|
|
|
|
}
|
2015-05-27 13:59:56 +02:00
|
|
|
} else if (result.inferiorPid != InvalidPid && runParameters().startMode == AttachExternal) {
|
2014-10-30 12:38:13 +01:00
|
|
|
// e.g. iOS Simulator
|
2015-05-27 13:59:56 +02:00
|
|
|
runParameters().attachPID = result.inferiorPid;
|
2014-09-18 20:01:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result.qmlServerPort != InvalidPort) {
|
2015-05-27 13:59:56 +02:00
|
|
|
d->m_runParameters.qmlServerPort = result.qmlServerPort;
|
|
|
|
|
d->m_runParameters.processArgs.replace(_("%qml_port%"), QString::number(result.qmlServerPort));
|
2014-09-18 20:01:19 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-18 19:21:27 +02:00
|
|
|
} else {
|
2014-11-25 14:19:17 +01:00
|
|
|
d->setRemoteSetupState(RemoteSetupFailed);
|
2014-09-18 19:21:27 +02:00
|
|
|
showMessage(_("NOTE: REMOTE SETUP FAILED: ") + result.reason);
|
|
|
|
|
}
|
2012-01-31 13:23:05 +01:00
|
|
|
}
|
|
|
|
|
|
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();
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Running."));
|
2011-01-14 18:47:44 +01:00
|
|
|
setState(InferiorRunOk);
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state());
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Stopped."));
|
2011-01-14 18:47:44 +01:00
|
|
|
setState(InferiorStopOk);
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorRunRequested()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR RUN REQUESTED"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorStopOk, qDebug() << this << state());
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Run requested..."));
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(InferiorRunRequested);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorRunOk()
|
|
|
|
|
{
|
2012-08-21 11:30:59 +02:00
|
|
|
if (state() == InferiorRunOk) {
|
|
|
|
|
showMessage(_("NOTE: INFERIOR RUN OK - REPEATED."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR RUN OK"));
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Running."));
|
2012-08-21 11:30:59 +02:00
|
|
|
// Transition from StopRequested can happen in remotegdbadapter.
|
2011-10-12 16:34:02 +02:00
|
|
|
QTC_ASSERT(state() == InferiorRunRequested
|
2012-08-21 11:30:59 +02:00
|
|
|
|| state() == InferiorStopOk
|
2011-10-12 16:34:02 +02:00
|
|
|
|| state() == InferiorStopRequested, qDebug() << this << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(InferiorRunOk);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorRunFailed()
|
|
|
|
|
{
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR RUN FAILED"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << this << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
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);
|
|
|
|
|
}
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (state() == InferiorStopOk || state() == InferiorStopFailed)
|
2010-07-13 08:41:27 +02:00
|
|
|
d->queueShutdownInferior();
|
|
|
|
|
showMessage(_("NOTE: ... IGNORING STOP MESSAGE"));
|
|
|
|
|
return;
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << this << state());
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Stopped."));
|
2010-07-13 08:41:27 +02:00
|
|
|
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
|
|
|
{
|
2011-03-22 15:17:24 +01:00
|
|
|
showMessage(_("NOTE: INFERIOR SPONTANEOUS STOP"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state());
|
2012-03-07 16:40:54 +01:00
|
|
|
showStatusMessage(tr("Stopped."));
|
2011-01-14 19:04:16 +01:00
|
|
|
setState(InferiorStopOk);
|
2014-07-28 14:23:52 +02:00
|
|
|
if (boolSetting(RaiseOnInterrupt))
|
2014-10-22 13:04:47 +02:00
|
|
|
ICore::raiseWindow(Internal::mainWindow());
|
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"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << this << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(InferiorStopFailed);
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
d->queueShutdownEngine();
|
2010-07-09 08:48:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEnginePrivate::doInterruptInferior()
|
|
|
|
|
{
|
2011-01-14 14:25:02 +01:00
|
|
|
//QTC_ASSERT(isMasterEngine(), return);
|
|
|
|
|
QTC_ASSERT(state() == InferiorRunOk, qDebug() << m_engine << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
m_engine->setState(InferiorStopRequested);
|
2010-07-13 08:41:27 +02:00
|
|
|
m_engine->showMessage(_("CALL: INTERRUPT INFERIOR"));
|
2012-03-07 16:40:54 +01:00
|
|
|
m_engine->showStatusMessage(tr("Attempting to interrupt."));
|
2010-07-09 08:48:33 +02:00
|
|
|
m_engine->interruptInferior();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEnginePrivate::doShutdownInferior()
|
|
|
|
|
{
|
2011-01-14 14:25:02 +01:00
|
|
|
//QTC_ASSERT(isMasterEngine(), return);
|
|
|
|
|
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << m_engine << state());
|
2010-12-17 11:30:32 +01:00
|
|
|
resetLocation();
|
2010-07-09 17:07:59 +02:00
|
|
|
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"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << this << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
d->m_lastGoodState = DebuggerNotReady; // A "neutral" value.
|
|
|
|
|
setState(InferiorShutdownOk);
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
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);
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2011-01-14 18:16:40 +01:00
|
|
|
void DebuggerEngine::shutdownSlaveEngine()
|
|
|
|
|
{
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(isAllowedTransition(state(),EngineShutdownRequested));
|
2011-01-14 18:16:40 +01:00
|
|
|
setState(EngineShutdownRequested);
|
|
|
|
|
shutdownEngine();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEnginePrivate::doShutdownEngine()
|
|
|
|
|
{
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(isMasterEngine(), qDebug() << m_engine; return);
|
|
|
|
|
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << m_engine << 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"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << this << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(EngineShutdownOk);
|
2011-01-14 17:34:42 +01: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"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << this << state());
|
2010-07-09 17:07:59 +02:00
|
|
|
setState(EngineShutdownFailed);
|
2011-01-14 17:34:42 +01: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"));
|
2011-01-14 14:25:02 +01:00
|
|
|
QTC_ASSERT(state() == DebuggerFinished, qDebug() << m_engine << state());
|
2011-01-18 09:46:32 +01:00
|
|
|
if (isMasterEngine() && m_runControl)
|
2010-11-25 11:34:46 +01:00
|
|
|
m_runControl->debuggingFinished();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
2012-01-31 13:23:05 +01:00
|
|
|
void DebuggerEnginePrivate::setRemoteSetupState(RemoteSetupState state)
|
|
|
|
|
{
|
2013-09-27 09:47:28 +02:00
|
|
|
bool allowedTransition = false;
|
2012-01-31 13:23:05 +01:00
|
|
|
if (m_remoteSetupState == RemoteSetupNone) {
|
|
|
|
|
if (state == RemoteSetupRequested)
|
|
|
|
|
allowedTransition = true;
|
|
|
|
|
}
|
|
|
|
|
if (m_remoteSetupState == RemoteSetupRequested) {
|
|
|
|
|
if (state == RemoteSetupCancelled
|
|
|
|
|
|| state == RemoteSetupSucceeded
|
|
|
|
|
|| state == RemoteSetupFailed)
|
|
|
|
|
allowedTransition = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!allowedTransition)
|
|
|
|
|
qDebug() << "*** UNEXPECTED REMOTE SETUP TRANSITION from"
|
|
|
|
|
<< m_remoteSetupState << "to" << state;
|
|
|
|
|
m_remoteSetupState = state;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-09 17:07:59 +02:00
|
|
|
void DebuggerEngine::notifyEngineIll()
|
|
|
|
|
{
|
2012-05-08 16:50:03 +02:00
|
|
|
#ifdef WITH_BENCHMARK
|
|
|
|
|
CALLGRIND_STOP_INSTRUMENTATION;
|
|
|
|
|
CALLGRIND_DUMP_STATS;
|
|
|
|
|
#endif
|
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:
|
2015-03-05 15:21:00 +01:00
|
|
|
notifyInferiorStopFailed();
|
|
|
|
|
break;
|
2010-07-13 08:41:27 +02:00
|
|
|
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);
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
d->queueShutdownEngine();
|
2010-07-13 08:41:27 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
d->queueShutdownEngine();
|
2010-07-13 08:41:27 +02:00
|
|
|
break;
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyEngineSpontaneousShutdown()
|
|
|
|
|
{
|
2012-05-08 16:50:03 +02:00
|
|
|
#ifdef WITH_BENCHMARK
|
|
|
|
|
CALLGRIND_STOP_INSTRUMENTATION;
|
|
|
|
|
CALLGRIND_DUMP_STATS;
|
|
|
|
|
#endif
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: ENGINE SPONTANEOUS SHUTDOWN"));
|
2010-07-20 18:54:06 +02:00
|
|
|
setState(EngineShutdownOk, true);
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
|
|
|
|
d->queueFinishDebugger();
|
2010-07-09 17:07:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::notifyInferiorExited()
|
|
|
|
|
{
|
2012-05-08 16:50:03 +02:00
|
|
|
#ifdef WITH_BENCHMARK
|
|
|
|
|
CALLGRIND_STOP_INSTRUMENTATION;
|
|
|
|
|
CALLGRIND_DUMP_STATS;
|
|
|
|
|
#endif
|
2010-07-13 08:41:27 +02:00
|
|
|
showMessage(_("NOTE: INFERIOR EXITED"));
|
2010-12-17 11:30:32 +01:00
|
|
|
d->resetLocation();
|
2011-01-14 19:32:47 +01:00
|
|
|
setState(InferiorShutdownOk);
|
|
|
|
|
if (isMasterEngine())
|
2011-01-14 14:25:02 +01:00
|
|
|
d->queueShutdownEngine();
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-05 11:11:32 +01:00
|
|
|
void DebuggerEngine::notifyDebuggerProcessFinished(int exitCode,
|
|
|
|
|
QProcess::ExitStatus exitStatus, const QString &backendName)
|
|
|
|
|
{
|
|
|
|
|
showMessage(_("%1 PROCESS FINISHED, status %2, exit code %3")
|
|
|
|
|
.arg(backendName).arg(exitStatus).arg(exitCode));
|
|
|
|
|
|
|
|
|
|
switch (state()) {
|
|
|
|
|
case DebuggerFinished:
|
|
|
|
|
// Nothing to do.
|
|
|
|
|
break;
|
|
|
|
|
case EngineShutdownRequested:
|
|
|
|
|
notifyEngineShutdownOk();
|
|
|
|
|
break;
|
|
|
|
|
case InferiorRunOk:
|
|
|
|
|
// This could either be a real gdb/lldb crash or a quickly exited inferior
|
|
|
|
|
// in the terminal adapter. In this case the stub proc will die soon,
|
|
|
|
|
// too, so there's no need to act here.
|
|
|
|
|
showMessage(_("The %1 process exited somewhat unexpectedly.").arg(backendName));
|
|
|
|
|
notifyEngineSpontaneousShutdown();
|
|
|
|
|
break;
|
|
|
|
|
default: {
|
|
|
|
|
notifyEngineIll(); // Initiate shutdown sequence
|
|
|
|
|
const QString msg = exitStatus == QProcess::CrashExit ?
|
|
|
|
|
tr("The %1 process terminated.") :
|
2015-03-16 15:34:45 +01:00
|
|
|
tr("The %2 process terminated unexpectedly (exit code %1).").arg(exitCode);
|
2015-03-05 11:11:32 +01:00
|
|
|
AsynchronousMessageBox::critical(tr("Unexpected %1 Exit").arg(backendName),
|
|
|
|
|
msg.arg(backendName));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-14 14:25:02 +01:00
|
|
|
void DebuggerEngine::slaveEngineStateChanged(DebuggerEngine *slaveEngine,
|
|
|
|
|
DebuggerState state)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(slaveEngine);
|
|
|
|
|
Q_UNUSED(state);
|
2010-07-08 14:26:35 +02:00
|
|
|
}
|
|
|
|
|
|
2011-12-21 14:02:52 +01:00
|
|
|
static inline QString msgStateChanged(DebuggerState oldState, DebuggerState newState,
|
|
|
|
|
bool forced, bool master)
|
|
|
|
|
{
|
|
|
|
|
QString result;
|
|
|
|
|
QTextStream str(&result);
|
|
|
|
|
str << "State changed";
|
|
|
|
|
if (forced)
|
|
|
|
|
str << " BY FORCE";
|
|
|
|
|
str << " from " << DebuggerEngine::stateName(oldState) << '(' << oldState
|
|
|
|
|
<< ") to " << DebuggerEngine::stateName(newState) << '(' << newState << ')';
|
|
|
|
|
if (master)
|
|
|
|
|
str << " [master]";
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-16 11:08:54 +02:00
|
|
|
void DebuggerEngine::setState(DebuggerState state, bool forced)
|
|
|
|
|
{
|
2011-12-21 14:02:52 +01:00
|
|
|
const QString msg = msgStateChanged(d->m_state, state, forced, isMasterEngine());
|
|
|
|
|
if (isStateDebugging())
|
|
|
|
|
qDebug("%s", qPrintable(msg));
|
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;
|
|
|
|
|
|
|
|
|
|
if (!forced && !isAllowedTransition(oldState, state))
|
2011-01-14 14:25:02 +01:00
|
|
|
qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg;
|
2010-06-16 11:08:54 +02:00
|
|
|
|
2014-07-10 18:10:56 +02:00
|
|
|
if (state == EngineRunRequested) {
|
|
|
|
|
DebuggerToolTipManager::registerEngine(this);
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-10 16:33:11 +01:00
|
|
|
if (state == DebuggerFinished) {
|
|
|
|
|
// Give up ownership on claimed breakpoints.
|
2015-01-10 01:07:01 +01:00
|
|
|
foreach (Breakpoint bp, breakHandler()->engineBreakpoints(this))
|
|
|
|
|
bp.notifyBreakpointReleased();
|
2014-07-10 18:10:56 +02:00
|
|
|
DebuggerToolTipManager::deregisterEngine(this);
|
2015-05-21 15:12:34 +02:00
|
|
|
d->m_memoryAgent.handleDebuggerFinished();
|
2010-11-10 16:33:11 +01:00
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
2012-01-31 16:23:34 +01:00
|
|
|
emit stateChanged(d->m_state);
|
2011-01-14 14:25:02 +01:00
|
|
|
|
|
|
|
|
if (isSlaveEngine())
|
|
|
|
|
masterEngine()->slaveEngineStateChanged(this, 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.
|
2011-01-14 14:25:02 +01:00
|
|
|
if (isMasterEngine())
|
2014-10-22 13:04:47 +02:00
|
|
|
Internal::updateState(this);
|
2010-10-27 14:21:33 +02:00
|
|
|
}
|
|
|
|
|
|
2010-10-27 14:25:36 +02:00
|
|
|
bool DebuggerEngine::isSlaveEngine() const
|
|
|
|
|
{
|
2011-01-12 12:10:12 +01:00
|
|
|
return d->m_masterEngine != 0;
|
2010-06-16 11:08:54 +02:00
|
|
|
}
|
|
|
|
|
|
2011-01-14 14:25:02 +01:00
|
|
|
bool DebuggerEngine::isMasterEngine() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_masterEngine == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-15 14:33:39 +02:00
|
|
|
void DebuggerEngine::setMasterEngine(DebuggerEngine *masterEngine)
|
|
|
|
|
{
|
|
|
|
|
d->m_masterEngine = masterEngine;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-12 13:43:23 +01:00
|
|
|
DebuggerEngine *DebuggerEngine::masterEngine() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_masterEngine;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-08 18:07:11 +02:00
|
|
|
bool DebuggerEngine::canDisplayTooltip() const
|
|
|
|
|
{
|
|
|
|
|
return state() == InferiorStopOk;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-22 11:50:05 +01:00
|
|
|
QString DebuggerEngine::toFileInProject(const QUrl &fileUrl)
|
|
|
|
|
{
|
|
|
|
|
// make sure file finder is properly initialized
|
2015-05-27 13:59:56 +02:00
|
|
|
const DebuggerRunParameters &rp = runParameters();
|
|
|
|
|
d->m_fileFinder.setProjectDirectory(rp.projectSourceDirectory);
|
|
|
|
|
d->m_fileFinder.setProjectFiles(rp.projectSourceFiles);
|
|
|
|
|
d->m_fileFinder.setAdditionalSearchDirectories(rp.additionalSearchDirectories);
|
|
|
|
|
d->m_fileFinder.setSysroot(rp.sysRoot);
|
2012-02-22 11:50:05 +01:00
|
|
|
|
|
|
|
|
return d->m_fileFinder.findFile(fileUrl);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-31 16:35:24 +02:00
|
|
|
void DebuggerEngine::removeBreakpointMarker(const Breakpoint &bp)
|
2015-07-21 15:28:31 +02:00
|
|
|
{
|
2015-08-31 16:35:24 +02:00
|
|
|
d->m_disassemblerAgent.removeBreakpointMarker(bp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::updateBreakpointMarker(const Breakpoint &bp)
|
|
|
|
|
{
|
|
|
|
|
d->m_disassemblerAgent.updateBreakpointMarker(bp);
|
2015-07-21 15:28:31 +02:00
|
|
|
}
|
|
|
|
|
|
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:
|
2011-01-14 14:25:02 +01:00
|
|
|
case InferiorSetupOk:
|
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)
|
|
|
|
|
{
|
|
|
|
|
if (d->m_inferiorPid == pid)
|
|
|
|
|
return;
|
|
|
|
|
d->m_inferiorPid = pid;
|
2011-04-28 10:02:34 +02:00
|
|
|
if (pid) {
|
|
|
|
|
showMessage(tr("Taking notice of pid %1").arg(pid));
|
2015-05-27 13:59:56 +02:00
|
|
|
if (d->m_runParameters.startMode == StartInternal
|
|
|
|
|
|| d->m_runParameters.startMode == StartExternal
|
|
|
|
|
|| d->m_runParameters.startMode == AttachExternal)
|
2011-04-28 10:02:34 +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
|
|
|
|
|
{
|
2014-10-22 13:04:47 +02:00
|
|
|
return Internal::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()
|
|
|
|
|
{
|
2011-10-31 16:15:48 +01:00
|
|
|
showMessage(_("QUIT DEBUGGER REQUESTED IN STATE %1").arg(state()));
|
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;
|
2012-01-19 10:49:50 +01:00
|
|
|
case EngineSetupRequested:
|
|
|
|
|
notifyEngineSetupFailed();
|
|
|
|
|
break;
|
2012-02-21 15:59:38 +01:00
|
|
|
case EngineSetupOk:
|
|
|
|
|
setState(InferiorSetupRequested);
|
|
|
|
|
notifyInferiorSetupFailed();
|
|
|
|
|
break;
|
2011-09-29 16:49:18 +02:00
|
|
|
case EngineRunRequested:
|
|
|
|
|
notifyEngineRunFailed();
|
|
|
|
|
break;
|
2012-01-19 11:46:22 +01:00
|
|
|
case EngineShutdownRequested:
|
|
|
|
|
break;
|
2011-09-29 16:49:18 +02:00
|
|
|
case EngineRunFailed:
|
|
|
|
|
case DebuggerFinished:
|
2012-03-22 13:05:57 +01:00
|
|
|
case InferiorShutdownOk:
|
2011-09-29 16:49:18 +02:00
|
|
|
break;
|
2011-10-31 16:15:48 +01:00
|
|
|
case InferiorSetupRequested:
|
|
|
|
|
notifyInferiorSetupFailed();
|
|
|
|
|
break;
|
2010-08-18 11:08:50 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2011-10-31 16:15:48 +01:00
|
|
|
void DebuggerEngine::abortDebugger()
|
|
|
|
|
{
|
|
|
|
|
// Overridden in e.g. GdbEngine.
|
|
|
|
|
quitDebugger();
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2011-01-14 14:25:02 +01:00
|
|
|
return d->runControl();
|
2010-08-18 13:54:12 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-14 16:58:10 +01:00
|
|
|
Terminal *DebuggerEngine::terminal() const
|
|
|
|
|
{
|
|
|
|
|
return &d->m_terminal;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-08 18:07:11 +02:00
|
|
|
void DebuggerEngine::selectWatchData(const QByteArray &)
|
2012-11-23 13:35:44 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::watchPoint(const QPoint &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-03 12:01:57 +01:00
|
|
|
void DebuggerEngine::runCommand(const DebuggerCommand &)
|
|
|
|
|
{
|
|
|
|
|
// Overridden in the engines that use the interface.
|
|
|
|
|
QTC_CHECK(false);
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-14 12:29:32 +01:00
|
|
|
void DebuggerEngine::fetchDisassembler(DisassemblerAgent *)
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::activateFrame(int)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::reloadModules()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::examineModules()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::loadSymbols(const QString &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::loadAllSymbols()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-21 13:34:59 +01:00
|
|
|
void DebuggerEngine::loadSymbolsForStack()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::requestModuleSymbols(const QString &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-07 18:31:17 +01:00
|
|
|
void DebuggerEngine::requestModuleSections(const QString &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::reloadRegisters()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::reloadSourceFiles()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::reloadFullStack()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-07 18:10:02 +01:00
|
|
|
void DebuggerEngine::loadAdditionalQmlStack()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-10 12:40:50 +01:00
|
|
|
void DebuggerEngine::reloadDebuggingHelpers()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-30 09:22:42 +02:00
|
|
|
void DebuggerEngine::addOptionPages(QList<IOptionsPage*> *) const
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::isSynchronous() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray DebuggerEngine::qtNamespace() const
|
|
|
|
|
{
|
2015-03-26 13:03:38 +01:00
|
|
|
return d->m_qtNamespace;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::setQtNamespace(const QByteArray &ns)
|
|
|
|
|
{
|
|
|
|
|
d->m_qtNamespace = ns;
|
2010-09-13 13:30:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::createSnapshot()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-08 18:07:11 +02:00
|
|
|
void DebuggerEngine::updateLocals()
|
|
|
|
|
{
|
|
|
|
|
watchHandler()->resetValueCache();
|
|
|
|
|
doUpdateLocals(UpdateParameters());
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::updateAll()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-10 16:33:11 +01:00
|
|
|
#if 0
|
|
|
|
|
// FIXME: Remove explicit use of BreakpointData
|
|
|
|
|
if (!bp->engine && acceptsBreakpoint(id)) {
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(state == BreakpointNew);
|
2010-11-10 16:33:11 +01:00
|
|
|
// Take ownership of the breakpoint.
|
|
|
|
|
bp->engine = this;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-09-13 13:30:35 +02:00
|
|
|
void DebuggerEngine::attemptBreakpointSynchronization()
|
|
|
|
|
{
|
2012-04-01 20:40:05 +02:00
|
|
|
showMessage(_("ATTEMPT BREAKPOINT SYNCHRONIZATION"));
|
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();
|
|
|
|
|
|
2015-01-10 01:07:01 +01:00
|
|
|
foreach (Breakpoint bp, handler->unclaimedBreakpoints()) {
|
2010-11-10 16:33:11 +01:00
|
|
|
// Take ownership of the breakpoint. Requests insertion.
|
2015-01-10 01:07:01 +01:00
|
|
|
if (acceptsBreakpoint(bp)) {
|
2012-04-01 20:40:05 +02:00
|
|
|
showMessage(_("TAKING OWNERSHIP OF BREAKPOINT %1 IN STATE %2")
|
2015-01-10 01:07:01 +01:00
|
|
|
.arg(bp.id().toString()).arg(bp.state()));
|
|
|
|
|
bp.setEngine(this);
|
2012-04-01 20:40:05 +02:00
|
|
|
} else {
|
|
|
|
|
showMessage(_("BREAKPOINT %1 IN STATE %2 IS NOT ACCEPTABLE")
|
2015-01-10 01:07:01 +01:00
|
|
|
.arg(bp.id().toString()).arg(bp.state()));
|
2012-04-01 20:40:05 +02:00
|
|
|
}
|
2010-11-10 16:33:11 +01:00
|
|
|
}
|
|
|
|
|
|
2010-11-25 11:51:09 +01:00
|
|
|
bool done = true;
|
2015-01-10 01:07:01 +01:00
|
|
|
foreach (Breakpoint bp, handler->engineBreakpoints(this)) {
|
|
|
|
|
switch (bp.state()) {
|
2010-11-10 16:33:11 +01:00
|
|
|
case BreakpointNew:
|
|
|
|
|
// Should not happen once claimed.
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(false);
|
2010-11-10 16:33:11 +01:00
|
|
|
continue;
|
|
|
|
|
case BreakpointInsertRequested:
|
2010-11-25 11:51:09 +01:00
|
|
|
done = false;
|
2015-01-10 01:07:01 +01:00
|
|
|
insertBreakpoint(bp);
|
2010-11-10 16:33:11 +01:00
|
|
|
continue;
|
|
|
|
|
case BreakpointChangeRequested:
|
2010-11-25 11:51:09 +01:00
|
|
|
done = false;
|
2015-01-10 01:07:01 +01:00
|
|
|
changeBreakpoint(bp);
|
2010-11-10 16:33:11 +01:00
|
|
|
continue;
|
|
|
|
|
case BreakpointRemoveRequested:
|
2010-11-25 11:51:09 +01:00
|
|
|
done = false;
|
2015-01-10 01:07:01 +01:00
|
|
|
removeBreakpoint(bp);
|
2010-11-10 16:33:11 +01:00
|
|
|
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:
|
2015-07-02 10:00:43 +02:00
|
|
|
// Can happen temporarily during Breakpoint destruction.
|
|
|
|
|
// BreakpointItem::deleteThis() intentionally lets the event loop run,
|
|
|
|
|
// during which an attemptBreakpointSynchronization() might kick in.
|
2010-11-10 16:33:11 +01:00
|
|
|
continue;
|
2010-11-09 12:50:46 +01:00
|
|
|
}
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
2010-11-10 16:33:11 +01:00
|
|
|
|
2012-04-01 20:40:05 +02:00
|
|
|
if (done) {
|
|
|
|
|
showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
|
|
|
|
|
} else {
|
|
|
|
|
showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
|
|
|
|
|
}
|
2010-09-13 13:30:35 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-10 01:07:01 +01:00
|
|
|
bool DebuggerEngine::acceptsBreakpoint(Breakpoint bp) const
|
2010-11-08 18:55:32 +01:00
|
|
|
{
|
2015-01-10 01:07:01 +01:00
|
|
|
Q_UNUSED(bp);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::insertBreakpoint(Breakpoint bp)
|
|
|
|
|
{
|
|
|
|
|
BreakpointState state = bp.state();
|
|
|
|
|
QTC_ASSERT(state == BreakpointInsertRequested,
|
|
|
|
|
qDebug() << bp.id() << this << state);
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(false);
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
|
|
|
|
|
2015-01-10 01:07:01 +01:00
|
|
|
void DebuggerEngine::removeBreakpoint(Breakpoint bp)
|
2010-11-08 18:55:32 +01:00
|
|
|
{
|
2015-01-10 01:07:01 +01:00
|
|
|
BreakpointState state = bp.state();
|
|
|
|
|
QTC_ASSERT(state == BreakpointRemoveRequested,
|
|
|
|
|
qDebug() << bp.id() << this << state);
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(false);
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
|
|
|
|
|
2015-01-10 01:07:01 +01:00
|
|
|
void DebuggerEngine::changeBreakpoint(Breakpoint bp)
|
2010-11-08 18:55:32 +01:00
|
|
|
{
|
2015-01-10 01:07:01 +01:00
|
|
|
BreakpointState state = bp.state();
|
|
|
|
|
QTC_ASSERT(state == BreakpointChangeRequested,
|
|
|
|
|
qDebug() << bp.id() << this << state);
|
2011-07-29 12:00:11 +02:00
|
|
|
QTC_CHECK(false);
|
2010-11-08 18:55:32 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-19 12:42:53 +01:00
|
|
|
void DebuggerEngine::assignValueInDebugger(WatchItem *,
|
2010-12-14 12:29:32 +01:00
|
|
|
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
|
|
|
{
|
2011-08-03 18:57:37 +02:00
|
|
|
QTC_ASSERT(d->m_state == InferiorStopOk || d->m_state == InferiorUnrunnable
|
|
|
|
|
|| d->m_state == InferiorRunOk, qDebug() << d->m_state);
|
|
|
|
|
quitDebugger();
|
2010-11-08 15:19:13 +01:00
|
|
|
}
|
|
|
|
|
|
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()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-23 10:16:11 +01:00
|
|
|
void DebuggerEngine::executeRunToLine(const ContextData &)
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::executeRunToFunction(const QString &)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-23 10:16:11 +01:00
|
|
|
void DebuggerEngine::executeJumpToLine(const ContextData &)
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-10 09:36:15 +02:00
|
|
|
void DebuggerEngine::executeDebuggerCommand(const QString &, DebuggerLanguages)
|
2010-09-13 13:30:35 +02:00
|
|
|
{
|
2011-02-16 12:41:06 +01:00
|
|
|
showStatusMessage(tr("This debugger cannot handle user input."));
|
2010-11-04 09:54:23 +01:00
|
|
|
}
|
2010-09-13 13:30:35 +02:00
|
|
|
|
2010-12-14 12:29:32 +01:00
|
|
|
BreakHandler *DebuggerEngine::breakHandler() const
|
2010-11-04 09:54:23 +01:00
|
|
|
{
|
2014-07-28 14:23:52 +02:00
|
|
|
return Internal::breakHandler();
|
2010-09-13 13:30:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::isDying() const
|
|
|
|
|
{
|
|
|
|
|
return targetState() == DebuggerFinished;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-17 17:16:34 +01:00
|
|
|
QString DebuggerEngine::msgStopped(const QString &reason)
|
|
|
|
|
{
|
2015-03-16 15:34:45 +01:00
|
|
|
return reason.isEmpty() ? tr("Stopped.") : tr("Stopped: \"%1\".").arg(reason);
|
2010-11-17 17:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
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
|
|
|
{
|
2011-02-23 11:28:20 +01:00
|
|
|
return tr("Stopped: %1 (Signal %2).").arg(meaning, name);
|
2010-11-17 17:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
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())
|
2013-10-17 14:52:10 +02:00
|
|
|
name = QLatin1Char(' ') + tr("<Unknown>", "name") + QLatin1Char(' ');
|
2010-11-17 17:16:34 +01:00
|
|
|
if (meaning.isEmpty())
|
2013-10-17 14:52:10 +02:00
|
|
|
meaning = QLatin1Char(' ') + tr("<Unknown>", "meaning") + QLatin1Char(' ');
|
2010-11-17 17:16:34 +01:00
|
|
|
const QString msg = tr("<p>The inferior stopped because it received a "
|
2015-03-16 15:34:45 +01:00
|
|
|
"signal from the operating system.<p>"
|
2010-11-17 17:16:34 +01:00
|
|
|
"<table><tr><td>Signal name : </td><td>%1</td></tr>"
|
|
|
|
|
"<tr><td>Signal meaning : </td><td>%2</td></tr></table>")
|
|
|
|
|
.arg(name, meaning);
|
2015-03-16 15:34:45 +01:00
|
|
|
AsynchronousMessageBox::information(tr("Signal Received"), msg);
|
2010-11-17 17:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2015-02-03 23:58:49 +02:00
|
|
|
AsynchronousMessageBox::information(tr("Exception Triggered"), msg);
|
2010-11-17 17:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
2014-12-17 13:14:29 +01:00
|
|
|
void DebuggerEngine::openMemoryView(const MemoryViewSetupData &data)
|
2010-12-08 12:43:11 +01:00
|
|
|
{
|
2014-12-17 13:14:29 +01:00
|
|
|
d->m_memoryAgent.createBinEditor(data);
|
2011-04-08 16:18:47 +02:00
|
|
|
}
|
|
|
|
|
|
2010-12-13 18:17:31 +01:00
|
|
|
void DebuggerEngine::updateMemoryViews()
|
|
|
|
|
{
|
2010-12-14 12:29:32 +01:00
|
|
|
d->m_memoryAgent.updateContents();
|
2010-12-08 12:43:11 +01:00
|
|
|
}
|
|
|
|
|
|
2010-12-16 19:06:33 +01:00
|
|
|
void DebuggerEngine::openDisassemblerView(const Location &location)
|
2010-12-08 12:43:11 +01:00
|
|
|
{
|
2010-12-14 12:29:32 +01:00
|
|
|
DisassemblerAgent *agent = new DisassemblerAgent(this);
|
2010-12-16 19:06:33 +01:00
|
|
|
agent->setLocation(location);
|
2010-12-08 12:43:11 +01:00
|
|
|
}
|
|
|
|
|
|
2011-01-14 14:25:02 +01:00
|
|
|
bool DebuggerEngine::isStateDebugging() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_isStateDebugging;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerEngine::setStateDebugging(bool on)
|
|
|
|
|
{
|
|
|
|
|
d->m_isStateDebugging = on;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-27 13:59:56 +02:00
|
|
|
void DebuggerEngine::validateExecutable(DebuggerRunParameters *sp)
|
2013-03-04 00:42:36 -08:00
|
|
|
{
|
2015-03-31 07:55:00 +02:00
|
|
|
if (sp->skipExecutableValidation)
|
|
|
|
|
return;
|
2014-09-07 23:24:10 +03:00
|
|
|
if (sp->languages == QmlLanguage)
|
2013-03-04 00:42:36 -08:00
|
|
|
return;
|
2014-09-07 23:24:10 +03:00
|
|
|
QString binary = sp->executable;
|
2013-03-04 00:42:36 -08:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
2014-09-07 23:24:10 +03:00
|
|
|
const bool warnOnRelease = boolSetting(WarnOnReleaseBuilds);
|
2013-03-04 00:42:36 -08:00
|
|
|
QString detailedWarning;
|
2014-09-07 23:24:10 +03:00
|
|
|
switch (sp->toolChainAbi.binaryFormat()) {
|
2015-02-03 23:58:49 +02:00
|
|
|
case Abi::PEFormat: {
|
2014-09-07 23:24:10 +03:00
|
|
|
if (!warnOnRelease || (sp->masterEngineType != CdbEngineType))
|
2013-03-04 00:42:36 -08:00
|
|
|
return;
|
|
|
|
|
if (!binary.endsWith(QLatin1String(".exe"), Qt::CaseInsensitive))
|
|
|
|
|
binary.append(QLatin1String(".exe"));
|
|
|
|
|
QString errorMessage;
|
|
|
|
|
QStringList rc;
|
|
|
|
|
if (getPDBFiles(binary, &rc, &errorMessage) && !rc.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
if (!errorMessage.isEmpty()) {
|
2013-04-15 13:45:43 +02:00
|
|
|
detailedWarning.append(QLatin1Char('\n'));
|
|
|
|
|
detailedWarning.append(errorMessage);
|
2013-03-04 00:42:36 -08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-02-03 23:58:49 +02:00
|
|
|
case Abi::ElfFormat: {
|
2013-03-04 00:42:36 -08:00
|
|
|
|
|
|
|
|
Utils::ElfReader reader(binary);
|
|
|
|
|
Utils::ElfData elfData = reader.readHeaders();
|
|
|
|
|
QString error = reader.errorString();
|
|
|
|
|
|
2014-10-22 13:04:47 +02:00
|
|
|
Internal::showMessage(_("EXAMINING ") + binary, LogDebug);
|
2013-03-04 00:42:36 -08:00
|
|
|
QByteArray msg = "ELF SECTIONS: ";
|
|
|
|
|
|
|
|
|
|
static QList<QByteArray> interesting;
|
|
|
|
|
if (interesting.isEmpty()) {
|
|
|
|
|
interesting.append(".debug_info");
|
|
|
|
|
interesting.append(".debug_abbrev");
|
|
|
|
|
interesting.append(".debug_line");
|
|
|
|
|
interesting.append(".debug_str");
|
|
|
|
|
interesting.append(".debug_loc");
|
|
|
|
|
interesting.append(".debug_range");
|
|
|
|
|
interesting.append(".gdb_index");
|
|
|
|
|
interesting.append(".note.gnu.build-id");
|
|
|
|
|
interesting.append(".gnu.hash");
|
|
|
|
|
interesting.append(".gnu_debuglink");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QSet<QByteArray> seen;
|
|
|
|
|
foreach (const Utils::ElfSectionHeader &header, elfData.sectionHeaders) {
|
|
|
|
|
msg.append(header.name);
|
|
|
|
|
msg.append(' ');
|
|
|
|
|
if (interesting.contains(header.name))
|
|
|
|
|
seen.insert(header.name);
|
|
|
|
|
}
|
2014-10-22 13:04:47 +02:00
|
|
|
Internal::showMessage(_(msg), LogDebug);
|
2013-03-04 00:42:36 -08:00
|
|
|
|
|
|
|
|
if (!error.isEmpty()) {
|
2014-10-22 13:04:47 +02:00
|
|
|
Internal::showMessage(_("ERROR WHILE READING ELF SECTIONS: ") + error,
|
2013-03-04 00:42:36 -08:00
|
|
|
LogDebug);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (elfData.sectionHeaders.isEmpty()) {
|
2014-10-22 13:04:47 +02:00
|
|
|
Internal::showMessage(_("NO SECTION HEADERS FOUND. IS THIS AN EXECUTABLE?"),
|
2013-03-04 00:42:36 -08:00
|
|
|
LogDebug);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Note: .note.gnu.build-id also appears in regular release builds.
|
|
|
|
|
// bool hasBuildId = elfData.indexOf(".note.gnu.build-id") >= 0;
|
|
|
|
|
bool hasEmbeddedInfo = elfData.indexOf(".debug_info") >= 0;
|
|
|
|
|
bool hasLink = elfData.indexOf(".gnu_debuglink") >= 0;
|
2014-09-07 23:24:10 +03:00
|
|
|
if (hasEmbeddedInfo) {
|
2014-10-22 13:04:47 +02:00
|
|
|
QSharedPointer<GlobalDebuggerOptions> options = Internal::globalDebuggerOptions();
|
2014-09-21 09:27:08 +03:00
|
|
|
SourcePathRegExpMap globalRegExpSourceMap;
|
|
|
|
|
globalRegExpSourceMap.reserve(options->sourcePathRegExpMap.size());
|
|
|
|
|
foreach (auto entry, options->sourcePathRegExpMap) {
|
2014-10-15 14:45:31 +02:00
|
|
|
const QString expanded = Utils::globalMacroExpander()->expand(entry.second);
|
2014-09-21 09:27:08 +03:00
|
|
|
if (!expanded.isEmpty())
|
|
|
|
|
globalRegExpSourceMap.push_back(qMakePair(entry.first, expanded));
|
|
|
|
|
}
|
|
|
|
|
if (globalRegExpSourceMap.isEmpty())
|
|
|
|
|
return;
|
2014-09-07 23:24:10 +03:00
|
|
|
if (QSharedPointer<Utils::ElfMapper> mapper = reader.readSection(".debug_str")) {
|
|
|
|
|
const char *str = mapper->start;
|
|
|
|
|
const char *limit = str + mapper->fdlen;
|
2014-09-20 23:07:58 +03:00
|
|
|
bool found = false;
|
2014-09-07 23:24:10 +03:00
|
|
|
while (str < limit) {
|
2014-09-20 23:07:58 +03:00
|
|
|
const QString string = QString::fromUtf8(str);
|
|
|
|
|
for (auto itExp = globalRegExpSourceMap.begin(), itEnd = globalRegExpSourceMap.end();
|
|
|
|
|
itExp != itEnd;
|
|
|
|
|
++itExp) {
|
2014-09-07 23:24:10 +03:00
|
|
|
QRegExp exp = itExp->first;
|
|
|
|
|
int index = exp.indexIn(string);
|
|
|
|
|
if (index != -1) {
|
|
|
|
|
sp->sourcePathMap.insert(string.left(index) + exp.cap(1), itExp->second);
|
2014-09-20 23:07:58 +03:00
|
|
|
found = true;
|
|
|
|
|
break;
|
2014-09-07 23:24:10 +03:00
|
|
|
}
|
|
|
|
|
}
|
2014-09-20 23:07:58 +03:00
|
|
|
if (found)
|
2014-09-07 23:24:10 +03:00
|
|
|
break;
|
|
|
|
|
|
2015-02-19 16:44:58 +01:00
|
|
|
const int len = int(strlen(str));
|
2014-09-07 23:24:10 +03:00
|
|
|
if (len == 0)
|
|
|
|
|
break;
|
|
|
|
|
str += len + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-03-04 00:42:36 -08:00
|
|
|
if (hasEmbeddedInfo || hasLink)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
foreach (const QByteArray &name, interesting) {
|
2013-05-14 17:36:28 +02:00
|
|
|
const QString found = seen.contains(name) ? tr("Found.") : tr("Not found.");
|
2014-02-28 14:37:46 +01:00
|
|
|
detailedWarning.append(QLatin1Char('\n') + tr("Section %1: %2").arg(_(name)).arg(found));
|
2013-03-04 00:42:36 -08:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-09-07 23:24:10 +03:00
|
|
|
if (warnOnRelease) {
|
2015-02-03 23:58:49 +02:00
|
|
|
AsynchronousMessageBox::information(tr("Warning"),
|
2014-09-07 23:24:10 +03:00
|
|
|
tr("This does not seem to be a \"Debug\" build.\n"
|
|
|
|
|
"Setting breakpoints by file name and line number may fail.")
|
|
|
|
|
+ QLatin1Char('\n') + detailedWarning);
|
|
|
|
|
}
|
2013-03-04 00:42:36 -08:00
|
|
|
}
|
|
|
|
|
|
2015-03-26 13:03:38 +01:00
|
|
|
void DebuggerEngine::updateLocalsView(const GdbMi &all)
|
|
|
|
|
{
|
|
|
|
|
WatchHandler *handler = watchHandler();
|
|
|
|
|
|
|
|
|
|
const bool partial = all["partial"].toInt();
|
|
|
|
|
|
|
|
|
|
const GdbMi typeInfo = all["typeinfo"];
|
|
|
|
|
if (typeInfo.type() == GdbMi::List) {
|
|
|
|
|
foreach (const GdbMi &s, typeInfo.children()) {
|
|
|
|
|
const GdbMi name = s["name"];
|
|
|
|
|
const GdbMi size = s["size"];
|
|
|
|
|
if (name.isValid() && size.isValid())
|
|
|
|
|
d->m_typeInfoCache.insert(QByteArray::fromHex(name.data()),
|
|
|
|
|
TypeInfo(size.data().toUInt()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GdbMi data = all["data"];
|
|
|
|
|
foreach (const GdbMi &child, data.children()) {
|
2015-12-16 17:17:38 +01:00
|
|
|
WatchItem *item = new WatchItem;
|
|
|
|
|
item->parse(child);
|
2015-03-26 13:03:38 +01:00
|
|
|
const TypeInfo ti = d->m_typeInfoCache.value(item->type);
|
2015-12-16 17:17:38 +01:00
|
|
|
if (ti.size && !item->size)
|
2015-03-26 13:03:38 +01:00
|
|
|
item->size = ti.size;
|
|
|
|
|
|
|
|
|
|
handler->insertItem(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GdbMi ns = all["qtnamespace"];
|
|
|
|
|
if (ns.isValid()) {
|
|
|
|
|
setQtNamespace(ns.data());
|
|
|
|
|
showMessage(_("FOUND NAMESPACED QT: " + ns.data()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int count = 0;
|
|
|
|
|
showMessage(_("<Rebuild Watchmodel %1 @ %2 >")
|
|
|
|
|
.arg(++count).arg(LogWindow::logTimeStamp()), LogMiscInput);
|
|
|
|
|
showStatusMessage(GdbEngine::tr("Finished retrieving data"), 400); // FIXME: String
|
|
|
|
|
|
|
|
|
|
DebuggerToolTipManager::updateEngine(this);
|
|
|
|
|
|
|
|
|
|
if (!partial)
|
|
|
|
|
emit stackFrameCompleted();
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-08 18:07:11 +02:00
|
|
|
bool DebuggerEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
|
|
|
|
|
{
|
|
|
|
|
return state() == InferiorStopOk && context.isCppEditor;
|
|
|
|
|
}
|
2015-05-27 13:59:56 +02:00
|
|
|
|
2015-07-15 17:14:29 +02:00
|
|
|
void DebuggerEngine::updateItem(const QByteArray &iname)
|
2015-05-27 13:59:56 +02:00
|
|
|
{
|
2015-06-08 18:07:11 +02:00
|
|
|
UpdateParameters params;
|
|
|
|
|
params.partialVariable = iname;
|
|
|
|
|
doUpdateLocals(params);
|
2015-05-27 13:59:56 +02:00
|
|
|
}
|
|
|
|
|
|
2015-07-15 17:14:29 +02:00
|
|
|
void DebuggerEngine::expandItem(const QByteArray &iname)
|
|
|
|
|
{
|
|
|
|
|
updateItem(iname);
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-11 16:51:11 +02:00
|
|
|
void DebuggerEngine::checkState(DebuggerState state, const char *file, int line)
|
|
|
|
|
{
|
|
|
|
|
const DebuggerState current = d->m_state;
|
|
|
|
|
if (current == state)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QString msg = QString::fromLatin1("UNEXPECTED STATE: %1 WANTED: %2 IN %3:%4")
|
|
|
|
|
.arg(current).arg(state).arg(QLatin1String(file)).arg(line);
|
|
|
|
|
|
|
|
|
|
showMessage(msg, LogError);
|
|
|
|
|
qDebug("%s", qPrintable(msg));
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-08 16:19:57 +02:00
|
|
|
bool DebuggerEngine::isNativeMixedEnabled() const
|
|
|
|
|
{
|
|
|
|
|
return runParameters().nativeMixedEnabled && (runParameters().languages & QmlLanguage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::isNativeMixedActive() const
|
|
|
|
|
{
|
|
|
|
|
return isNativeMixedEnabled(); //&& boolSetting(OperateNativeMixed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DebuggerEngine::isNativeMixedActiveFrame() const
|
|
|
|
|
{
|
|
|
|
|
if (!isNativeMixedActive())
|
|
|
|
|
return false;
|
|
|
|
|
if (stackHandler()->frames().isEmpty())
|
|
|
|
|
return false;
|
|
|
|
|
StackFrame frame = stackHandler()->frameAt(0);
|
|
|
|
|
return frame.language == QmlLanguage;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-12 15:33:16 +01:00
|
|
|
} // namespace Internal
|
2010-06-16 11:08:54 +02:00
|
|
|
} // namespace Debugger
|
2010-06-25 16:06:48 +02:00
|
|
|
|
|
|
|
|
#include "debuggerengine.moc"
|