diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /toolkit/crashreporter/google-breakpad/src/client/ios/handler | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/client/ios/handler')
2 files changed, 284 insertions, 0 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h b/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h new file mode 100644 index 000000000..21133e632 --- /dev/null +++ b/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h @@ -0,0 +1,74 @@ +// 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. + +// ios_exception_minidump_generator.h: Create a fake minidump from a +// NSException. + +#ifndef CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_ +#define CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_ + +#include <Foundation/Foundation.h> + +#include "client/mac/handler/minidump_generator.h" + +namespace google_breakpad { + +class IosExceptionMinidumpGenerator : public MinidumpGenerator { + public: + explicit IosExceptionMinidumpGenerator(NSException *exception); + virtual ~IosExceptionMinidumpGenerator(); + + protected: + virtual bool WriteExceptionStream(MDRawDirectory *exception_stream); + virtual bool WriteThreadStream(mach_port_t thread_id, MDRawThread *thread); + + private: + + // Get the crashing program counter from the exception. + uintptr_t GetPCFromException(); + + // Get the crashing link register from the exception. + uintptr_t GetLRFromException(); + + // Write a virtual thread context for the crashing site. + bool WriteCrashingContext(MDLocationDescriptor *register_location); + // Per-CPU implementations of the above method. +#ifdef HAS_ARM_SUPPORT + bool WriteCrashingContextARM(MDLocationDescriptor *register_location); +#endif +#ifdef HAS_ARM64_SUPPORT + bool WriteCrashingContextARM64(MDLocationDescriptor *register_location); +#endif + + NSArray *return_addresses_; +}; + +} // namespace google_breakpad + +#endif // CLIENT_IOS_HANDLER_IOS_EXCEPTION_MINIDUMP_GENERATOR_H_ 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 new file mode 100644 index 000000000..82ea5bb5d --- /dev/null +++ b/toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm @@ -0,0 +1,210 @@ +// 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 |