summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAssam Boudjelthia <[email protected]>2023-11-24 13:51:47 +0200
committerQt Cherry-pick Bot <[email protected]>2023-11-29 15:42:07 +0000
commitfb1acc83f0898030dd0c8072bd19f8f9bab82447 (patch)
tree17ec68195e2d675e5a80c93b8f75e29ea0faef66
parentb1e02458cb2a1af313f0aac69c571130097696bc (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.cpp49
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";