diff options
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm')
-rw-r--r-- | toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm | 210 |
1 files changed, 0 insertions, 210 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm b/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm deleted file mode 100644 index 82ea5bb5d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (c) 2012, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "client/ios/handler/ios_exception_minidump_generator.h" - -#include <pthread.h> - -#include "google_breakpad/common/minidump_cpu_arm.h" -#include "google_breakpad/common/minidump_cpu_arm64.h" -#include "google_breakpad/common/minidump_exception_mac.h" -#include "client/minidump_file_writer-inl.h" -#include "common/scoped_ptr.h" - -#if defined(HAS_ARM_SUPPORT) && defined(HAS_ARM64_SUPPORT) -#error "This file should be compiled for only one architecture at a time" -#endif - -namespace { - -const int kExceptionType = EXC_SOFTWARE; -const int kExceptionCode = MD_EXCEPTION_CODE_MAC_NS_EXCEPTION; - -#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) -const uintptr_t kExpectedFinalFp = sizeof(uintptr_t); -const uintptr_t kExpectedFinalSp = 0; - -// Append the given value to the sp position of the stack represented -// by memory. -void AppendToMemory(uint8_t *memory, uintptr_t sp, uintptr_t data) { - memcpy(memory + sp, &data, sizeof(data)); -} -#endif - -} // namespace - -namespace google_breakpad { - -IosExceptionMinidumpGenerator::IosExceptionMinidumpGenerator( - NSException *exception) - : MinidumpGenerator(mach_task_self(), 0) { - return_addresses_ = [[exception callStackReturnAddresses] retain]; - SetExceptionInformation(kExceptionType, - kExceptionCode, - 0, - pthread_mach_thread_np(pthread_self())); -} - -IosExceptionMinidumpGenerator::~IosExceptionMinidumpGenerator() { - [return_addresses_ release]; -} - -bool IosExceptionMinidumpGenerator::WriteCrashingContext( - MDLocationDescriptor *register_location) { -#ifdef HAS_ARM_SUPPORT - return WriteCrashingContextARM(register_location); -#elif defined(HAS_ARM64_SUPPORT) - return WriteCrashingContextARM64(register_location); -#else - assert(false); - return false; -#endif -} - -#ifdef HAS_ARM_SUPPORT -bool IosExceptionMinidumpGenerator::WriteCrashingContextARM( - MDLocationDescriptor *register_location) { - TypedMDRVA<MDRawContextARM> context(&writer_); - if (!context.Allocate()) - return false; - *register_location = context.location(); - MDRawContextARM *context_ptr = context.get(); - memset(context_ptr, 0, sizeof(MDRawContextARM)); - context_ptr->context_flags = MD_CONTEXT_ARM_FULL; - context_ptr->iregs[MD_CONTEXT_ARM_REG_IOS_FP] = kExpectedFinalFp; // FP - context_ptr->iregs[MD_CONTEXT_ARM_REG_SP] = kExpectedFinalSp; // SP - context_ptr->iregs[MD_CONTEXT_ARM_REG_LR] = GetLRFromException(); // LR - context_ptr->iregs[MD_CONTEXT_ARM_REG_PC] = GetPCFromException(); // PC - return true; -} -#endif - -#ifdef HAS_ARM64_SUPPORT -bool IosExceptionMinidumpGenerator::WriteCrashingContextARM64( - MDLocationDescriptor *register_location) { - TypedMDRVA<MDRawContextARM64> context(&writer_); - if (!context.Allocate()) - return false; - *register_location = context.location(); - MDRawContextARM64 *context_ptr = context.get(); - memset(context_ptr, 0, sizeof(*context_ptr)); - context_ptr->context_flags = MD_CONTEXT_ARM64_FULL; - context_ptr->iregs[MD_CONTEXT_ARM64_REG_FP] = kExpectedFinalFp; // FP - context_ptr->iregs[MD_CONTEXT_ARM64_REG_SP] = kExpectedFinalSp; // SP - context_ptr->iregs[MD_CONTEXT_ARM64_REG_LR] = GetLRFromException(); // LR - context_ptr->iregs[MD_CONTEXT_ARM64_REG_PC] = GetPCFromException(); // PC - return true; -} -#endif - -uintptr_t IosExceptionMinidumpGenerator::GetPCFromException() { - return [[return_addresses_ objectAtIndex:0] unsignedIntegerValue]; -} - -uintptr_t IosExceptionMinidumpGenerator::GetLRFromException() { - return [[return_addresses_ objectAtIndex:1] unsignedIntegerValue]; -} - -bool IosExceptionMinidumpGenerator::WriteExceptionStream( - MDRawDirectory *exception_stream) { -#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) - TypedMDRVA<MDRawExceptionStream> exception(&writer_); - - if (!exception.Allocate()) - return false; - - exception_stream->stream_type = MD_EXCEPTION_STREAM; - exception_stream->location = exception.location(); - MDRawExceptionStream *exception_ptr = exception.get(); - exception_ptr->thread_id = pthread_mach_thread_np(pthread_self()); - - // This naming is confusing, but it is the proper translation from - // mach naming to minidump naming. - exception_ptr->exception_record.exception_code = kExceptionType; - exception_ptr->exception_record.exception_flags = kExceptionCode; - - if (!WriteCrashingContext(&exception_ptr->thread_context)) - return false; - - exception_ptr->exception_record.exception_address = GetPCFromException(); - return true; -#else - return MinidumpGenerator::WriteExceptionStream(exception_stream); -#endif -} - -bool IosExceptionMinidumpGenerator::WriteThreadStream(mach_port_t thread_id, - MDRawThread *thread) { -#if defined(HAS_ARM_SUPPORT) || defined(HAS_ARM64_SUPPORT) - if (pthread_mach_thread_np(pthread_self()) != thread_id) - return MinidumpGenerator::WriteThreadStream(thread_id, thread); - - size_t frame_count = [return_addresses_ count]; - if (frame_count == 0) - return false; - UntypedMDRVA memory(&writer_); - size_t pointer_size = sizeof(uintptr_t); - size_t frame_record_size = 2 * pointer_size; - size_t stack_size = frame_record_size * (frame_count - 1) + pointer_size; - if (!memory.Allocate(stack_size)) - return false; - scoped_array<uint8_t> stack_memory(new uint8_t[stack_size]); - uintptr_t sp = stack_size - pointer_size; - uintptr_t fp = 0; - uintptr_t lr = 0; - for (size_t current_frame = frame_count - 1; - current_frame > 0; - --current_frame) { - AppendToMemory(stack_memory.get(), sp, lr); - sp -= pointer_size; - AppendToMemory(stack_memory.get(), sp, fp); - fp = sp; - sp -= pointer_size; - lr = [[return_addresses_ objectAtIndex:current_frame] unsignedIntegerValue]; - } - if (!memory.Copy(stack_memory.get(), stack_size)) - return false; - assert(sp == kExpectedFinalSp); - assert(fp == kExpectedFinalFp); - assert(lr == GetLRFromException()); - thread->stack.start_of_memory_range = sp; - thread->stack.memory = memory.location(); - memory_blocks_.push_back(thread->stack); - - if (!WriteCrashingContext(&thread->thread_context)) - return false; - - thread->thread_id = thread_id; - return true; -#else - return MinidumpGenerator::WriteThreadStream(thread_id, thread); -#endif -} - -} // namespace google_breakpad |