diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 3ac02bde43b79c4264416232f9d81537284bb73d..6b2c0e1d42c428cb183474322551f8d2b5f6e9bc 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -843,7 +843,8 @@ bool CPPEditor::isElectricCharacter(const QChar &ch) const { if (ch == QLatin1Char('{') || ch == QLatin1Char('}') || - ch == QLatin1Char('#')) { + ch == QLatin1Char('#') || + ch == QLatin1Char(':')) { return true; } return false; diff --git a/src/plugins/debugger/Debugger.pluginspec b/src/plugins/debugger/Debugger.pluginspec index d8e1d86c6cfe40dbc80f4e10701dfd6df00a79be..5e98b53131921aec7e19c17336a067b8087ac50b 100644 --- a/src/plugins/debugger/Debugger.pluginspec +++ b/src/plugins/debugger/Debugger.pluginspec @@ -25,6 +25,11 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <dependency name="Find" version="1.1.80"/> </dependencyList> <argumentList> - <argument name="-disable-cdb">Disable CDB debugger engine</argument> + <argument name="-disable-cdb">Disable Cdb debugger engine</argument> + <argument name="-disable-gdb">Disable Gdb debugger engine</argument> + <argument name="-disable-sdb">Disable Qt Script debugger engine</argument> + <argument name="-disable-tcf">Disable Tcf debugger engine</argument> + <argument name="-debug" parameter="process-id">Attach to Process-Id</argument> + <argument name="-winexception" parameter="exception-code">Exception code</argument> </argumentList> </plugin> diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index babce3a0f09f2d785555e0d4ac60acff124e4843..7b606a9e0ea9bec8a70d7fb1f732ffc81c70ebd9 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -100,7 +100,7 @@ QString msgDebugEngineComResult(HRESULT hr) case E_UNEXPECTED: return QLatin1String("E_UNEXPECTED"); case E_NOTIMPL: - return QLatin1String("E_NOTIMPL"); + return QLatin1String("E_NOTIMPL"); } if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) return QLatin1String("ERROR_ACCESS_DENIED");; @@ -127,6 +127,22 @@ static inline QString msgLibLoadFailed(const QString &lib, const QString &why) arg(lib, why); } +// Format function failure message. Pass in Q_FUNC_INFO +static QString msgFunctionFailed(const char *func, const QString &why) +{ + // Strip a "cdecl_ int namespace1::class::foo(int bar)" as + // returned by Q_FUNC_INFO down to "foo" + QString function = QLatin1String(func); + const int firstParentPos = function.indexOf(QLatin1Char('(')); + if (firstParentPos != -1) + function.truncate(firstParentPos); + const int classSepPos = function.lastIndexOf(QLatin1String("::")); + if (classSepPos != -1) + function.remove(0, classSepPos + 2); + //: Function call failed + return CdbDebugEngine::tr("The function \"%1()\" failed: %2").arg(function, why); +} + // ----- Engine helpers static inline ULONG getInterruptTimeOutSecs(CIDebugControl *ctl) @@ -515,6 +531,7 @@ bool CdbDebugEngine::startDebugger() m_d->clearDisplay(); const DebuggerStartMode mode = m_d->m_debuggerManager->startMode(); + const QSharedPointer<DebuggerStartParameters> sp = m_d->m_debuggerManager->startParameters(); // Figure out dumper. @TODO: same in gdb... const QString dumperLibName = QDir::toNativeSeparators(m_d->m_debuggerManagerAccess->qtDumperLibraryName()); bool dumperEnabled = mode != AttachCore && !dumperLibName.isEmpty() @@ -535,19 +552,19 @@ bool CdbDebugEngine::startDebugger() m_d->clearForRun(); switch (mode) { case AttachExternal: - rc = startAttachDebugger(m_d->m_debuggerManager->m_attachedPID, &errorMessage); + rc = startAttachDebugger(sp->attachPID, &errorMessage); needWatchTimer = true; break; case StartInternal: case StartExternal: - if (m_d->m_debuggerManager->m_useTerminal) { + if (sp->useTerminal) { // Launch console stub and wait for its startup m_d->m_consoleStubProc.stop(); // We leave the console open, so recycle it now. - m_d->m_consoleStubProc.setWorkingDirectory(m_d->m_debuggerManager->m_workingDir); - m_d->m_consoleStubProc.setEnvironment(m_d->m_debuggerManager->m_environment); - rc = m_d->m_consoleStubProc.start(m_d->m_debuggerManager->m_executable, m_d->m_debuggerManager->m_processArgs); + m_d->m_consoleStubProc.setWorkingDirectory(sp->workingDir); + m_d->m_consoleStubProc.setEnvironment(sp->environment); + rc = m_d->m_consoleStubProc.start(sp->executable, sp->processArgs); if (!rc) - errorMessage = tr("The console stub process was unable to start '%1'.").arg(m_d->m_debuggerManager->m_executable); + errorMessage = tr("The console stub process was unable to start '%1'.").arg(sp->executable); // continues in slotConsoleStubStarted()... } else { needWatchTimer = true; @@ -563,7 +580,7 @@ bool CdbDebugEngine::startDebugger() if (needWatchTimer) startWatchTimer(); } else { - qWarning("%s\n", qPrintable(errorMessage)); + warning(errorMessage); } return rc; } @@ -593,7 +610,8 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString * memset(&dbgopts, 0, sizeof(dbgopts)); dbgopts.CreateFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS; - const QString filename(m_d->m_debuggerManager->m_executable); + const QSharedPointer<DebuggerStartParameters> sp = m_d->m_debuggerManager->startParameters(); + const QString filename(sp->executable); if (debugCDB) qDebug() << Q_FUNC_INFO <<filename; @@ -604,20 +622,20 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString * //m_cif.debugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH); // TODO console - const QString cmd = Core::Utils::AbstractProcess::createWinCommandline(filename, m_d->m_debuggerManager->m_processArgs); + const QString cmd = Core::Utils::AbstractProcess::createWinCommandline(filename, sp->processArgs); if (debugCDB) qDebug() << "Starting " << cmd; PCWSTR env = 0; QByteArray envData; - if (!m_d->m_debuggerManager->m_environment.empty()) { - envData = Core::Utils::AbstractProcess::createWinEnvironment(Core::Utils::AbstractProcess::fixWinEnvironment(m_d->m_debuggerManager->m_environment)); + if (!sp->environment.empty()) { + envData = Core::Utils::AbstractProcess::createWinEnvironment(Core::Utils::AbstractProcess::fixWinEnvironment(sp->environment)); env = reinterpret_cast<PCWSTR>(envData.data()); } const HRESULT hr = m_d->m_cif.debugClient->CreateProcess2Wide(NULL, const_cast<PWSTR>(cmd.utf16()), &dbgopts, sizeof(dbgopts), - m_d->m_debuggerManager->m_workingDir.utf16(), + sp->workingDir.utf16(), env); if (FAILED(hr)) { *errorMessage = tr("Unable to create a process '%1': %2").arg(cmd, msgDebugEngineComResult(hr)); @@ -660,7 +678,9 @@ void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG6 // Clear any saved breakpoints and set initial breakpoints m_engine->executeDebuggerCommand(QLatin1String("bc")); if (m_debuggerManagerAccess->breakHandler()->hasPendingBreakpoints()) - m_engine->attemptBreakpointSynchronization(); + m_engine->attemptBreakpointSynchronization(); + if (debugCDB) + qDebug() << Q_FUNC_INFO << '\n' << executionStatusString(m_cif.debugControl); } void CdbDebugEngine::processTerminated(unsigned long exitCode) @@ -704,7 +724,7 @@ void CdbDebugEnginePrivate::endDebugging(EndDebuggingMode em) if (wasRunning) { // Process must be stopped in order to terminate interruptInterferiorProcess(&errorMessage); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); - } + } HRESULT hr; switch (action) { case Detach: @@ -729,7 +749,7 @@ void CdbDebugEnginePrivate::endDebugging(EndDebuggingMode em) if (!errorMessage.isEmpty()) { errorMessage = QString::fromLatin1("There were errors trying to end debugging: %1").arg(errorMessage); m_debuggerManagerAccess->showDebuggerOutput(QLatin1String("error"), errorMessage); - qWarning("%s\n", qPrintable(errorMessage)); + m_engine->warning(errorMessage); } } @@ -782,7 +802,7 @@ bool CdbDebugEnginePrivate::updateLocals(int frameIndex, m_engine->filterEvaluateWatchers(&incompletes, wh); if (!incompletes.empty()) { const QString msg = QLatin1String("Warning: Locals left in incomplete list: ") + formatWatchList(incompletes); - qWarning("%s\n", qPrintable(msg)); + m_engine->warning(msg); } bool success = false; @@ -876,7 +896,7 @@ void CdbDebugEngine::updateWatchModel() success = true; } while (false); if (!success) - qWarning("%s : %s", Q_FUNC_INFO, qPrintable(errorMessage)); + warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } void CdbDebugEngine::stepExec() @@ -887,7 +907,7 @@ void CdbDebugEngine::stepExec() m_d->clearForRun(); const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO); if (FAILED(hr)) - qWarning("%s : %s", Q_FUNC_INFO, qPrintable(msgComFailed("SetExecutionStatus", hr))); + warning(msgFunctionFailed(Q_FUNC_INFO, msgComFailed("SetExecutionStatus", hr))); m_d->m_breakEventMode = CdbDebugEnginePrivate::BreakEventIgnoreOnce; startWatchTimer(); @@ -902,7 +922,7 @@ void CdbDebugEngine::stepOutExec() const int idx = sh->currentIndex() + 1; QList<StackFrame> stackframes = sh->frames(); if (idx < 0 || idx >= stackframes.size()) { - qWarning("cannot step out"); + warning(QString::fromLatin1("cannot step out")); return; } @@ -932,7 +952,7 @@ void CdbDebugEngine::stepOutExec() success = true; } while (false); if (!success) - qWarning("stepOutExec: %s\n", qPrintable(errorMessage)); + warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } void CdbDebugEngine::nextExec() @@ -945,13 +965,13 @@ void CdbDebugEngine::nextExec() if (SUCCEEDED(hr)) { startWatchTimer(); } else { - qWarning("%s failed: %s", Q_FUNC_INFO, qPrintable(msgDebugEngineComResult(hr))); + warning(msgFunctionFailed(Q_FUNC_INFO, msgComFailed("SetExecutionStatus", hr))); } } void CdbDebugEngine::stepIExec() { - qWarning("CdbDebugEngine::stepIExec() not implemented"); + warning(QString::fromLatin1("CdbDebugEngine::stepIExec() not implemented")); } void CdbDebugEngine::nextIExec() @@ -964,7 +984,7 @@ void CdbDebugEngine::nextIExec() if (SUCCEEDED(hr)) { startWatchTimer(); } else { - qWarning("%s failed: %s", Q_FUNC_INFO, qPrintable(msgDebugEngineComResult(hr))); + warning(msgFunctionFailed(Q_FUNC_INFO, msgDebugEngineComResult(hr))); } } @@ -972,7 +992,7 @@ void CdbDebugEngine::continueInferior() { QString errorMessage; if (!m_d->continueInferior(&errorMessage)) - qWarning("continueInferior: %s\n", qPrintable(errorMessage)); + warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } // Continue process without notifications @@ -986,7 +1006,7 @@ bool CdbDebugEnginePrivate::continueInferiorProcess(QString *errorMessagePtr /* if (errorMessagePtr) { *errorMessagePtr = errorMessage; } else { - qWarning("continueInferiorProcess: %s\n", qPrintable(errorMessage)); + m_engine->warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } return false; } @@ -1004,7 +1024,7 @@ bool CdbDebugEnginePrivate::continueInferior(QString *errorMessage) qDebug() << Q_FUNC_INFO << "\n ex=" << executionStatus; if (executionStatus == DEBUG_STATUS_GO) { - qWarning("continueInferior() called while debuggee is running."); + m_engine->warning(QLatin1String("continueInferior() called while debuggee is running.")); return true; } @@ -1054,7 +1074,7 @@ void CdbDebugEngine::interruptInferior() if (m_d->interruptInterferiorProcess(&errorMessage)) { m_d->m_debuggerManagerAccess->notifyInferiorStopped(); } else { - qWarning("interruptInferior: %s\n", qPrintable(errorMessage)); + warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } } @@ -1101,7 +1121,7 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v } while (false); if (!success) { const QString msg = tr("Unable to assign the value '%1' to '%2': %3").arg(value, expr, errorMessage); - qWarning("%s\n", qPrintable(msg)); + warning(msg); } } @@ -1109,7 +1129,7 @@ void CdbDebugEngine::executeDebuggerCommand(const QString &command) { QString errorMessage; if (!CdbDebugEnginePrivate::executeDebuggerCommand(m_d->m_cif.debugControl, command, &errorMessage)) - qWarning("%s\n", qPrintable(errorMessage)); + warning(errorMessage); } bool CdbDebugEnginePrivate::executeDebuggerCommand(CIDebugControl *ctrl, const QString &command, QString *errorMessage) @@ -1208,7 +1228,7 @@ void CdbDebugEngine::activateFrame(int frameIndex) success =true; } while (false); if (!success) - qWarning("%s", qPrintable(errorMessage)); + warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); m_d->m_firstActivatedFrame = false; } @@ -1230,7 +1250,7 @@ void CdbDebugEngine::attemptBreakpointSynchronization() { QString errorMessage; if (!m_d->attemptBreakpointSynchronization(&errorMessage)) - qWarning("attemptBreakpointSynchronization: %s\n", qPrintable(errorMessage)); + warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessage) @@ -1288,7 +1308,7 @@ void CdbDebugEngine::reloadDisassembler() if (lines.size() > ContextLines) dh->setCurrentLine(ContextLines); } else { - qWarning("reloadDisassembler: %s\n", qPrintable(errorMessage)); + warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } } else { dh->setLines(QList<DisassemblerLine>()); @@ -1326,7 +1346,7 @@ QList<Symbol> CdbDebugEngine::moduleSymbols(const QString &moduleName) success = true; } while (false); if (!success) - qWarning("%s\n", qPrintable(errorMessage)); + warning(errorMessage); return rc; } @@ -1357,7 +1377,7 @@ void CdbDebugEngine::reloadRegisters() QList<Register> registers; QString errorMessage; if (!getRegisters(m_d->m_cif.debugControl, m_d->m_cif.debugRegisters, ®isters, &errorMessage, intBase)) - qWarning("reloadRegisters() failed: %s\n", qPrintable(errorMessage)); + warning(msgFunctionFailed("reloadRegisters" , errorMessage)); m_d->m_debuggerManagerAccess->registerHandler()->setRegisters(registers); } @@ -1398,7 +1418,6 @@ void CdbDebugEngine::slotConsoleStubStarted() // Attach to console process QString errorMessage; if (startAttachDebugger(appPid, &errorMessage)) { - m_d->m_debuggerManager->m_attachedPID = appPid; startWatchTimer(); m_d->m_debuggerManagerAccess->notifyInferiorPidChanged(appPid); m_d->m_debuggerManagerAccess->notifyInferiorRunning(); @@ -1417,6 +1436,13 @@ void CdbDebugEngine::slotConsoleStubTerminated() exitDebugger(); } +void CdbDebugEngine::warning(const QString &w) +{ + static const QString prefix = QLatin1String("warning:"); + m_d->m_debuggerManagerAccess->showDebuggerOutput(prefix, w); + qWarning("%s\n", qPrintable(w)); +} + void CdbDebugEnginePrivate::notifyCrashed() { // Cannot go over crash point to execute calls. @@ -1437,7 +1463,7 @@ void CdbDebugEnginePrivate::handleDebugEvent() case BreakEventHandle: m_debuggerManagerAccess->notifyInferiorStopped(); updateThreadList(); - updateStackTrace(); + updateStackTrace(); break; case BreakEventIgnoreOnce: m_engine->startWatchTimer(); @@ -1449,7 +1475,7 @@ void CdbDebugEnginePrivate::handleDebugEvent() m_engine->startWatchTimer(); continueInferiorProcess(&errorMessage); if (!errorMessage.isEmpty()) - qWarning("handleDebugEvent: %s\n", qPrintable(errorMessage)); + m_engine->warning(QString::fromLatin1("In handleDebugEvent: %1").arg(errorMessage)); } break; } @@ -1497,7 +1523,7 @@ void CdbDebugEnginePrivate::updateThreadList() success = true; } while (false); if (!success) - qWarning("updateThreadList() failed: %s\n", qPrintable(errorMessage)); + m_engine->warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); } void CdbDebugEnginePrivate::updateStackTrace() @@ -1511,7 +1537,7 @@ void CdbDebugEnginePrivate::updateStackTrace() m_currentStackTrace = CdbStackTraceContext::create(m_dumper, m_currentThreadId, &errorMessage); if (!m_currentStackTrace) { - qWarning("%s: failed to create trace context: %s", Q_FUNC_INFO, qPrintable(errorMessage)); + m_engine->warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); return; } // Disassembling slows things down a bit. Assembler is still available via menu. @@ -1541,7 +1567,7 @@ void CdbDebugEnginePrivate::updateModules() QList<Module> modules; QString errorMessage; if (!getModuleList(m_cif.debugSymbols, &modules, &errorMessage)) - qWarning("updateModules() failed: %s\n", qPrintable(errorMessage)); + m_engine->warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); m_debuggerManagerAccess->modulesHandler()->setModules(modules); } @@ -1582,7 +1608,7 @@ void CdbDebugEngine::syncDebuggerPaths() if (!m_d->setSourcePaths(m_d->m_options->sourcePaths, &errorMessage) || !m_d->setSymbolPaths(m_d->m_options->symbolPaths, &errorMessage)) { errorMessage = QString::fromLatin1("Unable to set the debugger paths: %1").arg(errorMessage); - qWarning("%s\n", qPrintable(errorMessage)); + warning(errorMessage); } } @@ -1624,7 +1650,7 @@ bool CdbDebugEnginePrivate::setSymbolPaths(const QStringList &s, QString *errorM // Accessed by DebuggerManager Debugger::Internal::IDebuggerEngine *createWinEngine(Debugger::Internal::DebuggerManager *parent, - bool cmdLineDisabled, + bool cmdLineEnabled, QList<Core::IOptionsPage*> *opts) { // Create options page @@ -1632,7 +1658,7 @@ Debugger::Internal::IDebuggerEngine *createWinEngine(Debugger::Internal::Debugge options->fromSettings(Core::ICore::instance()->settings()); Debugger::Internal::CdbOptionsPage *optionsPage = new Debugger::Internal::CdbOptionsPage(options); opts->push_back(optionsPage); - if (cmdLineDisabled || !options->enabled) + if (!cmdLineEnabled || !options->enabled) return 0; // Create engine QString errorMessage; @@ -1640,7 +1666,7 @@ Debugger::Internal::IDebuggerEngine *createWinEngine(Debugger::Internal::Debugge Debugger::Internal::CdbDebugEngine::create(parent, options, &errorMessage); if (!engine) { optionsPage->setFailureMessage(errorMessage); - qWarning("%s", qPrintable(errorMessage)); + qWarning("%s\n" ,qPrintable(errorMessage)); } QObject::connect(optionsPage, SIGNAL(debuggerPathsChanged()), engine, SLOT(syncDebuggerPaths())); return engine; diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index 8dd0fa601f8024953b1c1e2c5b0215f7c9696dec..7c0caff2c20cd13f1e34dab9c4b029d270345f01 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -107,6 +107,7 @@ private slots: void slotConsoleStubStarted(); void slotConsoleStubError(const QString &msg); void slotConsoleStubTerminated(); + void warning(const QString &w); private: bool startAttachDebugger(qint64 pid, QString *errorMessage); diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 316d4fbf081514f6a63fd316f281a6d147f199b1..8798bae480130647e1574b064fe9097bcfe3f4f0 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -289,9 +289,9 @@ void AttachExternalDialog::procSelected(const QModelIndex &proxyIndex) } } -int AttachExternalDialog::attachPID() const +qint64 AttachExternalDialog::attachPID() const { - return m_ui->pidLineEdit->text().toInt(); + return m_ui->pidLineEdit->text().toLongLong(); } void AttachExternalDialog::pidChanged(const QString &pid) diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h index 98008e7612cbb1ce4a3d700cf3e0fe52a54b3e00..56f18699b686f35247ae3f87b609003a775ad3a1 100644 --- a/src/plugins/debugger/debuggerdialogs.h +++ b/src/plugins/debugger/debuggerdialogs.h @@ -87,7 +87,7 @@ public: explicit AttachExternalDialog(QWidget *parent); ~AttachExternalDialog(); - int attachPID() const; + qint64 attachPID() const; private slots: void rebuildProcessList(); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 1e32bc5074b2115a46ecad881582b34775945cc6..6768c63d0255c594dd2c45af2e5fc70563fda0d3 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -84,14 +84,31 @@ #include <QtGui/QPushButton> #include <QtGui/QToolTip> +namespace Debugger { + namespace Internal { +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 + << " serverStartScript=" << p.serverStartScript << '\n'; + return str; +} +} // namespace Internal +} // namespace Debugger + using namespace Debugger; using namespace Debugger::Internal; using namespace Debugger::Constants; static const QString tooltipIName = "tooltip"; -#define _(s) QString::fromLatin1(s) - static const char *stateName(int s) { switch (s) { @@ -148,7 +165,7 @@ static IDebuggerEngine *tcfEngine = 0; // This allows for having a "enabled" toggle on the page indepently // of the engine. IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *); -IDebuggerEngine *createWinEngine(DebuggerManager *, bool /* cmdLineDisabled */, QList<Core::IOptionsPage*> *) +IDebuggerEngine *createWinEngine(DebuggerManager *, bool /* cmdLineEnabled */, QList<Core::IOptionsPage*> *) #ifdef CDB_ENABLED ; #else @@ -157,7 +174,33 @@ IDebuggerEngine *createWinEngine(DebuggerManager *, bool /* cmdLineDisabled */, IDebuggerEngine *createScriptEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *); IDebuggerEngine *createTcfEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *); -DebuggerManager::DebuggerManager() +// ---------------- DebuggerStartParameters + +DebuggerStartParameters::DebuggerStartParameters() : + attachPID(-1), + useTerminal(false) +{ +} + +void DebuggerStartParameters::clear() +{ + executable.clear(); + coreFile.clear(); + processArgs.clear(); + environment.clear(); + workingDir.clear(); + buildDir.clear(); + attachPID = -1; + useTerminal = false; + remoteChannel.clear(); + remoteArchitecture.clear(); + serverStartScript.clear(); +} + +// --------- DebuggerManager +DebuggerManager::DebuggerManager() : + m_startParameters(new DebuggerStartParameters), + m_inferiorPid(0) { init(); } @@ -177,7 +220,6 @@ void DebuggerManager::init() m_status = -1; m_busy = false; - m_attachedPID = 0; m_runControl = 0; m_disassemblerHandler = 0; @@ -284,7 +326,7 @@ void DebuggerManager::init() connect(sourceFilesView, SIGNAL(fileOpenRequested(QString)), this, SLOT(fileOpen(QString))); - // Registers + // Registers QAbstractItemView *registerView = qobject_cast<QAbstractItemView *>(m_registerWindow); m_registerHandler = new RegisterHandler; @@ -295,7 +337,7 @@ void DebuggerManager::init() QTreeView *localsView = qobject_cast<QTreeView *>(m_localsWindow); localsView->setModel(m_watchHandler->model()); - // Watchers + // Watchers QTreeView *watchersView = qobject_cast<QTreeView *>(m_watchersWindow); watchersView->setModel(m_watchHandler->model()); connect(m_watchHandler, SIGNAL(sessionValueRequested(QString,QVariant*)), @@ -444,14 +486,16 @@ void DebuggerManager::init() setStatus(DebuggerProcessNotReady); } -QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(const QStringList &arguments) +QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(unsigned enabledTypeFlags) { QList<Core::IOptionsPage*> rc; - gdbEngine = createGdbEngine(this, &rc); - const bool cdbDisabled = arguments.contains(_("-disable-cdb")); - winEngine = createWinEngine(this, cdbDisabled, &rc); - scriptEngine = createScriptEngine(this, &rc); - tcfEngine = createTcfEngine(this, &rc); + 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); m_engine = 0; if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << gdbEngine << winEngine << scriptEngine << rc.size(); @@ -643,12 +687,15 @@ void DebuggerManager::notifyInferiorExited() showStatusMessage(tr("Stopped."), 5000); } -void DebuggerManager::notifyInferiorPidChanged(int pid) +void DebuggerManager::notifyInferiorPidChanged(qint64 pid) { if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << pid; - //QMessageBox::warning(0, "PID", "PID: " + QString::number(pid)); - emit inferiorPidChanged(pid); + qDebug() << Q_FUNC_INFO << m_inferiorPid << pid; + + if (m_inferiorPid != pid) { + m_inferiorPid = pid; + emit inferiorPidChanged(pid); + } } void DebuggerManager::showApplicationOutput(const QString &str) @@ -720,7 +767,7 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) QTC_ASSERT(m_breakHandler, return); if (status() != DebuggerInferiorRunning - && status() != DebuggerInferiorStopped + && status() != DebuggerInferiorStopped && status() != DebuggerProcessNotReady) { showStatusMessage(tr("Changing breakpoint state requires either a " "fully running or fully stopped application.")); @@ -732,7 +779,7 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) m_breakHandler->setBreakpoint(fileName, lineNumber); else m_breakHandler->removeBreakpoint(index); - + attemptBreakpointSynchronization(); } @@ -743,7 +790,7 @@ void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineN QTC_ASSERT(m_breakHandler, return); if (status() != DebuggerInferiorRunning - && status() != DebuggerInferiorStopped + && status() != DebuggerInferiorStopped && status() != DebuggerProcessNotReady) { showStatusMessage(tr("Changing breakpoint state requires either a " "fully running or fully stopped application.")); @@ -781,26 +828,6 @@ QVariant DebuggerManager::sessionValue(const QString &name) return value; } -QVariant DebuggerManager::configValue(const QString &name) -{ - // this is answered by the plugin - QVariant value; - emit configValueRequested(name, &value); - return value; -} - -void DebuggerManager::queryConfigValue(const QString &name, QVariant *value) -{ - // this is answered by the plugin - emit configValueRequested(name, value); -} - -void DebuggerManager::setConfigValue(const QString &name, const QVariant &value) -{ - // this is answered by the plugin - emit setConfigValueRequested(name, value); -} - // Figure out the debugger type of an executable static IDebuggerEngine *determineDebuggerEngine(const QString &executable, QString *errorMessage, @@ -844,160 +871,14 @@ static IDebuggerEngine *determineDebuggerEngine(int /* pid */, #endif } -void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl) +void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl, const QSharedPointer<DebuggerStartParameters> &startParameters) { - m_runControl = runControl; - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << startMode(); - - // FIXME: Clean up - - switch (startMode()) { - case StartExternal: { - StartExternalDialog dlg(mainWindow()); - dlg.setExecutableFile( - configValue(_("LastExternalExecutableFile")).toString()); - dlg.setExecutableArguments( - configValue(_("LastExternalExecutableArguments")).toString()); - if (dlg.exec() != QDialog::Accepted) { - runControl->debuggingFinished(); - return; - } - setConfigValue(_("LastExternalExecutableFile"), - dlg.executableFile()); - setConfigValue(_("LastExternalExecutableArguments"), - dlg.executableArguments()); - m_executable = dlg.executableFile(); - m_processArgs = dlg.executableArguments().split(' '); - m_workingDir = QString(); - m_attachedPID = -1; - break; - } - case AttachExternal: { - AttachExternalDialog dlg(mainWindow()); - if (dlg.exec() != QDialog::Accepted) { - runControl->debuggingFinished(); - return; - } - m_executable = QString(); - m_processArgs = QStringList(); - m_workingDir = QString(); - m_attachedPID = dlg.attachPID(); - if (m_attachedPID == 0) { - QMessageBox::warning(mainWindow(), tr("Warning"), - tr("Cannot attach to PID 0")); - runControl->debuggingFinished(); - return; - } - break; - } - case StartInternal: { - if (m_executable.isEmpty()) { - QString startDirectory = m_executable; - if (m_executable.isEmpty()) { - QString fileName; - emit currentTextEditorRequested(&fileName, 0, 0); - if (!fileName.isEmpty()) { - const QFileInfo editorFile(fileName); - startDirectory = editorFile.dir().absolutePath(); - } - } - StartExternalDialog dlg(mainWindow()); - dlg.setExecutableFile(startDirectory); - if (dlg.exec() != QDialog::Accepted) { - runControl->debuggingFinished(); - return; - } - m_executable = dlg.executableFile(); - m_processArgs = dlg.executableArguments().split(' '); - m_workingDir = QString(); - m_attachedPID = 0; - } else { - //m_executable = QDir::convertSeparators(m_executable); - //m_processArgs = sd.processArgs.join(_(" ")); - m_attachedPID = 0; - } - break; - } - case AttachCore: { - AttachCoreDialog dlg(mainWindow()); - dlg.setExecutableFile( - configValue(_("LastExternalExecutableFile")).toString()); - dlg.setCoreFile( - configValue(_("LastExternalCoreFile")).toString()); - if (dlg.exec() != QDialog::Accepted) { - runControl->debuggingFinished(); - return; - } - setConfigValue(_("LastExternalExecutableFile"), - dlg.executableFile()); - setConfigValue(_("LastExternalCoreFile"), - dlg.coreFile()); - m_executable = dlg.executableFile(); - m_coreFile = dlg.coreFile(); - m_processArgs.clear(); - m_workingDir = QString(); - m_attachedPID = -1; - break; - } - case StartRemote: { - StartRemoteDialog dlg(mainWindow()); - QStringList arches; - arches.append(_("i386:x86-64:intel")); - dlg.setRemoteArchitectures(arches); - dlg.setRemoteChannel( - configValue(_("LastRemoteChannel")).toString()); - dlg.setRemoteArchitecture( - configValue(_("LastRemoteArchitecture")).toString()); - dlg.setServerStartScript( - configValue(_("LastServerStartScript")).toString()); - dlg.setUseServerStartScript( - configValue(_("LastUseServerStartScript")).toBool()); - if (dlg.exec() != QDialog::Accepted) { - runControl->debuggingFinished(); - return; - } - setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel()); - setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture()); - setConfigValue(_("LastServerStartScript"), dlg.serverStartScript()); - setConfigValue(_("LastUseServerStartScript"), dlg.useServerStartScript()); - m_remoteChannel = dlg.remoteChannel(); - m_remoteArchitecture = dlg.remoteArchitecture(); - m_serverStartScript = dlg.serverStartScript(); - if (!dlg.useServerStartScript()) - m_serverStartScript.clear(); - break; - } - case AttachTcf: { - AttachTcfDialog dlg(mainWindow()); - QStringList arches; - arches.append(_("i386:x86-64:intel")); - dlg.setRemoteArchitectures(arches); - dlg.setRemoteChannel( - configValue(_("LastTcfRemoteChannel")).toString()); - dlg.setRemoteArchitecture( - configValue(_("LastTcfRemoteArchitecture")).toString()); - dlg.setServerStartScript( - configValue(_("LastTcfServerStartScript")).toString()); - dlg.setUseServerStartScript( - configValue(_("LastTcfUseServerStartScript")).toBool()); - if (dlg.exec() != QDialog::Accepted) { - runControl->debuggingFinished(); - return; - } - setConfigValue(_("LastTcfRemoteChannel"), dlg.remoteChannel()); - setConfigValue(_("LastTcfRemoteArchitecture"), dlg.remoteArchitecture()); - setConfigValue(_("LastTcfServerStartScript"), dlg.serverStartScript()); - setConfigValue(_("LastTcfUseServerStartScript"), dlg.useServerStartScript()); - m_remoteChannel = dlg.remoteChannel(); - m_remoteArchitecture = dlg.remoteArchitecture(); - m_serverStartScript = dlg.serverStartScript(); - if (!dlg.useServerStartScript()) - m_serverStartScript.clear(); - break; - } - } + qDebug() << Q_FUNC_INFO << '\n' << *startParameters; + + m_startParameters = startParameters; + m_inferiorPid = startParameters->attachPID > 0 ? startParameters->attachPID : 0; + m_runControl = runControl; emit debugModeRequested(); @@ -1005,13 +886,13 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl) QString settingsIdHint; switch (startMode()) { case AttachExternal: - m_engine = determineDebuggerEngine(m_attachedPID, &errorMessage); + m_engine = determineDebuggerEngine(m_startParameters->attachPID, &errorMessage); break; case AttachTcf: m_engine = tcfEngine; break; default: - m_engine = determineDebuggerEngine(m_executable, &errorMessage, &settingsIdHint); + m_engine = determineDebuggerEngine(m_startParameters->executable, &errorMessage, &settingsIdHint); break; } @@ -1019,7 +900,7 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl) debuggingFinished(); // Create Message box with possibility to go to settings QAbstractButton *settingsButton = 0; - QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), tr("Cannot debug '%1': %2").arg(m_executable, errorMessage), QMessageBox::Ok); + QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), tr("Cannot debug '%1': %2").arg(m_startParameters->executable, errorMessage), QMessageBox::Ok); if (!settingsIdHint.isEmpty()) settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole); msgBox.exec(); @@ -1028,7 +909,7 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl) return; } if (Debugger::Constants::Internal::debug) - qDebug() << m_executable << m_engine; + qDebug() << m_startParameters->executable << m_engine; setBusyCursor(false); setStatus(DebuggerProcessStartingUp); @@ -1037,8 +918,6 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl) debuggingFinished(); return; } - - return; } void DebuggerManager::cleanupViews() @@ -1066,6 +945,21 @@ void DebuggerManager::exitDebugger() emit debuggingFinished(); } +QSharedPointer<DebuggerStartParameters> DebuggerManager::startParameters() const +{ + return m_startParameters; +} + +void DebuggerManager::setQtDumperLibraryName(const QString &dl) +{ + m_dumperLib = dl; +} + +qint64 DebuggerManager::inferiorPid() const +{ + return m_inferiorPid; +} + void DebuggerManager::assignValueInDebugger() { if (QAction *action = qobject_cast<QAction *>(sender())) { @@ -1117,7 +1011,7 @@ void DebuggerManager::stepExec() QTC_ASSERT(m_engine, return); resetLocation(); m_engine->stepExec(); -} +} void DebuggerManager::stepOutExec() { @@ -1173,7 +1067,7 @@ void DebuggerManager::sessionLoaded() void DebuggerManager::sessionUnloaded() { return; - //FIXME: Breakview crashes on startup as there is + //FIXME: Breakview crashes on startup as there is //cleanupViews(); if (m_engine) m_engine->shutdown(); @@ -1207,7 +1101,7 @@ void DebuggerManager::dumpLog() QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) return; - QTextStream ts(&file); + QTextStream ts(&file); ts << m_outputWindow->inputContents(); ts << "\n\n=======================================\n\n"; ts << m_outputWindow->combinedContents(); @@ -1245,7 +1139,7 @@ void DebuggerManager::breakByFunction(const QString &functionName) void DebuggerManager::breakByFunction() { BreakByFunctionDialog dlg(m_mainWindow); - if (dlg.exec()) + if (dlg.exec()) breakByFunction(dlg.functionName()); } @@ -1268,7 +1162,7 @@ static bool isAllowedTransition(int from, int to) || (from == DebuggerInferiorRunning && to == DebuggerInferiorStopRequested) || (from == DebuggerInferiorRunning && to == DebuggerInferiorStopped) || (from == DebuggerInferiorStopRequested && to == DebuggerInferiorStopped) - || (to == DebuggerProcessNotReady); + || (to == DebuggerProcessNotReady); } void DebuggerManager::setStatus(int status) @@ -1619,9 +1513,9 @@ void DebuggerManager::reloadFullStack() void DebuggerManager::runTest(const QString &fileName) { - m_executable = fileName; - m_processArgs = QStringList() << "--run-debuggee"; - m_workingDir = QString(); + m_startParameters->executable = fileName; + m_startParameters->processArgs = QStringList() << "--run-debuggee"; + m_startParameters->workingDir.clear(); //startNewDebugger(StartInternal); } diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index c9fd72d2ec92c6128709a56a7e26b8e62ab7741b..c28b8d45ffdd41c3de6e1abcacaf1fb7ec300df7 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -34,6 +34,7 @@ #include <QtCore/QObject> #include <QtCore/QStringList> #include <QtCore/QVariant> +#include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE class QAction; @@ -44,6 +45,7 @@ class QMainWindow; class QPoint; class QTimer; class QWidget; +class QDebug; QT_END_NAMESPACE namespace Core { @@ -87,9 +89,9 @@ class Symbol; // DebuggerProcessStartingUp // | <-------------------------------------. // DebuggerInferiorRunningRequested | -// | | -// DebuggerInferiorRunning | -// | | +// | | +// DebuggerInferiorRunning | +// | | // DebuggerInferiorStopRequested | // | | // DebuggerInferiorStopped | @@ -124,12 +126,41 @@ enum DebuggerStartMode StartRemote // Start and attach to a remote process }; +struct DebuggerStartParameters { + DebuggerStartParameters(); + void clear(); + + QString executable; + QString coreFile; + QStringList processArgs; + QStringList environment; + QString workingDir; + QString buildDir; + qint64 attachPID; + bool useTerminal; + // for remote debugging + QString remoteChannel; + QString remoteArchitecture; + QString serverStartScript; +}; + +QDebug operator<<(QDebug str, const DebuggerStartParameters &); + class IDebuggerEngine; class GdbEngine; class ScriptEngine; class CdbDebugEngine; struct CdbDebugEnginePrivate; +// Flags for initialization +enum DebuggerEngineTypeFlags { + GdbEngineType = 0x1, + ScriptEngineType = 0x2, + CdbEngineType = 0x4, + TcfEngineType = 0x8, + AllEngineTypes = (GdbEngineType|ScriptEngineType|CdbEngineType|TcfEngineType) +}; + // The construct below is not nice but enforces a bit of order. The // DebuggerManager interfaces a lots of thing: The DebuggerPlugin, // the DebuggerEngines, the RunMode, the handlers and views. @@ -150,6 +181,7 @@ public: private: // This is the part of the interface that's exclusively seen by the // debugger engines + friend class CdbDebugEngine; friend class CdbDebugEventCallback; friend class CdbDumperHelper; @@ -161,11 +193,11 @@ private: // called from the engines after successful startup virtual void notifyInferiorStopRequested() = 0; - virtual void notifyInferiorStopped() = 0; + virtual void notifyInferiorStopped() = 0; virtual void notifyInferiorRunningRequested() = 0; virtual void notifyInferiorRunning() = 0; virtual void notifyInferiorExited() = 0; - virtual void notifyInferiorPidChanged(int) = 0; + virtual void notifyInferiorPidChanged(qint64) = 0; virtual DisassemblerHandler *disassemblerHandler() = 0; virtual ModulesHandler *modulesHandler() = 0; @@ -179,7 +211,7 @@ private: virtual void showApplicationOutput(const QString &data) = 0; virtual void showDebuggerOutput(const QString &prefix, const QString &msg) = 0; virtual void showDebuggerInput(const QString &prefix, const QString &msg) = 0; - + virtual void reloadDisassembler() = 0; virtual void reloadModules() = 0; virtual void reloadSourceFiles() = 0; @@ -189,6 +221,9 @@ private: virtual QString qtDumperLibraryName() const = 0; virtual void showQtDumperLibraryWarning(const QString &details = QString()) = 0; + virtual qint64 inferiorPid() const = 0; + + virtual QSharedPointer<DebuggerStartParameters> startParameters() const = 0; }; @@ -203,7 +238,7 @@ class DebuggerManager : public QObject, public: DebuggerManager(); - QList<Core::IOptionsPage*> initializeEngines(const QStringList &arguments); + QList<Core::IOptionsPage*> initializeEngines(unsigned enabledTypeFlags); ~DebuggerManager(); @@ -212,8 +247,13 @@ public: QLabel *statusLabel() const { return m_statusLabel; } public slots: - void startNewDebugger(DebuggerRunControl *runControl); - void exitDebugger(); + void startNewDebugger(DebuggerRunControl *runControl, const QSharedPointer<DebuggerStartParameters> &startParameters); + void exitDebugger(); + + virtual QSharedPointer<DebuggerStartParameters> startParameters() const; + virtual qint64 inferiorPid() const; + + void setQtDumperLibraryName(const QString &dl); // Run Control void setSimpleDockWidgetArrangement(); void setLocked(bool locked); @@ -222,9 +262,6 @@ public slots: void setBusyCursor(bool on); void queryCurrentTextEditor(QString *fileName, int *lineNumber, QObject **ed); - QVariant configValue(const QString &name); - void queryConfigValue(const QString &name, QVariant *value); - void setConfigValue(const QString &name, const QVariant &value); QVariant sessionValue(const QString &name); void gotoLocation(const QString &file, int line, bool setLocationMarker); @@ -254,7 +291,7 @@ public slots: void addToWatchWindow(); void updateWatchModel(); - + void sessionLoaded(); void sessionUnloaded(); void aboutToSaveSession(); @@ -293,7 +330,7 @@ private slots: private: // // Implementation of IDebuggerManagerAccessForEngines - // + // DisassemblerHandler *disassemblerHandler() { return m_disassemblerHandler; } ModulesHandler *modulesHandler() { return m_modulesHandler; } BreakHandler *breakHandler() { return m_breakHandler; } @@ -308,9 +345,9 @@ private: void notifyInferiorStopRequested(); void notifyInferiorRunning(); void notifyInferiorExited(); - void notifyInferiorPidChanged(int); + void notifyInferiorPidChanged(qint64); - void cleanupViews(); + void cleanupViews(); // // Implementation of IDebuggerManagerAccessForDebugMode @@ -322,15 +359,15 @@ private: virtual QString qtDumperLibraryName() const; virtual void showQtDumperLibraryWarning(const QString &details = QString()); - // + // // internal implementation - // + // Q_SLOT void loadSessionData(); Q_SLOT void saveSessionData(); Q_SLOT void dumpLog(); public: - // stuff in this block should be made private by moving it to + // stuff in this block should be made private by moving it to // one of the interfaces QAbstractItemModel *threadsModel(); int status() const { return m_status; } @@ -357,20 +394,6 @@ signals: void applicationOutputAvailable(const QString &output); public: - // FIXME: make private - QString m_executable; - QString m_coreFile; - QStringList m_environment; - QString m_workingDir; - QString m_buildDir; - QStringList m_processArgs; - QString m_dumperLib; - int m_attachedPID; - bool m_useTerminal; - // for remote debugging - QString m_remoteChannel; - QString m_remoteArchitecture; - QString m_serverStartScript; private: void init(); @@ -388,7 +411,11 @@ private: BreakpointData *findBreakpoint(const QString &fileName, int lineNumber); void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); + QSharedPointer<DebuggerStartParameters> m_startParameters; DebuggerRunControl *m_runControl; + QString m_dumperLib; + qint64 m_inferiorPid; + /// Views QMainWindow *m_mainWindow; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 8d796060649b81f63ebdfde9f07c6952a86ebef9..250a065f736684f2afbb572add130aef83ebf7d7 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -31,6 +31,7 @@ #include "breakhandler.h" #include "debuggeractions.h" +#include "debuggerdialogs.h" #include "debuggerconstants.h" #include "debuggermanager.h" #include "debuggerrunner.h" @@ -76,6 +77,7 @@ #include <QtCore/QSettings> #include <QtCore/QtPlugin> #include <QtCore/QCoreApplication> +#include <QtCore/QTimer> #include <QtGui/QLineEdit> #include <QtGui/QDockWidget> @@ -83,7 +85,7 @@ #include <QtGui/QPlainTextEdit> #include <QtGui/QTextBlock> #include <QtGui/QTextCursor> - +#include <QtGui/QMessageBox> using namespace Core; using namespace Debugger::Constants; @@ -274,15 +276,15 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent) m_ui.setupUi(w); m_group.clear(); - m_group.insert(theDebuggerAction(ListSourceFiles), + m_group.insert(theDebuggerAction(ListSourceFiles), m_ui.checkBoxListSourceFiles); - m_group.insert(theDebuggerAction(UseAlternatingRowColors), + m_group.insert(theDebuggerAction(UseAlternatingRowColors), m_ui.checkBoxUseAlternatingRowColors); - m_group.insert(theDebuggerAction(SkipKnownFrames), + m_group.insert(theDebuggerAction(SkipKnownFrames), m_ui.checkBoxSkipKnownFrames); - m_group.insert(theDebuggerAction(UseToolTips), + m_group.insert(theDebuggerAction(UseToolTips), m_ui.checkBoxUseToolTips); - m_group.insert(theDebuggerAction(MaximalStackDepth), + m_group.insert(theDebuggerAction(MaximalStackDepth), m_ui.spinBoxMaximalStackDepth); return w; @@ -396,6 +398,9 @@ DebuggerPlugin::DebuggerPlugin() m_debugMode(0), m_locationMark(0), m_gdbRunningContext(0), + m_cmdLineEnabledEngines(AllEngineTypes), + m_cmdLineAttachPid(0), + m_cmdLineWinException(0), m_toggleLockedAction(0) {} @@ -425,13 +430,92 @@ void DebuggerPlugin::shutdown() m_manager = 0; } +static inline QString msgParameterMissing(const QString &a) +{ + return DebuggerPlugin::tr("Option '%1' is missing the parameter.").arg(a); +} + +static inline QString msgInvalidNumericParameter(const QString &a, const QString &number) +{ + return DebuggerPlugin::tr("The parameter '%1' of option '%2' is not a number.").arg(number, a); +} + +// Parse arguments +bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it, + const QStringList::const_iterator& cend, + QString *errorMessage) +{ + const QString &option = *it; + // '-debug <pid>' + if (*it == QLatin1String("-debug")) { + ++it; + if (it == cend) { + *errorMessage = msgParameterMissing(*it); + return false; + } + bool ok; + m_cmdLineAttachPid = it->toULongLong(&ok); + if (!ok) { + *errorMessage = msgInvalidNumericParameter(option, *it); + return false; + } + return true; + } + // -winexception <exception code>, passed in by Windows System + if (*it == QLatin1String("-winexception")) { + ++it; + if (it == cend) { + *errorMessage = msgParameterMissing(*it); + return false; + } + bool ok; + m_cmdLineWinException = it->toULong(&ok); + if (!ok) { + *errorMessage = msgInvalidNumericParameter(option, *it); + return false; + } + return true; + } + // engine disabling + if (option == QLatin1String("-disable-cdb")) { + m_cmdLineEnabledEngines &= ~CdbEngineType; + return true; + } + if (option == QLatin1String("-disable-gdb")) { + m_cmdLineEnabledEngines &= ~GdbEngineType; + return true; + } + if (option == QLatin1String("-disable-sdb")) { + m_cmdLineEnabledEngines &= ~ScriptEngineType; + return true; + } + if (option == QLatin1String("-disable-tcf")) { + m_cmdLineEnabledEngines &= ~TcfEngineType; + return true; + } + + *errorMessage = tr("Invalid debugger option: %1").arg(option); + return false; +} + +bool DebuggerPlugin::parseArguments(const QStringList &args, QString *errorMessage) +{ + const QStringList::const_iterator cend = args.constEnd(); + for (QStringList::const_iterator it = args.constBegin(); it != cend; ++it) + if (!parseArgument(it, cend, errorMessage)) + return false; + if (Debugger::Constants::Internal::debug) + qDebug().nospace() << args << "engines=0x" << QString::number(m_cmdLineEnabledEngines, 16) << " pid" << m_cmdLineAttachPid << '\n'; + return true; +} + bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage) { - Q_UNUSED(arguments); - Q_UNUSED(errorMessage); + if (!parseArguments(arguments, errorMessage)) + return false; m_manager = new DebuggerManager; - const QList<Core::IOptionsPage *> engineOptionPages = m_manager->initializeEngines(arguments); + const QList<Core::IOptionsPage *> engineOptionPages = m_manager->initializeEngines(m_cmdLineEnabledEngines); ICore *core = ICore::instance(); QTC_ASSERT(core, return false); @@ -664,7 +748,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess // FIXME: addAutoReleasedObject(new CommonOptionsPage); - addAutoReleasedObject(new DebuggingHelperOptionPage); + addAutoReleasedObject(new DebuggingHelperOptionPage); foreach (Core::IOptionsPage* op, engineOptionPages) addAutoReleasedObject(op); @@ -786,10 +870,6 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess this, SLOT(setSessionValue(QString,QVariant))); connect(m_manager, SIGNAL(sessionValueRequested(QString,QVariant*)), this, SLOT(querySessionValue(QString,QVariant*))); - connect(m_manager, SIGNAL(setConfigValueRequested(QString,QVariant)), - this, SLOT(setConfigValue(QString,QVariant))); - connect(m_manager, SIGNAL(configValueRequested(QString,QVariant*)), - this, SLOT(queryConfigValue(QString,QVariant*))); connect(m_manager, SIGNAL(resetLocationRequested()), this, SLOT(resetLocation())); @@ -814,10 +894,21 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess void DebuggerPlugin::extensionsInitialized() { // time gdb -i mi -ex 'debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin - QByteArray env = qgetenv("QTC_DEBUGGER_TEST"); + const QByteArray env = qgetenv("QTC_DEBUGGER_TEST"); //qDebug() << "EXTENSIONS INITIALIZED:" << env; if (!env.isEmpty()) m_manager->runTest(QString::fromLocal8Bit(env)); + if (m_cmdLineAttachPid) + QTimer::singleShot(0, this, SLOT(attachCmdLinePid())); +} + +void DebuggerPlugin::attachCmdLinePid() +{ + const QString msg = m_cmdLineWinException ? + tr("Attaching to PID %1 (exception code %2).").arg(m_cmdLineAttachPid).arg(m_cmdLineWinException) : + tr("Attaching to PID %1.").arg(m_cmdLineAttachPid); + m_manager->showStatusMessage(msg); + attachExternalApplication(m_cmdLineAttachPid); } /*! Activates the previous mode when the current mode is the debug mode. */ @@ -967,6 +1058,12 @@ void DebuggerPlugin::setConfigValue(const QString &name, const QVariant &value) settings()->setValue(name, value); } +QVariant DebuggerPlugin::configValue(const QString &name) const +{ + QTC_ASSERT(m_debugMode, return QVariant()); + return settings()->value(name); +} + void DebuggerPlugin::queryConfigValue(const QString &name, QVariant *value) { QTC_ASSERT(m_debugMode, return); @@ -1072,41 +1169,133 @@ static QSharedPointer<RunConfiguration> activeRunConfiguration() void DebuggerPlugin::startExternalApplication() { + const QSharedPointer<DebuggerStartParameters> sp(new DebuggerStartParameters); + StartExternalDialog dlg(m_manager->mainWindow()); + dlg.setExecutableFile( + configValue(_("LastExternalExecutableFile")).toString()); + dlg.setExecutableArguments( + configValue(_("LastExternalExecutableArguments")).toString()); + if (dlg.exec() != QDialog::Accepted) { + return; + } + setConfigValue(_("LastExternalExecutableFile"), + dlg.executableFile()); + setConfigValue(_("LastExternalExecutableArguments"), + dlg.executableArguments()); + sp->executable = dlg.executableFile(); + sp->processArgs = dlg.executableArguments().split(QLatin1Char(' ')); + QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); if (RunControl *runControl = m_debuggerRunner - ->run(rc, ProjectExplorer::Constants::DEBUGMODE, StartExternal)) + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, sp, StartExternal)) runControl->start(); } void DebuggerPlugin::attachExternalApplication() { + AttachExternalDialog dlg(m_manager->mainWindow()); + if (dlg.exec() == QDialog::Accepted) + attachExternalApplication(dlg.attachPID()); +} + +void DebuggerPlugin::attachExternalApplication(qint64 pid) +{ + if (pid == 0) { + QMessageBox::warning(m_manager->mainWindow(), tr("Warning"), tr("Cannot attach to PID 0")); + return; + } + const QSharedPointer<DebuggerStartParameters> sp(new DebuggerStartParameters); + sp->attachPID = pid; QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); if (RunControl *runControl = m_debuggerRunner - ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachExternal)) + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, sp, AttachExternal)) runControl->start(); } void DebuggerPlugin::attachCore() { + const QSharedPointer<DebuggerStartParameters> sp(new DebuggerStartParameters); + AttachCoreDialog dlg(m_manager->mainWindow()); + dlg.setExecutableFile( + configValue(_("LastExternalExecutableFile")).toString()); + dlg.setCoreFile( + configValue(_("LastExternalCoreFile")).toString()); + if (dlg.exec() != QDialog::Accepted) + return; + setConfigValue(_("LastExternalExecutableFile"), + dlg.executableFile()); + setConfigValue(_("LastExternalCoreFile"), + dlg.coreFile()); + sp->executable = dlg.executableFile(); + sp->coreFile = dlg.coreFile(); QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); if (RunControl *runControl = m_debuggerRunner - ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachCore)) + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, sp, AttachCore)) runControl->start(); } void DebuggerPlugin::startRemoteApplication() { + const QSharedPointer<DebuggerStartParameters> sp(new DebuggerStartParameters); + StartRemoteDialog dlg(m_manager->mainWindow()); + QStringList arches; + arches.append(_("i386:x86-64:intel")); + dlg.setRemoteArchitectures(arches); + dlg.setRemoteChannel( + configValue(_("LastRemoteChannel")).toString()); + dlg.setRemoteArchitecture( + configValue(_("LastRemoteArchitecture")).toString()); + dlg.setServerStartScript( + configValue(_("LastServerStartScript")).toString()); + dlg.setUseServerStartScript( + configValue(_("LastUseServerStartScript")).toBool()); + if (dlg.exec() != QDialog::Accepted) + return; + setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel()); + setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture()); + setConfigValue(_("LastServerStartScript"), dlg.serverStartScript()); + setConfigValue(_("LastUseServerStartScript"), dlg.useServerStartScript()); + sp->remoteChannel = dlg.remoteChannel(); + sp->remoteArchitecture = dlg.remoteArchitecture(); + if (dlg.useServerStartScript()) + sp->serverStartScript = dlg.serverStartScript(); + QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); if (RunControl *runControl = m_debuggerRunner - ->run(rc, ProjectExplorer::Constants::DEBUGMODE, StartRemote)) + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, sp, StartRemote)) runControl->start(); } void DebuggerPlugin::attachRemoteTcf() { + const QSharedPointer<DebuggerStartParameters> sp(new DebuggerStartParameters); + AttachTcfDialog dlg(m_manager->mainWindow()); + QStringList arches; + arches.append(_("i386:x86-64:intel")); + dlg.setRemoteArchitectures(arches); + dlg.setRemoteChannel( + configValue(_("LastTcfRemoteChannel")).toString()); + dlg.setRemoteArchitecture( + configValue(_("LastTcfRemoteArchitecture")).toString()); + dlg.setServerStartScript( + configValue(_("LastTcfServerStartScript")).toString()); + dlg.setUseServerStartScript( + configValue(_("LastTcfUseServerStartScript")).toBool()); + if (dlg.exec() != QDialog::Accepted) + return; + setConfigValue(_("LastTcfRemoteChannel"), dlg.remoteChannel()); + setConfigValue(_("LastTcfRemoteArchitecture"), dlg.remoteArchitecture()); + setConfigValue(_("LastTcfServerStartScript"), dlg.serverStartScript()); + setConfigValue(_("LastTcfUseServerStartScript"), dlg.useServerStartScript()); + sp->remoteChannel = dlg.remoteChannel(); + sp->remoteArchitecture = dlg.remoteArchitecture(); + sp->serverStartScript = dlg.serverStartScript(); + if (dlg.useServerStartScript()) + sp->serverStartScript = dlg.serverStartScript(); + QSharedPointer<RunConfiguration> rc = activeRunConfiguration(); if (RunControl *runControl = m_debuggerRunner - ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachTcf)) + ->run(rc, ProjectExplorer::Constants::DEBUGMODE, sp, AttachTcf)) runControl->start(); } diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index c022e3a0ab81a133680cf85f4295626b5025f1b7..082a01e0160f9903bf12d56ff14b00b1ea089e53 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -33,6 +33,7 @@ #include <extensionsystem/iplugin.h> #include <QtCore/QObject> +#include <QtCore/QStringList> QT_BEGIN_NAMESPACE class QAbstractItemView; @@ -69,9 +70,11 @@ public: ~DebuggerPlugin(); private: - bool initialize(const QStringList &arguments, QString *error_message); - void shutdown(); - void extensionsInitialized(); + virtual bool initialize(const QStringList &arguments, QString *error_message); + virtual void shutdown(); + virtual void extensionsInitialized(); + + QVariant configValue(const QString &name) const; private slots: void activatePreviousMode(); @@ -90,7 +93,6 @@ private slots: int lineNumber, QMenu *menu); void updateActions(int status); - void resetLocation(); void gotoLocation(const QString &fileName, int line, bool setMarker); @@ -104,10 +106,16 @@ private slots: void attachExternalApplication(); void attachCore(); void attachRemoteTcf(); + void attachCmdLinePid(); private: void readSettings(); void writeSettings() const; + bool parseArguments(const QStringList &args, QString *errorMessage); + inline bool parseArgument(QStringList::const_iterator &it, + const QStringList::const_iterator& end, + QString *errorMessage); + void attachExternalApplication(qint64 pid); friend class DebuggerManager; friend class GdbOptionPage; @@ -121,7 +129,10 @@ private: QString m_previousMode; LocationMark *m_locationMark; int m_gdbRunningContext; - + unsigned m_cmdLineEnabledEngines; + quint64 m_cmdLineAttachPid; + // Exception that crashed an app passed on by Windows + unsigned long m_cmdLineWinException; QAction *m_toggleLockedAction; QAction *m_startExternalAction; diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 8739091296c8c11c156652289a7ad9e46ea841f9..b91ef2c565e9fc429f540ab9e060322dcb7fe53b 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -58,13 +58,13 @@ using ProjectExplorer::ApplicationRunConfiguration; //////////////////////////////////////////////////////////////////////// // A factory to create DebuggerRunControls -DebuggerRunner::DebuggerRunner(DebuggerManager *manager) - : m_manager(manager) +DebuggerRunner::DebuggerRunner(DebuggerManager *manager) : + m_manager(manager) {} bool DebuggerRunner::canRun(RunConfigurationPtr runConfiguration, const QString &mode) { - return mode == ProjectExplorer::Constants::DEBUGMODE + return mode == ProjectExplorer::Constants::DEBUGMODE && !qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration).isNull(); } @@ -74,22 +74,24 @@ QString DebuggerRunner::displayName() const } RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration, - const QString &mode, DebuggerStartMode startMode) + const QString &mode, + const QSharedPointer<DebuggerStartParameters> &sp, + DebuggerStartMode startMode) { QTC_ASSERT(mode == ProjectExplorer::Constants::DEBUGMODE, return 0); ApplicationRunConfigurationPtr rc = qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration); //QTC_ASSERT(rc, return 0); //qDebug() << "***** Debugging" << rc->name() << rc->executable(); - DebuggerRunControl *runControl = new DebuggerRunControl(m_manager, rc); - runControl->setStartMode(startMode); + DebuggerRunControl *runControl = new DebuggerRunControl(m_manager, startMode, sp, rc); return runControl; } RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration, const QString &mode) { - return run(runConfiguration, mode, StartInternal); + const QSharedPointer<DebuggerStartParameters> sp(new DebuggerStartParameters); + return run(runConfiguration, mode, sp, StartInternal); } QWidget *DebuggerRunner::configurationWidget(RunConfigurationPtr runConfiguration) @@ -109,8 +111,14 @@ QWidget *DebuggerRunner::configurationWidget(RunConfigurationPtr runConfiguratio DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager, - QSharedPointer<ApplicationRunConfiguration> runConfiguration) - : RunControl(runConfiguration), m_manager(manager), m_running(false) + DebuggerStartMode mode, + const QSharedPointer<DebuggerStartParameters> &startParameters, + QSharedPointer<ApplicationRunConfiguration> runConfiguration) : + RunControl(runConfiguration), + m_mode(mode), + m_startParameters(startParameters), + m_manager(manager), + m_running(false) { connect(m_manager, SIGNAL(debuggingFinished()), this, SLOT(debuggingFinished()), @@ -131,28 +139,31 @@ void DebuggerRunControl::start() ApplicationRunConfigurationPtr rc = qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration()); if (rc) { - m_manager->m_executable = rc->executable(); - m_manager->m_environment = rc->environment().toStringList(); - m_manager->m_workingDir = rc->workingDirectory(); - m_manager->m_processArgs = rc->commandLineArguments(); - m_manager->m_dumperLib = rc->dumperLibrary(); - ProjectExplorer::Project *project = rc->project(); - QTC_ASSERT(project, /**/); - if (project) { - m_manager->m_buildDir = - project->buildDirectory(project->activeBuildConfiguration()); + // Enhance parameters by info from the project, but do not clobber + // arguments given in the dialogs + if (m_startParameters->executable.isEmpty()) + m_startParameters->executable = rc->executable(); + if (m_startParameters->environment.empty()) + m_startParameters->environment = rc->environment().toStringList(); + if (m_startParameters->workingDir.isEmpty()) + m_startParameters->workingDir = rc->workingDirectory(); + if (m_mode != StartExternal) + m_startParameters->processArgs = rc->commandLineArguments(); + m_manager->setQtDumperLibraryName(rc->dumperLibrary()); + if (const ProjectExplorer::Project *project = rc->project()) { + m_startParameters->buildDir = project->buildDirectory(project->activeBuildConfiguration()); } - m_manager->m_useTerminal = rc->runMode() == ApplicationRunConfiguration::Console; + m_startParameters->useTerminal = rc->runMode() == ApplicationRunConfiguration::Console; } //emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable)); - m_manager->startNewDebugger(this); + m_manager->startNewDebugger(this, m_startParameters); emit started(); //debuggingFinished(); } void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data) -{ +{ emit addToOutputWindowInline(this, data); } diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h index 619498bba6ecc374c414eea12c9d7020c7d75367..4a4620f9ae0e6e0c038f6e2edc58dc976a3a3458 100644 --- a/src/plugins/debugger/debuggerrunner.h +++ b/src/plugins/debugger/debuggerrunner.h @@ -59,14 +59,19 @@ public: // ProjectExplorer::IRunConfigurationRunner virtual bool canRun(RunConfigurationPtr runConfiguration, const QString &mode); + virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration, const QString &mode); virtual QString displayName() const; - virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration, - const QString &mode); + virtual QWidget *configurationWidget(RunConfigurationPtr runConfiguration); - virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration, - const QString &mode, DebuggerStartMode startMode); + virtual ProjectExplorer::RunControl + *run(RunConfigurationPtr runConfiguration, + const QString &mode, + const QSharedPointer<DebuggerStartParameters> &sp, + DebuggerStartMode startMode); + private: + QSharedPointer<DebuggerStartParameters> m_startParameters; DebuggerManager *m_manager; }; @@ -76,18 +81,20 @@ class DebuggerRunControl : public ProjectExplorer::RunControl Q_OBJECT public: - DebuggerRunControl(DebuggerManager *manager, - ApplicationRunConfigurationPtr runConfiguration); + explicit DebuggerRunControl(DebuggerManager *manager, + DebuggerStartMode mode, + const QSharedPointer<DebuggerStartParameters> &sp, + ApplicationRunConfigurationPtr runConfiguration); + + DebuggerStartMode startMode() const { return m_mode; } // ProjectExplorer::RunControl virtual void start(); virtual void stop(); virtual bool isRunning() const; - void setStartMode(DebuggerStartMode mode) { m_mode = mode; } - DebuggerStartMode startMode() const { return m_mode; } Q_SLOT void debuggingFinished(); - + signals: void stopRequested(); @@ -95,9 +102,10 @@ private slots: void slotAddToOutputWindowInline(const QString &output); private: + const DebuggerStartMode m_mode; + const QSharedPointer<DebuggerStartParameters> m_startParameters; DebuggerManager *m_manager; bool m_running; - DebuggerStartMode m_mode; }; } // namespace Internal diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 98e1b9b9a078ff5ef5277c804661ab69cf21fb88..a3eb6f0c7e44d435924d1b9f4aac9c6a580f8dc3 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -542,9 +542,9 @@ void GdbEngine::handleStubAttached(const GdbResultRecord &, const QVariant &) void GdbEngine::stubStarted() { - q->m_attachedPID = m_stubProc.applicationPID(); - qq->notifyInferiorPidChanged(q->m_attachedPID); - postCommand(_("attach %1").arg(q->m_attachedPID), CB(handleStubAttached)); + const qint64 attachedPID = m_stubProc.applicationPID(); + qq->notifyInferiorPidChanged(attachedPID); + postCommand(_("attach %1").arg(attachedPID), CB(handleStubAttached)); } void GdbEngine::stubError(const QString &msg) @@ -602,26 +602,27 @@ void GdbEngine::interruptInferior() return; } - if (q->m_attachedPID <= 0) { + const qint64 attachedPID = q->inferiorPid(); + if (attachedPID <= 0) { debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED")); return; } - if (!interruptProcess(q->m_attachedPID)) - debugMessage(_("CANNOT INTERRUPT %1").arg(q->m_attachedPID)); + if (!interruptProcess(attachedPID)) + debugMessage(_("CANNOT INTERRUPT %1").arg(attachedPID)); } void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0) { - int pid = pid0.toInt(); + const qint64 pid = pid0.toLongLong(); if (pid == 0) { debugMessage(_("Cannot parse PID from %1").arg(pid0)); return; } - if (pid == q->m_attachedPID) + if (pid == q->inferiorPid()) return; - debugMessage(_("FOUND PID %1").arg(pid)); - q->m_attachedPID = pid; + debugMessage(_("FOUND PID %1").arg(pid)); + qq->notifyInferiorPidChanged(pid); if (m_dumperInjectionLoad) tryLoadDebuggingHelpers(); @@ -1364,27 +1365,29 @@ bool GdbEngine::startDebugger() gdbArgs.prepend(_("mi")); gdbArgs.prepend(_("-i")); + const QSharedPointer<DebuggerStartParameters> sp = q->startParameters(); + if (q->startMode() == AttachCore || q->startMode() == AttachExternal) { // nothing to do } else if (q->startMode() == StartRemote) { // Start the remote server - if (q->m_serverStartScript.isEmpty()) { + if (sp->serverStartScript.isEmpty()) { q->showStatusMessage(_("No server start script given. " "Assuming server runs already.")); } else { - if (!q->m_workingDir.isEmpty()) - m_uploadProc.setWorkingDirectory(q->m_workingDir); - if (!q->m_environment.isEmpty()) - m_uploadProc.setEnvironment(q->m_environment); - m_uploadProc.start(_("/bin/sh ") + q->m_serverStartScript); + if (!sp->workingDir.isEmpty()) + m_uploadProc.setWorkingDirectory(sp->workingDir); + if (!sp->environment.isEmpty()) + m_uploadProc.setEnvironment(sp->environment); + m_uploadProc.start(_("/bin/sh ") + sp->serverStartScript); m_uploadProc.waitForStarted(); } - } else if (q->m_useTerminal) { + } else if (sp->useTerminal) { m_stubProc.stop(); // We leave the console open, so recycle it now. - m_stubProc.setWorkingDirectory(q->m_workingDir); - m_stubProc.setEnvironment(q->m_environment); - if (!m_stubProc.start(q->m_executable, q->m_processArgs)) + m_stubProc.setWorkingDirectory(sp->workingDir); + m_stubProc.setEnvironment(sp->environment); + if (!m_stubProc.start(sp->executable, sp->processArgs)) return false; // Error message for user is delivered via a signal. } else { if (!m_outputCollector.listen()) { @@ -1395,10 +1398,10 @@ bool GdbEngine::startDebugger() } gdbArgs.prepend(_("--tty=") + m_outputCollector.serverName()); - if (!q->m_workingDir.isEmpty()) - m_gdbProc.setWorkingDirectory(q->m_workingDir); - if (!q->m_environment.isEmpty()) - m_gdbProc.setEnvironment(q->m_environment); + if (!sp->workingDir.isEmpty()) + m_gdbProc.setWorkingDirectory(sp->workingDir); + if (!sp->environment.isEmpty()) + m_gdbProc.setEnvironment(sp->environment); } #if 0 @@ -1407,8 +1410,8 @@ bool GdbEngine::startDebugger() qDebug() << "ScriptFile:" << q->settings()->m_scriptFile; qDebug() << "Environment:" << m_gdbProc.environment(); qDebug() << "Arguments:" << gdbArgs; - qDebug() << "BuildDir:" << q->m_buildDir; - qDebug() << "ExeFile:" << q->m_executable; + qDebug() << "BuildDir:" << sp->buildDir; + qDebug() << "ExeFile:" << sp->executable; #endif QString loc = theDebuggerStringSetting(GdbLocation); @@ -1504,38 +1507,38 @@ bool GdbEngine::startDebugger() } if (q->startMode() == AttachExternal) { - postCommand(_("attach %1").arg(q->m_attachedPID), CB(handleAttach)); + postCommand(_("attach %1").arg(sp->attachPID), CB(handleAttach)); qq->breakHandler()->removeAllBreakpoints(); } else if (q->startMode() == AttachCore) { - QFileInfo fi(q->m_executable); + QFileInfo fi(sp->executable); QString fileName = _c('"') + fi.absoluteFilePath() + _c('"'); - QFileInfo fi2(q->m_coreFile); + QFileInfo fi2(sp->coreFile); // quoting core name below fails in gdb 6.8-debian QString coreName = fi2.absoluteFilePath(); postCommand(_("-file-exec-and-symbols ") + fileName); postCommand(_("target core ") + coreName, CB(handleTargetCore)); qq->breakHandler()->removeAllBreakpoints(); } else if (q->startMode() == StartRemote) { - postCommand(_("set architecture %1").arg(q->m_remoteArchitecture)); + postCommand(_("set architecture %1").arg(sp->remoteArchitecture)); qq->breakHandler()->setAllPending(); - //QFileInfo fi(q->m_executable); + //QFileInfo fi(sp->executable); //QString fileName = fi.absoluteFileName(); - QString fileName = q->m_executable; + QString fileName = sp->executable; postCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName)); // works only for > 6.8 postCommand(_("set target-async on"), CB(handleSetTargetAsync)); - } else if (q->m_useTerminal) { + } else if (sp->useTerminal) { qq->breakHandler()->setAllPending(); } else if (q->startMode() == StartInternal || q->startMode() == StartExternal) { - QFileInfo fi(q->m_executable); + QFileInfo fi(sp->executable); QString fileName = _c('"') + fi.absoluteFilePath() + _c('"'); postCommand(_("-file-exec-and-symbols ") + fileName, CB(handleFileExecAndSymbols)); //postCommand(_("file ") + fileName, handleFileExecAndSymbols); #ifdef Q_OS_MAC postCommand(_("sharedlibrary apply-load-rules all")); #endif - if (!q->m_processArgs.isEmpty()) - postCommand(_("-exec-arguments ") + q->m_processArgs.join(_(" "))); + if (!sp->processArgs.isEmpty()) + postCommand(_("-exec-arguments ") + sp->processArgs.join(_(" "))); #ifndef Q_OS_MAC if (!m_dumperInjectionLoad) postCommand(_("set auto-solib-add off")); @@ -1624,7 +1627,7 @@ void GdbEngine::handleSetTargetAsync(const GdbResultRecord &record, const QVaria if (record.resultClass == GdbResultDone) { //postCommand(_("info target"), handleStart); qq->notifyInferiorRunningRequested(); - postCommand(_("target remote %1").arg(q->m_remoteChannel), + postCommand(_("target remote %1").arg(q->startParameters()->remoteChannel), CB(handleTargetRemote)); } else if (record.resultClass == GdbResultError) { // a typical response on "old" gdb is: @@ -3485,7 +3488,7 @@ void GdbEngine::updateLocals() { // Asynchronous load of injected library, initialize in first stop if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried && m_dumperHelper.typeCount() == 0 - && q->m_attachedPID > 0) + && q->inferiorPid() > 0) tryQueryDebuggingHelpers(); m_pendingRequests = 0; @@ -3884,7 +3887,7 @@ void GdbEngine::tryLoadDebuggingHelpers() postCommand(_(contents)); return; } - if (m_dumperInjectionLoad && q->m_attachedPID <= 0) // Need PID to inject + if (m_dumperInjectionLoad && q->inferiorPid() <= 0) // Need PID to inject return; PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS"); @@ -3906,7 +3909,7 @@ void GdbEngine::tryLoadDebuggingHelpers() #if defined(Q_OS_WIN) if (m_dumperInjectionLoad) { /// Launch asynchronous remote thread to load. - SharedLibraryInjector injector(q->m_attachedPID); + SharedLibraryInjector injector(q->inferiorPid()); QString errorMessage; if (injector.remoteInject(lib, false, &errorMessage)) { debugMessage(tr("Dumper injection loading triggered (%1)...").arg(lib)); diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp index c8efb92ca984fe5e0a3251504d620b491c5389ef..652e3e8d7b55b7385a6ac58eb986bba03f048ae9 100644 --- a/src/plugins/debugger/script/scriptengine.cpp +++ b/src/plugins/debugger/script/scriptengine.cpp @@ -224,7 +224,8 @@ bool ScriptEngine::startDebugger() m_stopped = false; m_stopOnNextLine = false; m_scriptEngine->abortEvaluation(); - QFileInfo fi(q->m_executable); + const QSharedPointer<DebuggerStartParameters> sp = q->startParameters(); + QFileInfo fi(sp->executable); m_scriptFileName = fi.absoluteFilePath(); QFile scriptFile(m_scriptFileName); if (!scriptFile.open(QIODevice::ReadOnly)) diff --git a/src/plugins/debugger/tcf/tcfengine.cpp b/src/plugins/debugger/tcf/tcfengine.cpp index 6e7fac9f3799cada6ff8b5042c69c881a6a1f96d..c6bbf7426fe52ee4a27b4543c0fc8063c53e6443 100644 --- a/src/plugins/debugger/tcf/tcfengine.cpp +++ b/src/plugins/debugger/tcf/tcfengine.cpp @@ -224,9 +224,10 @@ void TcfEngine::exitDebugger() bool TcfEngine::startDebugger() { qq->notifyInferiorRunningRequested(); - int pos = q->m_remoteChannel.indexOf(':'); - QString host = q->m_remoteChannel.left(pos); - quint16 port = q->m_remoteChannel.mid(pos + 1).toInt(); + const QSharedPointer<DebuggerStartParameters> sp = qq->startParameters(); + const int pos = sp->remoteChannel.indexOf(QLatin1Char(':')); + const QString host = sp->remoteChannel.left(pos); + const quint16 port = sp->remoteChannel.mid(pos + 1).toInt(); //QTimer::singleShot(0, this, SLOT(runInferior())); m_socket->connectToHost(host, port); return true; diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index e9ef013d8a31a9eb0fb8a45ad8d79a68cbd40627..9bad0d2f20a6c30dc05af8905a7a0227e7b9de99 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -714,7 +714,6 @@ void Qt4ProFileNode::update() // update other variables QHash<Qt4Variable, QStringList> newVarValues; - newVarValues[CxxCompilerVar] << reader->value(QLatin1String("QMAKE_CXX")); newVarValues[DefinesVar] = reader->values(QLatin1String("DEFINES")); newVarValues[IncludePathVar] = includePaths(reader); newVarValues[UiDirVar] = uiDirPaths(reader); diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index f5599e90b61c944a4be5ee014150072d3e7926f7..070bd39c5df901fafaa80fea9e3d80b0b2b42e24 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -97,7 +97,6 @@ enum Qt4ProjectType { enum Qt4Variable { DefinesVar = 1, IncludePathVar, - CxxCompilerVar, UiDirVar, MocDirVar, PkgConfigVar diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 593aadbf9b80cd12fdbbd5ae33ca698c391b5f87..ebdbf43d3fe4401dfc2f9d6560e0066c30789c21 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -225,7 +225,6 @@ void Qt4ProjectFile::modified(Core::IFile::ReloadBehavior *) */ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) : - m_toolChain(0), m_manager(manager), m_rootProjectNode(0), m_nodesWatcher(new Internal::Qt4NodesWatcher(this)), @@ -251,8 +250,6 @@ Qt4Project::~Qt4Project() { m_manager->unregisterProject(this); delete m_projectFiles; - delete m_toolChain; - m_toolChain = 0; } void Qt4Project::defaultQtVersionChanged() @@ -380,57 +377,7 @@ void Qt4Project::scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFile QString Qt4Project::makeCommand(const QString &buildConfiguration) const { - return toolChain(buildConfiguration)->makeCommand(); -} - -ProjectExplorer::ToolChain *Qt4Project::toolChain(const QString &buildConfiguration) const -{ - if (debug) - qDebug()<<"Qt4Project::toolChain() for buildconfiguration:"<<buildConfiguration; - Q_UNUSED(buildConfiguration); - ToolChain *m_test= 0; - QtVersion *version = qtVersion(activeBuildConfiguration()); - ToolChain::ToolChainType t = version->toolchainType(); - if (t == ToolChain::MinGW) { - QStringList list = rootProjectNode()->variableValue(Internal::CxxCompilerVar); - QString qmake_cxx = list.isEmpty() ? QString::null : list.first(); - Environment env = Environment::systemEnvironment(); - qtVersion(activeBuildConfiguration())->addToEnvironment(env); - env.prependOrSetPath(qtVersion(activeBuildConfiguration())->mingwDirectory()+"/bin"); - qmake_cxx = env.searchInPath(qmake_cxx); - m_test = ToolChain::createMinGWToolChain(qmake_cxx, version->mingwDirectory()); - //qDebug()<<"Mingw ToolChain"; - } else if(t == ToolChain::MSVC) { - m_test = ToolChain::createMSVCToolChain(version->msvcVersion(), version->isMSVC64Bit()); - //qDebug()<<"MSVC ToolChain ("<<version->msvcVersion()<<")"; - } else if(t == ToolChain::WINCE) { - m_test = ToolChain::createWinCEToolChain(version->msvcVersion(), version->wincePlatform()); - //qDebug()<<"WinCE ToolChain ("<<version->msvcVersion()<<","<<version->wincePlatform()<<")"; - } else if(t == ToolChain::GCC || t == ToolChain::LinuxICC) { - QStringList list = rootProjectNode()->variableValue(Internal::CxxCompilerVar); - QString qmake_cxx = list.isEmpty() ? QString::null : list.first(); - Environment env = Environment::systemEnvironment(); - qtVersion(activeBuildConfiguration())->addToEnvironment(env); - qmake_cxx = env.searchInPath(qmake_cxx); - if (qmake_cxx.isEmpty()) { - // macx-xcode mkspec resets the value of QMAKE_CXX. - // Unfortunately, we need a valid QMAKE_CXX to configure the parser. - qmake_cxx = QLatin1String("cc"); - } - m_test = ToolChain::createGccToolChain(qmake_cxx); - //qDebug()<<"GCC ToolChain ("<<qmake_cxx<<")"; - } else { - qDebug()<<"Could not detect ToolChain for"<<version->mkspec(); - qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines."; - } - - if (ToolChain::equals(m_test, m_toolChain)) { - delete m_test; - } else { - delete m_toolChain; - m_toolChain = m_test; - } - return m_toolChain; + return qtVersion(buildConfiguration)->toolChain()->makeCommand(); } void Qt4Project::updateCodeModel() @@ -449,7 +396,7 @@ void Qt4Project::updateCodeModel() QStringList predefinedFrameworkPaths; QByteArray predefinedMacros; - ToolChain *tc = toolChain(activeBuildConfiguration()); + ToolChain *tc = qtVersion(activeBuildConfiguration())->toolChain(); QList<HeaderPath> allHeaderPaths; if (tc) { predefinedMacros = tc->predefinedMacros(); @@ -755,9 +702,6 @@ ProjectExplorer::Environment Qt4Project::baseEnvironment(const QString &buildCon { Environment env = useSystemEnvironment(buildConfiguration) ? Environment(QProcess::systemEnvironment()) : Environment(); qtVersion(buildConfiguration)->addToEnvironment(env); - ToolChain *tc = toolChain(buildConfiguration); - if (tc) - tc->addToEnvironment(env); return env; } diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h index 1bf27c59d0afbc0aae5ce6983430a553d369ac47..d89158737a1d74e02b0d60a5446d82034edeb66e 100644 --- a/src/plugins/qt4projectmanager/qt4project.h +++ b/src/plugins/qt4projectmanager/qt4project.h @@ -223,10 +223,6 @@ private: static void findProFile(const QString& fileName, Internal::Qt4ProFileNode *root, QList<Internal::Qt4ProFileNode *> &list); static bool hasSubNode(Internal::Qt4PriFileNode *root, const QString &path); - ProjectExplorer::ToolChain *toolChain(const QString &buildConfiguration) const; - mutable ProjectExplorer::ToolChain *m_toolChain; - - QList<Internal::Qt4ProFileNode *> m_applicationProFileChange; ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const; diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 608e05b8a519eb4c0b51ff167b0d9a61db7e8239..62c59936aae2f101de038e98d5c26ffbe05e96d7 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -30,6 +30,7 @@ #include "qtversionmanager.h" #include "qt4projectmanagerconstants.h" +#include "profilereader.h" #include <projectexplorer/debugginghelper.h> #include <projectexplorer/projectexplorer.h> @@ -39,6 +40,7 @@ #include <help/helpplugin.h> #include <utils/qtcassert.h> + #include <QtCore/QProcess> #include <QtCore/QSettings> #include <QtCore/QTime> @@ -314,10 +316,11 @@ void QtVersionManager::setNewQtVersions(QList<QtVersion *> newVersions, int newD QtVersion::QtVersion(const QString &name, const QString &path, int id, bool isSystemVersion) : m_name(name), m_isSystemVersion(isSystemVersion), + m_hasDebuggingHelper(false), m_notInstalled(false), m_defaultConfigIsDebug(true), m_defaultConfigIsDebugAndRelease(true), - m_hasDebuggingHelper(false) + m_toolChain(0) { if (id == -1) m_id = getUniqueId(); @@ -328,15 +331,22 @@ QtVersion::QtVersion(const QString &name, const QString &path, int id, bool isSy QtVersion::QtVersion(const QString &name, const QString &path) : m_name(name), - m_versionInfoUpToDate(false), - m_mkspecUpToDate(false), m_isSystemVersion(false), - m_hasDebuggingHelper(false) + m_hasDebuggingHelper(false), + m_mkspecUpToDate(false), + m_versionInfoUpToDate(false), + m_toolChain(0) { m_id = getUniqueId(); setPath(path); } +QtVersion::~QtVersion() +{ + m_toolChain = 0; + delete m_toolChain; +} + QString QtVersion::name() const { return m_name; @@ -376,6 +386,13 @@ QHash<QString,QString> QtVersion::versionInfo() const return m_versionInfo; } +QString QtVersion::qmakeCXX() const +{ + updateQMakeCXX(); + return m_qmakeCXX; +} + + void QtVersion::setName(const QString &name) { m_name = name; @@ -390,6 +407,9 @@ void QtVersion::setPath(const QString &path) m_designerCommand = m_linguistCommand = m_qmakeCommand = m_uicCommand = QString::null; // TODO do i need to optimize this? m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty(); + m_qmakeCXX = QString::null; + m_qmakeCXXUpToDate = false; + m_toolChainUpToDate = false; } void QtVersion::updateSourcePath() @@ -757,6 +777,73 @@ QString QtVersion::qmakeCommand() const return QString::null; } +void QtVersion::updateQMakeCXX() const +{ + if (m_qmakeCXXUpToDate) + return; + ProFileReader *reader = new ProFileReader(); + reader->setCumulative(false); + reader->setParsePreAndPostFiles(false); + reader->readProFile(mkspecPath() + "/qmake.conf"); + m_qmakeCXX = reader->value("QMAKE_CXX"); + delete reader; + m_qmakeCXXUpToDate = true; +} + +ProjectExplorer::ToolChain *QtVersion::toolChain() const +{ + updateToolChain(); + return m_toolChain; +} + +void QtVersion::updateToolChain() const +{ + if (m_toolChainUpToDate) + return; + ProjectExplorer::ToolChain *m_test= 0; + ProjectExplorer::ToolChain::ToolChainType t = toolchainType(); + if (t == ProjectExplorer::ToolChain::MinGW) { + QString qmake_cxx = qmakeCXX(); + ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); + //addToEnvironment(env); + env.prependOrSetPath(mingwDirectory()+"/bin"); + qmake_cxx = env.searchInPath(qmake_cxx); + m_test = ProjectExplorer::ToolChain::createMinGWToolChain(qmake_cxx, mingwDirectory()); + //qDebug()<<"Mingw ToolChain"; + } else if(t == ProjectExplorer::ToolChain::MSVC) { + m_test = ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isMSVC64Bit()); + //qDebug()<<"MSVC ToolChain ("<<version->msvcVersion()<<")"; + } else if(t == ProjectExplorer::ToolChain::WINCE) { + m_test = ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatform()); + //qDebug()<<"WinCE ToolChain ("<<version->msvcVersion()<<","<<version->wincePlatform()<<")"; + } else if(t == ProjectExplorer::ToolChain::GCC || t == ProjectExplorer::ToolChain::LinuxICC) { + QString qmake_cxx = qmakeCXX(); + ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); + //addToEnvironment(env); + qmake_cxx = env.searchInPath(qmake_cxx); + if (qmake_cxx.isEmpty()) { + // macx-xcode mkspec resets the value of QMAKE_CXX. + // Unfortunately, we need a valid QMAKE_CXX to configure the parser. + qmake_cxx = QLatin1String("cc"); + } + m_test = ProjectExplorer::ToolChain::createGccToolChain(qmake_cxx); + //qDebug()<<"GCC ToolChain ("<<qmake_cxx<<")"; + } else { + qDebug()<<"Could not detect ToolChain for"<<mkspec(); + qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines."; + } + + if (ProjectExplorer::ToolChain::equals(m_test, m_toolChain)) { + delete m_test; + } else { + delete m_toolChain; + m_toolChain = m_test; + } + + m_toolChainUpToDate = true; +} + + QString QtVersion::findQtBinary(const QStringList &possibleCommands) const { const QString qtdirbin = versionInfo().value(QLatin1String("QT_INSTALL_BINS")) + QLatin1Char('/'); @@ -849,6 +936,7 @@ QString QtVersion::mingwDirectory() const void QtVersion::setMingwDirectory(const QString &directory) { m_mingwDirectory = directory; + m_toolChainUpToDate = false; } QString QtVersion::msvcVersion() const @@ -865,9 +953,10 @@ QString QtVersion::wincePlatform() const void QtVersion::setMsvcVersion(const QString &version) { m_msvcVersion = version; + m_toolChainUpToDate = false; } -void QtVersion::addToEnvironment(ProjectExplorer::Environment &env) +void QtVersion::addToEnvironment(ProjectExplorer::Environment &env) const { env.set("QTDIR", m_path); QString qtdirbin = versionInfo().value("QT_INSTALL_BINS"); @@ -875,6 +964,9 @@ void QtVersion::addToEnvironment(ProjectExplorer::Environment &env) // add libdir, includedir and bindir // or add Mingw dirs // or do nothing on other + ProjectExplorer::ToolChain *tc = toolChain(); + if (tc) + tc->addToEnvironment(env); } int QtVersion::uniqueId() const @@ -946,36 +1038,9 @@ QString QtVersion::buildDebuggingHelperLibrary() ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); addToEnvironment(env); - // TODO this is a hack to get, to be removed and rewritten for 1.2 - // For MSVC and MINGW, we need a toolchain to get the right environment - ProjectExplorer::ToolChain::ToolChainType t = toolchainType(); - ProjectExplorer::ToolChain *toolChain = 0; - if (t == ProjectExplorer::ToolChain::MinGW) - toolChain = ProjectExplorer::ToolChain::createMinGWToolChain("g++", mingwDirectory()); - else if(t == ProjectExplorer::ToolChain::MSVC) - toolChain = ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isMSVC64Bit()); - if (toolChain) { - toolChain->addToEnvironment(env); - delete toolChain; - toolChain = 0; - } - - QString make; - // TODO this is butt ugly - // only qt4projects have a toolchain() method. (Reason mostly, that in order to create - // the toolchain, we need to have the path to gcc - // which might depend on environment settings of the project - // so we hardcode the toolchainType to make conversation here - // and think about how to fix that later - if (t == ProjectExplorer::ToolChain::MinGW) - make = "mingw32-make.exe"; - else if(t == ProjectExplorer::ToolChain::MSVC || t == ProjectExplorer::ToolChain::WINCE) - make = "nmake.exe"; - else if (t == ProjectExplorer::ToolChain::GCC || t == ProjectExplorer::ToolChain::LinuxICC) - make = "make"; - + ProjectExplorer::ToolChain *tc = toolChain(); QString directory = DebuggingHelperLibrary::copyDebuggingHelperLibrary(qtInstallData, path()); - QString output = DebuggingHelperLibrary::buildDebuggingHelperLibrary(directory, make, qmakeCommand(), mkspec(), env); + QString output = DebuggingHelperLibrary::buildDebuggingHelperLibrary(directory, tc->makeCommand(), qmakeCommand(), mkspec(), env); m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty(); return output; } diff --git a/src/plugins/qt4projectmanager/qtversionmanager.h b/src/plugins/qt4projectmanager/qtversionmanager.h index c407f6f879e7ee185e043785ad97b489367d0923..f81d139314a7115cca97d4cca0398b3c10722a50 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.h +++ b/src/plugins/qt4projectmanager/qtversionmanager.h @@ -51,8 +51,9 @@ public: QtVersion(const QString &name, const QString &path); QtVersion(const QString &name, const QString &path, int id, bool isSystemVersion = false); QtVersion() - :m_name(QString::null), m_path(QString::null), m_id(-1) - { } + :m_name(QString::null), m_id(-1), m_toolChain(0) + { setPath(QString::null); } + ~QtVersion(); bool isValid() const; //TOOD check that the dir exists and the name is non empty bool isInstalled() const; @@ -67,6 +68,8 @@ public: QString uicCommand() const; QString designerCommand() const; QString linguistCommand() const; + QString qmakeCXX() const; + ProjectExplorer::ToolChain *toolChain() const; QString qtVersionString() const; // Returns the PREFIX, BINPREFIX, DOCPREFIX and similar information @@ -79,7 +82,7 @@ public: QString msvcVersion() const; QString wincePlatform() const; void setMsvcVersion(const QString &version); - void addToEnvironment(ProjectExplorer::Environment &env); + void addToEnvironment(ProjectExplorer::Environment &env) const; bool hasDebuggingHelper() const; QString debuggingHelperLibrary() const; @@ -104,32 +107,41 @@ private: void setName(const QString &name); void setPath(const QString &path); void updateSourcePath(); - void updateVersionInfo() const; void updateMkSpec() const; + void updateVersionInfo() const; + void updateQMakeCXX() const; + void updateToolChain() const; QString findQtBinary(const QStringList &possibleName) const; QString m_name; - mutable bool m_versionInfoUpToDate; - mutable bool m_mkspecUpToDate; QString m_path; QString m_sourcePath; - mutable QString m_mkspec; // updated lazily - mutable QString m_mkspecFullPath; QString m_mingwDirectory; QString m_msvcVersion; - mutable QHash<QString,QString> m_versionInfo; // updated lazily int m_id; bool m_isSystemVersion; + bool m_hasDebuggingHelper; + + mutable bool m_mkspecUpToDate; + mutable QString m_mkspec; // updated lazily + mutable QString m_mkspecFullPath; + + mutable bool m_versionInfoUpToDate; + mutable QHash<QString,QString> m_versionInfo; // updated lazily mutable bool m_notInstalled; mutable bool m_defaultConfigIsDebug; mutable bool m_defaultConfigIsDebugAndRelease; + mutable QString m_qmakeCommand; + mutable QString m_qtVersionString; mutable QString m_uicCommand; mutable QString m_designerCommand; mutable QString m_linguistCommand; - // This is updated on first call to qmakeCommand - // That function is called from updateVersionInfo() - mutable QString m_qtVersionString; - bool m_hasDebuggingHelper; + + mutable bool m_qmakeCXXUpToDate; + mutable QString m_qmakeCXX; + + mutable bool m_toolChainUpToDate; + mutable ProjectExplorer::ToolChain *m_toolChain; }; class QtVersionManager : public QObject diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 3ded8b3c8d84619a1bca22448c2ee8af5fd202ae..eac61f480a0e536a024b2ae9578d4c0273455611 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -992,11 +992,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) QTextCursor cursor = textCursor(); const QString text = e->text(); cursor.insertText(text); - const QString leftText = cursor.block().text().left(cursor.position() - 1 - cursor.block().position()); - if (leftText.simplified().isEmpty()) { - const QChar typedChar = e->text().at(0); - indent(document(), cursor, typedChar); - } + indent(document(), cursor, QChar::Null); #if 0 TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(document()->documentLayout()); QTC_ASSERT(documentLayout, return); diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 04652b7db9f5f481bccc41148deecd6099114bad..133fd2a702ec411862218ba1b0563cbb5677ff5c 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -221,6 +221,7 @@ public: ProFile *m_prevProFile; // See m_prevLineNo QStringList m_addUserConfigCmdArgs; QStringList m_removeUserConfigCmdArgs; + bool m_parsePreAndPostFiles; }; ProFileEvaluator::Private::Private(ProFileEvaluator *q_) @@ -240,6 +241,7 @@ ProFileEvaluator::Private::Private(ProFileEvaluator *q_) m_invertNext = false; m_skipLevel = 0; m_isFirstVariableValue = true; + m_parsePreAndPostFiles = true; } bool ProFileEvaluator::Private::read(ProFile *pro) @@ -648,11 +650,9 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro) m_profileStack.push(pro); const QString mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS")); - if (!mkspecDirectory.isEmpty()) { + if (!mkspecDirectory.isEmpty() && m_parsePreAndPostFiles) { bool cumulative = m_cumulative; m_cumulative = false; - // This is what qmake does, everything set in the mkspec is also set - // But this also creates a lot of problems evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok); evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &ok); @@ -677,7 +677,7 @@ bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro) m_lineNo = pro->lineNumber(); if (m_profileStack.count() == 1 && !m_oldPath.isEmpty()) { const QString &mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS")); - if (!mkspecDirectory.isEmpty()) { + if (!mkspecDirectory.isEmpty() && m_parsePreAndPostFiles) { bool cumulative = m_cumulative; m_cumulative = false; @@ -2322,6 +2322,11 @@ void ProFileEvaluator::setUserConfigCmdArgs(const QStringList &addUserConfigCmdA d->m_removeUserConfigCmdArgs = removeUserConfigCmdArgs; } +void ProFileEvaluator::setParsePreAndPostFiles(bool on) +{ + d->m_parsePreAndPostFiles = on; +} + void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap) { QStringList sourceFiles; diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index b6df287b7d79d444ea2bc9bd7aad40f902449daa..d7eb5a549a8ba6f122581c7fc0b7a5c8c0dbe51c 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -66,6 +66,7 @@ public: void setCumulative(bool on); // Default is true! void setOutputDir(const QString &dir); // Default is empty void setUserConfigCmdArgs(const QStringList &addUserConfigCmdArgs, const QStringList &removeUserConfigCmdArgs); + void setParsePreAndPostFiles(bool on); // Default is true bool queryProFile(ProFile *pro); bool accept(ProFile *pro);