summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/client/ios/handler
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /toolkit/crashreporter/google-breakpad/src/client/ios/handler
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-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')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.h74
-rw-r--r--toolkit/crashreporter/google-breakpad/src/client/ios/handler/ios_exception_minidump_generator.mm210
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