Skip to content
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

[PLAT-8545] Capture the current thread name on crash #1406

Merged
merged 6 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from 5 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
22 changes: 22 additions & 0 deletions Bugsnag.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,15 @@
CB6419B625A7419400613D25 /* v0_files in Resources */ = {isa = PBXBuildFile; fileRef = CB6419B325A7419400613D25 /* v0_files */; };
CB7FEA45282BD8F700D5356A /* BSGRunContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0154E20128070AEA009044E4 /* BSGRunContext.m */; };
CB9103642502320A00E9D1E2 /* BugsnagApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9103632502320A00E9D1E2 /* BugsnagApiClientTest.m */; };
CB9C1EE52863007B00569006 /* BSGOS.h in Headers */ = {isa = PBXBuildFile; fileRef = CB9C1EE32863007B00569006 /* BSGOS.h */; };
CB9C1EE62863007B00569006 /* BSGOS.h in Headers */ = {isa = PBXBuildFile; fileRef = CB9C1EE32863007B00569006 /* BSGOS.h */; };
CB9C1EE72863007B00569006 /* BSGOS.h in Headers */ = {isa = PBXBuildFile; fileRef = CB9C1EE32863007B00569006 /* BSGOS.h */; };
CB9C1EE82863007B00569006 /* BSGOS.h in Headers */ = {isa = PBXBuildFile; fileRef = CB9C1EE32863007B00569006 /* BSGOS.h */; };
CB9C1EE92863007B00569006 /* BSGOS.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9C1EE42863007B00569006 /* BSGOS.m */; };
CB9C1EEA2863007C00569006 /* BSGOS.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9C1EE42863007B00569006 /* BSGOS.m */; };
CB9C1EEB2863007C00569006 /* BSGOS.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9C1EE42863007B00569006 /* BSGOS.m */; };
CB9C1EEC2863007C00569006 /* BSGOS.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9C1EE42863007B00569006 /* BSGOS.m */; };
CB9C1EED2863007C00569006 /* BSGOS.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9C1EE42863007B00569006 /* BSGOS.m */; };
CBA2249B251E429C00B87416 /* TestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = CBA2249A251E429C00B87416 /* TestSupport.m */; };
CBA2249C251E429C00B87416 /* TestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = CBA2249A251E429C00B87416 /* TestSupport.m */; };
CBA2249D251E429C00B87416 /* TestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = CBA2249A251E429C00B87416 /* TestSupport.m */; };
Expand Down Expand Up @@ -1650,6 +1659,8 @@
CB6419AA25A73E8C00613D25 /* BSGStorageMigratorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BSGStorageMigratorTests.m; sourceTree = "<group>"; };
CB6419B325A7419400613D25 /* v0_files */ = {isa = PBXFileReference; lastKnownFileType = folder; path = v0_files; sourceTree = "<group>"; };
CB9103632502320A00E9D1E2 /* BugsnagApiClientTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BugsnagApiClientTest.m; sourceTree = "<group>"; };
CB9C1EE32863007B00569006 /* BSGOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BSGOS.h; sourceTree = "<group>"; };
CB9C1EE42863007B00569006 /* BSGOS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BSGOS.m; sourceTree = "<group>"; };
CBA22499251E429C00B87416 /* TestSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestSupport.h; sourceTree = "<group>"; };
CBA2249A251E429C00B87416 /* TestSupport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestSupport.m; sourceTree = "<group>"; };
CBB0928A2519F891007698BC /* BugsnagSystemState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagSystemState.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2159,6 +2170,8 @@
CBCF77A125010648004AF22A /* BSGJSONSerialization.h */,
CBCF77A225010648004AF22A /* BSGJSONSerialization.m */,
008968152486DA5600DC48C2 /* BSGKeys.h */,
CB9C1EE32863007B00569006 /* BSGOS.h */,
CB9C1EE42863007B00569006 /* BSGOS.m */,
0154E20028070AEA009044E4 /* BSGRunContext.h */,
0154E20128070AEA009044E4 /* BSGRunContext.m */,
008968112486DA5600DC48C2 /* BSGSerialization.h */,
Expand Down Expand Up @@ -2407,6 +2420,7 @@
01CCAEEA25D414D60057268D /* BugsnagLastRunInfo.h in Headers */,
010993B1273D2F6200128BBE /* BugsnagFeatureFlagStore.h in Headers */,
01099393273D123800128BBE /* BugsnagFeatureFlag.h in Headers */,
CB9C1EE52863007B00569006 /* BSGOS.h in Headers */,
01468F5225876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */,
00896A292486DAD100DC48C2 /* BSG_KSCrashType.h in Headers */,
008969DB2486DAD100DC48C2 /* BSG_KSCrash.h in Headers */,
Expand Down Expand Up @@ -2510,6 +2524,7 @@
01468F5325876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */,
010993B2273D2F6200128BBE /* BugsnagFeatureFlagStore.h in Headers */,
01099394273D123800128BBE /* BugsnagFeatureFlag.h in Headers */,
CB9C1EE62863007B00569006 /* BSGOS.h in Headers */,
01CCAEEB25D414D60057268D /* BugsnagLastRunInfo.h in Headers */,
00896A2A2486DAD100DC48C2 /* BSG_KSCrashType.h in Headers */,
008969DC2486DAD100DC48C2 /* BSG_KSCrash.h in Headers */,
Expand Down Expand Up @@ -2613,6 +2628,7 @@
01468F5425876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */,
010993B3273D2F6200128BBE /* BugsnagFeatureFlagStore.h in Headers */,
01099395273D123800128BBE /* BugsnagFeatureFlag.h in Headers */,
CB9C1EE72863007B00569006 /* BSGOS.h in Headers */,
01CCAEEC25D414D60057268D /* BugsnagLastRunInfo.h in Headers */,
00896A2B2486DAD100DC48C2 /* BSG_KSCrashType.h in Headers */,
008969DD2486DAD100DC48C2 /* BSG_KSCrash.h in Headers */,
Expand Down Expand Up @@ -2653,6 +2669,7 @@
CBBDE931280068AD0070DCD3 /* BSGEventUploadOperation.h in Headers */,
CBBDE9BA280069B20070DCD3 /* BSG_KSBacktrace_Private.h in Headers */,
CBBDE95B280068FD0070DCD3 /* BugsnagBreadcrumb.h in Headers */,
CB9C1EE82863007B00569006 /* BSGOS.h in Headers */,
CBBDE99B2800699C0070DCD3 /* BSG_KSCrashSentry_MachException.h in Headers */,
CBBDE917280068560070DCD3 /* BugsnagSessionTracker.h in Headers */,
CBBDE93F280068D40070DCD3 /* BSGSerialization.h in Headers */,
Expand Down Expand Up @@ -3151,6 +3168,7 @@
01B79DAC267CC4A000C8CC5E /* BSGUtils.m in Sources */,
008969E42486DAD100DC48C2 /* BSG_KSCrashIdentifier.m in Sources */,
008967DA2486DA2D00DC48C2 /* BugsnagConfiguration.m in Sources */,
CB9C1EE92863007B00569006 /* BSGOS.m in Sources */,
008969A52486DAD100DC48C2 /* BSG_KSBacktrace.c in Sources */,
00896A202486DAD100DC48C2 /* BSG_KSCrashSentry.c in Sources */,
00AD1F272486A17900A27979 /* BSGCrashSentry.m in Sources */,
Expand Down Expand Up @@ -3324,6 +3342,7 @@
00896A362486DAD100DC48C2 /* BSG_KSSystemInfo.m in Sources */,
01B79DAD267CC4A000C8CC5E /* BSGUtils.m in Sources */,
008969E52486DAD100DC48C2 /* BSG_KSCrashIdentifier.m in Sources */,
CB9C1EEA2863007C00569006 /* BSGOS.m in Sources */,
008967DB2486DA2D00DC48C2 /* BugsnagConfiguration.m in Sources */,
008969A62486DAD100DC48C2 /* BSG_KSBacktrace.c in Sources */,
00896A212486DAD100DC48C2 /* BSG_KSCrashSentry.c in Sources */,
Expand Down Expand Up @@ -3494,6 +3513,7 @@
01B79DAE267CC4A000C8CC5E /* BSGUtils.m in Sources */,
008969E62486DAD100DC48C2 /* BSG_KSCrashIdentifier.m in Sources */,
008967DC2486DA2D00DC48C2 /* BugsnagConfiguration.m in Sources */,
CB9C1EEB2863007C00569006 /* BSGOS.m in Sources */,
008969A72486DAD100DC48C2 /* BSG_KSBacktrace.c in Sources */,
00896A222486DAD100DC48C2 /* BSG_KSCrashSentry.c in Sources */,
00AD1F292486A17900A27979 /* BSGCrashSentry.m in Sources */,
Expand Down Expand Up @@ -3655,6 +3675,7 @@
008968872486DA9600DC48C2 /* BugsnagNotifier.m in Sources */,
CBE9063025A34DAB0045B965 /* BSGStorageMigratorV0V1.m in Sources */,
0089683D2486DA6C00DC48C2 /* BugsnagMetadata.m in Sources */,
CB9C1EED2863007C00569006 /* BSGOS.m in Sources */,
0089682E2486DA5600DC48C2 /* BSGSerialization.m in Sources */,
015F528725C15BB7000D1915 /* MRCCanary.m in Sources */,
0089686E2486DA9500DC48C2 /* BugsnagEvent.m in Sources */,
Expand Down Expand Up @@ -3763,6 +3784,7 @@
CBBDE939280068D40070DCD3 /* BSGJSONSerialization.m in Sources */,
CBBDE9A02800699C0070DCD3 /* BSG_KSCrashSentry_Signal.c in Sources */,
CB7FEA45282BD8F700D5356A /* BSGRunContext.m in Sources */,
CB9C1EEC2863007C00569006 /* BSGOS.m in Sources */,
CBBDE96A280069290070DCD3 /* BugsnagEvent.m in Sources */,
CBBDE91B2800687B0070DCD3 /* BSGNotificationBreadcrumbs.m in Sources */,
CBBDE9662800691A0070DCD3 /* BugsnagBreadcrumb.m in Sources */,
Expand Down
3 changes: 3 additions & 0 deletions Bugsnag/Client/BugsnagClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#import "BSGAppKit.h"
#import "BSGUIKit.h"
#import "BSGHardware.h"
#import "BSGOS.h"

