diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index fcb8fc788ec337c34c20ae4520831cb2d9090b87..f4296747e4a54ebe5cc9c74f8d846727beffb61a 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -167,9 +167,10 @@ public: QString displayName() const { return tr("Debugger Settings"); } private slots: - void useCppDebuggerToggled(bool toggled); - void useQmlDebuggerToggled(bool toggled); + void useCppDebuggerToggled(bool on); + void useQmlDebuggerToggled(bool on); void qmlDebugServerPortChanged(int port); + void useMultiProcessToggled(bool on); public: DebuggerRunConfigurationAspect *m_aspect; // not owned @@ -179,6 +180,7 @@ public: QSpinBox *m_debugServerPort; QLabel *m_debugServerPortLabel; QLabel *m_qmlDebuggerInfoLabel; + QCheckBox *m_useMultiProcess; }; DebuggerRunConfigWidget::DebuggerRunConfigWidget(RunConfiguration *runConfiguration) @@ -204,6 +206,12 @@ DebuggerRunConfigWidget::DebuggerRunConfigWidget(RunConfiguration *runConfigurat m_debugServerPort->setValue(m_aspect->qmlDebugServerPort()); + static const QByteArray env = qgetenv("QTC_DEBUGGER_MULTIPROCESS"); + m_useMultiProcess = + new QCheckBox(tr("Enable Debugging of Subprocesses"), this); + m_useMultiProcess->setChecked(m_aspect->useMultiProcess()); + m_useMultiProcess->setVisible(env.toInt()); + connect(m_qmlDebuggerInfoLabel, SIGNAL(linkActivated(QString)), Core::HelpManager::instance(), SLOT(handleHelpRequest(QString))); connect(m_useQmlDebugger, SIGNAL(toggled(bool)), @@ -212,6 +220,8 @@ DebuggerRunConfigWidget::DebuggerRunConfigWidget(RunConfiguration *runConfigurat SLOT(useCppDebuggerToggled(bool))); connect(m_debugServerPort, SIGNAL(valueChanged(int)), SLOT(qmlDebugServerPortChanged(int))); + connect(m_useMultiProcess, SIGNAL(toggled(bool)), + SLOT(useMultiProcessToggled(bool))); if (m_aspect->isDisplaySuppressed()) hide(); @@ -242,6 +252,7 @@ DebuggerRunConfigWidget::DebuggerRunConfigWidget(RunConfiguration *runConfigurat layout->setMargin(0); layout->addWidget(m_useCppDebugger); layout->addLayout(qmlLayout); + layout->addWidget(m_useMultiProcess); setLayout(layout); } @@ -250,25 +261,30 @@ void DebuggerRunConfigWidget::qmlDebugServerPortChanged(int port) m_aspect->m_qmlDebugServerPort = port; } -void DebuggerRunConfigWidget::useCppDebuggerToggled(bool toggled) +void DebuggerRunConfigWidget::useCppDebuggerToggled(bool on) { - m_aspect->m_useCppDebugger = toggled; - if (!toggled && !m_useQmlDebugger->isChecked()) + m_aspect->m_useCppDebugger = on; + if (!on && !m_useQmlDebugger->isChecked()) m_useQmlDebugger->setChecked(true); } -void DebuggerRunConfigWidget::useQmlDebuggerToggled(bool toggled) +void DebuggerRunConfigWidget::useQmlDebuggerToggled(bool on) { - m_debugServerPort->setEnabled(toggled); - m_debugServerPortLabel->setEnabled(toggled); + m_debugServerPort->setEnabled(on); + m_debugServerPortLabel->setEnabled(on); - m_aspect->m_useQmlDebugger = toggled + m_aspect->m_useQmlDebugger = on ? DebuggerRunConfigurationAspect::EnableQmlDebugger : DebuggerRunConfigurationAspect::DisableQmlDebugger; - if (!toggled && !m_useCppDebugger->isChecked()) + if (!on && !m_useCppDebugger->isChecked()) m_useCppDebugger->setChecked(true); } +void DebuggerRunConfigWidget::useMultiProcessToggled(bool on) +{ + m_aspect->m_useMultiProcess = on; +} + //////////////////////////////////////////////////////////////////////// // // DebuggerRunControlPrivate @@ -900,12 +916,15 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu } } - if (runConfiguration->debuggerAspect()->useCppDebugger()) + DebuggerRunConfigurationAspect *aspect = runConfiguration->debuggerAspect(); + sp.multiProcess = aspect->useMultiProcess(); + + if (aspect->useCppDebugger()) sp.languages |= CppLanguage; - if (runConfiguration->debuggerAspect()->useQmlDebugger()) { + if (aspect->useQmlDebugger()) { sp.qmlServerAddress = _("127.0.0.1"); - sp.qmlServerPort = runConfiguration->debuggerAspect()->qmlDebugServerPort(); + sp.qmlServerPort = aspect->qmlDebugServerPort(); sp.languages |= QmlLanguage; // Makes sure that all bindings go through the JavaScript engine, so that diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index 4adc77a8d07bb2c38b9e5826c5d9028e023d38ce..513bdea8e1b8be24602ab26cc87ccb7e9cdf3c28 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -61,6 +61,7 @@ public: attachPID(-1), useTerminal(false), breakOnMain(false), + multiProcess(false), languages(AnyLanguage), qmlServerAddress(QLatin1String("127.0.0.1")), qmlServerPort(ProjectExplorer::Constants::QML_DEFAULT_DEBUG_SERVER_PORT), @@ -88,6 +89,7 @@ public: qint64 attachPID; bool useTerminal; bool breakOnMain; + bool multiProcess; DebuggerLanguages languages; // Used by AttachCrashedExternal. diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index db8cb4bac1c7a7cfafe0a7b5dc86a6c067fa3e32..f7de50eb9f67c4156f879f77edad92c07ee94afe 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -423,6 +423,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) } if (pid) notifyInferiorPid(pid); + handleThreadGroupCreated(result); } else if (asyncClass == "thread-created") { //"{id="1",group-id="28902"}" QByteArray id = result.findChild("id").data(); @@ -431,6 +432,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) // Archer has "{id="28902"}" QByteArray id = result.findChild("id").data(); showStatusMessage(tr("Thread group %1 exited").arg(_(id)), 1000); + handleThreadGroupExited(result); } else if (asyncClass == "thread-exited") { //"{id="1",group-id="28902"}" QByteArray id = result.findChild("id").data(); @@ -1725,6 +1727,9 @@ void GdbEngine::handleShowVersion(const GdbResponse &response) postCommand("set target-async on", ConsoleCommand); else postCommand("set target-async off", ConsoleCommand); + + if (startParameters().multiProcess) + postCommand("set detach-on-fork off", ConsoleCommand); } } @@ -1988,6 +1993,18 @@ void GdbEngine::handleDetach(const GdbResponse &response) notifyInferiorExited(); } +void GdbEngine::handleThreadGroupCreated(const GdbMi &result) +{ + QByteArray id = result.findChild("id").data(); + QByteArray pid = result.findChild("pid").data(); + Q_UNUSED(pid); +} + +void GdbEngine::handleThreadGroupExited(const GdbMi &result) +{ + QByteArray id = result.findChild("id").data(); +} + int GdbEngine::currentFrame() const { return stackHandler()->currentIndex(); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 0403bcd12bd1a0fce9962a1e86cf9384df26c5d4..ee3afea9eb804a64212fea08601201526a96982e 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -655,6 +655,9 @@ private: ////////// View & Data Stuff ////////// void handleDebuggingHelperVersionCheckClassic(const GdbResponse &response); void handleDetach(const GdbResponse &response); + void handleThreadGroupCreated(const GdbMi &result); + void handleThreadGroupExited(const GdbMi &result); + Q_SLOT void createFullBacktrace(); void handleCreateFullBacktrace(const GdbResponse &response); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 765b22b0e155b4ee4397696a5b6d5ef507e61859..dad8503c5a6508a7c7d036556ecbba11dd656e67 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -64,6 +64,7 @@ const char USE_CPP_DEBUGGER_KEY[] = "RunConfiguration.UseCppDebugger"; const char USE_QML_DEBUGGER_KEY[] = "RunConfiguration.UseQmlDebugger"; const char USE_QML_DEBUGGER_AUTO_KEY[] = "RunConfiguration.UseQmlDebuggerAuto"; const char QML_DEBUG_SERVER_PORT_KEY[] = "RunConfiguration.QmlDebugServerPort"; +const char USE_MULTIPROCESS_KEY[] = "RunConfiguration.UseMultiProcess"; // Function objects: @@ -203,6 +204,7 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(RunConfiguration m_useCppDebugger(true), m_useQmlDebugger(AutoEnableQmlDebugger), m_qmlDebugServerPort(Constants::QML_DEFAULT_DEBUG_SERVER_PORT), + m_useMultiProcess(false), m_suppressDisplay(false), m_suppressQmlDebuggingOptions(false), m_suppressCppDebuggingOptions(false), @@ -214,6 +216,7 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(DebuggerRunConfig m_useCppDebugger(other->m_useCppDebugger), m_useQmlDebugger(other->m_useQmlDebugger), m_qmlDebugServerPort(other->m_qmlDebugServerPort), + m_useMultiProcess(other->m_useMultiProcess), m_suppressDisplay(other->m_suppressDisplay), m_suppressQmlDebuggingOptions(other->m_suppressQmlDebuggingOptions), m_suppressCppDebuggingOptions(other->m_suppressCppDebuggingOptions), @@ -266,6 +269,16 @@ void DebuggerRunConfigurationAspect::setQmllDebugServerPort(uint port) m_qmlDebugServerPort = port; } +bool DebuggerRunConfigurationAspect::useMultiProcess() const +{ + return m_useMultiProcess; +} + +void DebuggerRunConfigurationAspect::setUseMultiProcess(bool value) +{ + m_useMultiProcess = value; +} + void DebuggerRunConfigurationAspect::suppressDisplay() { m_suppressDisplay = true; @@ -318,6 +331,7 @@ QVariantMap DebuggerRunConfigurationAspect::toMap() const map.insert(QLatin1String(USE_QML_DEBUGGER_KEY), m_useQmlDebugger == EnableQmlDebugger); map.insert(QLatin1String(USE_QML_DEBUGGER_AUTO_KEY), m_useQmlDebugger == AutoEnableQmlDebugger); map.insert(QLatin1String(QML_DEBUG_SERVER_PORT_KEY), m_qmlDebugServerPort); + map.insert(QLatin1String(USE_MULTIPROCESS_KEY), m_useMultiProcess); return map; } @@ -330,6 +344,7 @@ void DebuggerRunConfigurationAspect::fromMap(const QVariantMap &map) bool useQml = map.value(QLatin1String(USE_QML_DEBUGGER_KEY), false).toBool(); m_useQmlDebugger = useQml ? EnableQmlDebugger : DisableQmlDebugger; } + m_useMultiProcess = map.value(QLatin1String(USE_MULTIPROCESS_KEY), false).toBool(); } diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index aa6981f0d8ba1115ad64fcf01f666f61d796054b..4eef069db01c3f475d3208a59af88a4593ff697f 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -106,12 +106,14 @@ public: QString displayName() const; - void setUseQmlDebugger(bool value); - void setUseCppDebugger(bool value); bool useCppDebugger() const; + void setUseCppDebugger(bool value); bool useQmlDebugger() const; + void setUseQmlDebugger(bool value); uint qmlDebugServerPort() const; void setQmllDebugServerPort(uint port); + bool useMultiProcess() const; + void setUseMultiProcess(bool on); void suppressDisplay(); void suppressQmlDebuggingOptions(); void suppressCppDebuggingOptions(); @@ -130,6 +132,8 @@ public: bool m_useCppDebugger; QmlDebuggerStatus m_useQmlDebugger; uint m_qmlDebugServerPort; + bool m_useMultiProcess; + bool m_suppressDisplay; bool m_suppressQmlDebuggingOptions; bool m_suppressCppDebuggingOptions;