Skip to content

Commit

Permalink
fix(reporting): Add missing mach handler imports (#314)
Browse files Browse the repository at this point in the history
Restore mach handler to full functionality. There was a 
missing import which led to an undefined `define` which
was required, causing fallback to the signal handler in
situations where more debugging information was available.
  • Loading branch information
kattrali authored Sep 13, 2018
1 parent 3a68f27 commit caef876
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 64 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========

## TBD

### Bug Fixes

* Fix mach handler declaration and imports. This resolves an issue where signal
codes were less specific than is possible.
[#314](https://github.com/bugsnag/bugsnag-cocoa/pull/314)

## 5.16.3 (14 Aug 2018)

### Bug Fixes
Expand Down
52 changes: 27 additions & 25 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
GIT
remote: https://github.com/bugsnag/maze-runner
revision: f7123450d5a75b719911c6dd3baa0507e6062c2d
revision: 420b5be876c22feb4f085c645c8f121bf05cea29
specs:
bugsnag-maze-runner (1.0.0)
cucumber (~> 3.1.0)
cucumber-expressions (= 5.0.15)
minitest (~> 5.0)
rack (~> 2.0.0)
rake (~> 12.3.0)
test-unit (~> 3.2.0)

GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.6)
CFPropertyList (3.0.0)
activesupport (4.2.10)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
atomos (0.1.2)
backports (3.11.3)
atomos (0.1.3)
backports (3.11.4)
builder (3.2.3)
claide (1.0.2)
cocoapods (1.4.0)
cocoapods (1.5.3)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.4.0)
cocoapods-core (= 1.5.3)
cocoapods-deintegrate (>= 1.0.2, < 2.0)
cocoapods-downloader (>= 1.1.3, < 2.0)
cocoapods-downloader (>= 1.2.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
Expand All @@ -37,21 +38,21 @@ GEM
escape (~> 0.0.4)
fourflusher (~> 2.0.1)
gh_inspector (~> 1.0)
molinillo (~> 0.6.4)
molinillo (~> 0.6.5)
nap (~> 1.0)
ruby-macho (~> 1.1)
xcodeproj (>= 1.5.4, < 2.0)
cocoapods-core (1.4.0)
xcodeproj (>= 1.5.7, < 2.0)
cocoapods-core (1.5.3)
activesupport (>= 4.0.2, < 6)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.2)
cocoapods-downloader (1.1.3)
cocoapods-downloader (1.2.1)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.3.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
Expand All @@ -78,32 +79,33 @@ GEM
fourflusher (2.0.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
gherkin (5.0.0)
gherkin (5.1.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
minitest (5.11.3)
molinillo (0.6.4)
molinillo (0.6.6)
multi_json (1.13.1)
multi_test (0.1.2)
nanaimo (0.2.3)
nanaimo (0.2.6)
nap (1.1.0)
netrc (0.11.0)
power_assert (1.1.1)
rack (2.0.4)
power_assert (1.1.3)
rack (2.0.5)
rake (12.3.1)
rouge (2.0.7)
ruby-macho (1.1.0)
test-unit (3.2.7)
ruby-macho (1.2.0)
test-unit (3.2.8)
power_assert
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
xcodeproj (1.5.6)
CFPropertyList (~> 2.3.3)
atomos (~> 0.1.2)
xcodeproj (1.6.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.3)
xcpretty (0.2.8)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)

PLATFORMS
Expand All @@ -115,4 +117,4 @@ DEPENDENCIES
xcpretty

BUNDLED WITH
1.16.1
1.16.2
1 change: 1 addition & 0 deletions Source/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#import <Foundation/Foundation.h>

#import "BSG_KSSystemCapabilities.h"
#import "BSG_KSCrashReportFilterCompletion.h"
#import "BSG_KSCrashReportWriter.h"
#import "BSG_KSCrashType.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
// THE SOFTWARE.
//

#include "BSG_KSSystemCapabilities.h"
#include "BSG_KSCrashSentry.h"
#include "BSG_KSCrashSentry_Private.h"

#include "BSG_KSCrashSentry_CPPException.h"
#include "BSG_KSCrashSentry_Deadlock.h"
#include "BSG_KSCrashSentry_NSException.h"
#include "BSG_KSCrashSentry_MachException.h"
#include "BSG_KSCrashSentry_Signal.h"
#include "BSG_KSCrashSentry_User.h"
#include "BSG_KSLogger.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
//

#include "BSG_KSCrashSentry_MachException.h"
#include "BSG_KSSystemCapabilities.h"

//#define BSG_KSLogger_LocalLevel TRACE
#include "BSG_KSLogger.h"

#if BSG_KSCRASH_HAS_MACH

#include "BSG_KSMach.h"
#include "BSG_KSCrashSentry_Private.h"
#include <pthread.h>
#include <mach/mach.h>

// ============================================================================
#pragma mark - Constants -
Expand Down Expand Up @@ -144,13 +148,13 @@ static BSG_KSCrash_SentryContext *bsg_g_context;
*
* @param machineContext The machine context to fill out.
*/
bool ksmachexc_i_fetchMachineState(
bool bsg_ksmachexc_i_fetchMachineState(
const thread_t thread, BSG_STRUCT_MCONTEXT_L *const machineContext) {
if (!ksmach_threadState(thread, machineContext)) {
if (!bsg_ksmachthreadState(thread, machineContext)) {
return false;
}

if (!ksmach_exceptionState(thread, machineContext)) {
if (!bsg_ksmachexceptionState(thread, machineContext)) {
return false;
}

Expand All @@ -161,7 +165,7 @@ bool ksmachexc_i_fetchMachineState(
*/
void bsg_ksmachexc_i_restoreExceptionPorts(void) {
BSG_KSLOG_DEBUG("Restoring original exception ports.");
if (g_previousExceptionPorts.count == 0) {
if (bsg_g_previousExceptionPorts.count == 0) {
BSG_KSLOG_DEBUG("Original exception ports were already restored.");
return;
}
Expand Down Expand Up @@ -203,7 +207,7 @@ void *ksmachexc_i_handleExceptions(void *const userData) {
pthread_setname_np(threadName);
if (threadName == kThreadSecondary) {
BSG_KSLOG_DEBUG("This is the secondary thread. Suspending.");
thread_suspend(bsg_ksmach_thread_self());
thread_suspend(bsg_ksmachthread_self());
}

for (;;) {
Expand Down Expand Up @@ -235,18 +239,18 @@ void *ksmachexc_i_handleExceptions(void *const userData) {

// Switch to the secondary thread if necessary, or uninstall the handler
// to avoid a death loop.
if (bsg_ksmach_thread_self() == bsg_g_primaryMachThread) {
if (bsg_ksmachthread_self() == bsg_g_primaryMachThread) {
BSG_KSLOG_DEBUG("This is the primary exception thread. Activating "
"secondary thread.");
if (thread_resume(g_secondaryMachThread) != KERN_SUCCESS) {
if (thread_resume(bsg_g_secondaryMachThread) != KERN_SUCCESS) {
BSG_KSLOG_DEBUG("Could not activate secondary thread. "
"Restoring original exception ports.");
ksmachexc_i_restoreExceptionPorts();
bsg_ksmachexc_i_restoreExceptionPorts();
}
} else {
BSG_KSLOG_DEBUG("This is the secondary exception thread. Restoring "
"original exception ports.");
ksmachexc_i_restoreExceptionPorts();
bsg_ksmachexc_i_restoreExceptionPorts();
}

if (wasHandlingCrash) {
Expand Down Expand Up @@ -326,7 +330,7 @@ bool bsg_kscrashsentry_installMachHandler(
}
bsg_g_installed = 1;

if (bsg_ksmach_isBeingTraced()) {
if (bsg_ksmachisBeingTraced()) {
// Different debuggers hook into different exception types.
// For example, GDB uses EXC_BAD_ACCESS for single stepping,
// and LLDB uses EXC_SOFTWARE to stop a debug session.
Expand All @@ -341,18 +345,18 @@ bool bsg_kscrashsentry_installMachHandler(
BSG_KSLOG_DEBUG("Backing up original exception ports.");
kr = task_get_exception_ports(
thisTask, mask, bsg_g_previousExceptionPorts.masks,
&g_previousExceptionPorts.count, bsg_g_previousExceptionPorts.ports,
&bsg_g_previousExceptionPorts.count, bsg_g_previousExceptionPorts.ports,
bsg_g_previousExceptionPorts.behaviors,
bsg_g_previousExceptionPorts.flavors);
if (kr != KERN_SUCCESS) {
BSG_KSLOG_ERROR("task_get_exception_ports: %s", mach_error_string(kr));
goto failed;
}

if (g_exceptionPort == MACH_PORT_NULL) {
if (bsg_g_exceptionPort == MACH_PORT_NULL) {
BSG_KSLOG_DEBUG("Allocating new port with receive rights.");
kr = mach_port_allocate(thisTask, MACH_PORT_RIGHT_RECEIVE,
&g_exceptionPort);
&bsg_g_exceptionPort);
if (kr != KERN_SUCCESS) {
BSG_KSLOG_ERROR("mach_port_allocate: %s", mach_error_string(kr));
goto failed;
Expand Down Expand Up @@ -381,26 +385,26 @@ bool bsg_kscrashsentry_installMachHandler(
pthread_attr_init(&attr);
attributes_created = true;
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
error = pthread_create(&g_secondaryPThread, &attr,
error = pthread_create(&bsg_g_secondaryPThread, &attr,
&ksmachexc_i_handleExceptions, kThreadSecondary);
if (error != 0) {
BSG_KSLOG_ERROR("pthread_create_suspended_np: %s", strerror(error));
goto failed;
}
bsg_g_secondaryMachThread = pthread_mach_thread_np(g_secondaryPThread);
context->reservedThreads[KSCrashReservedThreadTypeMachSecondary] =
bsg_g_secondaryMachThread = pthread_mach_thread_np(bsg_g_secondaryPThread);
context->reservedThreads[BSG_KSCrashReservedThreadTypeMachSecondary] =
bsg_g_secondaryMachThread;

BSG_KSLOG_DEBUG("Creating primary exception thread.");
error = pthread_create(&g_primaryPThread, &attr,
error = pthread_create(&bsg_g_primaryPThread, &attr,
&ksmachexc_i_handleExceptions, kThreadPrimary);
if (error != 0) {
BSG_KSLOG_ERROR("pthread_create: %s", strerror(error));
goto failed;
}
pthread_attr_destroy(&attr);
bsg_g_primaryMachThread = pthread_mach_thread_np(g_primaryPThread);
context->reservedThreads[KSCrashReservedThreadTypeMachPrimary] =
bsg_g_primaryMachThread = pthread_mach_thread_np(bsg_g_primaryPThread);
context->reservedThreads[BSG_KSCrashReservedThreadTypeMachPrimary] =
bsg_g_primaryMachThread;

BSG_KSLOG_DEBUG("Mach exception handler installed.");
Expand All @@ -426,26 +430,26 @@ void bsg_kscrashsentry_uninstallMachHandler(void) {
// NOTE: Do not deallocate the exception port. If a secondary crash occurs
// it will hang the process.

ksmachexc_i_restoreExceptionPorts();
bsg_ksmachexc_i_restoreExceptionPorts();

thread_t thread_self = bsg_ksmachthread_self();

if (g_primaryPThread != 0 && bsg_g_primaryMachThread != thread_self) {
if (bsg_g_primaryPThread != 0 && bsg_g_primaryMachThread != thread_self) {
BSG_KSLOG_DEBUG("Cancelling primary exception thread.");
if (bsg_g_context->handlingCrash) {
thread_terminate(g_primaryMachThread);
thread_terminate(bsg_g_primaryMachThread);
} else {
pthread_cancel(g_primaryPThread);
pthread_cancel(bsg_g_primaryPThread);
}
bsg_g_primaryMachThread = 0;
bsg_g_primaryPThread = 0;
}
if (g_secondaryPThread != 0 && bsg_g_secondaryMachThread != thread_self) {
if (bsg_g_secondaryPThread != 0 && bsg_g_secondaryMachThread != thread_self) {
BSG_KSLOG_DEBUG("Cancelling secondary exception thread.");
if (bsg_g_context->handlingCrash) {
thread_terminate(g_secondaryMachThread);
thread_terminate(bsg_g_secondaryMachThread);
} else {
pthread_cancel(g_secondaryPThread);
pthread_cancel(bsg_g_secondaryPThread);
}
bsg_g_secondaryMachThread = 0;
bsg_g_secondaryPThread = 0;
Expand Down
Loading

0 comments on commit caef876

Please sign in to comment.