static NSString *const BSTabCrash = @"crash";
static NSString *const BSAttributeDepth = @"depth";
Expand Down Expand Up @@ -214,6 +215,8 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration {
}

- (void)start {
bsgos_init();

if (self.configuration.telemetry & BSGTelemetryInternalErrors) {
BSGInternalErrorReporter.sharedInstance = [[BSGInternalErrorReporter alloc] initWithDataSource:self];
} else {
Expand Down
44 changes: 44 additions & 0 deletions Bugsnag/Helpers/BSGOS.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// BSGOS.h
// Bugsnag
//
// Created by Karl Stenerud on 22.06.22.
// Copyright © 2022 Bugsnag Inc. All rights reserved.
//

#ifndef HDR_BSGOS_h
#define HDR_BSGOS_h

#ifdef __cplusplus
extern "C" {
#endif

#include <CoreFoundation/CoreFoundation.h>

typedef CF_ENUM(unsigned, BSGOS_Platform) {
BSGOS_UNKNOWN_OS = 0,
BSGOS_IOS = 1,
BSGOS_TVOS = 2,
BSGOS_MACOS = 3,
BSGOS_WATCHOS = 4,
};

/**
* Initialize the OS data. This function is idempotent.
*/
void bsgos_init(void);

/**
* Async-safe alternative to __builtin_available to check if we are running the specified OS with a minimum version.
*
* To check for at least iOS 11: if (bsgos_available(BSGOS_IOS, 11, 0))
* To check for at least macOS 10.14: if (bsgos_available(BSGOS_MACOS, 10, 14))
*/
bool bsgos_available(BSGOS_Platform wanted_platform, unsigned major_version, unsigned minor_version);


#ifdef __cplusplus
}
#endif

#endif // HDR_BSGOS_h
58 changes: 58 additions & 0 deletions Bugsnag/Helpers/BSGOS.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// BSGOS.m
// Bugsnag
//
// Created by Karl Stenerud on 22.06.22.
// Copyright © 2022 Bugsnag Inc. All rights reserved.
//

#import "BSGOS.h"
#import "BSG_KSSystemInfo.h"

static bool bsgos_initialized = false;
static BSGOS_Platform current_platform = BSGOS_UNKNOWN_OS;
static unsigned current_version = 0;

static inline unsigned make_version(unsigned major, unsigned minor) {
return (major << 16) | minor;
}

void bsgos_init(void) {
if (bsgos_initialized) {
return;
}

NSDictionary *sysInfo = [BSG_KSSystemInfo systemInfo];

const char *platform_str = [sysInfo[@BSG_KSSystemField_SystemName] UTF8String];
if (platform_str != NULL) {
if (strcmp(platform_str, "iOS") == 0) {
current_platform = BSGOS_IOS;
} else if (strcmp(platform_str, "tvOS") == 0) {
current_platform = BSGOS_TVOS;
} else if (strcmp(platform_str, "watchOS") == 0) {
current_platform = BSGOS_WATCHOS;
} else if (strcmp(platform_str, "Mac OS") == 0) {
// [BSG_KSSystemInfo buildSystemInfoStatic] calls it "Mac OS".
current_platform = BSGOS_MACOS;
}
}

const char *version_str = [sysInfo[@BSG_KSSystemField_SystemVersion] UTF8String];
if (version_str != NULL) {
unsigned version_major = (unsigned)atoi(version_str);
unsigned version_minor = 0;
const char* dot = strchr(version_str, '.');
if (dot != NULL) {
version_minor = (unsigned)atoi(dot+1);
}
current_version = make_version(version_major, version_minor);
}

bsgos_initialized = true;
}

bool bsgos_available(BSGOS_Platform wanted_platform, unsigned major_version, unsigned minor_version) {
unsigned wanted_version = make_version(major_version, minor_version);
return (current_platform == wanted_platform && current_version >= wanted_version);
}
16 changes: 15 additions & 1 deletion Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "BSG_KSCrashSentry.h"
#include "BSG_Symbolicate.h"
#include "BSGDefines.h"
#include "BSGOS.h"

#include <mach-o/loader.h>
#include <sys/time.h>
Expand Down Expand Up @@ -895,6 +896,7 @@ void bsg_kscrw_i_writeThread(const BSG_KSCrashReportWriter *const writer,
const integer_t threadRunState,
const bool writeNotableAddresses) {
bool isCrashedThread = thread == crash->offendingThread;
bool isSelfThread = thread == bsg_ksmachthread_self();
BSG_STRUCT_MCONTEXT_L machineContextBuffer;
uintptr_t backtraceBuffer[BSG_kMaxBacktraceDepth];
int backtraceLength = sizeof(backtraceBuffer) / sizeof(*backtraceBuffer);
Expand Down Expand Up @@ -926,7 +928,19 @@ void bsg_kscrw_i_writeThread(const BSG_KSCrashReportWriter *const writer,
writer->addBooleanElement(writer, BSG_KSCrashField_Crashed,
isCrashedThread);
writer->addBooleanElement(writer, BSG_KSCrashField_CurrentThread,
thread == bsg_ksmachthread_self());
isSelfThread);

// Fetching the current thread name is only safe as of libpthread-330.201.1
// which was used in ios+tvos 12 and macos 10.14
if (bsgos_available(BSGOS_IOS, 12, 0) ||
bsgos_available(BSGOS_TVOS, 12, 0) ||
bsgos_available(BSGOS_MACOS, 10, 14)) {
nickdowell marked this conversation as resolved.
Show resolved Hide resolved
if (isSelfThread) {
char buff[100];
bsg_ksmachgetThreadName(thread, buff, sizeof(buff));
writer->addStringElement(writer, BSG_KSCrashField_Name, buff);
}
}
if (isCrashedThread && machineContext != NULL) {
bsg_kscrw_i_writeStackOverflow(writer, BSG_KSCrashField_Stack,
machineContext, skippedEntries > 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ pthread_t bsg_ksmachpthreadFromMachThread(const thread_t thread) {

bool bsg_ksmachgetThreadName(const thread_t thread, char *const buffer,
size_t bufLength) {
// WARNING: This implementation is no longer async-safe!
// WARNING: This implementation is only async-safe for the current thread
// as of libpthread-330.201.1, and is still unsafe for other threads.

const pthread_t pthread = pthread_from_mach_thread_np(thread);
if (pthread == NULL) {
Expand Down
1 change: 1 addition & 0 deletions Bugsnag/Payload/BugsnagThread.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ - (instancetype)initWithThread:(NSDictionary *)thread binaryImages:(NSArray *)bi
if ((self = [super init])) {
_errorReportingThread = [thread[@BSG_KSCrashField_Crashed] boolValue];
_id = [thread[@BSG_KSCrashField_Index] stringValue];
_name = thread[@BSG_KSCrashField_Name];
_type = BSGThreadTypeCocoa;
_state = thread[@BSG_KSCrashField_State];
_crashInfoMessage = [thread[@BSG_KSCrashField_CrashInfoMessage] copy];
Expand Down
1 change: 1 addition & 0 deletions features/fixtures/shared/scenarios/CxxBareThrowScenario.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ @interface CxxBareThrowScenario : Scenario
@implementation CxxBareThrowScenario

- (void)run {
[[NSThread mainThread] setName:@"œ´¨ø“‘"];
try {
throw;
} catch (...) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ - (void)startBugsnag {
}

- (void)run {
[[NSThread mainThread] setName:@"BSG MAIN THREAD"];
[self crash];
}

Expand Down
1 change: 1 addition & 0 deletions features/fixtures/shared/scenarios/CxxExceptionScenario.mm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ - (void)startBugsnag {
}

- (void)run {
[[NSThread mainThread] setName:@"потік"];
[self crash];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ @interface CxxUnexpectedScenario : Scenario
@implementation CxxUnexpectedScenario

- (void)run {
[[NSThread mainThread] setName:@"BSG MAIN THREAD"];
std::unexpected();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ - (void)startBugsnag {
}

- (void)run __attribute__((noreturn)) {
[[NSThread mainThread] setName:@"メインスレッド"];
@throw [NSException exceptionWithName:NSGenericException reason:@"An uncaught exception! SCREAM."
userInfo:@{NSLocalizedDescriptionKey: @"I'm in your program, catching your exceptions!"}];
}
Expand Down
1 change: 1 addition & 0 deletions features/fixtures/shared/scenarios/ObjCExceptionScenario.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ - (void)startBugsnag {
}

- (void)run __attribute__((noreturn)) {
[[NSThread mainThread] setName:@"BSG MAIN THREAD"];
@throw [NSException exceptionWithName:NSGenericException reason:@"An uncaught exception! SCREAM."
userInfo:@{NSLocalizedDescriptionKey: @"I'm in your program, catching your exceptions!"}];
}
Expand Down
12 changes: 10 additions & 2 deletions features/steps/reusable_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@
step(step_text) if platform.downcase == Maze::Helper.get_current_platform
end

Then(/^on (iOS|macOS) (\d+) and later, (.+)/) do |platform, version, step_text|
step(step_text) if platform.downcase == Maze::Helper.get_current_platform && Maze.config.os_version >= version
Then(/^on (\w+) ([0-9.]+) and later, (.+)/) do |test_platform, test_version, step_text|
actual_platform = Maze::Helper.get_current_platform
unless %w[ios macos].include? actual_platform
raise "Unexpected platform #{actual_platform}, this step can only handle ios and macos"
end

actual_version = Maze.config.os_version
next unless test_platform.downcase == actual_platform && actual_version >= test_version.to_f

step(step_text)
end

Then(/^on !(iOS|macOS|watchOS), (.+)/) do |platform, step_text|
Expand Down
8 changes: 8 additions & 0 deletions features/unhandled_cpp_exception.feature
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Feature: Thrown C++ exceptions are captured by Bugsnag
And the event "severity" equals "error"
And the event "unhandled" is true
And the event "severityReason.type" equals "unhandledException"
And on iOS 12 and later, the event "threads.0.name" equals "потік"
And on macOS 10.14 and later, the event "threads.0.name" equals "потік"

Scenario: Throwing a C++ exception with unhandled override
When I run "CxxExceptionOverrideScenario" and relaunch the crashed app
Expand All @@ -27,6 +29,8 @@ Feature: Thrown C++ exceptions are captured by Bugsnag
And the event "unhandled" is false
And the event "severityReason.unhandledOverridden" is true
And the event "severityReason.type" equals "unhandledException"
And on iOS 12 and later, the event "threads.0.name" equals "BSG MAIN THREAD"
And on macOS 10.14 and later, the event "threads.0.name" equals "BSG MAIN THREAD"

Scenario: Throwing without an exception
When I run "CxxBareThrowScenario" and relaunch the crashed app
Expand All @@ -36,6 +40,8 @@ Feature: Thrown C++ exceptions are captured by Bugsnag
And the exception "errorClass" equals "std::terminate"
And the exception "message" equals "throw may have been called without an exception"
And the "method" of stack frame 2 equals "-[CxxBareThrowScenario run]"
And on iOS 12 and later, the event "threads.0.name" equals "œ´¨ø“‘"
And on macOS 10.14 and later, the event "threads.0.name" equals "œ´¨ø“‘"

Scenario: Causing an unexpected event
When I run "CxxUnexpectedScenario" and relaunch the crashed app
Expand All @@ -45,3 +51,5 @@ Feature: Thrown C++ exceptions are captured by Bugsnag
And the exception "errorClass" equals "std::terminate"
And the exception "message" equals "throw may have been called without an exception"
And the "method" of stack frame 4 equals "-[CxxUnexpectedScenario run]"
And on iOS 12 and later, the event "threads.0.name" equals "BSG MAIN THREAD"
And on macOS 10.14 and later, the event "threads.0.name" equals "BSG MAIN THREAD"
4 changes: 4 additions & 0 deletions features/unhandled_nsexception.feature
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Feature: Uncaught NSExceptions are captured by Bugsnag
And the event "severity" equals "error"
And the event "unhandled" is true
And the event "severityReason.type" equals "unhandledException"
And on iOS 12 and later, the event "threads.0.name" equals "BSG MAIN THREAD"
And on macOS 10.14 and later, the event "threads.0.name" equals "BSG MAIN THREAD"

Scenario: Throw a NSException with unhandled override
When I run "ObjCExceptionOverrideScenario" and relaunch the crashed app
Expand All @@ -37,3 +39,5 @@ Feature: Uncaught NSExceptions are captured by Bugsnag
And the event "unhandled" is false
And the event "severityReason.unhandledOverridden" is true
And the event "severityReason.type" equals "unhandledException"
And on iOS 12 and later, the event "threads.0.name" equals "メインスレッド"
And on macOS 10.14 and later, the event "threads.0.name" equals "メインスレッド"