Commit bf87fc96 authored by hjk's avatar hjk

Debugger: Rework 'Attach to unstarted application' startup

Change-Id: I42c7ce8e413c850e05b02f5d6fe1b83376436c65
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 02732805
......@@ -487,7 +487,7 @@ AttachToQmlPortDialog::AttachToQmlPortDialog(QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowTitle(tr("Start Debugger"));
d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::RemoteDebugging, this);
d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging, this);
d->kitChooser->populate();
d->portSpinBox = new QSpinBox(this);
......
......@@ -59,12 +59,14 @@ class StartApplicationParameters;
class StartApplicationDialogPrivate;
class StartRemoteEngineDialogPrivate;
class DebuggerKitChooser : public ProjectExplorer::KitChooser {
class DebuggerKitChooser : public ProjectExplorer::KitChooser
{
Q_OBJECT
public:
enum Mode { RemoteDebugging, LocalDebugging };
enum Mode { AnyDebugging, LocalDebugging };
explicit DebuggerKitChooser(Mode mode = RemoteDebugging, QWidget *parent = 0);
explicit DebuggerKitChooser(Mode mode = AnyDebugging, QWidget *parent = 0);
protected:
bool kitMatches(const ProjectExplorer::Kit *k) const;
......
......@@ -612,7 +612,8 @@ public:
m_threadBox->setCurrentIndex(index);
m_threadBox->blockSignals(state);
}
DebuggerRunControl *attachToRunningProcess(Kit *kit, DeviceProcessItem process);
DebuggerRunControl *attachToRunningProcess(Kit *kit, DeviceProcessItem process, bool contAfterAttach);
void writeSettings()
{
......@@ -710,13 +711,10 @@ public:
void startAndDebugApplication();
void startRemoteCdbSession();
void startRemoteServer();
void startRemoteServerAndAttachToProcess();
void attachToRemoteServer();
void attachToProcess(bool startServerOnly);
void attachToRunningApplication();
void attachToUnstartedApplicationDialog();
void attachToFoundProcess();
void continueOnAttach(Debugger::DebuggerState state);
void attachToQmlPort();
Q_SLOT void runScheduled();
void attachCore();
......@@ -1400,22 +1398,32 @@ void DebuggerPluginPrivate::attachToRemoteServer()
}
}
void DebuggerPluginPrivate::startRemoteServer()
void DebuggerPluginPrivate::startRemoteServerAndAttachToProcess()
{
attachToProcess(true);
auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging);
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {
delete dlg;
return;
}
dlg->setAttribute(Qt::WA_DeleteOnClose);
Kit *kit = kitChooser->currentKit();
QTC_ASSERT(kit, return);
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return);
GdbServerStarter *starter = new GdbServerStarter(dlg, true);
starter->run();
}
void DebuggerPluginPrivate::attachToRunningApplication()
{
attachToProcess(false);
}
auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::LocalDebugging);
void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
{
const DebuggerKitChooser::Mode mode = startServerOnly ?
DebuggerKitChooser::RemoteDebugging : DebuggerKitChooser::LocalDebugging;
DebuggerKitChooser *kitChooser = new DebuggerKitChooser(mode);
DeviceProcessesDialog *dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
dlg->showAllDevices();
if (dlg->exec() == QDialog::Rejected) {
......@@ -1429,62 +1437,41 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return);
if (device->type() != PE::DESKTOP_DEVICE_TYPE) {
GdbServerStarter *starter = new GdbServerStarter(dlg, startServerOnly);
starter->run();
if (device->type() == PE::DESKTOP_DEVICE_TYPE) {
attachToRunningProcess(kit, dlg->currentProcess(), false);
} else {
attachToRunningProcess(kit, dlg->currentProcess());
GdbServerStarter *starter = new GdbServerStarter(dlg, true);
starter->run();
}
}
void DebuggerPluginPrivate::attachToUnstartedApplicationDialog()
{
UnstartedAppWatcherDialog *dlg = new UnstartedAppWatcherDialog(ICore::dialogParent());
auto dlg = new UnstartedAppWatcherDialog(ICore::dialogParent());
connect(dlg, &QDialog::finished, dlg, &QObject::deleteLater);
connect(dlg, &UnstartedAppWatcherDialog::processFound, this, &DebuggerPluginPrivate::attachToFoundProcess);
dlg->show();
}
void DebuggerPluginPrivate::attachToFoundProcess()
{
UnstartedAppWatcherDialog *dlg = qobject_cast<UnstartedAppWatcherDialog *>(QObject::sender());
if (!dlg)
return;
DebuggerRunControl *rc = attachToRunningProcess(dlg->currentKit(), dlg->currentProcess());
if (!rc)
return;
if (dlg->hideOnAttach())
connect(rc, &RunControl::finished, dlg, &UnstartedAppWatcherDialog::startWatching);
connect(dlg, &UnstartedAppWatcherDialog::processFound, this, [this, dlg] {
DebuggerRunControl *rc = attachToRunningProcess(dlg->currentKit(),
dlg->currentProcess(),
dlg->continueOnAttach());
if (!rc)
return;
if (dlg->continueOnAttach()) {
connect(currentEngine(), &DebuggerEngine::stateChanged,
this, &DebuggerPluginPrivate::continueOnAttach);
}
}
if (dlg->hideOnAttach())
connect(rc, &RunControl::finished, dlg, &UnstartedAppWatcherDialog::startWatching);
});
void DebuggerPluginPrivate::continueOnAttach(Debugger::DebuggerState state)
{
// wait for state when we can continue
if (state != InferiorStopOk)
return;
// disconnect and continue
disconnect(currentEngine(), &DebuggerEngine::stateChanged,
this, &DebuggerPluginPrivate::continueOnAttach);
handleExecContinue();
dlg->show();
}
DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
DeviceProcessItem process)
DeviceProcessItem process, bool contAfterAttach)
{
QTC_ASSERT(kit, return 0);
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return 0);
if (process.pid == 0) {
AsynchronousMessageBox::warning(tr("Warning"),
tr("Cannot attach to process with PID 0"));
AsynchronousMessageBox::warning(tr("Warning"), tr("Cannot attach to process with PID 0"));
return 0;
}
......@@ -1512,6 +1499,7 @@ DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
sp.executable = process.exe;
sp.startMode = AttachExternal;
sp.closeMode = DetachAtClose;
sp.continueAfterAttach = contAfterAttach;
return DebuggerRunControlFactory::createAndScheduleRun(sp);
}
......@@ -2648,7 +2636,7 @@ void DebuggerPluginPrivate::extensionsInitialized()
act = m_startRemoteServerAction = new QAction(this);
act->setText(tr("Start Remote Debug Server Attached to Process..."));
connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startRemoteServer);
connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startRemoteServerAndAttachToProcess);
act = m_attachToRunningApplication = new QAction(this);
act->setText(tr("Attach to Running Application..."));
......
......@@ -54,6 +54,8 @@ private:
QObject *remoteCommand(const QStringList &options, const QStringList &arguments);
ShutdownFlag aboutToShutdown();
void extensionsInitialized();
// Called from AppOutputPane::attachToRunControl().
Q_SLOT void attachExternalApplication(ProjectExplorer::RunControl *rc);
#ifdef WITH_TESTS
......
......@@ -89,12 +89,17 @@ void GdbAttachEngine::handleAttach(const DebuggerResponse &response)
case ResultRunning:
showMessage(_("INFERIOR ATTACHED"));
if (state() == EngineRunRequested) {
// FIXME: Really? Looks like we are always stopped already.
// Happens e.g. for "Attach to unstarted application"
// We will get a '*stopped' later that we'll interpret as 'spontaneous'
// So acknowledge the current state and put a delayed 'continue' in the pipe.
showMessage(msgAttachedToStoppedInferior(), StatusBar);
showMessage(tr("Attached to running application"), StatusBar);
notifyEngineRunAndInferiorRunOk();
interruptInferior();
} else {
// InferiorStopOk, e.g. for "Attach to running application".
// The *stopped came in between sending the 'attach' and
// receiving its '^done'.
if (startParameters().continueAfterAttach)
continueInferiorInternal();
}
break;
case ResultError:
......
......@@ -63,7 +63,7 @@ public:
StartGdbServerDialogPrivate() : dialog(0), kit(0) {}
DeviceProcessesDialog *dialog;
bool startServerOnly;
bool attachToServer;
DeviceProcessItem process;
Kit *kit;
IDevice::ConstPtr device;
......@@ -72,7 +72,7 @@ public:
SshRemoteProcessRunner runner;
};
GdbServerStarter::GdbServerStarter(DeviceProcessesDialog *dlg, bool startServerOnly)
GdbServerStarter::GdbServerStarter(DeviceProcessesDialog *dlg, bool attachAfterServerStart)
: QObject(dlg)
{
d = new StartGdbServerDialogPrivate;
......@@ -80,7 +80,7 @@ GdbServerStarter::GdbServerStarter(DeviceProcessesDialog *dlg, bool startServerO
d->kit = dlg->kitChooser()->currentKit();
d->process = dlg->currentProcess();
d->device = DeviceKitInformation::device(d->kit);
d->startServerOnly = startServerOnly;
d->attachToServer = attachAfterServerStart;
}
GdbServerStarter::~GdbServerStarter()
......@@ -167,7 +167,7 @@ void GdbServerStarter::handleProcessErrorOutput()
logMessage(tr("Port %1 is now accessible.").arg(port));
logMessage(tr("Server started on %1:%2")
.arg(d->device->sshParameters().host).arg(port));
if (!d->startServerOnly)
if (d->attachToServer)
attach(port);
}
}
......
......@@ -45,7 +45,8 @@ class GdbServerStarter : public QObject
Q_OBJECT
public:
GdbServerStarter(ProjectExplorer::DeviceProcessesDialog *dlg, bool startServerOnly);
GdbServerStarter(ProjectExplorer::DeviceProcessesDialog *dlg,
bool attachAfterServerStart);
~GdbServerStarter();
void run();
......
......@@ -263,7 +263,7 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent)
d->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::RemoteDebugging, this);
d->kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging, this);
d->kitChooser->populate();
d->forceLocalCheckBox = new QCheckBox(this);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment