aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/debugger/debuggerplugin.cpp
diff options
context:
space:
mode:
authorPetar Perisin <[email protected]>2013-09-20 16:48:01 +0200
committerhjk <[email protected]>2014-02-12 11:20:23 +0100
commit183822427757acc8985bbc7a018656805f838432 (patch)
tree8815d5b8f9ddae35a234176fa81c80bfc6541cb4 /src/plugins/debugger/debuggerplugin.cpp
parent8d319ce8993fa767c58e8d92da78a3d5c58d8f45 (diff)
Attach to unstarted Application
This patch adds a dialog that can be useful in situations where you have a script-based test tool, that starts executable and executes test on it. This dialog allows user to specify executable and to begin watching process, where dialog simply waits for executable to be started. As soon as executable is found, QtCreator will attach to it. also, since script-based test can constantly start-stop executable. as soon as it is detected that executable is down, another waiting process starts where dialog waits for executable to come up again. Change-Id: I3bd62f656d34f8dff5641f6747ec12d97cbae2a4 Reviewed-by: hjk <[email protected]>
Diffstat (limited to 'src/plugins/debugger/debuggerplugin.cpp')
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp103
1 files changed, 88 insertions, 15 deletions
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 0f1a9f06385..b833456f1d0 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -60,6 +60,7 @@
#include "watchhandler.h"
#include "watchwindow.h"
#include "watchutils.h"
+#include "unstartedappwatcherdialog.h"
#include "debuggertooltipmanager.h"
#include "localsandexpressionswindow.h"
#include "loadcoredialog.h"
@@ -741,6 +742,7 @@ public:
m_threadBox->setCurrentIndex(index);
m_threadBox->blockSignals(state);
}
+ DebuggerRunControl *attachToRunningProcess(Kit *kit, DeviceProcessItem process);
public slots:
void writeSettings()
@@ -877,6 +879,9 @@ public slots:
void attachToRemoteServer();
void attachToProcess(bool startServerOnly);
void attachToRunningApplication();
+ void attachToUnstartedApplicationDialog();
+ void attachToFoundProcess();
+ void continueOnAttach(Debugger::DebuggerState state);
void attachExternalApplication(ProjectExplorer::RunControl *rc);
void attachToQmlPort();
void startRemoteEngine();
@@ -1199,6 +1204,7 @@ public:
QAction *m_startAndDebugApplicationAction;
QAction *m_startRemoteServerAction;
QAction *m_attachToRunningApplication;
+ QAction *m_attachToUnstartedApplication;
QAction *m_attachToQmlPortAction;
QAction *m_attachToRemoteServerAction;
QAction *m_startRemoteCdbAction;
@@ -1313,6 +1319,7 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) :
m_startAndDebugApplicationAction = 0;
m_attachToRemoteServerAction = 0;
m_attachToRunningApplication = 0;
+ m_attachToUnstartedApplication = 0;
m_attachToQmlPortAction = 0;
m_startRemoteCdbAction = 0;
m_attachToCoreAction = 0;
@@ -1663,11 +1670,65 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
QTC_ASSERT(kit, return);
IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return);
- DeviceProcessItem process = dlg->currentProcess();
+
+ if (device->type() != PE::DESKTOP_DEVICE_TYPE) {
+ GdbServerStarter *starter = new GdbServerStarter(dlg, startServerOnly);
+ starter->run();
+ } else {
+ attachToRunningProcess(kit, dlg->currentProcess());
+ }
+}
+
+
+void DebuggerPluginPrivate::attachToUnstartedApplicationDialog()
+{
+ UnstartedAppWatcherDialog *dlg = new UnstartedAppWatcherDialog(mainWindow());
+
+ connect(dlg, SIGNAL(finished(int)), dlg, SLOT(deleteLater()));
+ connect(dlg, SIGNAL(processFound()), this, SLOT(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, SIGNAL(finished()), dlg, SLOT(startWatching()));
+
+ if (dlg->continueOnAttach()) {
+ connect(currentEngine(), SIGNAL(stateChanged(Debugger::DebuggerState)),
+ this, SLOT(continueOnAttach(Debugger::DebuggerState)));
+ }
+}
+
+void DebuggerPluginPrivate::continueOnAttach(Debugger::DebuggerState state)
+{
+ // wait for state when we can continue
+ if (state != InferiorStopOk)
+ return;
+ // disconnect and continue
+ disconnect(currentEngine(), SIGNAL(stateChanged(Debugger::DebuggerState)),
+ this, SLOT(continueOnAttach(Debugger::DebuggerState)));
+ handleExecContinue();
+}
+
+DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit,
+ DeviceProcessItem process)
+{
+ QTC_ASSERT(kit, return 0);
+ IDevice::ConstPtr device = DeviceKitInformation::device(kit);
+ QTC_ASSERT(device, return 0);
if (process.pid == 0) {
QMessageBox::warning(ICore::mainWindow(), tr("Warning"),
tr("Cannot attach to process with PID 0"));
- return;
+ return 0;
}
bool isWindows = false;
@@ -1677,22 +1738,23 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
QMessageBox::warning(ICore::mainWindow(), tr("Process Already Under Debugger Control"),
tr("The process %1 is already under the control of a debugger.\n"
"Qt Creator cannot attach to it.").arg(process.pid));
- return;
+ return 0;
}
- if (device->type() == PE::DESKTOP_DEVICE_TYPE) {
- DebuggerStartParameters sp;
- QTC_ASSERT(fillParameters(&sp, kit), return);
- sp.attachPID = process.pid;
- sp.displayName = tr("Process %1").arg(process.pid);
- sp.executable = process.exe;
- sp.startMode = AttachExternal;
- sp.closeMode = DetachAtClose;
- DebuggerRunControlFactory::createAndScheduleRun(sp);
- } else {
- GdbServerStarter *starter = new GdbServerStarter(dlg, startServerOnly);
- starter->run();
+ if (device->type() != PE::DESKTOP_DEVICE_TYPE) {
+ QMessageBox::warning(ICore::mainWindow(), tr("Not a Desktop Device Type"),
+ tr("It is only possible to attach to local running process."));
+ return 0;
}
+
+ DebuggerStartParameters sp;
+ QTC_ASSERT(fillParameters(&sp, kit), return 0);
+ sp.attachPID = process.pid;
+ sp.displayName = tr("Process %1").arg(process.pid);
+ sp.executable = process.exe;
+ sp.startMode = AttachExternal;
+ sp.closeMode = DetachAtClose;
+ return DebuggerRunControlFactory::createAndScheduleRun(sp);
}
void DebuggerPluginPrivate::attachExternalApplication(RunControl *rc)
@@ -2140,6 +2202,7 @@ void DebuggerPluginPrivate::setInitialState()
m_attachToCoreAction->setEnabled(true);
m_attachToRemoteServerAction->setEnabled(true);
m_attachToRunningApplication->setEnabled(true);
+ m_attachToUnstartedApplication->setEnabled(true);
m_detachAction->setEnabled(false);
m_watchAction1->setEnabled(true);
@@ -2263,6 +2326,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_attachToCoreAction->setEnabled(true);
m_attachToRemoteServerAction->setEnabled(true);
m_attachToRunningApplication->setEnabled(true);
+ m_attachToUnstartedApplication->setEnabled(true);
m_threadBox->setEnabled(state == InferiorStopOk || state == InferiorUnrunnable);
@@ -2864,6 +2928,10 @@ void DebuggerPluginPrivate::extensionsInitialized()
act->setText(tr("Attach to Running Application..."));
connect(act, SIGNAL(triggered()), SLOT(attachToRunningApplication()));
+ act = m_attachToUnstartedApplication = new QAction(this);
+ act->setText(tr("Attach to Unstarted Application..."));
+ connect(act, SIGNAL(triggered()), SLOT(attachToUnstartedApplicationDialog()));
+
act = m_attachToQmlPortAction = new QAction(this);
act->setText(tr("Attach to QML Port..."));
connect(act, SIGNAL(triggered()), SLOT(attachToQmlPort()));
@@ -2911,6 +2979,11 @@ void DebuggerPluginPrivate::extensionsInitialized()
cmd->setDescription(tr("Attach to Running Application"));
mstart->addAction(cmd, Debugger::Constants::G_GENERAL);
+ cmd = ActionManager::registerAction(m_attachToUnstartedApplication,
+ "Debugger.AttachToUnstartedProcess", globalcontext);
+ cmd->setDescription(tr("Attach to Unstarted Application"));
+ mstart->addAction(cmd, Debugger::Constants::G_GENERAL);
+
cmd = ActionManager::registerAction(m_startAndDebugApplicationAction,
"Debugger.StartAndDebugApplication", globalcontext);
cmd->setAttribute(Command::CA_Hide);