Skip to content

Exit tests shouldn't emit crash logs. #670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions Sources/Testing/ExitTests/ExitTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,39 @@ public struct ExitTest: Sendable {
/// processes, so it can be used to uniquely identify an exit test at runtime.
public var sourceLocation: SourceLocation

/// Disable crash reporting, crash logging, or core dumps for the current
/// process.
private static func _disableCrashReporting() {
#if SWT_TARGET_OS_APPLE && !SWT_NO_MACH_PORTS
// We don't need to create a crash log (a "corpse notification") for an exit
// test. In the future, we might want to investigate actually setting up a
// listener port in the parent process and tracking interesting exceptions
// as separate exit conditions.
//
// BUG: The system may still opt to write crash logs to /Library/Logs
// instead of the user's home folder. rdar://47982238
_ = task_set_exception_ports(
swt_mach_task_self(),
exception_mask_t(EXC_MASK_CORPSE_NOTIFY),
mach_port_t(MACH_PORT_NULL),
EXCEPTION_DEFAULT,
THREAD_STATE_NONE
)
#elseif os(Linux)
// On Linux, disable the generation of core files (although they will often
// be disabled by default.) If a particular Linux distro performs additional
// crash diagnostics, we may want to special-case them as well if we can.
var rl = rlimit(rlim_cur: 0, rlim_max: 0)
_ = setrlimit(CInt(RLIMIT_CORE.rawValue), &rl)
#elseif os(Windows)
// On Windows, similarly disable Windows Error Reporting and the Windows
// Error Reporting UI. Note we expect to be the first component to call
// these functions, so we don't attempt to preserve any previously-set bits.
_ = SetErrorMode(UINT(SEM_NOGPFAULTERRORBOX))
_ = WerSetFlags(DWORD(WER_FAULT_REPORTING_NO_UI))
#endif
}

/// Call the exit test in the current process.
///
/// This function invokes the closure originally passed to
Expand All @@ -37,6 +70,8 @@ public struct ExitTest: Sendable {
/// terminate the process in a way that causes the corresponding expectation
/// to fail.
public func callAsFunction() async -> Never {
Self._disableCrashReporting()

do {
try await body()
} catch {
Expand Down
11 changes: 10 additions & 1 deletion Sources/_TestingInternals/include/Includes.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@
#include <string.h>
#include <time.h>

#if defined(__APPLE__) && __has_include(<dispatch/dispatch.h>)
#if defined(__APPLE__) && !SWT_NO_MACH_PORTS
#include <mach/mach_init.h>
#include <mach/task.h>
#endif

#if defined(__APPLE__) && !SWT_NO_LIBDISPATCH
#include <dispatch/dispatch.h>
#endif

Expand All @@ -53,6 +58,10 @@
#include <sys/fcntl.h>
#endif

#if __has_include(<sys/resource.h>)
#include <sys/resource.h>
#endif

#if __has_include(<sys/stat.h>)
#include <sys/stat.h>
#endif
Expand Down
11 changes: 11 additions & 0 deletions Sources/_TestingInternals/include/Stubs.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ static bool swt_S_ISFIFO(mode_t mode) {
#endif
#endif

#if defined(__APPLE__) && !SWT_NO_MACH_PORTS
/// Get a Mach port representing the current task (process.)
///
/// This function is provided because `mach_task_self()` is a complex macro, but
/// directly accessing `mach_task_self_` from Swift triggers concurrency
/// warnings about accessing shared mutable state.
static mach_port_t swt_mach_task_self(void) {
return mach_task_self();
}
#endif

#if defined(_WIN32)
/// Make a Win32 language ID.
///
Expand Down