aboutsummaryrefslogtreecommitdiff
path: root/src/client/mac/crash_generation
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/mac/crash_generation')
-rw-r--r--src/client/mac/crash_generation/Inspector.h18
-rw-r--r--src/client/mac/crash_generation/Inspector.mm43
2 files changed, 59 insertions, 2 deletions
diff --git a/src/client/mac/crash_generation/Inspector.h b/src/client/mac/crash_generation/Inspector.h
index 9d93b2a7..e6705819 100644
--- a/src/client/mac/crash_generation/Inspector.h
+++ b/src/client/mac/crash_generation/Inspector.h
@@ -33,6 +33,8 @@
#import "common/mac/SimpleStringDictionary.h"
#import <Foundation/Foundation.h>
+#include <mach/mach.h>
+
#import "client/mac/handler/minidump_generator.h"
#define VERBOSE 0
@@ -163,6 +165,18 @@ class Inspector {
void Inspect(const char *receive_port_name);
private:
+ // The Inspector is invoked with its bootstrap port set to the bootstrap
+ // subset established in OnDemandServer.mm OnDemandServer::Initialize.
+ // For proper communication with the system, the sender (which will inherit
+ // the Inspector's bootstrap port) needs the per-session bootstrap namespace
+ // available directly in its bootstrap port. OnDemandServer stashed this
+ // port into the subset namespace under a special name. ResetBootstrapPort
+ // recovers this port and switches this task to use it as its own bootstrap
+ // (ensuring that children like the sender will inherit it), and saves the
+ // subset in bootstrap_subset_port_ for use by ServiceCheckIn and
+ // ServiceCheckOut.
+ void ResetBootstrapPort();
+
kern_return_t ServiceCheckIn(const char *receive_port_name);
kern_return_t ServiceCheckOut(const char *receive_port_name);
@@ -174,6 +188,10 @@ class Inspector {
void SetCrashTimeParameters();
+ // The bootstrap port in which the inspector is registered and into which it
+ // must check in.
+ mach_port_t bootstrap_subset_port_;
+
mach_port_t service_rcv_port_;
int exception_type_;
diff --git a/src/client/mac/crash_generation/Inspector.mm b/src/client/mac/crash_generation/Inspector.mm
index 1b0b97cb..77187082 100644
--- a/src/client/mac/crash_generation/Inspector.mm
+++ b/src/client/mac/crash_generation/Inspector.mm
@@ -203,6 +203,8 @@ void ConfigFile::WriteFile(const SimpleStringDictionary *configurationParameters
//=============================================================================
void Inspector::Inspect(const char *receive_port_name) {
+ ResetBootstrapPort();
+
kern_return_t result = ServiceCheckIn(receive_port_name);
if (result == KERN_SUCCESS) {
@@ -241,10 +243,47 @@ void Inspector::Inspect(const char *receive_port_name) {
}
//=============================================================================
+void Inspector::ResetBootstrapPort() {
+ // A reasonable default, in case anything fails.
+ bootstrap_subset_port_ = bootstrap_port;
+
+ mach_port_t self_task = mach_task_self();
+
+ kern_return_t kr = task_get_bootstrap_port(self_task,
+ &bootstrap_subset_port_);
+ if (kr != KERN_SUCCESS) {
+ NSLog(@"ResetBootstrapPort: task_get_bootstrap_port failed: %s (%d)",
+ mach_error_string(kr), kr);
+ return;
+ }
+
+ mach_port_t bootstrap_parent_port;
+ kr = bootstrap_look_up(bootstrap_subset_port_,
+ "BootstrapParentPort",
+ &bootstrap_parent_port);
+ if (kr != KERN_SUCCESS) {
+ NSLog(@"ResetBootstrapPort: bootstrap_look_up failed: %s (%d)",
+ bootstrap_strerror(kr), kr);
+ return;
+ }
+
+ kr = task_set_bootstrap_port(self_task, bootstrap_parent_port);
+ if (kr != KERN_SUCCESS) {
+ NSLog(@"ResetBootstrapPort: task_set_bootstrap_port failed: %s (%d)",
+ mach_error_string(kr), kr);
+ return;
+ }
+
+ // Some things access the bootstrap port through this global variable
+ // instead of calling task_get_bootstrap_port.
+ bootstrap_port = bootstrap_parent_port;
+}
+
+//=============================================================================
kern_return_t Inspector::ServiceCheckIn(const char *receive_port_name) {
// We need to get the mach port representing this service, so we can
// get information from the crashed process.
- kern_return_t kr = bootstrap_check_in(bootstrap_port,
+ kern_return_t kr = bootstrap_check_in(bootstrap_subset_port_,
(char*)receive_port_name,
&service_rcv_port_);
@@ -275,7 +314,7 @@ kern_return_t Inspector::ServiceCheckOut(const char *receive_port_name) {
}
// Unregister the service associated with the receive port.
- kr = bootstrap_register(bootstrap_port,
+ kr = bootstrap_register(bootstrap_subset_port_,
(char*)receive_port_name,
MACH_PORT_NULL);