mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
[ios] Bring up first draft exceptions snapshot.
Gather most of the necessary information for the exceptions snapshot. Note that: - The 'capture' portion of this CL will be moved out of the snapshot interface and into a separate in-process dump to disk location. - All of the pointer dereferences need to be wrapped in vm_read. - The read-fast-and-dump logic in thread_snapshot may end up in a different file completely, but until we pick a serialization/deserialization method, keep it as-is. Bug: crashpad:31 Change-Id: Iae4af436cddabd2302689b76c8a4574eb8e48c0e Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2098744 Commit-Queue: Justin Cohen <justincohen@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
d9c1ca1216
commit
faae6470cf
@ -45,6 +45,8 @@ class SignalHandler {
|
|||||||
// TODO(justincohen): This is incomplete.
|
// TODO(justincohen): This is incomplete.
|
||||||
ProcessSnapshotIOS process_snapshot;
|
ProcessSnapshotIOS process_snapshot;
|
||||||
process_snapshot.Initialize(system_data);
|
process_snapshot.Initialize(system_data);
|
||||||
|
process_snapshot.SetException(siginfo,
|
||||||
|
reinterpret_cast<ucontext_t*>(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -88,7 +90,6 @@ bool CrashpadClient::StartCrashpadInProcessHandler() {
|
|||||||
// static
|
// static
|
||||||
void CrashpadClient::DumpWithoutCrash() {
|
void CrashpadClient::DumpWithoutCrash() {
|
||||||
DCHECK(SignalHandler::Get());
|
DCHECK(SignalHandler::Get());
|
||||||
|
|
||||||
siginfo_t siginfo = {};
|
siginfo_t siginfo = {};
|
||||||
SignalHandler::Get()->HandleCrash(siginfo.si_signo, &siginfo, nullptr);
|
SignalHandler::Get()->HandleCrash(siginfo.si_signo, &siginfo, nullptr);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,8 @@ static_library("snapshot") {
|
|||||||
|
|
||||||
if (crashpad_is_ios) {
|
if (crashpad_is_ios) {
|
||||||
sources += [
|
sources += [
|
||||||
|
"ios/exception_snapshot_ios.cc",
|
||||||
|
"ios/exception_snapshot_ios.h",
|
||||||
"ios/memory_snapshot_ios.cc",
|
"ios/memory_snapshot_ios.cc",
|
||||||
"ios/memory_snapshot_ios.h",
|
"ios/memory_snapshot_ios.h",
|
||||||
"ios/module_snapshot_ios.cc",
|
"ios/module_snapshot_ios.cc",
|
||||||
|
122
snapshot/ios/exception_snapshot_ios.cc
Normal file
122
snapshot/ios/exception_snapshot_ios.cc
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
// Copyright 2020 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 "snapshot/ios/exception_snapshot_ios.h"
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "base/mac/mach_logging.h"
|
||||||
|
#include "base/strings/stringprintf.h"
|
||||||
|
#include "snapshot/cpu_context.h"
|
||||||
|
#include "snapshot/mac/cpu_context_mac.h"
|
||||||
|
#include "util/misc/from_pointer_cast.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
ExceptionSnapshotIOS::ExceptionSnapshotIOS()
|
||||||
|
: ExceptionSnapshot(),
|
||||||
|
context_(),
|
||||||
|
codes_(),
|
||||||
|
thread_id_(0),
|
||||||
|
exception_address_(0),
|
||||||
|
signal_number_(0),
|
||||||
|
signal_code_(0),
|
||||||
|
initialized_() {}
|
||||||
|
|
||||||
|
ExceptionSnapshotIOS::~ExceptionSnapshotIOS() {}
|
||||||
|
|
||||||
|
bool ExceptionSnapshotIOS::Initialize(const siginfo_t* siginfo,
|
||||||
|
const ucontext_t* context) {
|
||||||
|
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
||||||
|
|
||||||
|
if (!context)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mcontext_t mcontext = context->uc_mcontext;
|
||||||
|
#if defined(ARCH_CPU_X86_64)
|
||||||
|
context_.architecture = kCPUArchitectureX86_64;
|
||||||
|
context_.x86_64 = &context_x86_64_;
|
||||||
|
x86_debug_state64_t empty_debug_state;
|
||||||
|
InitializeCPUContextX86_64(&context_x86_64_,
|
||||||
|
THREAD_STATE_NONE,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
&mcontext->__ss,
|
||||||
|
&mcontext->__fs,
|
||||||
|
&empty_debug_state);
|
||||||
|
#elif defined(ARCH_CPU_ARM64)
|
||||||
|
context_.architecture = kCPUArchitectureARM64;
|
||||||
|
context_.arm64 = &context_arm64_;
|
||||||
|
InitializeCPUContextARM64(&context_arm64_, &mcontext->__ss, &mcontext->__ns);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Thread ID.
|
||||||
|
thread_identifier_info identifier_info;
|
||||||
|
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
|
||||||
|
kern_return_t kr =
|
||||||
|
thread_info(mach_thread_self(),
|
||||||
|
THREAD_IDENTIFIER_INFO,
|
||||||
|
reinterpret_cast<thread_info_t>(&identifier_info),
|
||||||
|
&count);
|
||||||
|
if (kr != KERN_SUCCESS) {
|
||||||
|
MACH_LOG(ERROR, kr) << "thread_identifier_info";
|
||||||
|
} else {
|
||||||
|
thread_id_ = identifier_info.thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_number_ = siginfo->si_signo;
|
||||||
|
signal_code_ = siginfo->si_code;
|
||||||
|
exception_address_ = FromPointerCast<uintptr_t>(siginfo->si_addr);
|
||||||
|
|
||||||
|
INITIALIZATION_STATE_SET_VALID(initialized_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CPUContext* ExceptionSnapshotIOS::Context() const {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
return &context_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ExceptionSnapshotIOS::ThreadID() const {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
return thread_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ExceptionSnapshotIOS::Exception() const {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
return signal_number_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ExceptionSnapshotIOS::ExceptionInfo() const {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
return signal_code_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ExceptionSnapshotIOS::ExceptionAddress() const {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
return exception_address_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<uint64_t>& ExceptionSnapshotIOS::Codes() const {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
return codes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const MemorySnapshot*> ExceptionSnapshotIOS::ExtraMemory() const {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
return std::vector<const MemorySnapshot*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace crashpad
|
79
snapshot/ios/exception_snapshot_ios.h
Normal file
79
snapshot/ios/exception_snapshot_ios.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Copyright 2020 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.
|
||||||
|
|
||||||
|
#ifndef CRASHPAD_SNAPSHOT_IOS_EXCEPTION_SNAPSHOT_IOS_H_
|
||||||
|
#define CRASHPAD_SNAPSHOT_IOS_EXCEPTION_SNAPSHOT_IOS_H_
|
||||||
|
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/macros.h"
|
||||||
|
#include "build/build_config.h"
|
||||||
|
#include "snapshot/cpu_context.h"
|
||||||
|
#include "snapshot/exception_snapshot.h"
|
||||||
|
#include "util/mach/mach_extensions.h"
|
||||||
|
#include "util/misc/initialization_state_dcheck.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
//! \brief An ExceptionSnapshot of an exception sustained by a running (or
|
||||||
|
//! crashed) process on an iOS system.
|
||||||
|
class ExceptionSnapshotIOS final : public ExceptionSnapshot {
|
||||||
|
public:
|
||||||
|
ExceptionSnapshotIOS();
|
||||||
|
~ExceptionSnapshotIOS() override;
|
||||||
|
|
||||||
|
//! \brief Initializes the object.
|
||||||
|
//!
|
||||||
|
//! \return `true` if the snapshot could be created, `false` otherwise with
|
||||||
|
//! an appropriate message logged.
|
||||||
|
bool Initialize(const siginfo_t* siginfo, const ucontext_t* context);
|
||||||
|
|
||||||
|
// ExceptionSnapshot:
|
||||||
|
|
||||||
|
const CPUContext* Context() const override;
|
||||||
|
uint64_t ThreadID() const override;
|
||||||
|
uint32_t Exception() const override;
|
||||||
|
uint32_t ExceptionInfo() const override;
|
||||||
|
uint64_t ExceptionAddress() const override;
|
||||||
|
const std::vector<uint64_t>& Codes() const override;
|
||||||
|
virtual std::vector<const MemorySnapshot*> ExtraMemory() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if defined(ARCH_CPU_X86_64)
|
||||||
|
CPUContextX86_64 context_x86_64_;
|
||||||
|
#elif defined(ARCH_CPU_ARM64)
|
||||||
|
CPUContextARM64 context_arm64_;
|
||||||
|
#else
|
||||||
|
#error Port.
|
||||||
|
#endif // ARCH_CPU_X86_64
|
||||||
|
CPUContext context_;
|
||||||
|
std::vector<uint64_t> codes_;
|
||||||
|
uint64_t thread_id_;
|
||||||
|
uintptr_t exception_address_;
|
||||||
|
int signal_number_;
|
||||||
|
int signal_code_;
|
||||||
|
InitializationStateDcheck initialized_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ExceptionSnapshotIOS);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace crashpad
|
||||||
|
|
||||||
|
#endif // CRASHPAD_SNAPSHOT_IOS_EXCEPTION_SNAPSHOT_IOS_H_
|
@ -42,6 +42,7 @@ ProcessSnapshotIOS::ProcessSnapshotIOS()
|
|||||||
system_(),
|
system_(),
|
||||||
threads_(),
|
threads_(),
|
||||||
modules_(),
|
modules_(),
|
||||||
|
exception_(),
|
||||||
report_id_(),
|
report_id_(),
|
||||||
client_id_(),
|
client_id_(),
|
||||||
annotations_simple_map_(),
|
annotations_simple_map_(),
|
||||||
@ -101,6 +102,15 @@ bool ProcessSnapshotIOS::Initialize(const IOSSystemDataCollector& system_data) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProcessSnapshotIOS::SetException(const siginfo_t* siginfo,
|
||||||
|
const ucontext_t* context) {
|
||||||
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
|
exception_.reset(new internal::ExceptionSnapshotIOS());
|
||||||
|
if (!exception_->Initialize(siginfo, context)) {
|
||||||
|
exception_.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pid_t ProcessSnapshotIOS::ProcessID() const {
|
pid_t ProcessSnapshotIOS::ProcessID() const {
|
||||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
return kern_proc_info_.kp_proc.p_pid;
|
return kern_proc_info_.kp_proc.p_pid;
|
||||||
@ -189,7 +199,7 @@ std::vector<UnloadedModuleSnapshot> ProcessSnapshotIOS::UnloadedModules()
|
|||||||
|
|
||||||
const ExceptionSnapshot* ProcessSnapshotIOS::Exception() const {
|
const ExceptionSnapshot* ProcessSnapshotIOS::Exception() const {
|
||||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
return nullptr;
|
return exception_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotIOS::MemoryMap()
|
std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotIOS::MemoryMap()
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "snapshot/ios/exception_snapshot_ios.h"
|
||||||
#include "snapshot/ios/module_snapshot_ios.h"
|
#include "snapshot/ios/module_snapshot_ios.h"
|
||||||
#include "snapshot/ios/system_snapshot_ios.h"
|
#include "snapshot/ios/system_snapshot_ios.h"
|
||||||
#include "snapshot/ios/thread_snapshot_ios.h"
|
#include "snapshot/ios/thread_snapshot_ios.h"
|
||||||
@ -43,6 +44,7 @@ class ProcessSnapshotIOS final : public ProcessSnapshot {
|
|||||||
//! an appropriate message logged.
|
//! an appropriate message logged.
|
||||||
bool Initialize(const IOSSystemDataCollector& system_data);
|
bool Initialize(const IOSSystemDataCollector& system_data);
|
||||||
|
|
||||||
|
void SetException(const siginfo_t* siginfo, const ucontext_t* context);
|
||||||
//! \brief Sets the value to be returned by ClientID().
|
//! \brief Sets the value to be returned by ClientID().
|
||||||
//!
|
//!
|
||||||
//! On iOS, the client ID is under the control of the snapshot producer,
|
//! On iOS, the client ID is under the control of the snapshot producer,
|
||||||
@ -92,6 +94,7 @@ class ProcessSnapshotIOS final : public ProcessSnapshot {
|
|||||||
internal::SystemSnapshotIOS system_;
|
internal::SystemSnapshotIOS system_;
|
||||||
std::vector<std::unique_ptr<internal::ThreadSnapshotIOS>> threads_;
|
std::vector<std::unique_ptr<internal::ThreadSnapshotIOS>> threads_;
|
||||||
std::vector<std::unique_ptr<internal::ModuleSnapshotIOS>> modules_;
|
std::vector<std::unique_ptr<internal::ModuleSnapshotIOS>> modules_;
|
||||||
|
std::unique_ptr<internal::ExceptionSnapshotIOS> exception_;
|
||||||
UUID report_id_;
|
UUID report_id_;
|
||||||
UUID client_id_;
|
UUID client_id_;
|
||||||
std::map<std::string, std::string> annotations_simple_map_;
|
std::map<std::string, std::string> annotations_simple_map_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user