debuggerrunner.cpp 10.5 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** 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.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** 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.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
#include "debuggerrunner.h"
hjk's avatar
hjk committed
31
#include "debuggermanager.h"
32
#include "debuggeroutputwindow.h"
con's avatar
con committed
33

34 35 36
#include "idebuggerengine.h"
#include "moduleshandler.h"

hjk's avatar
hjk committed
37
#include <projectexplorer/debugginghelper.h>
con's avatar
con committed
38 39 40
#include <projectexplorer/environment.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
Tobias Hunger's avatar
Tobias Hunger committed
41
#include <projectexplorer/target.h>
42
#include <projectexplorer/buildconfiguration.h>
43
#include <projectexplorer/applicationrunconfiguration.h> // For LocalApplication*
con's avatar
con committed
44

hjk's avatar
hjk committed
45
#include <utils/qtcassert.h>
46
#include <coreplugin/icore.h>
hjk's avatar
hjk committed
47

con's avatar
con committed
48 49 50
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
hjk's avatar
hjk committed
51

52
#include <QtGui/QAbstractItemView>
53
#include <QtGui/QTextDocument>
con's avatar
con committed
54

55
using namespace ProjectExplorer;
56 57
using namespace Debugger::Internal;

58

con's avatar
con committed
59 60
////////////////////////////////////////////////////////////////////////
//
61
// DebuggerRunControlFactory
con's avatar
con committed
62 63 64
//
////////////////////////////////////////////////////////////////////////

65 66
namespace Debugger {

67
// A factory to create DebuggerRunControls
68
DebuggerRunControlFactory::DebuggerRunControlFactory(DebuggerManager *manager)
69
    : m_manager(manager)
con's avatar
con committed
70 71
{}

72
bool DebuggerRunControlFactory::canRun(RunConfiguration *runConfiguration, const QString &mode) const
con's avatar
con committed
73
{
74
//    return mode == ProjectExplorer::Constants::DEBUGMODE;
75
    return mode == ProjectExplorer::Constants::DEBUGMODE
76
            && qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration);
con's avatar
con committed
77 78
}

79
QString DebuggerRunControlFactory::displayName() const
con's avatar
con committed
80
{
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
81
    return tr("Debug");
con's avatar
con committed
82 83
}

84
static DebuggerStartParameters localStartParameters(RunConfiguration *runConfiguration)
85
{
86
    DebuggerStartParameters sp;
87 88 89 90 91
    QTC_ASSERT(runConfiguration, return sp);
    LocalApplicationRunConfiguration *rc =
            qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration);
    QTC_ASSERT(rc, return sp);

92 93 94 95 96 97 98 99 100 101
    sp.startMode = StartInternal;
    sp.executable = rc->executable();
    sp.environment = rc->environment().toStringList();
    sp.workingDirectory = rc->workingDirectory();
    sp.processArgs = rc->commandLineArguments();
    sp.toolChainType = rc->toolChainType();
    sp.useTerminal = rc->runMode() == LocalApplicationRunConfiguration::Console;
    sp.dumperLibrary = rc->dumperLibrary();
    sp.dumperLibraryLocations = rc->dumperLibraryLocations();
    sp.displayName = rc->displayName();
102

103 104
    // Find qtInstallPath.
    QString qmakePath = DebuggingHelperLibrary::findSystemQt(rc->environment());
105 106 107 108 109 110 111 112 113
    if (!qmakePath.isEmpty()) {
        QProcess proc;
        QStringList args;
        args.append(QLatin1String("-query"));
        args.append(QLatin1String("QT_INSTALL_HEADERS"));
        proc.start(qmakePath, args);
        proc.waitForFinished();
        QByteArray ba = proc.readAllStandardOutput().trimmed();
        QFileInfo fi(QString::fromLocal8Bit(ba) + "/..");
114
        sp.qtInstallPath = fi.absoluteFilePath();
115 116
    }
    return sp;
117 118
}

119 120
RunControl *DebuggerRunControlFactory::create
    (RunConfiguration *runConfiguration, const QString &mode)
