debuggerrunner.cpp 9.56 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

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

hjk's avatar
hjk committed
42
#include <utils/qtcassert.h>
43
#include <coreplugin/icore.h>
hjk's avatar
hjk committed
44

con's avatar
con committed
45 46 47
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
hjk's avatar
hjk committed
48

49
#include <QtGui/QTextDocument>
con's avatar
con committed
50

51
using namespace ProjectExplorer;
52 53
using namespace Debugger::Internal;

54

con's avatar
con committed
55 56
////////////////////////////////////////////////////////////////////////
//
57
// DebuggerRunControlFactory
con's avatar
con committed
58 59 60
//
////////////////////////////////////////////////////////////////////////

61 62
namespace Debugger {

63
// A factory to create DebuggerRunControls
64
DebuggerRunControlFactory::DebuggerRunControlFactory(DebuggerManager *manager)
65
    : m_manager(manager)
con's avatar
con committed
66 67
{}

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

75
QString DebuggerRunControlFactory::displayName() const
con's avatar
con committed
76
{
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
77
    return tr("Debug");
con's avatar
con committed
78 79
}

80
static DebuggerStartParameters localStartParameters(RunConfiguration *runConfiguration)
81
{
82
    DebuggerStartParameters sp;
83 84 85 86 87
    QTC_ASSERT(runConfiguration, return sp);
    LocalApplicationRunConfiguration *rc =
            qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration);
    QTC_ASSERT(rc, return sp);

88 89 90 91 92 93 94 95 96 97
    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();
98

99 100
    // Find qtInstallPath.
    QString qmakePath = DebuggingHelperLibrary::findSystemQt(rc->environment());
101 102 103 104 105 106 107 108 109
    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) + "/..");
110
        sp.qtInstallPath = fi.absoluteFilePath();
111 112
    }
    return sp;
113 114
}

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

123
RunControl *DebuggerRunControlFactory::create(const DebuggerStartParameters &sp)
124
{
125
    return new DebuggerRunControl(m_manager, sp);
con's avatar
con committed
126 127
}

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


136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
////////////////////////////////////////////////////////////////////////
//
// DebuggerRunControl::Private
//
////////////////////////////////////////////////////////////////////////

class DebuggerRunControl::Private
{
public:
    Private(DebuggerRunControl *parent);

public:
    DebuggerRunControl *q;

    DebuggerStartParameters m_startParameters;
    DebuggerManager *m_manager;
    bool m_running;

/*
    // FIXME: Move from DebuggerManager
    BreakHandler *m_breakHandler;
    ModulesHandler *m_modulesHandler;
    RegisterHandler *m_registerHandler;
    SnapshotHandler *m_snapshotHandler;
    StackHandler *m_stackHandler;
    ThreadsHandler *m_threadsHandler;
    WatchHandler *m_watchHandler;
*/
};

DebuggerRunControl::Private::Private(DebuggerRunControl *parent)
  : q(parent)
{
}

con's avatar
con committed
171 172 173 174 175 176 177 178

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

DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
179
        const DebuggerStartParameters &startParameters)
180
    : RunControl(0, ProjectExplorer::Constants::DEBUGMODE),
181
      d(new Private(this))
182
{
183 184 185 186
    d->m_startParameters = startParameters;
    d->m_manager = manager;
    d->m_running = false;
    connect(d->m_manager, SIGNAL(debuggingFinished()),
187 188
            this, SLOT(debuggingFinished()),
            Qt::QueuedConnection);
189
    connect(d->m_manager, SIGNAL(messageAvailable(QString, bool)),
190
            this, SLOT(slotMessageAvailable(QString, bool)));
191
    connect(d->m_manager, SIGNAL(inferiorPidChanged(qint64)),
192 193 194
            this, SLOT(bringApplicationToForeground(qint64)),
            Qt::QueuedConnection);
    connect(this, SIGNAL(stopRequested()),
195
            d->m_manager, SLOT(exitDebugger()));
196

197 198 199
    if (d->m_startParameters.environment.empty())
        d->m_startParameters.environment = ProjectExplorer::Environment().toStringList();
    d->m_startParameters.useTerminal = false;
200

201 202
}

203 204 205 206 207
DebuggerRunControl::~DebuggerRunControl()
{
    delete d;
}

208 209
QString DebuggerRunControl::displayName() const
{
210
    return d->m_startParameters.displayName;
211 212
}

213 214
void DebuggerRunControl::setCustomEnvironment(ProjectExplorer::Environment env)
{
215
    d->m_startParameters.environment = env.toStringList();
216 217
}

218 219 220 221
void DebuggerRunControl::init()
{
}

222 223
void DebuggerRunControl::start()
{
224
    d->m_running = true;
225 226 227
    QString errorMessage;
    QString settingsCategory;
    QString settingsPage;
228
    if (d->m_manager->checkDebugConfiguration(d->m_startParameters.toolChainType,
229
            &errorMessage, &settingsCategory, &settingsPage)) {
230
        d->m_manager->startNewDebugger(this);
231
        emit started();
232
    } else {
233
        appendMessage(this, errorMessage, true);
234
        emit finished();
235 236
        Core::ICore::instance()->showWarningWithOptions(tr("Debugger"),
            errorMessage, QString(), settingsCategory, settingsPage);
237
    }
con's avatar
con committed
238 239
}

240 241
void DebuggerRunControl::showMessage(const QString &msg, int channel,
    int timeout)
242
{
243
    if (!d->m_manager)
Robert Loehning's avatar
Robert Loehning committed
244
        return;
245
    DebuggerOutputWindow *ow = d->m_manager->debuggerOutputWindow();
246 247 248
    QTC_ASSERT(ow, return);
    switch (channel) {
        case StatusBar:
249
            d->m_manager->showStatusMessage(msg, timeout);
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
            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;
    }
270 271 272 273 274
}

void DebuggerRunControl::slotMessageAvailable(const QString &data, bool isError)
{
    emit appendMessage(this, data, isError);
con's avatar
con committed
275 276 277 278
}

void DebuggerRunControl::stop()
{
279
    d->m_running = false;
hjk's avatar
hjk committed
280
    emit stopRequested();
con's avatar
con committed
281 282 283 284
}

void DebuggerRunControl::debuggingFinished()
{
285
    d->m_running = false;
con's avatar
con committed
286 287 288 289 290
    emit finished();
}

bool DebuggerRunControl::isRunning() const
{
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
    return d->m_running;
}

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

ModulesHandler *DebuggerRunControl::modulesHandler() const
{
    return d->m_manager->modulesHandler();
}

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
332
}
hjk's avatar
hjk committed
333 334

} // namespace Debugger