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 3 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
13 changes: 12 additions & 1 deletion Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,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 +927,17 @@ 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(__builtin_available(iOS 12.0, tvOS 12.0, macOS 10.14, *)) {
kstenerud 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
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
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
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
14 changes: 12 additions & 2 deletions features/steps/reusable_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@
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
actual_version = Maze.config.os_version

$logger.info "Detected actual platform/version: #{actual_platform} #{actual_version}"

unless test_platform.downcase == actual_platform && actual_version >= test_version.to_f
$logger.info "Skipping #{test_platform} #{test_version} check on #{actual_platform} #{actual_version}"
nickdowell marked this conversation as resolved.
Show resolved Hide resolved
next
end

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 "メインスレッド"