OSDN Git Service

ead2ec47f59ea0cf27a43db2c18f491a8538e4a0
[qt-creator-jp/qt-creator-jp.git] / src / plugins / debugger / debuggerrunner.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "debuggerrunner.h"
35 #include "debuggerruncontrolfactory.h"
36
37 #include "debuggeractions.h"
38 #include "debuggercore.h"
39 #include "debuggerengine.h"
40 #include "debuggermainwindow.h"
41 #include "debuggerplugin.h"
42 #include "debuggerstringutils.h"
43 #include "debuggerstartparameters.h"
44 #include "lldb/lldbenginehost.h"
45 #include "debuggertooltipmanager.h"
46 #include "qml/qmlengine.h"
47
48 #ifdef Q_OS_WIN
49 #  include "peutils.h"
50 #endif
51
52 #include <projectexplorer/abi.h>
53 #include <projectexplorer/debugginghelper.h>
54 #include <projectexplorer/project.h>
55 #include <projectexplorer/projectexplorerconstants.h>
56 #include <projectexplorer/target.h>
57 #include <projectexplorer/buildconfiguration.h>
58 #include <projectexplorer/outputformat.h>
59 #include <projectexplorer/toolchain.h>
60 #include <projectexplorer/applicationrunconfiguration.h> // For LocalApplication*
61
62 #include <utils/synchronousprocess.h>
63 #include <utils/qtcassert.h>
64 #include <utils/fancymainwindow.h>
65 #include <utils/qtcprocess.h>
66 #include <coreplugin/icore.h>
67 #include <utils/buildablehelperlibrary.h>
68
69 #include <QtCore/QDir>
70 #include <QtCore/QDebug>
71 #include <QtGui/QMessageBox>
72
73 using namespace ProjectExplorer;
74 using namespace Debugger::Internal;
75
76 enum { debug = 0 };
77
78 namespace Debugger {
79 namespace Internal {
80
81 bool isCdbEngineEnabled(); // Check the configuration page
82 bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check);
83 DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp,
84     DebuggerEngine *masterEngine, QString *error);
85
86 bool checkGdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check);
87 DebuggerEngine *createGdbEngine(const DebuggerStartParameters &sp,
88     DebuggerEngine *masterEngine);
89
90 DebuggerEngine *createScriptEngine(const DebuggerStartParameters &sp);
91 DebuggerEngine *createPdbEngine(const DebuggerStartParameters &sp);
92 QmlEngine *createQmlEngine(const DebuggerStartParameters &sp,
93     DebuggerEngine *masterEngine);
94 DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp,
95                                    DebuggerEngineType slaveEngineType,
96                                    QString *errorMessage);
97 DebuggerEngine *createLldbEngine(const DebuggerStartParameters &sp);
98
99 extern QString msgNoBinaryForToolChain(const Abi &abi);
100
101 static const char *engineTypeName(DebuggerEngineType et)
102 {
103     switch (et) {
104     case Debugger::NoEngineType:
105         break;
106     case Debugger::GdbEngineType:
107         return "Gdb engine";
108     case Debugger::ScriptEngineType:
109         return "Script engine";
110     case Debugger::CdbEngineType:
111         return "Cdb engine";
112     case Debugger::PdbEngineType:
113         return "Pdb engine";
114     case Debugger::TcfEngineType:
115         return "Tcf engine";
116     case Debugger::QmlEngineType:
117         return "QML engine";
118     case Debugger::QmlCppEngineType:
119         return "QML C++ engine";
120     case Debugger::LldbEngineType:
121         return "LLDB engine";
122     case Debugger::AllEngineTypes:
123         break;
124     }
125     return "No engine";
126 }
127
128 static inline QString engineTypeNames(const QList<DebuggerEngineType> &l)
129 {
130     QString rc;
131     foreach (DebuggerEngineType et, l) {
132         if (!rc.isEmpty())
133             rc.append(QLatin1String(", "));
134         rc += QLatin1String(engineTypeName(et));
135     }
136     return rc;
137 }
138
139 static QString msgEngineNotAvailable(const char *engine)
140 {
141     return DebuggerPlugin::tr("The application requires the debugger engine '%1', "
142         "which is disabled.").arg(_(engine));
143 }
144
145 static inline QString msgEngineNotAvailable(DebuggerEngineType et)
146 {
147     return msgEngineNotAvailable(engineTypeName(et));
148 }
149
150 ////////////////////////////////////////////////////////////////////////
151 //
152 // DebuggerRunControlPrivate
153 //
154 ////////////////////////////////////////////////////////////////////////
155
156 class DebuggerRunControlPrivate
157 {
158 public:
159     explicit DebuggerRunControlPrivate(DebuggerRunControl *parent,
160                                        RunConfiguration *runConfiguration);
161
162     DebuggerEngineType engineForExecutable(unsigned enabledEngineTypes,
163         const QString &executable);
164     DebuggerEngineType engineForMode(unsigned enabledEngineTypes,
165         DebuggerStartMode mode);
166
167 public:
168     DebuggerRunControl *q;
169     DebuggerEngine *m_engine;
170     const QWeakPointer<RunConfiguration> m_myRunConfiguration;
171     bool m_running;
172 };
173
174 DebuggerRunControlPrivate::DebuggerRunControlPrivate(DebuggerRunControl *parent,
175                                                      RunConfiguration *runConfiguration)
176     : q(parent)
177     , m_engine(0)
178     , m_myRunConfiguration(runConfiguration)
179     , m_running(false)
180 {
181 }
182
183 } // namespace Internal
184
185 DebuggerRunControl::DebuggerRunControl(RunConfiguration *runConfiguration,
186                                        const DebuggerStartParameters &sp,
187                                        const QPair<DebuggerEngineType, DebuggerEngineType> &masterSlaveEngineTypes)
188     : RunControl(runConfiguration, Constants::DEBUGMODE),
189       d(new DebuggerRunControlPrivate(this, runConfiguration))
190 {
191     connect(this, SIGNAL(finished()), SLOT(handleFinished()));
192     // Create the engine. Could arguably be moved to the factory, but
193     // we still have a derived S60DebugControl. Should rarely fail, though.
194     QString errorMessage;
195     d->m_engine = masterSlaveEngineTypes.first == QmlCppEngineType ?
196             createQmlCppEngine(sp, masterSlaveEngineTypes.second, &errorMessage) :
197             DebuggerRunControlFactory::createEngine(masterSlaveEngineTypes.first, sp,
198                                                     0, &errorMessage);
199     if (d->m_engine) {
200         DebuggerToolTipManager::instance()->registerEngine(d->m_engine);
201     } else {
202         debuggingFinished();
203         Core::ICore::instance()->showWarningWithOptions(DebuggerRunControl::tr("Debugger"), errorMessage);
204     }
205 }
206
207 DebuggerRunControl::~DebuggerRunControl()
208 {
209     disconnect();
210     if (DebuggerEngine *engine = d->m_engine) {
211         d->m_engine = 0;
212         engine->disconnect();
213         delete engine;
214     }
215 }
216
217 const DebuggerStartParameters &DebuggerRunControl::startParameters() const
218 {
219     QTC_ASSERT(d->m_engine, return *(new DebuggerStartParameters()));
220     return d->m_engine->startParameters();
221 }
222
223 QString DebuggerRunControl::displayName() const
224 {
225     QTC_ASSERT(d->m_engine, return QString());
226     return d->m_engine->startParameters().displayName;
227 }
228
229 void DebuggerRunControl::setCustomEnvironment(Utils::Environment env)
230 {
231     QTC_ASSERT(d->m_engine, return);
232     d->m_engine->startParameters().environment = env;
233 }
234
235 void DebuggerRunControl::start()
236 {
237     QTC_ASSERT(d->m_engine, return);
238     debuggerCore()->runControlStarted(d->m_engine);
239
240     // We might get a synchronous startFailed() notification on Windows,
241     // when launching the process fails. Emit a proper finished() sequence.
242     emit started();
243     d->m_running = true;
244
245     d->m_engine->startDebugger(this);
246
247     if (d->m_running)
248         appendMessage(tr("Debugging starts"), NormalMessageFormat);
249 }
250
251 void DebuggerRunControl::startFailed()
252 {
253     appendMessage(tr("Debugging has failed"), NormalMessageFormat);
254     d->m_running = false;
255     emit finished();
256     d->m_engine->handleStartFailed();
257 }
258
259 void DebuggerRunControl::handleFinished()
260 {
261     appendMessage(tr("Debugging has finished"), NormalMessageFormat);
262     if (d->m_engine)
263         d->m_engine->handleFinished();
264     debuggerCore()->runControlFinished(d->m_engine);
265 }
266
267 void DebuggerRunControl::showMessage(const QString &msg, int channel)
268 {
269     switch (channel) {
270         case AppOutput:
271             appendMessage(msg, StdOutFormatSameLine);
272             break;
273         case AppError:
274             appendMessage(msg, StdErrFormatSameLine);
275             break;
276         case AppStuff:
277             appendMessage(msg, NormalMessageFormat);
278             break;
279     }
280 }
281
282 bool DebuggerRunControl::promptToStop(bool *optionalPrompt) const
283 {
284     QTC_ASSERT(isRunning(), return true;)
285
286     if (optionalPrompt && !*optionalPrompt)
287         return true;
288
289     const QString question = tr("A debugging session is still in progress. "
290             "Terminating the session in the current"
291             " state can leave the target in an inconsistent state."
292             " Would you still like to terminate it?");
293     return showPromptToStopDialog(tr("Close Debugging Session"), question,
294                                   QString(), QString(), optionalPrompt);
295 }
296
297 RunControl::StopResult DebuggerRunControl::stop()
298 {
299     QTC_ASSERT(d->m_engine, return StoppedSynchronously);
300     d->m_engine->quitDebugger();
301     return AsynchronousStop;
302 }
303
304 void DebuggerRunControl::debuggingFinished()
305 {
306     d->m_running = false;
307     emit finished();
308 }
309
310 bool DebuggerRunControl::isRunning() const
311 {
312     return d->m_running;
313 }
314
315 DebuggerEngine *DebuggerRunControl::engine()
316 {
317     QTC_ASSERT(d->m_engine, /**/);
318     return d->m_engine;
319 }
320
321 RunConfiguration *DebuggerRunControl::runConfiguration() const
322 {
323     return d->m_myRunConfiguration.data();
324 }
325
326 ////////////////////////////////////////////////////////////////////////
327 //
328 // Engine detection logic: Detection functions depending on tool chain, binary,
329 // etc. Return a list of possible engines (order of prefererence) without
330 // consideration of configuration, etc.
331 //
332 ////////////////////////////////////////////////////////////////////////
333
334 static QList<DebuggerEngineType> enginesForToolChain(const Abi &toolChain)
335 {
336     QList<DebuggerEngineType> result;
337     switch (toolChain.binaryFormat()) {
338     case Abi::ElfFormat:
339     case Abi::MachOFormat:
340         result.push_back(LldbEngineType);
341         result.push_back(GdbEngineType);
342         break;
343    case Abi::PEFormat:
344         if (toolChain.osFlavor() == Abi::WindowsMSysFlavor) {
345             result.push_back(GdbEngineType);
346             result.push_back(CdbEngineType);
347         } else {
348             result.push_back(CdbEngineType);
349             result.push_back(GdbEngineType);
350         }
351         break;
352     case Abi::RuntimeQmlFormat:
353         result.push_back(QmlEngineType);
354         break;
355     default:
356         break;
357     }
358     return result;
359 }
360
361 static inline QList<DebuggerEngineType> enginesForScriptExecutables(const QString &executable)
362 {
363     QList<DebuggerEngineType> result;
364     if (executable.endsWith(_(".js"))) {
365         result.push_back(ScriptEngineType);
366     } else if (executable.endsWith(_(".py"))) {
367         result.push_back(PdbEngineType);
368     }
369     return result;
370 }
371
372 static QList<DebuggerEngineType> enginesForExecutable(const QString &executable)
373 {
374     QList<DebuggerEngineType> result = enginesForScriptExecutables(executable);
375     if (!result.isEmpty())
376         return result;
377 #ifdef Q_OS_WIN
378     // A remote executable?
379     if (!executable.endsWith(_(".exe"), Qt::CaseInsensitive)) {
380         result.push_back(GdbEngineType);
381         return result;
382     }
383
384     // If a file has PDB files, it has been compiled by VS.
385     QStringList pdbFiles;
386     QString errorMessage;
387     if (getPDBFiles(executable, &pdbFiles, &errorMessage) && !pdbFiles.isEmpty()) {
388         result.push_back(CdbEngineType);
389         result.push_back(GdbEngineType);
390         return result;
391     }
392     // Fixme: Gdb should only be preferred if MinGW can positively be detected.
393     result.push_back(GdbEngineType);
394     result.push_back(CdbEngineType);
395 #else
396     result.push_back(LldbEngineType);
397     result.push_back(GdbEngineType);
398 #endif
399     return result;
400 }
401
402 // Debugger type for mode.
403 static QList<DebuggerEngineType> enginesForMode(DebuggerStartMode startMode,
404                                                 bool hardConstraintsOnly)
405 {
406     QList<DebuggerEngineType> result;
407     switch (startMode) {
408     case Debugger::NoStartMode:
409         break;
410     case Debugger::StartInternal:
411     case Debugger::StartExternal:
412     case AttachExternal:
413         if (!hardConstraintsOnly) {
414 #ifdef Q_OS_WIN
415             result.push_back(CdbEngineType); // Preferably Windows debugger for attaching locally.
416 #endif
417             result.push_back(GdbEngineType);
418         }
419         break;
420     case Debugger::AttachCore:
421     case Debugger::StartRemoteGdb:
422         result.push_back(GdbEngineType);
423         break;
424     case Debugger::AttachToRemote:
425         if (!hardConstraintsOnly) {
426 #ifdef Q_OS_WIN
427             result.push_back(CdbEngineType);
428 #endif
429             result.push_back(GdbEngineType);
430         }
431         break;
432     case AttachTcf:
433         result.push_back(TcfEngineType);
434         break;
435     case AttachCrashedExternal:
436         result.push_back(CdbEngineType); // Only CDB can do this
437         break;
438     case StartRemoteEngine:
439         // FIXME: Unclear IPC override. Someone please have a better idea.
440         // For now thats the only supported IPC engine.
441         result.push_back(LldbEngineType);
442         break;
443     }
444     return result;
445 }
446
447 // Engine detection logic: Call all detection functions in order.
448
449 static QList<DebuggerEngineType> engineTypes(const DebuggerStartParameters &sp)
450 {
451     // Script executables and certain start modes are 'hard constraints'.
452     QList<DebuggerEngineType> result = enginesForScriptExecutables(sp.executable);
453     if (!result.isEmpty())
454         return result;
455
456     result = enginesForMode(sp.startMode, true);
457     if (!result.isEmpty())
458         return result;
459
460     //  'hard constraints' done (with the exception of QML ABI checked here),
461     // further try to restrict available engines.
462     if (sp.toolChainAbi.isValid()) {
463         result = enginesForToolChain(sp.toolChainAbi);
464         if (!result.isEmpty())
465             return result;
466     }
467
468     // FIXME: 1 of 3 testing hacks.
469     if (sp.processArgs.startsWith(__("@tcf@ "))) {
470         result.push_back(GdbEngineType);
471         return result;
472     }
473
474     if (sp.startMode != AttachToRemote && !sp.executable.isEmpty())
475         result = enginesForExecutable(sp.executable);
476     if (!result.isEmpty())
477         return result;
478
479     result = enginesForMode(sp.startMode, false);
480     return result;
481 }
482
483 // Engine detection logic: ConfigurationCheck.
484 ConfigurationCheck::ConfigurationCheck() :
485     masterSlaveEngineTypes(NoEngineType, NoEngineType)
486 {
487 }
488
489 ConfigurationCheck::operator bool() const
490 {
491     return errorMessage.isEmpty() &&  errorDetails.isEmpty() && masterSlaveEngineTypes.first != NoEngineType;
492 }
493
494 QString ConfigurationCheck::errorDetailsString() const
495 {
496     return errorDetails.join(QLatin1String("\n\n"));
497 }
498
499 // Convenience helper to check whether an engine is enabled and configured
500 // correctly.
501 static inline bool canUseEngine(DebuggerEngineType et,
502                                 const DebuggerStartParameters &sp,
503                                 unsigned cmdLineEnabledEngines,
504                                 ConfigurationCheck *result)
505 {
506     // Enabled?
507     if ((et & cmdLineEnabledEngines) == 0) {
508         result->errorDetails.push_back(DebuggerPlugin::tr("The debugger engine '%1' is disabled.").
509                                        arg(engineTypeName(et)));
510         return false;
511     }
512     // Configured.
513     switch (et) {
514     case Debugger::CdbEngineType:
515         return checkCdbConfiguration(sp, result);
516     case Debugger::GdbEngineType:
517         return checkGdbConfiguration(sp, result);
518     default:
519         break;
520     }
521     return true;
522 }
523
524 /*!
525     \fn ConfigurationCheck checkDebugConfiguration(unsigned cmdLineEnabledEngines,
526                                                    const DebuggerStartParameters &sp)
527
528     This is the master engine detection function that returns the
529     engine types for a given set of start parameters and checks their
530     configuration.
531 */
532
533 DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(const DebuggerStartParameters &sp)
534 {
535     ConfigurationCheck result;
536     const unsigned activeLangs = debuggerCore()->activeLanguages();
537     const bool qmlLanguage = activeLangs & QmlLanguage;
538     const bool cppLanguage = activeLangs & CppLanguage;
539     if (debug)
540         qDebug().nospace() << "checkDebugConfiguration " << sp.toolChainAbi.toString()
541                            << " Start mode=" << sp.startMode << " Executable=" << sp.executable
542                            << " Debugger command=" << sp.debuggerCommand;
543     // Get all applicable types.
544     QList<DebuggerEngineType> requiredTypes;
545     if (qmlLanguage && !cppLanguage) {
546         requiredTypes.push_back(QmlEngineType);
547     } else {
548         requiredTypes = engineTypes(sp);
549     }
550     if (requiredTypes.isEmpty()) {
551         result.errorMessage = QLatin1String("Internal error: Unable to determine debugger engine type for this configuration");
552         return result;
553     }
554     if (debug)
555         qDebug() << " Required: " << engineTypeNames(requiredTypes);
556     // Filter out disables types, command line + current settings.
557     unsigned cmdLineEnabledEngines = debuggerCore()->enabledEngines();
558 #ifdef WITH_LLDB
559     if (!Core::ICore::instance()->settings()->value(QLatin1String("LLDB/enabled")).toBool())
560         cmdLineEnabledEngines &= ~LldbEngineType;
561 #else
562      cmdLineEnabledEngines &= ~LldbEngineType;
563 #endif
564     DebuggerEngineType usableType = NoEngineType;
565     QList<DebuggerEngineType> unavailableTypes;
566     foreach (DebuggerEngineType et, requiredTypes) {
567         if (canUseEngine(et, sp, cmdLineEnabledEngines, &result)) {
568             usableType = et;
569             break;
570         } else {
571             unavailableTypes.push_back(et);
572         }
573     }
574     if (usableType == NoEngineType) {
575         if (requiredTypes.size() == 1) {
576             result.errorMessage = DebuggerPlugin::tr(
577                 "The debugger engine '%1' required for debugging binaries of the type '%2'"
578                 " is not configured correctly.").
579                 arg(QLatin1String(engineTypeName(requiredTypes.front())), sp.toolChainAbi.toString());
580         } else {
581             result.errorMessage = DebuggerPlugin::tr(
582                 "None of the debugger engines '%1' capable of debugging binaries of the type '%2'"
583                 " is configured correctly.").
584                 arg(engineTypeNames(requiredTypes), sp.toolChainAbi.toString());
585         }
586         return result;
587     }
588     if (debug)
589         qDebug() << "Configured engine: " << engineTypeName(usableType);
590     // Inform verbosely about MinGW-gdb/CDB fallbacks. Do not complain about LLDB, for now.
591     if (!result.errorDetails.isEmpty() && unavailableTypes.count(LldbEngineType) != unavailableTypes.size()) {
592         const QString msg = DebuggerPlugin::tr(
593             "The preferred debugger engine for debugging binaries of type '%1' is not available.\n"
594             "The debugger engine '%2' will be used as a fallback.\nDetails: %3").
595                 arg(sp.toolChainAbi.toString(), engineTypeName(usableType),
596                     result.errorDetails.join(QString(QLatin1Char('\n'))));
597         debuggerCore()->showMessage(msg, LogWarning);
598         showMessageBox(QMessageBox::Warning, "Warning", msg);
599     }
600     // Anything left: Happy.
601     result.errorMessage.clear();
602     result.errorDetails.clear();
603     if (qmlLanguage && cppLanguage) {
604         result.masterSlaveEngineTypes.first = QmlCppEngineType;
605         result.masterSlaveEngineTypes.second = usableType;
606     } else {
607         result.masterSlaveEngineTypes.first = usableType;
608     }
609     if (debug)
610         qDebug() << engineTypeName(result.masterSlaveEngineTypes.first) << engineTypeName(result.masterSlaveEngineTypes.second);
611     return result;
612 }
613
614 ////////////////////////////////////////////////////////////////////////
615 //
616 // DebuggerRunControlFactory
617 //
618 ////////////////////////////////////////////////////////////////////////
619
620 // A factory to create DebuggerRunControls
621 DebuggerRunControlFactory::DebuggerRunControlFactory(QObject *parent,
622         unsigned enabledEngines)
623     : IRunControlFactory(parent), m_enabledEngines(enabledEngines)
624 {}
625
626 bool DebuggerRunControlFactory::canRun(RunConfiguration *runConfiguration, const QString &mode) const
627 {
628 //    return mode == ProjectExplorer::Constants::DEBUGMODE;
629     return mode == Constants::DEBUGMODE
630             && qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration);
631 }
632
633 QString DebuggerRunControlFactory::displayName() const
634 {
635     return DebuggerRunControl::tr("Debug");
636 }
637
638 // Find Qt installation by running qmake
639 static inline QString findQtInstallPath(const QString &qmakePath)
640 {
641     QProcess proc;
642     QStringList args;
643     args.append(_("-query"));
644     args.append(_("QT_INSTALL_HEADERS"));
645     proc.start(qmakePath, args);
646     if (!proc.waitForStarted()) {
647         qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(qmakePath),
648            qPrintable(proc.errorString()));
649         return QString();
650     }
651     proc.closeWriteChannel();
652     if (!proc.waitForFinished()) {
653         Utils::SynchronousProcess::stopProcess(proc);
654         qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(qmakePath));
655         return QString();
656     }
657     if (proc.exitStatus() != QProcess::NormalExit) {
658         qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(qmakePath));
659         return QString();
660     }
661     const QByteArray ba = proc.readAllStandardOutput().trimmed();
662     QDir dir(QString::fromLocal8Bit(ba));
663     if (dir.exists() && dir.cdUp())
664         return dir.absolutePath();
665     return QString();
666 }
667
668 static DebuggerStartParameters localStartParameters(RunConfiguration *runConfiguration)
669 {
670     DebuggerStartParameters sp;
671     QTC_ASSERT(runConfiguration, return sp);
672     LocalApplicationRunConfiguration *rc =
673             qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration);
674     QTC_ASSERT(rc, return sp);
675
676     sp.startMode = StartInternal;
677     sp.environment = rc->environment();
678     sp.workingDirectory = rc->workingDirectory();
679     sp.executable = rc->executable();
680     sp.processArgs = rc->commandLineArguments();
681     sp.toolChainAbi = rc->abi();
682     sp.useTerminal = rc->runMode() == LocalApplicationRunConfiguration::Console;
683     sp.dumperLibrary = rc->dumperLibrary();
684     sp.dumperLibraryLocations = rc->dumperLibraryLocations();
685
686     if (const ProjectExplorer::Target *target = runConfiguration->target()) {
687         if (QByteArray(target->metaObject()->className()).contains("Qt4")) {
688             const QString qmake = Utils::BuildableHelperLibrary::findSystemQt(sp.environment);
689             if (!qmake.isEmpty())
690                 sp.qtInstallPath = findQtInstallPath(qmake);
691         }
692         if (const ProjectExplorer::Project *project = target->project()) {
693               sp.projectDir = project->projectDirectory();
694               if (const ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration()) {
695                   sp.projectBuildDir = buildConfig->buildDirectory();
696                   if (const ProjectExplorer::ToolChain *tc = buildConfig->toolChain())
697                     sp.debuggerCommand = tc->debuggerCommand();
698               }
699         }
700     }
701
702     if (debuggerCore()->isActiveDebugLanguage(QmlLanguage)) {
703         sp.qmlServerAddress = _("127.0.0.1");
704         sp.qmlServerPort = runConfiguration->qmlDebugServerPort();
705
706         // Makes sure that all bindings go through the JavaScript engine, so that
707         // breakpoints are actually hit!
708         const QString optimizerKey = _("QML_DISABLE_OPTIMIZER");
709         if (!sp.environment.hasKey(optimizerKey)) {
710             sp.environment.set(optimizerKey, _("1"));
711         }
712
713         Utils::QtcProcess::addArg(&sp.processArgs, _("-qmljsdebugger=port:")
714                                   + QString::number(sp.qmlServerPort));
715     }
716
717     // FIXME: If it's not yet build this will be empty and not filled
718     // when rebuild as the runConfiguration is not stored and therefore
719     // cannot be used to retrieve the dumper location.
720     //qDebug() << "DUMPER: " << sp.dumperLibrary << sp.dumperLibraryLocations;
721     sp.displayName = rc->displayName();
722
723     return sp;
724 }
725
726 RunControl *DebuggerRunControlFactory::create
727     (RunConfiguration *runConfiguration, const QString &mode)
728 {
729     QTC_ASSERT(mode == Constants::DEBUGMODE, return 0);
730     DebuggerStartParameters sp = localStartParameters(runConfiguration);
731     return create(sp, runConfiguration);
732 }
733
734 RunConfigWidget *DebuggerRunControlFactory::createConfigurationWidget
735     (RunConfiguration *runConfiguration)
736 {
737     // NBS TODO: Add GDB-specific configuration widget
738     Q_UNUSED(runConfiguration)
739     return 0;
740 }
741
742 DebuggerRunControl *DebuggerRunControlFactory::create
743     (const DebuggerStartParameters &sp, RunConfiguration *runConfiguration)
744 {
745     const ConfigurationCheck check = checkDebugConfiguration(sp);
746
747     if (!check) {
748         //appendMessage(errorMessage, true);
749         Core::ICore::instance()->showWarningWithOptions(DebuggerRunControl::tr("Debugger"),
750             check.errorMessage, check.errorDetailsString(), check.settingsCategory, check.settingsPage);
751         return 0;
752     }
753
754     return new DebuggerRunControl(runConfiguration, sp, check.masterSlaveEngineTypes);
755 }
756
757 DebuggerEngine *
758     DebuggerRunControlFactory::createEngine(DebuggerEngineType et,
759                                             const DebuggerStartParameters &sp,
760                                             DebuggerEngine *masterEngine,
761                                             QString *errorMessage)
762 {
763     switch (et) {
764     case GdbEngineType:
765         return createGdbEngine(sp, masterEngine);
766     case ScriptEngineType:
767         return createScriptEngine(sp);
768     case CdbEngineType:
769         return createCdbEngine(sp, masterEngine, errorMessage);
770         break;
771     case PdbEngineType:
772         return createPdbEngine(sp);
773         break;
774     case QmlEngineType:
775         return createQmlEngine(sp, masterEngine);
776         break;
777     case LldbEngineType:
778         return createLldbEngine(sp);
779     default:
780         break;
781     }
782     *errorMessage = DebuggerRunControl::tr("Unable to create a debugger engine of the type '%1'").
783                     arg(_(engineTypeName(et)));
784     return 0;
785 }
786
787
788 } // namespace Debugger