Android: add "threads" command for jdb settelment

By issuing "threads" the jdb will output the names of the running
threads. This makes sure that jdb has "settled" and is in a running
state.

Task-number: QTCREATORBUG-26592
Task-number: QTCREATORBUG-26709
Task-number: QTCREATORBUG-28141
Task-number: QTCREATORBUG-28428
Task-number: QTCREATORBUG-28851
Change-Id: Ib371e333eb9fc4d93a6b797bf7be68793f887fcd
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Cristian Adam
2023-03-07 17:47:33 +01:00
parent 03d3bf9f21
commit d154388f27
2 changed files with 26 additions and 21 deletions

View File

@@ -735,10 +735,10 @@ void AndroidRunnerWorker::handleJdbSettled()
{ {
qCDebug(androidRunWorkerLog) << "Handle JDB settled"; qCDebug(androidRunWorkerLog) << "Handle JDB settled";
auto waitForCommand = [this] { auto waitForCommand = [this] {
for (int i= 0; i < 5 && m_jdbProcess->state() == QProcess::Running; ++i) { for (int i = 0; i < 120 && m_jdbProcess->state() == QProcess::Running; ++i) {
m_jdbProcess->waitForReadyRead(500); m_jdbProcess->waitForReadyRead(500);
QByteArray lines = m_jdbProcess->readAll(); QByteArray lines = m_jdbProcess->readAll();
const auto linesList = lines.split('\n'); const auto linesList = lines.split('\n');
for (const auto &line : linesList) { for (const auto &line : linesList) {
auto msg = line.trimmed(); auto msg = line.trimmed();
if (msg.startsWith(">")) if (msg.startsWith(">"))
@@ -747,24 +747,29 @@ void AndroidRunnerWorker::handleJdbSettled()
} }
return false; return false;
}; };
if (waitForCommand()) {
m_jdbProcess->write("cont\n"); const QStringList commands{"threads", "cont", "exit"};
if (m_jdbProcess->waitForBytesWritten(5000) && waitForCommand()) { const int jdbTimeout = 5000;
m_jdbProcess->write("exit\n");
m_jdbProcess->waitForBytesWritten(5000); for (const QString &command : commands) {
if (!m_jdbProcess->waitForFinished(5000)) { if (waitForCommand()) {
m_jdbProcess->terminate(); m_jdbProcess->write(QString("%1\n").arg(command).toLatin1());
if (!m_jdbProcess->waitForFinished(5000)) { m_jdbProcess->waitForBytesWritten(jdbTimeout);
qCDebug(androidRunWorkerLog) << "Killing JDB process";
m_jdbProcess->kill();
m_jdbProcess->waitForFinished();
}
} else if (m_jdbProcess->exitStatus() == QProcess::NormalExit && m_jdbProcess->exitCode() == 0) {
qCDebug(androidRunWorkerLog) << "JDB settled";
return;
}
} }
} }
if (!m_jdbProcess->waitForFinished(jdbTimeout)) {
m_jdbProcess->terminate();
if (!m_jdbProcess->waitForFinished(jdbTimeout)) {
qCDebug(androidRunWorkerLog) << "Killing JDB process";
m_jdbProcess->kill();
m_jdbProcess->waitForFinished();
}
} else if (m_jdbProcess->exitStatus() == QProcess::NormalExit && m_jdbProcess->exitCode() == 0) {
qCDebug(androidRunWorkerLog) << "JDB settled";
return;
}
emit remoteProcessFinished(Tr::tr("Cannot attach JDB to the running application.")); emit remoteProcessFinished(Tr::tr("Cannot attach JDB to the running application."));
} }

View File

@@ -281,12 +281,12 @@ void LldbEngine::handleLldbStarted()
cmd2.arg("attachpid", attachedPID); cmd2.arg("attachpid", attachedPID);
} else { } else {
cmd2.arg("startmode", rp.startMode); cmd2.arg("startmode", rp.startMode);
// it is better not to check the start mode on the python sid (as we would have to duplicate the // it is better not to check the start mode on the python sid (as we would have to duplicate the
// enum values), and thus we assume that if the rp.attachPID is valid we really have to attach // enum values), and thus we assume that if the rp.attachPID is valid we really have to attach
QTC_CHECK(!rp.attachPID.isValid() || (rp.startMode == AttachToCrashedProcess QTC_CHECK(rp.attachPID.isValid() && (rp.startMode == AttachToRemoteProcess
|| rp.startMode == AttachToLocalProcess)); || rp.startMode == AttachToLocalProcess
|| rp.startMode == AttachToRemoteServer));
cmd2.arg("attachpid", rp.attachPID.pid()); cmd2.arg("attachpid", rp.attachPID.pid());
cmd2.arg("sysroot", rp.deviceSymbolsRoot.isEmpty() ? rp.sysRoot.toString() cmd2.arg("sysroot", rp.deviceSymbolsRoot.isEmpty() ? rp.sysRoot.toString()
: rp.deviceSymbolsRoot); : rp.deviceSymbolsRoot);