con's avatar
con committed
121
{
hjk's avatar
hjk committed
122
    QTC_ASSERT(mode == ProjectExplorer::Constants::DEBUGMODE, return 0);
123
    DebuggerStartParameters sp = localStartParameters(runConfiguration);
124
    return new DebuggerRunControl(m_manager, sp);
125 126
}

127
RunControl *DebuggerRunControlFactory::create(const DebuggerStartParameters &sp)
128
{
129
    return new DebuggerRunControl(m_manager, sp);
con's avatar
con committed
130 131
}

132
QWidget *DebuggerRunControlFactory::createConfigurationWidget(RunConfiguration *runConfiguration)
con's avatar
con committed
133 134
{
    // NBS TODO: Add GDB-specific configuration widget
135
    Q_UNUSED(runConfiguration)
con's avatar
con committed
136 137 138 139
    return 0;
}


140 141 142 143 144 145 146 147 148
////////////////////////////////////////////////////////////////////////
//
// DebuggerRunControl::Private
//
////////////////////////////////////////////////////////////////////////

class DebuggerRunControl::Private
{
public:
149 150 151
    Private(DebuggerRunControl *parent, DebuggerManager *manager,
        const DebuggerStartParameters &startParameters);
    ~Private();
152 153 154 155 156 157

public:
    DebuggerRunControl *q;

    DebuggerStartParameters m_startParameters;
    DebuggerManager *m_manager;
158
    Internal::IDebuggerEngine *m_engine;
159 160
    bool m_running;

161
    ModulesHandler *m_modulesHandler;
162 163 164 165 166 167 168 169 170 171 172
/*
    // FIXME: Move from DebuggerManager
    BreakHandler *m_breakHandler;
    RegisterHandler *m_registerHandler;
    SnapshotHandler *m_snapshotHandler;
    StackHandler *m_stackHandler;
    ThreadsHandler *m_threadsHandler;
    WatchHandler *m_watchHandler;
*/
};

173 174 175 176 177 178 179
DebuggerRunControl::Private::Private(DebuggerRunControl *parent,
        DebuggerManager *manager,
        const DebuggerStartParameters &startParameters)
  : q(parent),
    m_startParameters(startParameters),
    m_manager(manager),
    m_engine(0)
180
{
181 182 183 184 185 186 187 188 189
    m_running = false;
    m_modulesHandler = new ModulesHandler(q);
}

DebuggerRunControl::Private::~Private()
{
#define doDelete(ptr) delete ptr; ptr = 0
    doDelete(m_modulesHandler);
#undef doDelete
190 191
}

con's avatar
con committed
192 193 194 195 196 197 198 199

////////////////////////////////////////////////////////////////////////
//
// DebuggerRunControl
//
////////////////////////////////////////////////////////////////////////

DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
200
        const DebuggerStartParameters &startParameters)
201
    : RunControl(0, ProjectExplorer::Constants::DEBUGMODE),
202
      d(new Private(this, manager, startParameters))
203
{
204
    connect(d->m_manager, SIGNAL(debuggingFinished()),
205 206
            this, SLOT(debuggingFinished()),
            Qt::QueuedConnection);
207
    connect(d->m_manager, SIGNAL(messageAvailable(QString, bool)),
208
            this, SLOT(slotMessageAvailable(QString, bool)));
209
    connect(d->m_manager, SIGNAL(inferiorPidChanged(qint64)),
210 211 212
            this, SLOT(bringApplicationToForeground(qint64)),
            Qt::QueuedConnection);
    connect(this, SIGNAL(stopRequested()),
213
            d->m_manager, SLOT(exitDebugger()));
214

215 216 217
    if (d->m_startParameters.environment.empty())
        d->m_startParameters.environment = ProjectExplorer::Environment().toStringList();
    d->m_startParameters.useTerminal = false;
218

219 220
}

221 222 223 224 225
DebuggerRunControl::~DebuggerRunControl()
{
    delete d;
}

226 227
QString DebuggerRunControl::displayName() const
{
228
    return d->m_startParameters.displayName;
229 230
}

231 232
void DebuggerRunControl::setCustomEnvironment(ProjectExplorer::Environment env)
{
233
    d->m_startParameters.environment = env.toStringList();
234 235
}

