2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-06-17 00:01:27 +10:00
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Commercial Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and Nokia.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** If you are unsure which license is appropriate for your use, please
|
2009-08-14 09:30:56 +02:00
|
|
|
** contact the sales department at http://qt.nokia.com/contact.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
#include "debuggermanager.h"
|
|
|
|
|
|
2009-03-17 17:00:06 +01:00
|
|
|
#include "debuggeractions.h"
|
2009-05-05 17:48:54 +02:00
|
|
|
#include "debuggerrunner.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "debuggerconstants.h"
|
|
|
|
|
#include "idebuggerengine.h"
|
|
|
|
|
|
|
|
|
|
#include "breakwindow.h"
|
|
|
|
|
#include "debuggeroutputwindow.h"
|
|
|
|
|
#include "moduleswindow.h"
|
|
|
|
|
#include "registerwindow.h"
|
|
|
|
|
#include "stackwindow.h"
|
2009-02-17 14:08:49 +01:00
|
|
|
#include "sourcefileswindow.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "threadswindow.h"
|
|
|
|
|
#include "watchwindow.h"
|
|
|
|
|
|
|
|
|
|
#include "breakhandler.h"
|
|
|
|
|
#include "moduleshandler.h"
|
|
|
|
|
#include "registerhandler.h"
|
|
|
|
|
#include "stackhandler.h"
|
2009-08-17 16:03:27 +02:00
|
|
|
#include "stackframe.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "watchhandler.h"
|
|
|
|
|
|
2009-03-02 13:08:30 +01:00
|
|
|
#include "debuggerdialogs.h"
|
2009-03-03 14:01:58 +01:00
|
|
|
#ifdef Q_OS_WIN
|
2009-05-19 15:45:58 +02:00
|
|
|
# include "shared/peutils.h"
|
2009-03-03 14:01:58 +01:00
|
|
|
#endif
|
2009-04-20 16:40:50 +02:00
|
|
|
#include <coreplugin/icore.h>
|
2009-02-16 09:59:12 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2009-08-06 16:01:51 +02:00
|
|
|
#include <utils/fancymainwindow.h>
|
2009-06-18 15:16:18 +02:00
|
|
|
#include <projectexplorer/toolchain.h>
|
2009-02-16 09:59:12 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <QtCore/QDebug>
|
|
|
|
|
#include <QtCore/QDir>
|
|
|
|
|
#include <QtCore/QFileInfo>
|
2009-03-10 18:38:14 +01:00
|
|
|
#include <QtCore/QTextStream>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <QtCore/QTime>
|
2008-12-08 14:26:11 +01:00
|
|
|
#include <QtCore/QTimer>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-06-24 12:31:09 +02:00
|
|
|
#include <QtGui/QApplication>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <QtGui/QAction>
|
|
|
|
|
#include <QtGui/QComboBox>
|
|
|
|
|
#include <QtGui/QDockWidget>
|
|
|
|
|
#include <QtGui/QErrorMessage>
|
|
|
|
|
#include <QtGui/QFileDialog>
|
|
|
|
|
#include <QtGui/QLabel>
|
|
|
|
|
#include <QtGui/QMessageBox>
|
|
|
|
|
#include <QtGui/QPlainTextEdit>
|
2009-06-24 12:31:09 +02:00
|
|
|
#include <QtGui/QPushButton>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <QtGui/QStatusBar>
|
|
|
|
|
#include <QtGui/QTextBlock>
|
|
|
|
|
#include <QtGui/QTextCursor>
|
|
|
|
|
#include <QtGui/QToolButton>
|
|
|
|
|
#include <QtGui/QToolTip>
|
|
|
|
|
|
2009-06-24 12:31:09 +02:00
|
|
|
|
|
|
|
|
// The creation functions take a list of options pages they can add to.
|
|
|
|
|
// This allows for having a "enabled" toggle on the page indepently
|
|
|
|
|
// of the engine.
|
|
|
|
|
using namespace Debugger::Internal;
|
|
|
|
|
|
|
|
|
|
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *);
|
|
|
|
|
IDebuggerEngine *createWinEngine(DebuggerManager *, bool /* cmdLineEnabled */, QList<Core::IOptionsPage*> *)
|
|
|
|
|
#ifdef CDB_ENABLED
|
|
|
|
|
;
|
|
|
|
|
#else
|
|
|
|
|
{ return 0; }
|
|
|
|
|
#endif
|
|
|
|
|
IDebuggerEngine *createScriptEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *);
|
|
|
|
|
IDebuggerEngine *createTcfEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *);
|
|
|
|
|
|
|
|
|
|
|
2009-05-25 16:22:11 +02:00
|
|
|
namespace Debugger {
|
2009-06-24 12:31:09 +02:00
|
|
|
namespace Internal {
|
|
|
|
|
|
2009-05-25 16:22:11 +02:00
|
|
|
QDebug operator<<(QDebug str, const DebuggerStartParameters &p)
|
|
|
|
|
{
|
|
|
|
|
QDebug nospace = str.nospace();
|
|
|
|
|
const QString sep = QString(QLatin1Char(','));
|
|
|
|
|
nospace << "executable=" << p.executable << " coreFile=" << p.coreFile
|
|
|
|
|
<< " processArgs=" << p.processArgs.join(sep)
|
|
|
|
|
<< " environment=<" << p.environment.size() << " variables>"
|
|
|
|
|
<< " workingDir=" << p.workingDir << " buildDir=" << p.buildDir
|
|
|
|
|
<< " attachPID=" << p.attachPID << " useTerminal=" << p.useTerminal
|
|
|
|
|
<< " remoteChannel=" << p.remoteChannel
|
|
|
|
|
<< " remoteArchitecture=" << p.remoteArchitecture
|
2009-06-18 15:16:18 +02:00
|
|
|
<< " serverStartScript=" << p.serverStartScript
|
|
|
|
|
<< " toolchain=" << p.toolChainType << '\n';
|
2009-05-25 16:22:11 +02:00
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-24 12:31:09 +02:00
|
|
|
using namespace Constants;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
static const QString tooltipIName = "tooltip";
|
|
|
|
|
|
2009-03-25 13:42:47 +01:00
|
|
|
static const char *stateName(int s)
|
|
|
|
|
{
|
|
|
|
|
switch (s) {
|
|
|
|
|
case DebuggerProcessNotReady:
|
|
|
|
|
return "DebuggerProcessNotReady";
|
|
|
|
|
case DebuggerProcessStartingUp:
|
|
|
|
|
return "DebuggerProcessStartingUp";
|
|
|
|
|
case DebuggerInferiorRunningRequested:
|
|
|
|
|
return "DebuggerInferiorRunningRequested";
|
|
|
|
|
case DebuggerInferiorRunning:
|
|
|
|
|
return "DebuggerInferiorRunning";
|
|
|
|
|
case DebuggerInferiorStopRequested:
|
|
|
|
|
return "DebuggerInferiorStopRequested";
|
|
|
|
|
case DebuggerInferiorStopped:
|
|
|
|
|
return "DebuggerInferiorStopped";
|
|
|
|
|
}
|
|
|
|
|
return "<unknown>";
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
2009-06-24 12:31:09 +02:00
|
|
|
// DebuggerStartParameters
|
2008-12-02 12:01:29 +01:00
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2009-06-24 12:31:09 +02:00
|
|
|
DebuggerStartParameters::DebuggerStartParameters()
|
|
|
|
|
: attachPID(-1),
|
2009-06-18 15:16:18 +02:00
|
|
|
useTerminal(false),
|
|
|
|
|
toolChainType(ProjectExplorer::ToolChain::UNKNOWN)
|
2009-06-24 12:31:09 +02:00
|
|
|
{}
|
2009-05-25 16:22:11 +02:00
|
|
|
|
|
|
|
|
void DebuggerStartParameters::clear()
|
|
|
|
|
{
|
|
|
|
|
executable.clear();
|
|
|
|
|
coreFile.clear();
|
|
|
|
|
processArgs.clear();
|
|
|
|
|
environment.clear();
|
|
|
|
|
workingDir.clear();
|
|
|
|
|
buildDir.clear();
|
|
|
|
|
attachPID = -1;
|
|
|
|
|
useTerminal = false;
|
2009-05-26 16:27:24 +02:00
|
|
|
crashParameter.clear();
|
2009-05-25 16:22:11 +02:00
|
|
|
remoteChannel.clear();
|
|
|
|
|
remoteArchitecture.clear();
|
|
|
|
|
serverStartScript.clear();
|
2009-06-18 15:16:18 +02:00
|
|
|
toolChainType = ProjectExplorer::ToolChain::UNKNOWN;
|
2009-05-25 16:22:11 +02:00
|
|
|
}
|
|
|
|
|
|
2009-06-24 12:31:09 +02:00
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// DebuggerManager
|
|
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
static IDebuggerEngine *gdbEngine = 0;
|
|
|
|
|
static IDebuggerEngine *winEngine = 0;
|
|
|
|
|
static IDebuggerEngine *scriptEngine = 0;
|
|
|
|
|
static IDebuggerEngine *tcfEngine = 0;
|
|
|
|
|
|
|
|
|
|
DebuggerManager::DebuggerManager()
|
|
|
|
|
: m_startParameters(new DebuggerStartParameters),
|
2009-07-13 09:11:07 +02:00
|
|
|
m_inferiorPid(0)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-04-17 09:03:32 +02:00
|
|
|
init();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DebuggerManager::~DebuggerManager()
|
|
|
|
|
{
|
2009-05-11 10:22:03 +02:00
|
|
|
#define doDelete(ptr) delete ptr; ptr = 0
|
|
|
|
|
doDelete(gdbEngine);
|
|
|
|
|
doDelete(winEngine);
|
|
|
|
|
doDelete(scriptEngine);
|
|
|
|
|
doDelete(tcfEngine);
|
|
|
|
|
#undef doDelete
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-04-17 09:03:32 +02:00
|
|
|
void DebuggerManager::init()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
m_status = -1;
|
|
|
|
|
m_busy = false;
|
|
|
|
|
|
2009-05-05 17:48:54 +02:00
|
|
|
m_runControl = 0;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_modulesHandler = 0;
|
|
|
|
|
m_registerHandler = 0;
|
|
|
|
|
|
2008-12-08 14:26:11 +01:00
|
|
|
m_statusLabel = new QLabel;
|
2009-08-13 13:18:13 +02:00
|
|
|
m_statusLabel->setMinimumSize(QSize(30, 10));
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
m_breakWindow = new BreakWindow;
|
2009-04-15 12:01:58 +02:00
|
|
|
m_modulesWindow = new ModulesWindow(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
m_outputWindow = new DebuggerOutputWindow;
|
2009-08-14 13:04:05 +02:00
|
|
|
m_registerWindow = new RegisterWindow(this);
|
|
|
|
|
m_stackWindow = new StackWindow(this);
|
2009-02-17 14:08:49 +01:00
|
|
|
m_sourceFilesWindow = new SourceFilesWindow;
|
2008-12-02 12:01:29 +01:00
|
|
|
m_threadsWindow = new ThreadsWindow;
|
2009-08-12 10:51:25 +02:00
|
|
|
m_localsWindow = new WatchWindow(WatchWindow::LocalsType, this);
|
|
|
|
|
m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this);
|
|
|
|
|
//m_tooltipWindow = new WatchWindow(WatchWindow::TooltipType, this);
|
2008-12-08 14:26:11 +01:00
|
|
|
m_statusTimer = new QTimer(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_mainWindow = new Core::Utils::FancyMainWindow;
|
2008-12-02 12:01:29 +01:00
|
|
|
m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
|
|
|
|
|
m_mainWindow->setDocumentMode(true);
|
|
|
|
|
|
|
|
|
|
// Stack
|
|
|
|
|
m_stackHandler = new StackHandler;
|
|
|
|
|
QAbstractItemView *stackView =
|
|
|
|
|
qobject_cast<QAbstractItemView *>(m_stackWindow);
|
|
|
|
|
stackView->setModel(m_stackHandler->stackModel());
|
|
|
|
|
connect(stackView, SIGNAL(frameActivated(int)),
|
|
|
|
|
this, SLOT(activateFrame(int)));
|
2009-05-06 10:21:50 +02:00
|
|
|
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(reloadFullStack()));
|
|
|
|
|
connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(reloadFullStack()));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
// Threads
|
|
|
|
|
m_threadsHandler = new ThreadsHandler;
|
|
|
|
|
QAbstractItemView *threadsView =
|
|
|
|
|
qobject_cast<QAbstractItemView *>(m_threadsWindow);
|
|
|
|
|
threadsView->setModel(m_threadsHandler->threadsModel());
|
|
|
|
|
connect(threadsView, SIGNAL(threadSelected(int)),
|
|
|
|
|
this, SLOT(selectThread(int)));
|
|
|
|
|
|
|
|
|
|
// Breakpoints
|
2009-08-14 13:04:05 +02:00
|
|
|
m_breakHandler = new BreakHandler(this);
|
2008-12-02 12:01:29 +01:00
|
|
|
QAbstractItemView *breakView =
|
|
|
|
|
qobject_cast<QAbstractItemView *>(m_breakWindow);
|
|
|
|
|
breakView->setModel(m_breakHandler->model());
|
2009-03-10 17:30:11 +01:00
|
|
|
connect(breakView, SIGNAL(breakpointActivated(int)),
|
|
|
|
|
m_breakHandler, SLOT(activateBreakpoint(int)));
|
|
|
|
|
connect(breakView, SIGNAL(breakpointDeleted(int)),
|
2008-12-02 12:01:29 +01:00
|
|
|
m_breakHandler, SLOT(removeBreakpoint(int)));
|
2009-03-10 17:30:11 +01:00
|
|
|
connect(breakView, SIGNAL(breakpointSynchronizationRequested()),
|
|
|
|
|
this, SLOT(attemptBreakpointSynchronization()));
|
2009-06-12 11:54:01 +02:00
|
|
|
connect(breakView, SIGNAL(breakByFunctionRequested(QString)),
|
|
|
|
|
this, SLOT(breakByFunction(QString)), Qt::QueuedConnection);
|
2009-06-12 12:57:22 +02:00
|
|
|
connect(breakView, SIGNAL(breakByFunctionMainRequested()),
|
|
|
|
|
this, SLOT(breakByFunctionMain()), Qt::QueuedConnection);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
// Modules
|
|
|
|
|
QAbstractItemView *modulesView =
|
|
|
|
|
qobject_cast<QAbstractItemView *>(m_modulesWindow);
|
|
|
|
|
m_modulesHandler = new ModulesHandler;
|
|
|
|
|
modulesView->setModel(m_modulesHandler->model());
|
|
|
|
|
connect(modulesView, SIGNAL(reloadModulesRequested()),
|
|
|
|
|
this, SLOT(reloadModules()));
|
|
|
|
|
connect(modulesView, SIGNAL(loadSymbolsRequested(QString)),
|
|
|
|
|
this, SLOT(loadSymbols(QString)));
|
|
|
|
|
connect(modulesView, SIGNAL(loadAllSymbolsRequested()),
|
|
|
|
|
this, SLOT(loadAllSymbols()));
|
2009-03-10 19:35:17 +01:00
|
|
|
connect(modulesView, SIGNAL(fileOpenRequested(QString)),
|
|
|
|
|
this, SLOT(fileOpen(QString)));
|
2009-03-12 14:17:32 +01:00
|
|
|
connect(modulesView, SIGNAL(newDockRequested(QWidget*)),
|
|
|
|
|
this, SLOT(createNewDock(QWidget*)));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-02-17 14:08:49 +01:00
|
|
|
// Source Files
|
|
|
|
|
//m_sourceFilesHandler = new SourceFilesHandler;
|
|
|
|
|
QAbstractItemView *sourceFilesView =
|
|
|
|
|
qobject_cast<QAbstractItemView *>(m_sourceFilesWindow);
|
|
|
|
|
//sourceFileView->setModel(m_stackHandler->stackModel());
|
|
|
|
|
connect(sourceFilesView, SIGNAL(reloadSourceFilesRequested()),
|
|
|
|
|
this, SLOT(reloadSourceFiles()));
|
2009-03-10 19:35:17 +01:00
|
|
|
connect(sourceFilesView, SIGNAL(fileOpenRequested(QString)),
|
|
|
|
|
this, SLOT(fileOpen(QString)));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-25 16:22:11 +02:00
|
|
|
// Registers
|
2008-12-02 12:01:29 +01:00
|
|
|
QAbstractItemView *registerView =
|
|
|
|
|
qobject_cast<QAbstractItemView *>(m_registerWindow);
|
|
|
|
|
m_registerHandler = new RegisterHandler;
|
|
|
|
|
registerView->setModel(m_registerHandler->model());
|
|
|
|
|
|
2009-07-13 09:11:07 +02:00
|
|
|
// Locals
|
|
|
|
|
m_watchHandler = new WatchHandler;
|
|
|
|
|
QTreeView *localsView = qobject_cast<QTreeView *>(m_localsWindow);
|
|
|
|
|
localsView->setModel(m_watchHandler->model(LocalsWatch));
|
|
|
|
|
|
|
|
|
|
// Watchers
|
|
|
|
|
QTreeView *watchersView = qobject_cast<QTreeView *>(m_watchersWindow);
|
|
|
|
|
watchersView->setModel(m_watchHandler->model(WatchersWatch));
|
2008-12-17 17:43:01 +01:00
|
|
|
connect(m_watchHandler, SIGNAL(sessionValueRequested(QString,QVariant*)),
|
|
|
|
|
this, SIGNAL(sessionValueRequested(QString,QVariant*)));
|
|
|
|
|
connect(m_watchHandler, SIGNAL(setSessionValueRequested(QString,QVariant)),
|
|
|
|
|
this, SIGNAL(setSessionValueRequested(QString,QVariant)));
|
2009-03-19 15:54:52 +01:00
|
|
|
connect(theDebuggerAction(AssignValue), SIGNAL(triggered()),
|
2009-04-07 13:38:19 +02:00
|
|
|
this, SLOT(assignValueInDebugger()), Qt::QueuedConnection);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
// Tooltip
|
2009-07-13 09:11:07 +02:00
|
|
|
//QTreeView *tooltipView = qobject_cast<QTreeView *>(m_tooltipWindow);
|
|
|
|
|
//tooltipView->setModel(m_watchHandler->model(TooltipsWatch));
|
|
|
|
|
|
|
|
|
|
connect(m_watchHandler, SIGNAL(watchDataUpdateNeeded(WatchData)),
|
|
|
|
|
this, SLOT(updateWatchData(WatchData)));
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
m_continueAction = new QAction(this);
|
|
|
|
|
m_continueAction->setText(tr("Continue"));
|
2009-05-19 15:33:17 +02:00
|
|
|
m_continueAction->setIcon(QIcon(":/debugger/images/debugger_continue_small.png"));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_stopAction = new QAction(this);
|
|
|
|
|
m_stopAction->setText(tr("Interrupt"));
|
2009-05-19 15:33:17 +02:00
|
|
|
m_stopAction->setIcon(QIcon(":/debugger/images/debugger_interrupt_small.png"));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_resetAction = new QAction(this);
|
|
|
|
|
m_resetAction->setText(tr("Reset Debugger"));
|
|
|
|
|
|
|
|
|
|
m_nextAction = new QAction(this);
|
|
|
|
|
m_nextAction->setText(tr("Step Over"));
|
|
|
|
|
//m_nextAction->setShortcut(QKeySequence(tr("F6")));
|
2009-05-19 15:33:17 +02:00
|
|
|
m_nextAction->setIcon(QIcon(":/debugger/images/debugger_stepover_small.png"));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_stepAction = new QAction(this);
|
|
|
|
|
m_stepAction->setText(tr("Step Into"));
|
|
|
|
|
//m_stepAction->setShortcut(QKeySequence(tr("F7")));
|
2009-05-19 15:33:17 +02:00
|
|
|
m_stepAction->setIcon(QIcon(":/debugger/images/debugger_stepinto_small.png"));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_stepOutAction = new QAction(this);
|
|
|
|
|
m_stepOutAction->setText(tr("Step Out"));
|
|
|
|
|
//m_stepOutAction->setShortcut(QKeySequence(tr("Shift+F7")));
|
2009-05-19 15:33:17 +02:00
|
|
|
m_stepOutAction->setIcon(QIcon(":/debugger/images/debugger_stepout_small.png"));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_runToLineAction = new QAction(this);
|
|
|
|
|
m_runToLineAction->setText(tr("Run to Line"));
|
|
|
|
|
|
|
|
|
|
m_runToFunctionAction = new QAction(this);
|
|
|
|
|
m_runToFunctionAction->setText(tr("Run to Outermost Function"));
|
|
|
|
|
|
|
|
|
|
m_jumpToLineAction = new QAction(this);
|
|
|
|
|
m_jumpToLineAction->setText(tr("Jump to Line"));
|
|
|
|
|
|
|
|
|
|
m_breakAction = new QAction(this);
|
|
|
|
|
m_breakAction->setText(tr("Toggle Breakpoint"));
|
|
|
|
|
|
|
|
|
|
m_watchAction = new QAction(this);
|
|
|
|
|
m_watchAction->setText(tr("Add to Watch Window"));
|
|
|
|
|
|
2009-05-25 17:19:42 +02:00
|
|
|
m_reverseDirectionAction = new QAction(this);
|
|
|
|
|
m_reverseDirectionAction->setText(tr("Reverse Direction"));
|
|
|
|
|
m_reverseDirectionAction->setCheckable(true);
|
|
|
|
|
m_reverseDirectionAction->setChecked(false);
|
|
|
|
|
//m_reverseDirectionAction->setIcon(QIcon(":/debugger/images/debugger_stepoverproc_small.png"));
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
// For usuage hints oin focus{In,Out}
|
|
|
|
|
connect(m_continueAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(continueExec()));
|
|
|
|
|
|
|
|
|
|
connect(m_stopAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(interruptDebuggingRequest()));
|
|
|
|
|
connect(m_resetAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(exitDebugger()));
|
|
|
|
|
connect(m_nextAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(nextExec()));
|
|
|
|
|
connect(m_stepAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(stepExec()));
|
2009-08-14 13:04:05 +02:00
|
|
|
connect(theDebuggerAction(StepByInstruction), SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(stepByInstructionTriggered()));
|
2008-12-02 12:01:29 +01:00
|
|
|
connect(m_stepOutAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(stepOutExec()));
|
|
|
|
|
connect(m_runToLineAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(runToLineExec()));
|
|
|
|
|
connect(m_runToFunctionAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(runToFunctionExec()));
|
|
|
|
|
connect(m_jumpToLineAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(jumpToLineExec()));
|
|
|
|
|
connect(m_watchAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(addToWatchWindow()));
|
|
|
|
|
connect(m_breakAction, SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(toggleBreakpoint()));
|
|
|
|
|
|
2008-12-08 14:26:11 +01:00
|
|
|
connect(m_statusTimer, SIGNAL(timeout()),
|
|
|
|
|
this, SLOT(clearStatusMessage()));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-04-03 15:46:40 +02:00
|
|
|
connect(theDebuggerAction(ExecuteCommand), SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(executeDebuggerCommand()));
|
2009-08-14 13:04:05 +02:00
|
|
|
|
2009-07-01 12:49:41 +02:00
|
|
|
connect(theDebuggerAction(WatchPoint), SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(watchPoint()));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-08-14 13:04:05 +02:00
|
|
|
connect(theDebuggerAction(StepByInstruction), SIGNAL(triggered()),
|
|
|
|
|
this, SLOT(stepByInstructionTriggered()));
|
|
|
|
|
|
|
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_breakDock = m_mainWindow->addDockForWidget(m_breakWindow);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_modulesDock = m_mainWindow->addDockForWidget(m_modulesWindow);
|
2008-12-02 12:01:29 +01:00
|
|
|
connect(m_modulesDock->toggleViewAction(), SIGNAL(toggled(bool)),
|
|
|
|
|
this, SLOT(reloadModules()), Qt::QueuedConnection);
|
|
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_registerDock = m_mainWindow->addDockForWidget(m_registerWindow);
|
2008-12-02 12:01:29 +01:00
|
|
|
connect(m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)),
|
|
|
|
|
this, SLOT(reloadRegisters()), Qt::QueuedConnection);
|
|
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_outputDock = m_mainWindow->addDockForWidget(m_outputWindow);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_stackDock = m_mainWindow->addDockForWidget(m_stackWindow);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_sourceFilesDock = m_mainWindow->addDockForWidget(m_sourceFilesWindow);
|
2009-02-17 14:08:49 +01:00
|
|
|
connect(m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)),
|
|
|
|
|
this, SLOT(reloadSourceFiles()), Qt::QueuedConnection);
|
|
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
m_threadsDock = m_mainWindow->addDockForWidget(m_threadsWindow);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-15 14:47:28 +02:00
|
|
|
QSplitter *localsAndWatchers = new QSplitter(Qt::Vertical, 0);
|
|
|
|
|
localsAndWatchers->setWindowTitle(m_localsWindow->windowTitle());
|
|
|
|
|
localsAndWatchers->addWidget(m_localsWindow);
|
|
|
|
|
localsAndWatchers->addWidget(m_watchersWindow);
|
2009-06-24 12:31:09 +02:00
|
|
|
//localsAndWatchers->addWidget(m_tooltipWindow);
|
2009-05-15 14:47:28 +02:00
|
|
|
localsAndWatchers->setStretchFactor(0, 3);
|
|
|
|
|
localsAndWatchers->setStretchFactor(1, 1);
|
2009-06-24 12:31:09 +02:00
|
|
|
localsAndWatchers->setStretchFactor(2, 1);
|
2009-08-06 16:01:51 +02:00
|
|
|
m_watchDock = m_mainWindow->addDockForWidget(localsAndWatchers);
|
2009-05-15 14:47:28 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
setStatus(DebuggerProcessNotReady);
|
2009-04-17 09:03:32 +02:00
|
|
|
}
|
|
|
|
|
|
2009-05-25 16:22:11 +02:00
|
|
|
QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(unsigned enabledTypeFlags)
|
2009-04-17 09:03:32 +02:00
|
|
|
{
|
|
|
|
|
QList<Core::IOptionsPage*> rc;
|
2009-05-25 16:22:11 +02:00
|
|
|
if (enabledTypeFlags & GdbEngineType)
|
|
|
|
|
gdbEngine = createGdbEngine(this, &rc);
|
|
|
|
|
winEngine = createWinEngine(this, (enabledTypeFlags & CdbEngineType), &rc);
|
|
|
|
|
if (enabledTypeFlags & ScriptEngineType)
|
|
|
|
|
scriptEngine = createScriptEngine(this, &rc);
|
|
|
|
|
if (enabledTypeFlags & TcfEngineType)
|
|
|
|
|
tcfEngine = createTcfEngine(this, &rc);
|
2009-05-07 17:25:32 +02:00
|
|
|
m_engine = 0;
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
2009-04-17 09:03:32 +02:00
|
|
|
qDebug() << Q_FUNC_INFO << gdbEngine << winEngine << scriptEngine << rc.size();
|
|
|
|
|
return rc;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDebuggerEngine *DebuggerManager::engine()
|
|
|
|
|
{
|
|
|
|
|
return m_engine;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDebuggerManagerAccessForEngines *DebuggerManager::engineInterface()
|
|
|
|
|
{
|
|
|
|
|
return dynamic_cast<IDebuggerManagerAccessForEngines *>(this);
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-12 14:17:32 +01:00
|
|
|
void DebuggerManager::createNewDock(QWidget *widget)
|
|
|
|
|
{
|
|
|
|
|
QDockWidget *dockWidget = new QDockWidget(widget->windowTitle(), m_mainWindow);
|
|
|
|
|
dockWidget->setObjectName(widget->windowTitle());
|
|
|
|
|
dockWidget->setFeatures(QDockWidget::DockWidgetClosable);
|
|
|
|
|
dockWidget->setWidget(widget);
|
|
|
|
|
m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget);
|
|
|
|
|
dockWidget->show();
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::setSimpleDockWidgetArrangement()
|
|
|
|
|
{
|
2009-08-06 16:01:51 +02:00
|
|
|
m_mainWindow->setTrackingEnabled(false);
|
|
|
|
|
QList<QDockWidget *> dockWidgets = m_mainWindow->dockWidgets();
|
2009-08-11 16:28:22 +02:00
|
|
|
foreach (QDockWidget *dockWidget, dockWidgets) {
|
|
|
|
|
dockWidget->setFloating(false);
|
2008-12-02 12:01:29 +01:00
|
|
|
m_mainWindow->removeDockWidget(dockWidget);
|
2009-08-11 16:28:22 +02:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-08-06 16:01:51 +02:00
|
|
|
foreach (QDockWidget *dockWidget, dockWidgets) {
|
2008-12-02 12:01:29 +01:00
|
|
|
m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
|
|
|
|
|
dockWidget->show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_mainWindow->tabifyDockWidget(m_watchDock, m_breakDock);
|
|
|
|
|
m_mainWindow->tabifyDockWidget(m_watchDock, m_modulesDock);
|
|
|
|
|
m_mainWindow->tabifyDockWidget(m_watchDock, m_outputDock);
|
|
|
|
|
m_mainWindow->tabifyDockWidget(m_watchDock, m_registerDock);
|
|
|
|
|
m_mainWindow->tabifyDockWidget(m_watchDock, m_threadsDock);
|
2009-02-17 14:35:32 +01:00
|
|
|
m_mainWindow->tabifyDockWidget(m_watchDock, m_sourceFilesDock);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-05-11 10:22:03 +02:00
|
|
|
// They following views are rarely used in ordinary debugging. Hiding them
|
|
|
|
|
// saves cycles since the corresponding information won't be retrieved.
|
2009-02-17 14:35:32 +01:00
|
|
|
m_sourceFilesDock->hide();
|
2008-12-02 12:01:29 +01:00
|
|
|
m_registerDock->hide();
|
|
|
|
|
m_modulesDock->hide();
|
|
|
|
|
m_outputDock->hide();
|
2009-08-06 16:01:51 +02:00
|
|
|
m_mainWindow->setTrackingEnabled(true);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *DebuggerManager::threadsModel()
|
|
|
|
|
{
|
|
|
|
|
return qobject_cast<ThreadsWindow*>(m_threadsWindow)->model();
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-08 14:26:11 +01:00
|
|
|
void DebuggerManager::clearStatusMessage()
|
|
|
|
|
{
|
|
|
|
|
m_statusLabel->setText(m_lastPermanentStatusMessage);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::showStatusMessage(const QString &msg, int timeout)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(timeout)
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << "STATUS MSG: " << msg;
|
2009-06-19 12:04:21 +02:00
|
|
|
showDebuggerOutput(LogStatus, msg);
|
2009-05-29 10:35:04 +02:00
|
|
|
m_statusLabel->setText(QLatin1String(" ") + msg);
|
2008-12-08 14:26:11 +01:00
|
|
|
if (timeout > 0) {
|
|
|
|
|
m_statusTimer->setSingleShot(true);
|
|
|
|
|
m_statusTimer->start(timeout);
|
|
|
|
|
} else {
|
|
|
|
|
m_lastPermanentStatusMessage = msg;
|
|
|
|
|
m_statusTimer->stop();
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-02-16 18:28:15 +01:00
|
|
|
void DebuggerManager::notifyInferiorStopRequested()
|
|
|
|
|
{
|
|
|
|
|
setStatus(DebuggerInferiorStopRequested);
|
|
|
|
|
showStatusMessage(tr("Stop requested..."), 5000);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::notifyInferiorStopped()
|
|
|
|
|
{
|
|
|
|
|
resetLocation();
|
|
|
|
|
setStatus(DebuggerInferiorStopped);
|
|
|
|
|
showStatusMessage(tr("Stopped."), 5000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::notifyInferiorRunningRequested()
|
|
|
|
|
{
|
|
|
|
|
setStatus(DebuggerInferiorRunningRequested);
|
2009-02-12 13:31:19 +01:00
|
|
|
showStatusMessage(tr("Running requested..."), 5000);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::notifyInferiorRunning()
|
|
|
|
|
{
|
|
|
|
|
setStatus(DebuggerInferiorRunning);
|
|
|
|
|
showStatusMessage(tr("Running..."), 5000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::notifyInferiorExited()
|
|
|
|
|
{
|
2009-02-17 15:12:46 +01:00
|
|
|
setStatus(DebuggerProcessNotReady);
|
2008-12-02 12:01:29 +01:00
|
|
|
showStatusMessage(tr("Stopped."), 5000);
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-25 16:22:11 +02:00
|
|
|
void DebuggerManager::notifyInferiorPidChanged(qint64 pid)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
2009-05-25 16:22:11 +02:00
|
|
|
qDebug() << Q_FUNC_INFO << m_inferiorPid << pid;
|
|
|
|
|
|
|
|
|
|
if (m_inferiorPid != pid) {
|
|
|
|
|
m_inferiorPid = pid;
|
|
|
|
|
emit inferiorPidChanged(pid);
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-01-15 14:30:49 +01:00
|
|
|
void DebuggerManager::showApplicationOutput(const QString &str)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-01-15 14:30:49 +01:00
|
|
|
emit applicationOutputAvailable(str);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::shutdown()
|
|
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << m_engine;
|
|
|
|
|
|
|
|
|
|
if (m_engine)
|
2009-02-16 09:59:12 +01:00
|
|
|
m_engine->shutdown();
|
|
|
|
|
m_engine = 0;
|
|
|
|
|
|
2009-05-11 10:22:03 +02:00
|
|
|
#define doDelete(ptr) delete ptr; ptr = 0
|
|
|
|
|
doDelete(scriptEngine);
|
|
|
|
|
doDelete(gdbEngine);
|
|
|
|
|
doDelete(winEngine);
|
|
|
|
|
doDelete(tcfEngine);
|
2009-02-16 09:59:12 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
// Delete these manually before deleting the manager
|
|
|
|
|
// (who will delete the models for most views)
|
2009-05-11 10:22:03 +02:00
|
|
|
doDelete(m_breakWindow);
|
|
|
|
|
doDelete(m_modulesWindow);
|
|
|
|
|
doDelete(m_outputWindow);
|
|
|
|
|
doDelete(m_registerWindow);
|
|
|
|
|
doDelete(m_stackWindow);
|
|
|
|
|
doDelete(m_sourceFilesWindow);
|
|
|
|
|
doDelete(m_threadsWindow);
|
2009-06-24 12:31:09 +02:00
|
|
|
//doDelete(m_tooltipWindow);
|
2009-05-11 10:22:03 +02:00
|
|
|
doDelete(m_watchersWindow);
|
|
|
|
|
doDelete(m_localsWindow);
|
|
|
|
|
|
|
|
|
|
doDelete(m_breakHandler);
|
|
|
|
|
doDelete(m_threadsHandler);
|
|
|
|
|
doDelete(m_modulesHandler);
|
|
|
|
|
doDelete(m_registerHandler);
|
|
|
|
|
doDelete(m_stackHandler);
|
|
|
|
|
doDelete(m_watchHandler);
|
|
|
|
|
#undef doDelete
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-04-28 15:08:52 +02:00
|
|
|
BreakpointData *DebuggerManager::findBreakpoint(const QString &fileName, int lineNumber)
|
|
|
|
|
{
|
|
|
|
|
if (!m_breakHandler)
|
|
|
|
|
return 0;
|
|
|
|
|
int index = m_breakHandler->findBreakpoint(fileName, lineNumber);
|
|
|
|
|
return index == -1 ? 0 : m_breakHandler->at(index);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::toggleBreakpoint()
|
|
|
|
|
{
|
|
|
|
|
QString fileName;
|
|
|
|
|
int lineNumber = -1;
|
|
|
|
|
queryCurrentTextEditor(&fileName, &lineNumber, 0);
|
|
|
|
|
if (lineNumber == -1)
|
|
|
|
|
return;
|
|
|
|
|
toggleBreakpoint(fileName, lineNumber);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
|
|
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
|
|
|
|
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_breakHandler, return);
|
2009-02-17 15:12:46 +01:00
|
|
|
if (status() != DebuggerInferiorRunning
|
2009-05-25 16:22:11 +02:00
|
|
|
&& status() != DebuggerInferiorStopped
|
2009-02-17 15:12:46 +01:00
|
|
|
&& status() != DebuggerProcessNotReady) {
|
2009-02-16 18:28:15 +01:00
|
|
|
showStatusMessage(tr("Changing breakpoint state requires either a "
|
|
|
|
|
"fully running or fully stopped application."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-28 15:08:52 +02:00
|
|
|
int index = m_breakHandler->findBreakpoint(fileName, lineNumber);
|
2008-12-02 12:01:29 +01:00
|
|
|
if (index == -1)
|
2009-02-16 09:59:12 +01:00
|
|
|
m_breakHandler->setBreakpoint(fileName, lineNumber);
|
2008-12-02 12:01:29 +01:00
|
|
|
else
|
2009-02-16 09:59:12 +01:00
|
|
|
m_breakHandler->removeBreakpoint(index);
|
2009-05-25 16:22:11 +02:00
|
|
|
|
2009-05-06 10:13:36 +02:00
|
|
|
attemptBreakpointSynchronization();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-04-28 15:08:52 +02:00
|
|
|
void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineNumber)
|
|
|
|
|
{
|
|
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(m_breakHandler, return);
|
|
|
|
|
if (status() != DebuggerInferiorRunning
|
2009-05-25 16:22:11 +02:00
|
|
|
&& status() != DebuggerInferiorStopped
|
2009-04-28 15:08:52 +02:00
|
|
|
&& status() != DebuggerProcessNotReady) {
|
|
|
|
|
showStatusMessage(tr("Changing breakpoint state requires either a "
|
|
|
|
|
"fully running or fully stopped application."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_breakHandler->toggleBreakpointEnabled(fileName, lineNumber);
|
2009-05-06 10:13:36 +02:00
|
|
|
|
|
|
|
|
attemptBreakpointSynchronization();
|
2009-04-28 15:08:52 +02:00
|
|
|
}
|
|
|
|
|
|
2009-03-10 17:30:11 +01:00
|
|
|
void DebuggerManager::attemptBreakpointSynchronization()
|
|
|
|
|
{
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->attemptBreakpointSynchronization();
|
2009-03-10 17:30:11 +01:00
|
|
|
}
|
|
|
|
|
|
2009-05-14 14:29:37 +02:00
|
|
|
void DebuggerManager::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine)
|
2009-05-14 14:29:37 +02:00
|
|
|
m_engine->setToolTipExpression(mousePos, editor, cursorPos);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-07-13 09:11:07 +02:00
|
|
|
void DebuggerManager::updateWatchData(const WatchData &data)
|
|
|
|
|
{
|
|
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->updateWatchData(data);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-18 15:16:18 +02:00
|
|
|
static inline QString msgEngineNotAvailable(const char *engine)
|
|
|
|
|
{
|
|
|
|
|
return DebuggerManager::tr("The application requires the debugger engine '%1', which is disabled.").arg(QLatin1String(engine));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static IDebuggerEngine *debuggerEngineForToolChain(ProjectExplorer::ToolChain::ToolChainType tc)
|
|
|
|
|
{
|
|
|
|
|
IDebuggerEngine *rc = 0;
|
|
|
|
|
switch (tc) {
|
|
|
|
|
case ProjectExplorer::ToolChain::LinuxICC:
|
|
|
|
|
case ProjectExplorer::ToolChain::MinGW:
|
|
|
|
|
case ProjectExplorer::ToolChain::GCC:
|
|
|
|
|
rc = gdbEngine;
|
|
|
|
|
break;
|
|
|
|
|
case ProjectExplorer::ToolChain::MSVC:
|
|
|
|
|
case ProjectExplorer::ToolChain::WINCE:
|
|
|
|
|
rc = winEngine;
|
|
|
|
|
break;
|
|
|
|
|
case ProjectExplorer::ToolChain::OTHER:
|
|
|
|
|
case ProjectExplorer::ToolChain::UNKNOWN:
|
|
|
|
|
case ProjectExplorer::ToolChain::INVALID:
|
2009-08-13 17:36:23 +02:00
|
|
|
default:
|
2009-06-18 15:16:18 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << "Toolchain" << tc << rc;
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Figure out the debugger type of an executable. Analyze executable
|
|
|
|
|
// unless the toolchain provides a hint.
|
2009-05-07 17:25:32 +02:00
|
|
|
static IDebuggerEngine *determineDebuggerEngine(const QString &executable,
|
2009-06-18 15:16:18 +02:00
|
|
|
int toolChainType,
|
|
|
|
|
QString *errorMessage,
|
|
|
|
|
QString *settingsIdHint)
|
2009-03-03 14:01:58 +01:00
|
|
|
{
|
2009-06-18 15:16:18 +02:00
|
|
|
if (IDebuggerEngine *tce = debuggerEngineForToolChain(static_cast<ProjectExplorer::ToolChain::ToolChainType>(toolChainType)))
|
|
|
|
|
return tce;
|
|
|
|
|
|
|
|
|
|
if (executable.endsWith(_(".js"))) {
|
|
|
|
|
if (!scriptEngine) {
|
|
|
|
|
*errorMessage = msgEngineNotAvailable("Script Engine");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2009-05-07 17:25:32 +02:00
|
|
|
return scriptEngine;
|
2009-06-18 15:16:18 +02:00
|
|
|
}
|
2009-05-07 16:51:02 +02:00
|
|
|
|
2009-08-17 13:34:15 +02:00
|
|
|
#ifndef Q_OS_WIN
|
2009-05-20 11:48:31 +02:00
|
|
|
Q_UNUSED(settingsIdHint)
|
2009-06-18 15:16:18 +02:00
|
|
|
if (!gdbEngine) {
|
|
|
|
|
*errorMessage = msgEngineNotAvailable("Gdb Engine");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-07 17:25:32 +02:00
|
|
|
return gdbEngine;
|
2009-03-03 14:01:58 +01:00
|
|
|
#else
|
|
|
|
|
// If a file has PDB files, it has been compiled by VS.
|
|
|
|
|
QStringList pdbFiles;
|
|
|
|
|
if (!getPDBFiles(executable, &pdbFiles, errorMessage))
|
2009-05-07 17:25:32 +02:00
|
|
|
return 0;
|
2009-05-07 16:51:02 +02:00
|
|
|
if (pdbFiles.empty())
|
2009-05-07 17:25:32 +02:00
|
|
|
return gdbEngine;
|
2009-05-07 16:51:02 +02:00
|
|
|
|
2009-03-03 14:01:58 +01:00
|
|
|
// We need the CDB debugger in order to be able to debug VS
|
|
|
|
|
// executables
|
|
|
|
|
if (!winEngine) {
|
2009-05-20 11:48:31 +02:00
|
|
|
*errorMessage = DebuggerManager::tr("Debugging VS executables is currently not enabled.");
|
|
|
|
|
*settingsIdHint = QLatin1String("Cdb");
|
2009-05-07 17:25:32 +02:00
|
|
|
return 0;
|
2009-03-03 14:01:58 +01:00
|
|
|
}
|
2009-05-07 17:25:32 +02:00
|
|
|
return winEngine;
|
2009-03-03 14:01:58 +01:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-04 16:00:43 +01:00
|
|
|
// Figure out the debugger type of a PID
|
2009-05-07 17:25:32 +02:00
|
|
|
static IDebuggerEngine *determineDebuggerEngine(int /* pid */,
|
2009-06-18 15:16:18 +02:00
|
|
|
int toolChainType,
|
|
|
|
|
QString *errorMessage)
|
2009-03-04 16:00:43 +01:00
|
|
|
{
|
2009-06-18 15:16:18 +02:00
|
|
|
if (IDebuggerEngine *tce = debuggerEngineForToolChain(static_cast<ProjectExplorer::ToolChain::ToolChainType>(toolChainType)))
|
|
|
|
|
return tce;
|
2009-03-04 16:00:43 +01:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
// Preferably Windows debugger
|
2009-06-18 15:16:18 +02:00
|
|
|
if (winEngine)
|
|
|
|
|
return winEngine;
|
|
|
|
|
if (gdbEngine)
|
|
|
|
|
return gdbEngine;
|
|
|
|
|
*errorMessage = msgEngineNotAvailable("Gdb Engine");
|
|
|
|
|
return 0;
|
2009-03-04 16:00:43 +01:00
|
|
|
#else
|
2009-06-18 15:16:18 +02:00
|
|
|
if (!gdbEngine) {
|
|
|
|
|
*errorMessage = msgEngineNotAvailable("Gdb Engine");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-07 17:25:32 +02:00
|
|
|
return gdbEngine;
|
2009-03-04 16:00:43 +01:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-19 12:04:21 +02:00
|
|
|
void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl,
|
|
|
|
|
const QSharedPointer<DebuggerStartParameters> &startParameters)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
2009-05-25 16:22:11 +02:00
|
|
|
qDebug() << Q_FUNC_INFO << '\n' << *startParameters;
|
|
|
|
|
|
|
|
|
|
m_startParameters = startParameters;
|
|
|
|
|
m_inferiorPid = startParameters->attachPID > 0 ? startParameters->attachPID : 0;
|
|
|
|
|
m_runControl = runControl;
|
2009-06-18 15:16:18 +02:00
|
|
|
const QString toolChainName = ProjectExplorer::ToolChain::toolChainName(static_cast<ProjectExplorer::ToolChain::ToolChainType>(m_startParameters->toolChainType));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
emit debugModeRequested();
|
2009-08-13 10:16:47 +02:00
|
|
|
showDebuggerOutput(LogStatus,
|
|
|
|
|
tr("Starting debugger for tool chain '%1'...").arg(toolChainName));
|
2009-08-12 11:21:44 +02:00
|
|
|
showDebuggerOutput(LogDebug, DebuggerSettings::instance()->dump());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-03-03 14:01:58 +01:00
|
|
|
QString errorMessage;
|
2009-05-20 11:48:31 +02:00
|
|
|
QString settingsIdHint;
|
|
|
|
|
switch (startMode()) {
|
|
|
|
|
case AttachExternal:
|
2009-05-26 16:27:24 +02:00
|
|
|
case AttachCrashedExternal:
|
2009-06-18 15:16:18 +02:00
|
|
|
m_engine = determineDebuggerEngine(m_startParameters->attachPID, m_startParameters->toolChainType, &errorMessage);
|
2009-05-20 11:48:31 +02:00
|
|
|
break;
|
|
|
|
|
case AttachTcf:
|
2009-05-07 17:25:32 +02:00
|
|
|
m_engine = tcfEngine;
|
2009-05-20 11:48:31 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
2009-06-18 15:16:18 +02:00
|
|
|
m_engine = determineDebuggerEngine(m_startParameters->executable, m_startParameters->toolChainType, &errorMessage, &settingsIdHint);
|
2009-05-20 11:48:31 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2009-05-07 16:51:02 +02:00
|
|
|
|
2009-05-07 17:25:32 +02:00
|
|
|
if (!m_engine) {
|
2009-05-05 17:48:54 +02:00
|
|
|
debuggingFinished();
|
2009-05-20 11:48:31 +02:00
|
|
|
// Create Message box with possibility to go to settings
|
|
|
|
|
QAbstractButton *settingsButton = 0;
|
2009-08-13 10:16:47 +02:00
|
|
|
QMessageBox msgBox(QMessageBox::Warning, tr("Warning"),
|
|
|
|
|
tr("Cannot debug '%1' (tool chain: '%2'): %3").
|
|
|
|
|
arg(m_startParameters->executable, toolChainName, errorMessage),
|
|
|
|
|
QMessageBox::Ok);
|
2009-05-20 11:48:31 +02:00
|
|
|
if (!settingsIdHint.isEmpty())
|
|
|
|
|
settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole);
|
|
|
|
|
msgBox.exec();
|
|
|
|
|
if (msgBox.clickedButton() == settingsButton)
|
|
|
|
|
Core::ICore::instance()->showOptionsDialog(_(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint);
|
2009-05-05 17:48:54 +02:00
|
|
|
return;
|
2009-03-03 14:01:58 +01:00
|
|
|
}
|
2009-06-18 15:16:18 +02:00
|
|
|
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
2009-05-25 16:22:11 +02:00
|
|
|
qDebug() << m_startParameters->executable << m_engine;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-03-16 13:16:17 +01:00
|
|
|
setBusyCursor(false);
|
2009-02-17 15:12:46 +01:00
|
|
|
setStatus(DebuggerProcessStartingUp);
|
2009-05-26 16:27:24 +02:00
|
|
|
if (!m_engine->startDebugger(m_startParameters)) {
|
2009-02-17 15:12:46 +01:00
|
|
|
setStatus(DebuggerProcessNotReady);
|
2009-05-05 17:48:54 +02:00
|
|
|
debuggingFinished();
|
|
|
|
|
return;
|
2009-02-17 15:12:46 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::cleanupViews()
|
|
|
|
|
{
|
|
|
|
|
resetLocation();
|
|
|
|
|
breakHandler()->setAllPending();
|
|
|
|
|
stackHandler()->removeAll();
|
|
|
|
|
threadsHandler()->removeAll();
|
|
|
|
|
modulesHandler()->removeAll();
|
|
|
|
|
watchHandler()->cleanup();
|
2009-03-10 17:30:11 +01:00
|
|
|
m_sourceFilesWindow->removeAll();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::exitDebugger()
|
|
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO;
|
|
|
|
|
|
2009-02-16 13:29:57 +01:00
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->exitDebugger();
|
2008-12-02 12:01:29 +01:00
|
|
|
cleanupViews();
|
|
|
|
|
setStatus(DebuggerProcessNotReady);
|
|
|
|
|
setBusyCursor(false);
|
|
|
|
|
emit debuggingFinished();
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-25 16:22:11 +02:00
|
|
|
QSharedPointer<DebuggerStartParameters> DebuggerManager::startParameters() const
|
|
|
|
|
{
|
|
|
|
|
return m_startParameters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::setQtDumperLibraryName(const QString &dl)
|
|
|
|
|
{
|
|
|
|
|
m_dumperLib = dl;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-15 17:41:45 +02:00
|
|
|
void DebuggerManager::setQtDumperLibraryLocations(const QStringList &dl)
|
|
|
|
|
{
|
|
|
|
|
m_dumperLibLocations = dl;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-25 16:22:11 +02:00
|
|
|
qint64 DebuggerManager::inferiorPid() const
|
|
|
|
|
{
|
|
|
|
|
return m_inferiorPid;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-19 15:24:18 +01:00
|
|
|
void DebuggerManager::assignValueInDebugger()
|
|
|
|
|
{
|
|
|
|
|
if (QAction *action = qobject_cast<QAction *>(sender())) {
|
2009-03-19 15:33:11 +01:00
|
|
|
QString str = action->data().toString();
|
|
|
|
|
int i = str.indexOf('=');
|
|
|
|
|
if (i != -1)
|
|
|
|
|
assignValueInDebugger(str.left(i), str.mid(i + 1));
|
2009-03-19 15:24:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
2009-04-03 15:46:40 +02:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::assignValueInDebugger(const QString &expr, const QString &value)
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
|
|
|
|
m_engine->assignValueInDebugger(expr, value);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::activateFrame(int index)
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
|
|
|
|
m_engine->activateFrame(index);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::selectThread(int index)
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
|
|
|
|
m_engine->selectThread(index);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::loadAllSymbols()
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
|
|
|
|
m_engine->loadAllSymbols();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::loadSymbols(const QString &module)
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
|
|
|
|
m_engine->loadSymbols(module);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-04-15 12:01:58 +02:00
|
|
|
QList<Symbol> DebuggerManager::moduleSymbols(const QString &moduleName)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(m_engine, return QList<Symbol>());
|
|
|
|
|
return m_engine->moduleSymbols(moduleName);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::stepExec()
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
2008-12-02 12:01:29 +01:00
|
|
|
resetLocation();
|
2009-08-14 13:04:05 +02:00
|
|
|
if (theDebuggerBoolSetting(StepByInstruction))
|
|
|
|
|
m_engine->stepIExec();
|
|
|
|
|
else
|
|
|
|
|
m_engine->stepExec();
|
2009-05-25 16:22:11 +02:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
void DebuggerManager::stepOutExec()
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
2008-12-02 12:01:29 +01:00
|
|
|
resetLocation();
|
2009-02-16 09:59:12 +01:00
|
|
|
m_engine->stepOutExec();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::nextExec()
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
2008-12-02 12:01:29 +01:00
|
|
|
resetLocation();
|
2009-08-14 13:04:05 +02:00
|
|
|
if (theDebuggerBoolSetting(StepByInstruction))
|
|
|
|
|
m_engine->nextIExec();
|
|
|
|
|
else
|
|
|
|
|
m_engine->nextExec();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-07-01 12:49:41 +02:00
|
|
|
void DebuggerManager::watchPoint()
|
|
|
|
|
{
|
|
|
|
|
if (QAction *action = qobject_cast<QAction *>(sender()))
|
|
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->watchPoint(action->data().toPoint());
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-03 15:46:40 +02:00
|
|
|
void DebuggerManager::executeDebuggerCommand()
|
|
|
|
|
{
|
|
|
|
|
if (QAction *action = qobject_cast<QAction *>(sender()))
|
|
|
|
|
executeDebuggerCommand(action->data().toString());
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::executeDebuggerCommand(const QString &command)
|
|
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO <<command;
|
|
|
|
|
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_engine, return);
|
|
|
|
|
m_engine->executeDebuggerCommand(command);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::sessionLoaded()
|
|
|
|
|
{
|
2009-01-27 15:53:50 +01:00
|
|
|
cleanupViews();
|
|
|
|
|
setStatus(DebuggerProcessNotReady);
|
|
|
|
|
setBusyCursor(false);
|
2008-12-02 12:01:29 +01:00
|
|
|
loadSessionData();
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-13 17:10:53 +02:00
|
|
|
void DebuggerManager::aboutToUnloadSession()
|
2009-04-01 16:49:45 +02:00
|
|
|
{
|
2009-08-13 16:46:24 +02:00
|
|
|
cleanupViews();
|
2009-04-01 16:49:45 +02:00
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->shutdown();
|
|
|
|
|
setStatus(DebuggerProcessNotReady);
|
|
|
|
|
setBusyCursor(false);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::aboutToSaveSession()
|
|
|
|
|
{
|
|
|
|
|
saveSessionData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::loadSessionData()
|
|
|
|
|
{
|
|
|
|
|
m_breakHandler->loadSessionData();
|
2008-12-17 17:43:01 +01:00
|
|
|
m_watchHandler->loadSessionData();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::saveSessionData()
|
|
|
|
|
{
|
|
|
|
|
m_breakHandler->saveSessionData();
|
2008-12-17 17:43:01 +01:00
|
|
|
m_watchHandler->saveSessionData();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::dumpLog()
|
|
|
|
|
{
|
|
|
|
|
QString fileName = QFileDialog::getSaveFileName(mainWindow(),
|
|
|
|
|
tr("Save Debugger Log"), QDir::tempPath());
|
|
|
|
|
if (fileName.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
QFile file(fileName);
|
|
|
|
|
if (!file.open(QIODevice::WriteOnly))
|
|
|
|
|
return;
|
2009-05-25 16:22:11 +02:00
|
|
|
QTextStream ts(&file);
|
2008-12-02 12:01:29 +01:00
|
|
|
ts << m_outputWindow->inputContents();
|
|
|
|
|
ts << "\n\n=======================================\n\n";
|
|
|
|
|
ts << m_outputWindow->combinedContents();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::addToWatchWindow()
|
|
|
|
|
{
|
|
|
|
|
// requires a selection, but that's the only case we want...
|
|
|
|
|
QObject *ob = 0;
|
|
|
|
|
queryCurrentTextEditor(0, 0, &ob);
|
|
|
|
|
QPlainTextEdit *editor = qobject_cast<QPlainTextEdit*>(ob);
|
|
|
|
|
if (!editor)
|
|
|
|
|
return;
|
|
|
|
|
QTextCursor tc = editor->textCursor();
|
2009-03-19 15:44:26 +01:00
|
|
|
theDebuggerAction(WatchExpression)->setValue(tc.selectedText());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::setBreakpoint(const QString &fileName, int lineNumber)
|
|
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
|
|
|
|
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_breakHandler, return);
|
|
|
|
|
m_breakHandler->setBreakpoint(fileName, lineNumber);
|
2009-05-06 10:13:36 +02:00
|
|
|
attemptBreakpointSynchronization();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-06-12 12:57:22 +02:00
|
|
|
void DebuggerManager::breakByFunctionMain()
|
|
|
|
|
{
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
// FIXME: wrong on non-Qt based binaries
|
|
|
|
|
emit breakByFunction("qMain");
|
|
|
|
|
#else
|
|
|
|
|
emit breakByFunction("main");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::breakByFunction(const QString &functionName)
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_breakHandler, return);
|
|
|
|
|
m_breakHandler->breakByFunction(functionName);
|
2009-05-06 10:13:36 +02:00
|
|
|
attemptBreakpointSynchronization();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-03-16 13:16:17 +01:00
|
|
|
static bool isAllowedTransition(int from, int to)
|
|
|
|
|
{
|
|
|
|
|
return (from == -1)
|
|
|
|
|
|| (from == DebuggerProcessNotReady && to == DebuggerProcessStartingUp)
|
2009-03-17 14:57:43 +01:00
|
|
|
//|| (from == DebuggerProcessStartingUp && to == DebuggerInferiorStopped)
|
2009-03-16 13:16:17 +01:00
|
|
|
|| (from == DebuggerInferiorStopped && to == DebuggerInferiorRunningRequested)
|
|
|
|
|
|| (from == DebuggerInferiorRunningRequested && to == DebuggerInferiorRunning)
|
|
|
|
|
|| (from == DebuggerInferiorRunning && to == DebuggerInferiorStopRequested)
|
2009-03-17 14:57:43 +01:00
|
|
|
|| (from == DebuggerInferiorRunning && to == DebuggerInferiorStopped)
|
2009-03-16 13:16:17 +01:00
|
|
|
|| (from == DebuggerInferiorStopRequested && to == DebuggerInferiorStopped)
|
2009-05-25 16:22:11 +02:00
|
|
|
|| (to == DebuggerProcessNotReady);
|
2009-03-16 13:16:17 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::setStatus(int status)
|
|
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
2009-08-13 10:16:47 +02:00
|
|
|
qDebug() << Q_FUNC_INFO << "STATUS CHANGE: from" << stateName(m_status)
|
|
|
|
|
<< "to" << stateName(status);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
if (status == m_status)
|
|
|
|
|
return;
|
|
|
|
|
|
2009-04-06 16:30:11 +02:00
|
|
|
if (0 && !isAllowedTransition(m_status, status)) {
|
2009-08-13 10:16:47 +02:00
|
|
|
const QString msg = QString::fromLatin1("%1: UNEXPECTED TRANSITION: %2 -> %3")
|
|
|
|
|
.arg(_(Q_FUNC_INFO), _(stateName(m_status)), _(stateName(status)));
|
2009-03-25 13:42:47 +01:00
|
|
|
qWarning("%s", qPrintable(msg));
|
|
|
|
|
}
|
2009-03-16 13:16:17 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
m_status = status;
|
|
|
|
|
|
|
|
|
|
const bool started = status == DebuggerInferiorRunning
|
|
|
|
|
|| status == DebuggerInferiorRunningRequested
|
|
|
|
|
|| status == DebuggerInferiorStopRequested
|
2009-02-17 15:12:46 +01:00
|
|
|
|| status == DebuggerInferiorStopped;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
const bool running = status == DebuggerInferiorRunning;
|
2009-03-03 09:31:13 +01:00
|
|
|
|
|
|
|
|
const bool ready = status == DebuggerInferiorStopped
|
|
|
|
|
&& startMode() != AttachCore;
|
2009-07-15 16:50:49 +02:00
|
|
|
if (ready)
|
|
|
|
|
QApplication::alert(mainWindow(), 3000);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
m_watchAction->setEnabled(ready);
|
|
|
|
|
m_breakAction->setEnabled(true);
|
|
|
|
|
|
|
|
|
|
bool interruptIsExit = !running;
|
|
|
|
|
if (interruptIsExit) {
|
2009-05-19 15:33:17 +02:00
|
|
|
m_stopAction->setIcon(QIcon(":/debugger/images/debugger_stop_small.png"));
|
2008-12-02 12:01:29 +01:00
|
|
|
m_stopAction->setText(tr("Stop Debugger"));
|
|
|
|
|
} else {
|
2009-05-19 15:33:17 +02:00
|
|
|
m_stopAction->setIcon(QIcon(":/debugger/images/debugger_interrupt_small.png"));
|
2008-12-02 12:01:29 +01:00
|
|
|
m_stopAction->setText(tr("Interrupt"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_stopAction->setEnabled(started);
|
|
|
|
|
m_resetAction->setEnabled(true);
|
|
|
|
|
|
|
|
|
|
m_stepAction->setEnabled(ready);
|
|
|
|
|
m_stepOutAction->setEnabled(ready);
|
|
|
|
|
m_runToLineAction->setEnabled(ready);
|
|
|
|
|
m_runToFunctionAction->setEnabled(ready);
|
|
|
|
|
m_jumpToLineAction->setEnabled(ready);
|
|
|
|
|
m_nextAction->setEnabled(ready);
|
|
|
|
|
//showStatusMessage(QString("started: %1, running: %2").arg(started).arg(running));
|
|
|
|
|
emit statusChanged(m_status);
|
|
|
|
|
const bool notbusy = ready || status == DebuggerProcessNotReady;
|
|
|
|
|
setBusyCursor(!notbusy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::setBusyCursor(bool busy)
|
|
|
|
|
{
|
2009-03-16 13:16:17 +01:00
|
|
|
//qDebug() << "BUSY FROM: " << m_busy << " TO: " << m_busy;
|
2008-12-02 12:01:29 +01:00
|
|
|
if (busy == m_busy)
|
|
|
|
|
return;
|
|
|
|
|
m_busy = busy;
|
|
|
|
|
|
|
|
|
|
QCursor cursor(busy ? Qt::BusyCursor : Qt::ArrowCursor);
|
|
|
|
|
m_breakWindow->setCursor(cursor);
|
|
|
|
|
m_localsWindow->setCursor(cursor);
|
|
|
|
|
m_modulesWindow->setCursor(cursor);
|
|
|
|
|
m_outputWindow->setCursor(cursor);
|
|
|
|
|
m_registerWindow->setCursor(cursor);
|
|
|
|
|
m_stackWindow->setCursor(cursor);
|
2009-03-10 17:30:11 +01:00
|
|
|
m_sourceFilesWindow->setCursor(cursor);
|
2008-12-02 12:01:29 +01:00
|
|
|
m_threadsWindow->setCursor(cursor);
|
2009-06-24 12:31:09 +02:00
|
|
|
//m_tooltipWindow->setCursor(cursor);
|
2008-12-02 12:01:29 +01:00
|
|
|
m_watchersWindow->setCursor(cursor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber,
|
|
|
|
|
QObject **object)
|
|
|
|
|
{
|
|
|
|
|
emit currentTextEditorRequested(fileName, lineNumber, object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::continueExec()
|
|
|
|
|
{
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->continueInferior();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-05-07 15:20:44 +02:00
|
|
|
void DebuggerManager::detachDebugger()
|
|
|
|
|
{
|
|
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->detachDebugger();
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void DebuggerManager::interruptDebuggingRequest()
|
|
|
|
|
{
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << status();
|
2009-05-06 10:13:36 +02:00
|
|
|
if (!m_engine)
|
|
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
bool interruptIsExit = (status() != DebuggerInferiorRunning);
|
|
|
|
|
if (interruptIsExit)
|
|
|
|
|
exitDebugger();
|
|
|
|
|
else {
|
|
|
|
|
setStatus(DebuggerInferiorStopRequested);
|
2009-02-16 09:59:12 +01:00
|
|
|
m_engine->interruptInferior();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::runToLineExec()
|
|
|
|
|
{
|
|
|
|
|
QString fileName;
|
|
|
|
|
int lineNumber = -1;
|
|
|
|
|
emit currentTextEditorRequested(&fileName, &lineNumber, 0);
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine && !fileName.isEmpty()) {
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
2009-02-16 09:59:12 +01:00
|
|
|
m_engine->runToLineExec(fileName, lineNumber);
|
2009-03-03 14:01:58 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::runToFunctionExec()
|
|
|
|
|
{
|
|
|
|
|
QString fileName;
|
|
|
|
|
int lineNumber = -1;
|
|
|
|
|
QObject *object = 0;
|
|
|
|
|
emit currentTextEditorRequested(&fileName, &lineNumber, &object);
|
|
|
|
|
QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(object);
|
|
|
|
|
if (!ed)
|
|
|
|
|
return;
|
|
|
|
|
QTextCursor cursor = ed->textCursor();
|
|
|
|
|
QString functionName = cursor.selectedText();
|
|
|
|
|
if (functionName.isEmpty()) {
|
|
|
|
|
const QTextBlock block = cursor.block();
|
|
|
|
|
const QString line = block.text();
|
|
|
|
|
foreach (const QString &str, line.trimmed().split('(')) {
|
|
|
|
|
QString a;
|
|
|
|
|
for (int i = str.size(); --i >= 0; ) {
|
|
|
|
|
if (!str.at(i).isLetterOrNumber())
|
|
|
|
|
break;
|
|
|
|
|
a = str.at(i) + a;
|
|
|
|
|
}
|
|
|
|
|
if (!a.isEmpty()) {
|
|
|
|
|
functionName = a;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << functionName;
|
|
|
|
|
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine && !functionName.isEmpty())
|
2009-02-16 09:59:12 +01:00
|
|
|
m_engine->runToFunctionExec(functionName);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::jumpToLineExec()
|
|
|
|
|
{
|
|
|
|
|
QString fileName;
|
|
|
|
|
int lineNumber = -1;
|
|
|
|
|
emit currentTextEditorRequested(&fileName, &lineNumber, 0);
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine && !fileName.isEmpty()) {
|
2009-03-03 14:01:58 +01:00
|
|
|
if (Debugger::Constants::Internal::debug)
|
|
|
|
|
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
2009-02-16 09:59:12 +01:00
|
|
|
m_engine->jumpToLineExec(fileName, lineNumber);
|
2009-03-03 14:01:58 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::resetLocation()
|
|
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
// connected to the plugin
|
2008-12-02 12:01:29 +01:00
|
|
|
emit resetLocationRequested();
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-14 13:04:05 +02:00
|
|
|
void DebuggerManager::gotoLocation(const StackFrame &frame, bool setMarker)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
// connected to the plugin
|
2009-08-14 13:04:05 +02:00
|
|
|
emit gotoLocationRequested(frame, setMarker);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-03-10 19:35:17 +01:00
|
|
|
void DebuggerManager::fileOpen(const QString &fileName)
|
|
|
|
|
{
|
|
|
|
|
// connected to the plugin
|
2009-08-14 13:04:05 +02:00
|
|
|
StackFrame frame;
|
|
|
|
|
frame.file = fileName;
|
|
|
|
|
frame.line = -1;
|
|
|
|
|
emit gotoLocationRequested(frame, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::stepByInstructionTriggered()
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(m_stackHandler, return);
|
|
|
|
|
StackFrame frame = m_stackHandler->currentFrame();
|
|
|
|
|
gotoLocation(frame, true);
|
2009-03-10 19:35:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-02-17 14:08:49 +01:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
2009-04-06 17:27:15 +02:00
|
|
|
// Source files specific stuff
|
2009-02-17 14:08:49 +01:00
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::reloadSourceFiles()
|
|
|
|
|
{
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine && m_sourceFilesDock && m_sourceFilesDock->isVisible())
|
|
|
|
|
m_engine->reloadSourceFiles();
|
2009-02-17 14:08:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::sourceFilesDockToggled(bool on)
|
|
|
|
|
{
|
|
|
|
|
if (on)
|
|
|
|
|
reloadSourceFiles();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Modules specific stuff
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::reloadModules()
|
|
|
|
|
{
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine && m_modulesDock && m_modulesDock->isVisible())
|
|
|
|
|
m_engine->reloadModules();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::modulesDockToggled(bool on)
|
|
|
|
|
{
|
|
|
|
|
if (on)
|
|
|
|
|
reloadModules();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Output specific stuff
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2009-06-19 12:04:21 +02:00
|
|
|
void DebuggerManager::showDebuggerOutput(int channel, const QString &msg)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_outputWindow, return);
|
2009-06-19 12:04:21 +02:00
|
|
|
m_outputWindow->showOutput(channel, msg);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-06-19 12:04:21 +02:00
|
|
|
void DebuggerManager::showDebuggerInput(int channel, const QString &msg)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-02-16 09:59:12 +01:00
|
|
|
QTC_ASSERT(m_outputWindow, return);
|
2009-06-19 12:04:21 +02:00
|
|
|
m_outputWindow->showInput(channel, msg);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Register specific stuff
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::registerDockToggled(bool on)
|
|
|
|
|
{
|
|
|
|
|
if (on)
|
|
|
|
|
reloadRegisters();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::reloadRegisters()
|
|
|
|
|
{
|
2009-05-06 10:13:36 +02:00
|
|
|
if (m_engine && m_registerDock && m_registerDock->isVisible())
|
|
|
|
|
m_engine->reloadRegisters();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-04-20 16:40:50 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Dumpers. "Custom dumpers" are a library compiled against the current
|
|
|
|
|
// Qt containing functions to evaluate values of Qt classes
|
|
|
|
|
// (such as QString, taking pointers to their addresses).
|
|
|
|
|
// The library must be loaded into the debuggee.
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
bool DebuggerManager::qtDumperLibraryEnabled() const
|
|
|
|
|
{
|
|
|
|
|
return theDebuggerBoolSetting(UseDebuggingHelpers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString DebuggerManager::qtDumperLibraryName() const
|
|
|
|
|
{
|
|
|
|
|
if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool())
|
|
|
|
|
return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
|
|
|
|
|
return m_dumperLib;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-15 17:41:45 +02:00
|
|
|
QStringList DebuggerManager::qtDumperLibraryLocations() const
|
|
|
|
|
{
|
2009-07-30 16:44:16 +02:00
|
|
|
if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool()) {
|
|
|
|
|
const QString customLocation = theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
|
|
|
|
|
const QString location = tr("%1 (explicitly set in the Debugger Options)").arg(customLocation);
|
|
|
|
|
return QStringList(location);
|
|
|
|
|
}
|
2009-07-15 17:41:45 +02:00
|
|
|
return m_dumperLibLocations;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-20 16:40:50 +02:00
|
|
|
void DebuggerManager::showQtDumperLibraryWarning(const QString &details)
|
|
|
|
|
{
|
|
|
|
|
QMessageBox dialog(mainWindow());
|
|
|
|
|
QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"), QMessageBox::ActionRole);
|
|
|
|
|
QPushButton *helperOff = dialog.addButton(tr("Turn helper usage off"), QMessageBox::ActionRole);
|
|
|
|
|
QPushButton *justContinue = dialog.addButton(tr("Continue anyway"), QMessageBox::AcceptRole);
|
|
|
|
|
dialog.setDefaultButton(justContinue);
|
|
|
|
|
dialog.setWindowTitle(tr("Debugging helper missing"));
|
|
|
|
|
dialog.setText(tr("The debugger did not find the debugging helper library."));
|
2009-06-19 09:31:21 +02:00
|
|
|
dialog.setInformativeText(tr(
|
|
|
|
|
"The debugging helper is used to nicely format the values of some Qt "
|
|
|
|
|
"and Standard Library data types. "
|
|
|
|
|
"It must be compiled for each Qt version which "
|
|
|
|
|
"you can do in the Qt preferences page by selecting "
|
|
|
|
|
"a Qt installation and clicking on 'Rebuild' for the debugging "
|
|
|
|
|
"helper."));
|
2009-04-20 16:40:50 +02:00
|
|
|
if (!details.isEmpty())
|
|
|
|
|
dialog.setDetailedText(details);
|
|
|
|
|
dialog.exec();
|
|
|
|
|
if (dialog.clickedButton() == qtPref) {
|
2009-05-04 14:47:45 +02:00
|
|
|
Core::ICore::instance()->showOptionsDialog(_("Qt4"), _("Qt Versions"));
|
2009-04-20 16:40:50 +02:00
|
|
|
} else if (dialog.clickedButton() == helperOff) {
|
|
|
|
|
theDebuggerAction(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-05 17:48:54 +02:00
|
|
|
DebuggerStartMode DebuggerManager::startMode() const
|
|
|
|
|
{
|
2009-06-19 13:09:50 +02:00
|
|
|
return m_runControl ? m_runControl->startMode() : NoStartMode;
|
2009-05-05 17:48:54 +02:00
|
|
|
}
|
|
|
|
|
|
2009-05-06 10:21:50 +02:00
|
|
|
void DebuggerManager::reloadFullStack()
|
|
|
|
|
{
|
|
|
|
|
if (m_engine)
|
|
|
|
|
m_engine->reloadFullStack();
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-25 17:19:42 +02:00
|
|
|
bool DebuggerManager::isReverseDebugging() const
|
|
|
|
|
{
|
|
|
|
|
return m_reverseDirectionAction->isChecked();
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-14 13:04:05 +02:00
|
|
|
QVariant DebuggerManager::sessionValue(const QString &name)
|
|
|
|
|
{
|
|
|
|
|
// this is answered by the plugin
|
|
|
|
|
QVariant value;
|
|
|
|
|
emit sessionValueRequested(name, &value);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::setSessionValue(const QString &name, const QVariant &value)
|
|
|
|
|
{
|
|
|
|
|
emit setSessionValueRequested(name, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-04-06 16:30:11 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Testing
|
|
|
|
|
//
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void DebuggerManager::runTest(const QString &fileName)
|
|
|
|
|
{
|
2009-05-25 16:22:11 +02:00
|
|
|
m_startParameters->executable = fileName;
|
|
|
|
|
m_startParameters->processArgs = QStringList() << "--run-debuggee";
|
|
|
|
|
m_startParameters->workingDir.clear();
|
2009-05-05 17:48:54 +02:00
|
|
|
//startNewDebugger(StartInternal);
|
2009-04-06 16:30:11 +02:00
|
|
|
}
|
2009-06-24 12:31:09 +02:00
|
|
|
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace Debugger
|
|
|
|
|
|