testlib: Be more selective in choosing to show stacktraces on macOS

The built in crash reporter on macOS will by default not show the
dialog if the application is not one that will run in the foreground.

Change-Id: I0020520ae2f14a0e2f84fdca1d80ec6fe1247ffd
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
Tor Arne Vestbø 2020-01-31 18:19:14 +01:00
parent 19510abbff
commit 1a58e78db0
4 changed files with 31 additions and 15 deletions

View File

@ -180,20 +180,7 @@ static bool debuggerPresent()
static bool hasSystemCrashReporter() static bool hasSystemCrashReporter()
{ {
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
CFStringRef crashReporterType = static_cast<CFStringRef>( return QTestPrivate::macCrashReporterWillShowDialog();
CFPreferencesCopyAppValue(CFSTR("DialogType"), CFSTR("com.apple.CrashReporter")));
if (crashReporterType == nullptr)
return true;
auto equals = [](CFStringRef str1, CFStringRef str2) -> bool {
return CFStringCompare(str1, str2, kCFCompareCaseInsensitive) == kCFCompareEqualTo;
};
const bool createsStackTrace =
!equals(crashReporterType, CFSTR("server")) &&
!equals(crashReporterType, CFSTR("none"));
CFRelease(crashReporterType);
return createsStackTrace;
#else #else
return false; return false;
#endif #endif

View File

@ -39,6 +39,8 @@
#include "qtestutil_macos_p.h" #include "qtestutil_macos_p.h"
#include "QtCore/private/qcore_mac_p.h"
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -55,6 +57,32 @@ namespace QTestPrivate {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"ApplePersistenceIgnoreState"]; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"ApplePersistenceIgnoreState"];
} }
bool macCrashReporterWillShowDialog()
{
auto dialogType = QCFType<CFStringRef>(CFPreferencesCopyAppValue(
CFSTR("DialogType"), CFSTR("com.apple.CrashReporter")));
auto stringCompare = [](CFStringRef str1, CFStringRef str2) -> bool {
return CFStringCompare(str1, str2, kCFCompareCaseInsensitive) == kCFCompareEqualTo;
};
if (!dialogType || stringCompare(dialogType, CFSTR("basic"))) {
// The default (basic) dialog type only shows up if the
// application is 'user visible', as indicated by the
// activation policy.
auto *runningApp = NSRunningApplication.currentApplication;
return runningApp && runningApp.activationPolicy == NSApplicationActivationPolicyRegular;
} else if (stringCompare(dialogType, CFSTR("developer"))
|| stringCompare(dialogType, CFSTR("crashreport"))) {
// While in developer mode the dialog will show for all
// crashed applications, including backgrounded ones.
return true;
} else {
// Finally, 'server' or 'none' will result in no dialog
return false;
}
}
/*! \internal /*! \internal
\class AppNapDisabler \class AppNapDisabler
\brief Disables App Nap by registereing a bacground activity. \brief Disables App Nap by registereing a bacground activity.

View File

@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
namespace QTestPrivate { namespace QTestPrivate {
void disableWindowRestore(); void disableWindowRestore();
bool macCrashReporterWillShowDialog();
class AppNapDisabler class AppNapDisabler
{ {

View File

@ -112,7 +112,7 @@ mac {
macos { macos {
HEADERS += qtestutil_macos_p.h HEADERS += qtestutil_macos_p.h
OBJECTIVE_SOURCES += qtestutil_macos.mm OBJECTIVE_SOURCES += qtestutil_macos.mm
LIBS += -framework Foundation -framework ApplicationServices -framework IOKit LIBS += -framework Foundation -framework ApplicationServices -framework IOKit -framework AppKit
} }
# XCTest support (disabled for now) # XCTest support (disabled for now)