forked from qt-creator/qt-creator
Android: fix logcat not fetched when app exits/crash at start
Application output from logcat might not work if an app crashes at the start, so with this patch we avoid that by making logcat process fetch logs faster by not getting the full logs but only the logs starting from the moment we start the app (using -T arg). This can be very annoying bug, because when starting the app from QC it usually only prints "app_package_name died." which forces the user to go into the logcat manually and search for an error from thousands of lines. Change-Id: Ic5ac0389cb28e7c80586490877a697272f3648af Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
#include <utils/temporaryfile.h>
|
||||
#include <utils/url.h>
|
||||
|
||||
#include <QDate>
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
@@ -498,22 +499,45 @@ void AndroidRunnerWorker::setAndroidDeviceInfo(const AndroidDeviceInfo &info)
|
||||
<< m_deviceSerialNumber << m_apiLevel;
|
||||
}
|
||||
|
||||
void AndroidRunnerWorker::asyncStartHelper()
|
||||
void Android::Internal::AndroidRunnerWorker::asyncStartLogcat()
|
||||
{
|
||||
forceStop();
|
||||
|
||||
// Its assumed that the device or avd returned by selector() is online.
|
||||
// Start the logcat process before app starts.
|
||||
QTC_ASSERT(!m_adbLogcatProcess, /**/);
|
||||
m_adbLogcatProcess.reset(AndroidManager::runAdbCommandDetached(selector() << "logcat"));
|
||||
if (m_adbLogcatProcess) {
|
||||
m_adbLogcatProcess->setObjectName("AdbLogcatProcess");
|
||||
connect(m_adbLogcatProcess.get(), &QProcess::readyReadStandardOutput,
|
||||
this, &AndroidRunnerWorker::logcatReadStandardOutput);
|
||||
connect(m_adbLogcatProcess.get(), &QProcess::readyReadStandardError,
|
||||
this, &AndroidRunnerWorker::logcatReadStandardError);
|
||||
|
||||
// Ideally AndroidManager::runAdbCommandDetached() should be used, but here
|
||||
// we need to connect the readyRead signals from logcat otherwise we might
|
||||
// lost some output between the process start and connecting those signals.
|
||||
m_adbLogcatProcess.reset(new QProcess());
|
||||
|
||||
connect(m_adbLogcatProcess.get(), &QProcess::readyReadStandardOutput,
|
||||
this, &AndroidRunnerWorker::logcatReadStandardOutput);
|
||||
connect(m_adbLogcatProcess.get(), &QProcess::readyReadStandardError,
|
||||
this, &AndroidRunnerWorker::logcatReadStandardError);
|
||||
|
||||
// Get target current time to fetch only recent logs
|
||||
QString dateInSeconds;
|
||||
QStringList timeArg;
|
||||
if (runAdb({"shell", "date", "+%s"}, &dateInSeconds)) {
|
||||
timeArg << "-T";
|
||||
timeArg << QDateTime::fromSecsSinceEpoch(dateInSeconds.toInt())
|
||||
.toString("MM-dd hh:mm:ss.mmm");
|
||||
}
|
||||
|
||||
const QStringList logcatArgs = selector() << "logcat" << timeArg;
|
||||
const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
|
||||
qCDebug(androidRunWorkerLog) << "Running logcat command (async):"
|
||||
<< CommandLine(adb, logcatArgs).toUserOutput();
|
||||
m_adbLogcatProcess->start(adb, logcatArgs);
|
||||
if (m_adbLogcatProcess->waitForStarted(500) && m_adbLogcatProcess->state() == QProcess::Running)
|
||||
m_adbLogcatProcess->setObjectName("AdbLogcatProcess");
|
||||
}
|
||||
|
||||
void AndroidRunnerWorker::asyncStartHelper()
|
||||
{
|
||||
forceStop();
|
||||
asyncStartLogcat();
|
||||
|
||||
for (const QString &entry : m_beforeStartAdbCommands)
|
||||
runAdb(entry.split(' ', Qt::SkipEmptyParts));
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ private:
|
||||
bool deviceFileExists(const QString &filePath);
|
||||
bool packageFileExists(const QString& filePath);
|
||||
bool uploadDebugServer(const QString &debugServerFileName);
|
||||
void asyncStartLogcat();
|
||||
|
||||
enum class JDBState {
|
||||
Idle,
|
||||
|
||||
Reference in New Issue
Block a user