diff options
author | Assam Boudjelthia <[email protected]> | 2023-11-24 13:51:47 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <[email protected]> | 2023-11-29 15:42:07 +0000 |
commit | fb1acc83f0898030dd0c8072bd19f8f9bab82447 (patch) | |
tree | 17ec68195e2d675e5a80c93b8f75e29ea0faef66 | |
parent | b1e02458cb2a1af313f0aac69c571130097696bc (diff) |
AndroidTestRunner: use ndk-stack to pretty print crash reports
Use ndk-stack [*] tool provided by the Android NDK to pretty
print crash stacktraces to contain <source-file>:<line-number>
lines for calls, making debugging crashes much easier.
The ndk-stack path can be provided with the new param --ndk-stack,
otherwise, it would be deduced using ANDROID_NDK_ROOT env var.
If the tool is not found or the unstripped libs path cannot be
obtained, the default crash report is printed instead.
[*] https://developer.android.com/ndk/guides/ndk-stack
Task-number: QTQAINFRA-5928
Change-Id: I22c3ba131a44050c8fcbfd176d5ced096761d229
Reviewed-by: Axel Spoerl <[email protected]>
(cherry picked from commit 58fc33239e54ca429e41d0b5be8a1c6f917671e2)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
(cherry picked from commit 06e46b77ece7edb7c7e5f8ebcf9d5330ccda5c38)
-rw-r--r-- | src/tools/androidtestrunner/main.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp index cdd354cf797..ceb687cbbc3 100644 --- a/src/tools/androidtestrunner/main.cpp +++ b/src/tools/androidtestrunner/main.cpp @@ -125,6 +125,7 @@ struct Options QHash<QString, QString> outFiles; QString testArgs; QString apkPath; + QString ndkStackPath; int sdkVersion = -1; int pid = -1; bool showLogcatOutput = false; @@ -201,6 +202,11 @@ static bool parseOptions() g_options.skipAddInstallRoot = true; } else if (argument.compare(QStringLiteral("--show-logcat"), Qt::CaseInsensitive) == 0) { g_options.showLogcatOutput = true; + } else if (argument.compare("--ndk-stack"_L1, Qt::CaseInsensitive) == 0) { + if (i + 1 == arguments.size()) + g_options.helpRequested = true; + else + g_options.ndkStackPath = arguments.at(++i); } else if (argument.compare(QStringLiteral("--timeout"), Qt::CaseInsensitive) == 0) { if (i + 1 == arguments.size()) g_options.helpRequested = true; @@ -226,6 +232,14 @@ static bool parseOptions() QString serial = qEnvironmentVariable("ANDROID_DEVICE_SERIAL"); if (!serial.isEmpty()) g_options.adbCommand += QStringLiteral(" -s %1").arg(serial); + + if (g_options.ndkStackPath.isEmpty()) { + const QString ndkPath = qEnvironmentVariable("ANDROID_NDK_ROOT"); + const QString ndkStackPath = ndkPath + QDir::separator() + "ndk-stack"_L1; + if (QFile::exists(ndkStackPath)) + g_options.ndkStackPath = ndkStackPath; + } + return true; } @@ -259,6 +273,9 @@ static void printHelp() "\n" " --show-logcat: Print Logcat output to stdout.\n" "\n" + " --ndk-stack: Path to ndk-stack tool that symbolizes crash stacktraces.\n" + " By default, ANDROID_NDK_ROOT env var is used to deduce the tool path.\n" + "\n" " -- Arguments that will be passed to the test application.\n" "\n" " --verbose: Prints out information during processing.\n" @@ -518,10 +535,42 @@ void printLogcat(const QString &formattedTime) qDebug() << "****** End logcat output ******"; } +static QString getDeviceABI() +{ + const QString abiCmd = "%1 shell getprop ro.product.cpu.abi"_L1.arg(g_options.adbCommand); + QByteArray abi; + if (!execCommand(abiCmd, &abi)) { + qWarning() << "Warning: failed to get the device abi, fallback to first libs dir"; + return {}; + } + + return QString::fromUtf8(abi.simplified()); +} + void printLogcatCrashBuffer(const QString &formattedTime) { QString crashCmd = "%1 logcat -b crash -t '%2'"_L1.arg(g_options.adbCommand, formattedTime); + if (!g_options.ndkStackPath.isEmpty()) { + auto libsPath = "%1/libs/"_L1.arg(g_options.buildPath); + QString abi = getDeviceABI(); + if (abi.isEmpty()) { + QStringList subDirs = QDir(libsPath).entryList(QDir::Dirs | QDir::NoDotAndDotDot); + if (!subDirs.isEmpty()) + abi = subDirs.first(); + } + + if (!abi.isEmpty()) { + libsPath += abi; + crashCmd += " | %1 -sym %2"_L1.arg(g_options.ndkStackPath, libsPath); + } else { + qWarning() << "Warning: failed to get the libs abi, ndk-stack cannot be used."; + } + } else { + qWarning() << "Warning: ndk-stack path not provided and couldn't be deduced " + "using the ANDROID_NDK_ROOT environment variable."; + } + QByteArray crashLogcat; if (!execCommand(crashCmd, &crashLogcat)) { qCritical() << "Error: failed to fetch logcat crash buffer"; |