Chromium Code Reviews| Index: util/mach/exc_server_variants.cc |
| diff --git a/util/mach/exc_server_variants.cc b/util/mach/exc_server_variants.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c0d137b97bd26484a33c44bdcf6d69b1754cec0a |
| --- /dev/null |
| +++ b/util/mach/exc_server_variants.cc |
| @@ -0,0 +1,648 @@ |
| +// Copyright 2014 The Crashpad Authors. All rights reserved. |
| +// |
| +// Licensed under the Apache License, Version 2.0 (the "License"); |
| +// you may not use this file except in compliance with the License. |
| +// You may obtain a copy of the License at |
| +// |
| +// http://www.apache.org/licenses/LICENSE-2.0 |
| +// |
| +// Unless required by applicable law or agreed to in writing, software |
| +// distributed under the License is distributed on an "AS IS" BASIS, |
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| +// See the License for the specific language governing permissions and |
| +// limitations under the License. |
| + |
| +#include "util/mach/exc_server_variants.h" |
| + |
| +#include <algorithm> |
| +#include <vector> |
| + |
| +#include "base/basictypes.h" |
| +#include "base/logging.h" |
| +#include "util/mach/exc.h" |
| +#include "util/mach/excServer.h" |
| +#include "util/mach/mach_exc.h" |
| +#include "util/mach/mach_excServer.h" |
| + |
| +extern "C" { |
| + |
| +// These six functions are not used, and are in fact obsoleted by the other |
| +// functionality implemented in this file. The standard MIG-generated exc_server |
| +// (in excServer.c) and mach_exc_server (in mach_excServer.c) server dispatch |
| +// routines usable with the standard mach_msg_server() function call out to |
| +// these functions. exc_server() and mach_exc_server() are unused and are |
| +// replaced by the more flexible ExcServer and MachExcServer, but the linker |
| +// still needs to see these six function definitions. |
| + |
| +kern_return_t catch_exception_raise(exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + exception_data_t code, |
| + mach_msg_type_number_t code_count) { |
| + NOTREACHED(); |
| + return KERN_FAILURE; |
| +} |
| + |
| +kern_return_t catch_exception_raise_state( |
| + exception_handler_t exception_port, |
| + exception_type_t exception, |
| + exception_data_t code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + thread_state_t old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count) { |
| + NOTREACHED(); |
| + return KERN_FAILURE; |
| +} |
| + |
| +kern_return_t catch_exception_raise_state_identity( |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + exception_data_t code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + thread_state_t old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count) { |
| + NOTREACHED(); |
| + return KERN_FAILURE; |
| +} |
| + |
| +kern_return_t catch_mach_exception_raise(exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + mach_exception_data_t code, |
| + mach_msg_type_number_t code_count) { |
| + NOTREACHED(); |
| + return KERN_FAILURE; |
| +} |
| + |
| +kern_return_t catch_mach_exception_raise_state( |
| + exception_handler_t exception_port, |
| + exception_type_t exception, |
| + mach_exception_data_t code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + thread_state_t old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count) { |
| + NOTREACHED(); |
| + return KERN_FAILURE; |
| +} |
| + |
| +kern_return_t catch_mach_exception_raise_state_identity( |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + mach_exception_data_t code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + thread_state_t old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count) { |
| + NOTREACHED(); |
| + return KERN_FAILURE; |
| +} |
| + |
| +} // extern "C" |
| + |
| +namespace { |
| + |
| +void PrepareReplyFromRequest(const mach_msg_header_t* in_header, |
| + mach_msg_header_t* out_header) { |
| + out_header->msgh_bits = |
| + MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(in_header->msgh_bits), 0); |
| + out_header->msgh_remote_port = in_header->msgh_remote_port; |
| + out_header->msgh_size = sizeof(mig_reply_error_t); |
| + out_header->msgh_local_port = MACH_PORT_NULL; |
| + out_header->msgh_id = in_header->msgh_id + 100; |
| + reinterpret_cast<mig_reply_error_t*>(out_header)->NDR = NDR_record; |
| +} |
| + |
| +void SetReplyError(mach_msg_header_t* out_header, kern_return_t error) { |
| + reinterpret_cast<mig_reply_error_t*>(out_header)->RetCode = error; |
| +} |
| + |
| +// There are no predefined constants for these. |
| +enum MachMessageID : mach_msg_id_t { |
| + kMachMessageIDExceptionRaise = 2401, |
| + kMachMessageIDExceptionRaiseState = 2402, |
| + kMachMessageIDExceptionRaiseStateIdentity = 2403, |
| + kMachMessageIDMachExceptionRaise = 2405, |
| + kMachMessageIDMachExceptionRaiseState = 2406, |
| + kMachMessageIDMachExceptionRaiseStateIdentity = 2407, |
| +}; |
| + |
| +} // namespace |
| + |
| +namespace crashpad { |
| + |
| +ExcServer::ExcServer(ExcServer::Interface* interface) |
| + : MachMessageServer::Interface(), |
| + interface_(interface) { |
| +} |
| + |
| +bool ExcServer::MachMessageServerFunction(mach_msg_header_t* in_header, |
| + mach_msg_header_t* out_header, |
| + bool* destroy_complex_request) { |
| + PrepareReplyFromRequest(in_header, out_header); |
| + |
| + switch (in_header->msgh_id) { |
| + case kMachMessageIDExceptionRaise: { |
| + // exception_raise(), catch_exception_raise(). |
| + typedef __Request__exception_raise_t Request; |
| + Request* in_request = reinterpret_cast<Request*>(in_header); |
| + kern_return_t kr = __MIG_check__Request__exception_raise_t(in_request); |
| + if (kr != MACH_MSG_SUCCESS) { |
| + SetReplyError(out_header, kr); |
| + return true; |
| + } |
| + |
| + typedef __Reply__exception_raise_t Reply; |
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header); |
| + out_reply->RetCode = |
|
Robert Sesek
2014/09/10 16:44:41
Is out_reply->msgh_size correct here? (Right now i
Mark Mentovai
2014/09/10 20:12:56
rsesek wrote:
|
| + interface_->CatchExceptionRaise(in_header->msgh_local_port, |
| + in_request->thread.name, |
| + in_request->task.name, |
| + in_request->exception, |
| + in_request->code, |
| + in_request->codeCnt, |
| + destroy_complex_request); |
| + return true; |
| + } |
| + |
| + case kMachMessageIDExceptionRaiseState: { |
| + // exception_raise_state(), catch_exception_raise_state(). |
| + typedef __Request__exception_raise_state_t Request; |
| + Request* in_request = reinterpret_cast<Request*>(in_header); |
| + Request* in_request_1; |
|
Robert Sesek
2014/09/10 16:44:41
Don't really know what in_request_1 is.
|
| + kern_return_t kr = __MIG_check__Request__exception_raise_state_t( |
| + in_request, &in_request_1); |
| + if (kr != MACH_MSG_SUCCESS) { |
| + SetReplyError(out_header, kr); |
| + return true; |
| + } |
| + |
| + typedef __Reply__exception_raise_state_t Reply; |
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header); |
| + out_reply->new_stateCnt = arraysize(out_reply->new_state); |
| + out_reply->RetCode = |
| + interface_->CatchExceptionRaiseState(in_header->msgh_local_port, |
| + in_request->exception, |
| + in_request->code, |
| + in_request->codeCnt, |
| + &in_request_1->flavor, |
| + in_request_1->old_state, |
| + in_request_1->old_stateCnt, |
| + out_reply->new_state, |
| + &out_reply->new_stateCnt); |
| + if (out_reply->RetCode != KERN_SUCCESS) { |
| + return true; |
| + } |
| + |
| + out_reply->flavor = in_request_1->flavor; |
| + out_header->msgh_size = |
| + sizeof(*out_reply) - sizeof(out_reply->new_state) + |
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; |
| + return true; |
| + } |
| + |
| + case kMachMessageIDExceptionRaiseStateIdentity: { |
| + // exception_raise_state_identity(), |
| + // catch_exception_raise_state_identity(). |
| + typedef __Request__exception_raise_state_identity_t Request; |
| + Request* in_request = reinterpret_cast<Request*>(in_header); |
| + Request* in_request_1; |
| + kern_return_t kr = __MIG_check__Request__exception_raise_state_identity_t( |
| + in_request, &in_request_1); |
| + if (kr != MACH_MSG_SUCCESS) { |
| + SetReplyError(out_header, kr); |
| + return true; |
| + } |
| + |
| + typedef __Reply__exception_raise_state_identity_t Reply; |
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header); |
| + out_reply->new_stateCnt = arraysize(out_reply->new_state); |
| + out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity( |
| + in_header->msgh_local_port, |
| + in_request->thread.name, |
| + in_request->task.name, |
| + in_request->exception, |
| + in_request->code, |
| + in_request->codeCnt, |
| + &in_request_1->flavor, |
| + in_request_1->old_state, |
| + in_request_1->old_stateCnt, |
| + out_reply->new_state, |
| + &out_reply->new_stateCnt, |
| + destroy_complex_request); |
| + if (out_reply->RetCode != KERN_SUCCESS) { |
| + return true; |
| + } |
| + |
| + out_reply->flavor = in_request_1->flavor; |
| + out_header->msgh_size = |
| + sizeof(*out_reply) - sizeof(out_reply->new_state) + |
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; |
| + return true; |
| + } |
| + } |
| + |
| + SetReplyError(out_header, MIG_BAD_ID); |
| + return false; |
| +} |
| + |
| +mach_msg_size_t ExcServer::MachMessageServerRequestSize() { |
| + return sizeof(__RequestUnion__exc_subsystem); |
| +} |
| + |
| +mach_msg_size_t ExcServer::MachMessageServerReplySize() { |
| + return sizeof(__ReplyUnion__exc_subsystem); |
| +} |
| + |
| +MachExcServer::MachExcServer(MachExcServer::Interface* interface) |
| + : MachMessageServer::Interface(), |
| + interface_(interface) { |
| +} |
| + |
| +bool MachExcServer::MachMessageServerFunction(mach_msg_header_t* in_header, |
| + mach_msg_header_t* out_header, |
| + bool* destroy_complex_request) { |
| + PrepareReplyFromRequest(in_header, out_header); |
| + |
| + switch (in_header->msgh_id) { |
| + case kMachMessageIDMachExceptionRaise: { |
| + // mach_exception_raise(), catch_mach_exception_raise(). |
| + typedef __Request__mach_exception_raise_t Request; |
| + Request* in_request = reinterpret_cast<Request*>(in_header); |
| + kern_return_t kr = |
| + __MIG_check__Request__mach_exception_raise_t(in_request); |
| + if (kr != MACH_MSG_SUCCESS) { |
| + SetReplyError(out_header, kr); |
| + return true; |
| + } |
| + |
| + typedef __Reply__mach_exception_raise_t Reply; |
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header); |
| + out_reply->RetCode = |
| + interface_->CatchMachExceptionRaise(in_header->msgh_local_port, |
| + in_request->thread.name, |
| + in_request->task.name, |
| + in_request->exception, |
| + in_request->code, |
| + in_request->codeCnt, |
| + destroy_complex_request); |
| + return true; |
| + } |
| + |
| + case kMachMessageIDMachExceptionRaiseState: { |
| + // mach_exception_raise_state(), catch_mach_exception_raise_state(). |
| + typedef __Request__mach_exception_raise_state_t Request; |
| + Request* in_request = reinterpret_cast<Request*>(in_header); |
| + Request* in_request_1; |
| + kern_return_t kr = __MIG_check__Request__mach_exception_raise_state_t( |
| + in_request, &in_request_1); |
| + if (kr != MACH_MSG_SUCCESS) { |
| + SetReplyError(out_header, kr); |
| + return true; |
| + } |
| + |
| + typedef __Reply__mach_exception_raise_state_t Reply; |
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header); |
| + out_reply->new_stateCnt = arraysize(out_reply->new_state); |
| + out_reply->RetCode = |
| + interface_->CatchMachExceptionRaiseState(in_header->msgh_local_port, |
| + in_request->exception, |
| + in_request->code, |
| + in_request->codeCnt, |
| + &in_request_1->flavor, |
| + in_request_1->old_state, |
| + in_request_1->old_stateCnt, |
| + out_reply->new_state, |
| + &out_reply->new_stateCnt); |
| + if (out_reply->RetCode != KERN_SUCCESS) { |
| + return true; |
| + } |
| + |
| + out_reply->flavor = in_request_1->flavor; |
| + out_header->msgh_size = |
| + sizeof(*out_reply) - sizeof(out_reply->new_state) + |
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; |
| + return true; |
| + } |
| + |
| + case kMachMessageIDMachExceptionRaiseStateIdentity: { |
| + // mach_exception_raise_state_identity(), |
| + // catch_mach_exception_raise_state_identity(). |
| + typedef __Request__mach_exception_raise_state_identity_t Request; |
| + Request* in_request = reinterpret_cast<Request*>(in_header); |
| + Request* in_request_1; |
| + kern_return_t kr = |
| + __MIG_check__Request__mach_exception_raise_state_identity_t( |
| + in_request, &in_request_1); |
| + if (kr != MACH_MSG_SUCCESS) { |
| + SetReplyError(out_header, kr); |
| + return true; |
| + } |
| + |
| + typedef __Reply__mach_exception_raise_state_identity_t Reply; |
| + Reply* out_reply = reinterpret_cast<Reply*>(out_header); |
| + out_reply->new_stateCnt = arraysize(out_reply->new_state); |
| + out_reply->RetCode = interface_->CatchMachExceptionRaiseStateIdentity( |
| + in_header->msgh_local_port, |
| + in_request->thread.name, |
| + in_request->task.name, |
| + in_request->exception, |
| + in_request->code, |
| + in_request->codeCnt, |
| + &in_request_1->flavor, |
| + in_request_1->old_state, |
| + in_request_1->old_stateCnt, |
| + out_reply->new_state, |
| + &out_reply->new_stateCnt, |
| + destroy_complex_request); |
| + if (out_reply->RetCode != KERN_SUCCESS) { |
| + return true; |
| + } |
| + |
| + out_reply->flavor = in_request_1->flavor; |
| + out_header->msgh_size = |
| + sizeof(*out_reply) - sizeof(out_reply->new_state) + |
| + sizeof(out_reply->new_state[0]) * out_reply->new_stateCnt; |
| + return true; |
| + } |
| + } |
| + |
| + SetReplyError(out_header, MIG_BAD_ID); |
| + return false; |
| +} |
| + |
| +mach_msg_size_t MachExcServer::MachMessageServerRequestSize() { |
| + return sizeof(__RequestUnion__mach_exc_subsystem); |
| +} |
| + |
| +mach_msg_size_t MachExcServer::MachMessageServerReplySize() { |
| + return sizeof(__ReplyUnion__mach_exc_subsystem); |
| +} |
| + |
| +SimplifiedExcServer::SimplifiedExcServer( |
| + SimplifiedExcServer::Interface* interface) |
| + : ExcServer(this), |
| + ExcServer::Interface(), |
| + interface_(interface) { |
| +} |
| + |
| +kern_return_t SimplifiedExcServer::CatchExceptionRaise( |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + const exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + bool* destroy_request) { |
| + thread_state_flavor_t flavor = THREAD_STATE_NONE; |
| + mach_msg_type_number_t new_state_count = 0; |
| + return interface_->CatchException(EXCEPTION_DEFAULT, |
| + exception_port, |
| + thread, |
| + task, |
| + exception, |
| + code, |
| + code_count, |
| + &flavor, |
| + NULL, |
| + 0, |
| + NULL, |
| + &new_state_count, |
| + destroy_request); |
| +} |
| + |
| +kern_return_t SimplifiedExcServer::CatchExceptionRaiseState( |
| + exception_handler_t exception_port, |
| + exception_type_t exception, |
| + const exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + const natural_t* old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count) { |
| + bool destroy_complex_request = false; |
| + return interface_->CatchException(EXCEPTION_STATE, |
| + exception_port, |
| + MACH_PORT_NULL, |
| + MACH_PORT_NULL, |
| + exception, |
| + code, |
| + code_count, |
| + flavor, |
| + old_state, |
| + old_state_count, |
| + new_state, |
| + new_state_count, |
| + &destroy_complex_request); |
| +} |
| + |
| +kern_return_t SimplifiedExcServer::CatchExceptionRaiseStateIdentity( |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + const exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + const natural_t* old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count, |
| + bool* destroy_request) { |
| + return interface_->CatchException(EXCEPTION_STATE_IDENTITY, |
| + exception_port, |
| + thread, |
| + task, |
| + exception, |
| + code, |
| + code_count, |
| + flavor, |
| + old_state, |
| + old_state_count, |
| + new_state, |
| + new_state_count, |
| + destroy_request); |
| +} |
| + |
| +SimplifiedMachExcServer::SimplifiedMachExcServer( |
| + SimplifiedMachExcServer::Interface* interface) |
| + : MachExcServer(this), |
| + MachExcServer::Interface(), |
| + interface_(interface) { |
| +} |
| + |
| +kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaise( |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + const mach_exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + bool* destroy_request) { |
| + thread_state_flavor_t flavor = THREAD_STATE_NONE; |
| + mach_msg_type_number_t new_state_count = 0; |
| + return interface_->CatchMachException( |
| + EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, |
| + exception_port, |
| + thread, |
| + task, |
| + exception, |
| + code, |
| + code_count, |
| + &flavor, |
| + NULL, |
| + 0, |
| + NULL, |
| + &new_state_count, |
| + destroy_request); |
| +} |
| + |
| +kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseState( |
| + exception_handler_t exception_port, |
| + exception_type_t exception, |
| + const mach_exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + const natural_t* old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count) { |
| + bool destroy_complex_request = false; |
| + return interface_->CatchMachException(EXCEPTION_STATE | MACH_EXCEPTION_CODES, |
| + exception_port, |
| + MACH_PORT_NULL, |
| + MACH_PORT_NULL, |
| + exception, |
| + code, |
| + code_count, |
| + flavor, |
| + old_state, |
| + old_state_count, |
| + new_state, |
| + new_state_count, |
| + &destroy_complex_request); |
| +} |
| + |
| +kern_return_t SimplifiedMachExcServer::CatchMachExceptionRaiseStateIdentity( |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + const mach_exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + const natural_t* old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count, |
| + bool* destroy_request) { |
| + return interface_->CatchMachException( |
| + EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, |
| + exception_port, |
| + thread, |
| + task, |
| + exception, |
| + code, |
| + code_count, |
| + flavor, |
| + old_state, |
| + old_state_count, |
| + new_state, |
| + new_state_count, |
| + destroy_request); |
| +} |
| + |
| +UniversalMachExcServer::UniversalMachExcServer() |
| + : MachMessageServer::Interface(), |
| + SimplifiedExcServer::Interface(), |
| + SimplifiedMachExcServer::Interface(), |
| + exc_server_(this), |
| + mach_exc_server_(this) { |
| +} |
| + |
| +bool UniversalMachExcServer::MachMessageServerFunction( |
| + mach_msg_header_t* in_header, |
| + mach_msg_header_t* out_header, |
| + bool* destroy_complex_request) { |
| + switch (in_header->msgh_id) { |
| + case kMachMessageIDMachExceptionRaise: |
| + case kMachMessageIDMachExceptionRaiseState: |
| + case kMachMessageIDMachExceptionRaiseStateIdentity: |
| + return mach_exc_server_.MachMessageServerFunction( |
| + in_header, out_header, destroy_complex_request); |
| + case kMachMessageIDExceptionRaise: |
| + case kMachMessageIDExceptionRaiseState: |
| + case kMachMessageIDExceptionRaiseStateIdentity: |
| + return exc_server_.MachMessageServerFunction( |
| + in_header, out_header, destroy_complex_request); |
| + } |
| + |
| + // Do what the MIG-generated server routines do when they can’t dispatch a |
| + // message. |
| + PrepareReplyFromRequest(in_header, out_header); |
| + SetReplyError(out_header, MIG_BAD_ID); |
| + return false; |
| +} |
| + |
| +mach_msg_size_t UniversalMachExcServer::MachMessageServerRequestSize() { |
| + return std::max(mach_exc_server_.MachMessageServerRequestSize(), |
| + exc_server_.MachMessageServerRequestSize()); |
| +} |
| + |
| +mach_msg_size_t UniversalMachExcServer::MachMessageServerReplySize() { |
| + return std::max(mach_exc_server_.MachMessageServerReplySize(), |
| + exc_server_.MachMessageServerReplySize()); |
| +} |
| + |
| +kern_return_t UniversalMachExcServer::CatchException( |
| + exception_behavior_t behavior, |
| + exception_handler_t exception_port, |
| + thread_t thread, |
| + task_t task, |
| + exception_type_t exception, |
| + const exception_data_type_t* code, |
| + mach_msg_type_number_t code_count, |
| + thread_state_flavor_t* flavor, |
| + const natural_t* old_state, |
| + mach_msg_type_number_t old_state_count, |
| + thread_state_t new_state, |
| + mach_msg_type_number_t* new_state_count, |
| + bool* destroy_complex_request) { |
| + std::vector<mach_exception_data_type_t> mach_codes; |
|
Robert Sesek
2014/09/10 16:44:41
Reserve code_count space?
|
| + for (size_t index = 0; index < code_count; ++index) { |
| + mach_codes.push_back(code[index]); |
| + } |
| + |
| + return CatchMachException(behavior, |
| + exception_port, |
| + thread, |
| + task, |
| + exception, |
| + code_count ? &mach_codes[0] : NULL, |
| + code_count, |
| + flavor, |
| + old_state, |
| + old_state_count, |
| + new_state, |
| + new_state_count, |
| + destroy_complex_request); |
| +} |
| + |
| +} // namespace crashpad |