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 Pick-to: 6.5 Change-Id: I22c3ba131a44050c8fcbfd176d5ced096761d229 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> (cherry picked from commit 58fc33239e54ca429e41d0b5be8a1c6f917671e2) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
9c84620d4b
commit
06e46b77ec
@ -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"
|
||||
@ -517,10 +534,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";
|
||||
|
Loading…
x
Reference in New Issue
Block a user