236 237 238 239
void DebuggerRunControl::init()
{
}

240 241
void DebuggerRunControl::start()
{
242
    d->m_running = true;
243 244 245
    QString errorMessage;
    QString settingsCategory;
    QString settingsPage;
246
    if (d->m_manager->checkDebugConfiguration(d->m_startParameters.toolChainType,
247
            &errorMessage, &settingsCategory, &settingsPage)) {
248
        d->m_manager->startNewDebugger(this);
249
        emit started();
250
    } else {
251
        appendMessage(this, errorMessage, true);
252
        emit finished();
253 254
        Core::ICore::instance()->showWarningWithOptions(tr("Debugger"),
            errorMessage, QString(), settingsCategory, settingsPage);
255
    }
con's avatar
con committed
256 257
}

258 259
void DebuggerRunControl::showMessage(const QString &msg, int channel,
    int timeout)
260
{
261
    if (!d->m_manager)
Robert Loehning's avatar
Robert Loehning committed
262
        return;
263
    DebuggerOutputWindow *ow = d->m_manager->debuggerOutputWindow();
264 265 266
    QTC_ASSERT(ow, return);
    switch (channel) {
        case StatusBar:
267
            d->m_manager->showStatusMessage(msg, timeout);
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
            ow->showOutput(LogStatus, msg);
            break;
        case AppOutput:
            emit addToOutputWindowInline(this, msg, false);
            break;
        case AppError:
            emit addToOutputWindowInline(this, msg, true);
            break;
        case LogMiscInput:
            ow->showInput(LogMisc, msg);
            ow->showOutput(LogMisc, msg);
            break;
        case LogInput:
            ow->showInput(channel, msg);
            ow->showOutput(channel, msg);
            break;
        default:
            ow->showOutput(channel, msg);
            break;
    }
288 289 290 291 292
}

void DebuggerRunControl::slotMessageAvailable(const QString &data, bool isError)
{
    emit appendMessage(this, data, isError);
con's avatar
con committed
293 294 295 296
}

void DebuggerRunControl::stop()
{
297
    d->m_running = false;
hjk's avatar
hjk committed
298
    emit stopRequested();
con's avatar
con committed
299 300 301 302
}

void DebuggerRunControl::debuggingFinished()
{
303
    d->m_running = false;
con's avatar
con committed
304 305 306 307 308
    emit finished();
}

bool DebuggerRunControl::isRunning() const
{
309 310 311 312 313 314 315 316 317 318
    return d->m_running;
}

const DebuggerStartParameters &DebuggerRunControl::sp() const
{
    return d->m_startParameters;
}

ModulesHandler *DebuggerRunControl::modulesHandler() const
{
319
    return d->m_modulesHandler;
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
}

BreakHandler *DebuggerRunControl::breakHandler() const
{
    return d->m_manager->breakHandler();
}

RegisterHandler *DebuggerRunControl::registerHandler() const
{
    return d->m_manager->registerHandler();
}

StackHandler *DebuggerRunControl::stackHandler() const
{
    return d->m_manager->stackHandler();
}

ThreadsHandler *DebuggerRunControl::threadsHandler() const
{
    return d->m_manager->threadsHandler();
}

WatchHandler *DebuggerRunControl::watchHandler() const
{
    return d->m_manager->watchHandler();
}

SnapshotHandler *DebuggerRunControl::snapshotHandler() const
{
    return d->m_manager->snapshotHandler();
con's avatar
con committed
350
}
hjk's avatar
hjk committed
351

352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
void DebuggerRunControl::cleanup()
{
    modulesHandler()->removeAll();
}

Internal::IDebuggerEngine *DebuggerRunControl::engine()
{
    QTC_ASSERT(d->m_engine, /**/);
    return d->m_engine;
}

void DebuggerRunControl::startDebugger(IDebuggerEngine *engine)
{
    d->m_engine = engine;
    d->m_engine->setRunControl(this);
    d->m_manager->modulesWindow()->setModel(d->m_modulesHandler->model());
    d->m_engine->startDebugger();
}

hjk's avatar
hjk committed
371
} // namespace Debugger