macOS: Don't print stack trace via lldb on test failure if SIP prevents it

If the CSR_ALLOW_UNRESTRICTED_FS bit of System Integrity Protection (SIP)
is enabled lldb will fail to print a valid stack trace when launched from
the crashed process, and might also resulting in hanging or crashing the
parent process (Terminal e.g.):

  https://github.com/llvm/llvm-project/issues/53254

We detect this situation and avoid printing a stack trace if so.

Pick-to: 6.3 6.2
Change-Id: Iad8cab5fcdc545d810ca4d4e985aefc0988d0234
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
Tor Arne Vestbø 2022-01-19 12:45:37 +01:00
parent 13fa00519d
commit 985f0e9ca5
3 changed files with 42 additions and 1 deletions

View File

@ -58,6 +58,7 @@
#include <qdebug.h>
#include "qendian.h"
#include "qhash.h"
#include "qpair.h"
#include "qmutex.h"
@ -376,6 +377,38 @@ bool qt_mac_runningUnderRosetta()
return translated;
return false;
}
std::optional<uint32_t> qt_mac_sipConfiguration()
{
static auto configuration = []() -> std::optional<uint32_t> {
QIOType<io_registry_entry_t> nvram = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/options");
if (!nvram) {
qWarning("Failed to locate NVRAM entry in IO registry");
return {};
}
QCFType<CFTypeRef> csrConfig = IORegistryEntryCreateCFProperty(nvram,
CFSTR("csr-active-config"), kCFAllocatorDefault, IOOptionBits{});
if (!csrConfig) {
qWarning("Failed to locate SIP config in NVRAM");
return {};
}
if (auto type = CFGetTypeID(csrConfig); type != CFDataGetTypeID()) {
qWarning() << "Unexpected SIP config type" << CFCopyTypeIDDescription(type);
return {};
}
QByteArray data = QByteArray::fromRawCFData(csrConfig.as<CFDataRef>());
if (data.size() != sizeof(uint32_t)) {
qWarning() << "Unexpected SIP config size" << data.size();
return {};
}
return qFromLittleEndian<uint32_t>(data.constData());
}();
return configuration;
}
#endif
bool qt_apple_isApplicationExtension()

View File

@ -207,6 +207,7 @@ private:
#ifdef Q_OS_MACOS
Q_CORE_EXPORT bool qt_mac_applicationIsInDarkMode();
Q_CORE_EXPORT bool qt_mac_runningUnderRosetta();
Q_CORE_EXPORT std::optional<uint32_t> qt_mac_sipConfiguration();
#endif
#ifndef QT_NO_DEBUG_STREAM

View File

@ -212,7 +212,14 @@ static void stackTrace()
if (debuggerPresent() || hasSystemCrashReporter())
return;
#if defined(Q_OS_LINUX) || (defined(Q_OS_MACOS) && !defined(Q_PROCESSOR_ARM_64))
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
#if defined(Q_OS_MACOS)
#define CSR_ALLOW_UNRESTRICTED_FS (1 << 1)
std::optional<uint32_t> sipConfiguration = qt_mac_sipConfiguration();
if (!sipConfiguration || !(*sipConfiguration & CSR_ALLOW_UNRESTRICTED_FS))
return; // LLDB will fail to provide a valid stack trace
#endif
const int msecsFunctionTime = qRound(QTestLog::msecsFunctionTime());
const int msecsTotalTime = qRound(QTestLog::msecsTotalTime());