Debugger: Don't wait for app output for Qml debugger port retrieval

We know the port in advance nowadays.

Change-Id: Iacd6f2c8ef04665606a77625be77744a358bb560
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
This commit is contained in:
hjk
2017-08-10 19:03:07 +02:00
parent 94a9b4b0ea
commit c6ff65fd65
2 changed files with 12 additions and 89 deletions

View File

@@ -189,17 +189,6 @@ public:
void checkForFinishedUpdate(); void checkForFinishedUpdate();
ConsoleItem *constructLogItemTree(const QmlV8ObjectData &objectData); ConsoleItem *constructLogItemTree(const QmlV8ObjectData &objectData);
void filterApplicationMessage(ProjectExplorer::RunControl *runControl,
const QString &msg, Utils::OutputFormat format)
{
if (runControl != engine->runControl())
return;
if (format == StdErrFormatSameLine
|| format == StdOutFormatSameLine
|| format == DebugFormat)
outputParser.processOutput(msg);
}
public: public:
QHash<int, QmlV8ObjectData> refVals; // The mapping of target object handles to retrieved values. QHash<int, QmlV8ObjectData> refVals; // The mapping of target object handles to retrieved values.
int sequence = -1; int sequence = -1;
@@ -223,9 +212,7 @@ public:
InteractiveInterpreter interpreter; InteractiveInterpreter interpreter;
ApplicationLauncher applicationLauncher; ApplicationLauncher applicationLauncher;
QmlInspectorAgent inspectorAgent; QmlInspectorAgent inspectorAgent;
QmlOutputParser outputParser;
QTimer noDebugOutputTimer;
QList<quint32> queryIds; QList<quint32> queryIds;
bool retryOnConnectFail = false; bool retryOnConnectFail = false;
bool automaticConnect = false; bool automaticConnect = false;
@@ -277,24 +264,8 @@ QmlEngine::QmlEngine(bool useTerminal)
connect(&d->applicationLauncher, &ApplicationLauncher::processStarted, connect(&d->applicationLauncher, &ApplicationLauncher::processStarted,
this, &QmlEngine::handleLauncherStarted); this, &QmlEngine::handleLauncherStarted);
d->outputParser.setNoOutputText(ApplicationLauncher::msgWinCannotRetrieveDebuggingOutput());
connect(&d->outputParser, &QmlOutputParser::waitingForConnectionOnPort,
this, &QmlEngine::beginConnection);
connect(&d->outputParser, &QmlOutputParser::noOutputMessage,
this, [this] { tryToConnect(); });
connect(&d->outputParser, &QmlOutputParser::errorMessage,
this, &QmlEngine::appStartupFailed);
// Only wait 8 seconds for the 'Waiting for connection' on application output,
// then just try to connect (application output might be redirected / blocked)
d->noDebugOutputTimer.setSingleShot(true);
d->noDebugOutputTimer.setInterval(8000);
connect(&d->noDebugOutputTimer, &QTimer::timeout,
this, [this] { tryToConnect(); });
// we won't get any debug output // we won't get any debug output
if (useTerminal) { if (useTerminal) {
d->noDebugOutputTimer.setInterval(0);
d->retryOnConnectFail = true; d->retryOnConnectFail = true;
d->automaticConnect = true; d->automaticConnect = true;
} }
@@ -354,15 +325,6 @@ void QmlEngine::setState(DebuggerState state, bool forced)
updateCurrentContext(); updateCurrentContext();
} }
void QmlEngine::setRunTool(DebuggerRunTool *runTool)
{
DebuggerEngine::setRunTool(runTool);
d->startupMessageFilterConnection = connect(
runTool->runControl(), &RunControl::appendMessageRequested,
d, &QmlEnginePrivate::filterApplicationMessage);
}
void QmlEngine::setupInferior() void QmlEngine::setupInferior()
{ {
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
@@ -378,7 +340,7 @@ void QmlEngine::handleLauncherStarted()
// FIXME: The QmlEngine never calls notifyInferiorPid() triggering the // FIXME: The QmlEngine never calls notifyInferiorPid() triggering the
// raising, so do it here manually for now. // raising, so do it here manually for now.
runControl()->applicationProcessHandle().activate(); runControl()->applicationProcessHandle().activate();
d->noDebugOutputTimer.start(); tryToConnect();
} }
void QmlEngine::appMessage(const QString &msg, Utils::OutputFormat /* format */) void QmlEngine::appMessage(const QString &msg, Utils::OutputFormat /* format */)
@@ -394,29 +356,27 @@ void QmlEngine::connectionEstablished()
notifyEngineRunAndInferiorRunOk(); notifyEngineRunAndInferiorRunOk();
} }
void QmlEngine::tryToConnect(Utils::Port port) void QmlEngine::tryToConnect()
{ {
showMessage("QML Debugger: No application output received in time, trying to connect ...", LogStatus); showMessage("QML Debugger: Trying to connect ...", LogStatus);
d->retryOnConnectFail = true; d->retryOnConnectFail = true;
if (state() == EngineRunRequested) { if (state() == EngineRunRequested) {
if (isSlaveEngine()) { if (isSlaveEngine()) {
// Probably cpp is being debugged and hence we did not get the output yet. // Probably cpp is being debugged and hence we did not get the output yet.
if (!masterEngine()->isDying()) if (!masterEngine()->isDying())
beginConnection(port); beginConnection();
else else
appStartupFailed(tr("No application output received in time")); appStartupFailed(tr("No application output received in time"));
} else { } else {
beginConnection(port); beginConnection();
} }
} else { } else {
d->automaticConnect = true; d->automaticConnect = true;
} }
} }
void QmlEngine::beginConnection(Utils::Port port) void QmlEngine::beginConnection()
{ {
d->noDebugOutputTimer.stop();
if (state() != EngineRunRequested && d->retryOnConnectFail) if (state() != EngineRunRequested && d->retryOnConnectFail)
return; return;
@@ -429,6 +389,7 @@ void QmlEngine::beginConnection(Utils::Port port)
if (host.isEmpty()) if (host.isEmpty())
host = QHostAddress(QHostAddress::LocalHost).toString(); host = QHostAddress(QHostAddress::LocalHost).toString();
// FIXME: Not needed?
/* /*
* Let plugin-specific code override the port printed by the application. This is necessary * Let plugin-specific code override the port printed by the application. This is necessary
* in the case of port forwarding, when the port the application listens on is not the same that * in the case of port forwarding, when the port the application listens on is not the same that
@@ -440,8 +401,7 @@ void QmlEngine::beginConnection(Utils::Port port)
* the connection will be closed again (instead of returning the "connection refused" * the connection will be closed again (instead of returning the "connection refused"
* error that we expect). * error that we expect).
*/ */
if (runParameters().qmlServer.port.isValid()) Utils::Port port = runParameters().qmlServer.port;
port = runParameters().qmlServer.port;
if (!d->connection || d->connection->isConnected()) if (!d->connection || d->connection->isConnected())
return; return;
@@ -563,13 +523,13 @@ void QmlEngine::runEngine()
if (!isSlaveEngine()) { if (!isSlaveEngine()) {
if (runParameters().startMode == AttachToRemoteServer) if (runParameters().startMode == AttachToRemoteServer)
d->noDebugOutputTimer.start(); tryToConnect();
else if (runParameters().startMode == AttachToRemoteProcess) else if (runParameters().startMode == AttachToRemoteProcess)
beginConnection(); beginConnection();
else else
startApplicationLauncher(); startApplicationLauncher();
} else { } else {
d->noDebugOutputTimer.start(); tryToConnect();
} }
} }
@@ -594,39 +554,6 @@ void QmlEngine::stopApplicationLauncher()
} }
} }
// FIXME: Is the timeout raise still needed? Since the RunWorker conversion,
// the debugger tool only starts when the remote setup has all interesting
// ports gathered, so much less chance for waiting on longer operations.
//void QmlEngine::notifyEngineRemoteSetupFinished()
//{
// QObject::disconnect(d->startupMessageFilterConnection);
// switch (state()) {
// case InferiorSetupOk:
// // FIXME: This is not a legal transition, but we need to
// // get to EngineSetupOk somehow from InferiorSetupOk.
// // fallthrough. QTCREATORBUG-14089.
// case EngineSetupRequested:
// notifyEngineSetupOk();
// break;
// case EngineSetupOk:
// case EngineRunRequested:
// // QTCREATORBUG-17718: On Android while doing debugging in mixed mode, the QML debug engine
// // sometimes reports EngineSetupOK after the EngineRunRequested thus overwriting the state
// // which eventually results into app to waiting for the QML engine connection.
// // Skipping the EngineSetupOK in aforementioned case.
// // Nothing to do here. The setup is already done.
// break;
// default:
// QTC_ASSERT(false, qDebug() << "Unexpected state" << state());
// }
// // The remote setup can take while especialy with mixed debugging.
// // Just waiting for 8 seconds is not enough. Increase the timeout
// // to 60 s
// // In case we get an output the d->outputParser will start the connection.
// d->noDebugOutputTimer.setInterval(60000);
//}
void QmlEngine::shutdownInferior() void QmlEngine::shutdownInferior()
{ {
// End session. // End session.
@@ -649,7 +576,6 @@ void QmlEngine::shutdownEngine()
clearExceptionSelection(); clearExceptionSelection();
debuggerConsole()->setScriptEvaluator(ScriptEvaluator()); debuggerConsole()->setScriptEvaluator(ScriptEvaluator());
d->noDebugOutputTimer.stop();
// double check (ill engine?): // double check (ill engine?):
stopApplicationLauncher(); stopApplicationLauncher();
@@ -1095,7 +1021,6 @@ bool QmlEngine::hasCapability(unsigned cap) const
void QmlEngine::quitDebugger() void QmlEngine::quitDebugger()
{ {
d->noDebugOutputTimer.stop();
d->automaticConnect = false; d->automaticConnect = false;
d->retryOnConnectFail = false; d->retryOnConnectFail = false;
shutdownInferior(); shutdownInferior();

View File

@@ -46,8 +46,6 @@ public:
explicit QmlEngine(bool useTerminal); explicit QmlEngine(bool useTerminal);
~QmlEngine() override; ~QmlEngine() override;
void setRunTool(DebuggerRunTool *runTool) override;
void logServiceStateChange(const QString &service, float version, void logServiceStateChange(const QString &service, float version,
QmlDebug::QmlDebugClient::State newState); QmlDebug::QmlDebugClient::State newState);
void logServiceActivity(const QString &service, const QString &logMessage); void logServiceActivity(const QString &service, const QString &logMessage);
@@ -59,8 +57,8 @@ private:
void errorMessageBoxFinished(int result); void errorMessageBoxFinished(int result);
void updateCurrentContext(); void updateCurrentContext();
void tryToConnect(Utils::Port port = Utils::Port()); void tryToConnect();
void beginConnection(Utils::Port port = Utils::Port()); void beginConnection();
void handleLauncherStarted(); void handleLauncherStarted();
void connectionEstablished(); void connectionEstablished();
void connectionStartupFailed(); void connectionStartupFailed();