19ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
29ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
39ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// found in the LICENSE file.
49ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
59ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/process/launch.h"
69ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include <mach/mach.h>
86d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include <servers/bootstrap.h>
96d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/logging.h"
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochnamespace base {
139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochvoid RestoreDefaultExceptionHandler() {
159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // This function is tailored to remove the Breakpad exception handler.
169ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // exception_mask matches s_exception_mask in
179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // breakpad/src/client/mac/handler/exception_handler.cc
189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  const exception_mask_t exception_mask = EXC_MASK_BAD_ACCESS |
199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                          EXC_MASK_BAD_INSTRUCTION |
209ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                          EXC_MASK_ARITHMETIC |
219ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                                          EXC_MASK_BREAKPOINT;
229ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
239ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // Setting the exception port to MACH_PORT_NULL may not be entirely
249ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // kosher to restore the default exception handler, but in practice,
259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // it results in the exception port being set to Apple Crash Reporter,
269ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  // the desired behavior.
279ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  task_set_exception_ports(mach_task_self(), exception_mask, MACH_PORT_NULL,
289ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                           EXCEPTION_DEFAULT, THREAD_STATE_NONE);
299ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
309ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ReplaceBootstrapPort(const std::string& new_bootstrap_name) {
326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // This function is called between fork() and exec(), so it should take care
336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // to run properly in that situation.
346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  mach_port_t port = MACH_PORT_NULL;
366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  kern_return_t kr = bootstrap_look_up(bootstrap_port,
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      new_bootstrap_name.c_str(), &port);
386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (kr != KERN_SUCCESS) {
396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    RAW_LOG(FATAL, "Failed to look up replacement bootstrap port.");
406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  kr = task_set_bootstrap_port(mach_task_self(), port);
436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (kr != KERN_SUCCESS) {
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    RAW_LOG(FATAL, "Failed to replace bootstrap port.");
456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
489ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}  // namespace base
49