Add the Snapshot interface.

These are all of the abstract base classes used in the Snapshot series,
discussed in the thread at
https://groups.google.com/a/chromium.org/d/topic/crashpad-dev/4pACgjhIz-I.

R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/597673004
This commit is contained in:
Mark Mentovai 2014-10-02 17:09:37 -04:00
parent ae7ad05090
commit 7b2e7efcc2
11 changed files with 1060 additions and 0 deletions

View File

@ -22,6 +22,7 @@
'client/client.gyp:*',
'compat/compat.gyp:*',
'minidump/minidump.gyp:*',
'snapshot/snapshot.gyp:*',
'tools/tools.gyp:*',
'util/util.gyp:*',
],

View File

@ -0,0 +1,39 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_SNAPSHOT_CPU_ARCHITECTURE_H_
#define CRASHPAD_SNAPSHOT_SNAPSHOT_CPU_ARCHITECTURE_H_
namespace crashpad {
//! \brief A systems CPU architecture.
//!
//! This can be used to represent the CPU architecture of an entire system
//! as in SystemSnapshot::CPUArchitecture(). It can also be used to represent
//! the architecture of a CPUContext structure in its CPUContext::architecture
//! field without reference to external data.
enum CPUArchitecture {
//! \brief The CPU architecture is unknown.
kCPUArchitectureUnknown = 0,
//! \brief 32-bit x86.
kCPUArchitectureX86,
//! \brief x86_64.
kCPUArchitectureX86_64,
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_SNAPSHOT_CPU_ARCHITECTURE_H_

33
snapshot/cpu_context.cc Normal file
View File

@ -0,0 +1,33 @@
// 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 "snapshot/cpu_context.h"
#include "base/logging.h"
namespace crashpad {
uint64_t CPUContext::InstructionPointer() const {
switch (architecture) {
case kCPUArchitectureX86:
return x86->eip;
case kCPUArchitectureX86_64:
return x86_64->rip;
default:
NOTREACHED();
return -1;
}
}
} // namespace crashpad

173
snapshot/cpu_context.h Normal file
View File

@ -0,0 +1,173 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_SNAPSHOT_CPU_CONTEXT_H_
#define CRASHPAD_SNAPSHOT_SNAPSHOT_CPU_CONTEXT_H_
#include <stdint.h>
#include "snapshot/cpu_architecture.h"
namespace crashpad {
//! \brief A context structure carrying 32-bit x86 CPU state.
struct CPUContextX86 {
typedef uint8_t X87Register[10];
union X87OrMMXRegister {
struct {
X87Register st;
uint8_t st_reserved[6];
};
struct {
uint8_t mm_value[8];
uint8_t mm_reserved[8];
};
};
typedef uint8_t XMMRegister[16];
struct Fxsave {
uint16_t fcw; // FPU control word
uint16_t fsw; // FPU status word
uint8_t ftw; // abridged FPU tag word
uint8_t reserved_1;
uint16_t fop; // FPU opcode
uint32_t fpu_ip; // FPU instruction pointer offset
uint16_t fpu_cs; // FPU instruction pointer segment selector
uint16_t reserved_2;
uint32_t fpu_dp; // FPU data pointer offset
uint16_t fpu_ds; // FPU data pointer segment selector
uint16_t reserved_3;
uint32_t mxcsr; // multimedia extensions status and control register
uint32_t mxcsr_mask; // valid bits in mxcsr
X87OrMMXRegister st_mm[8];
XMMRegister xmm[8];
uint8_t reserved_4[176];
uint8_t available[48];
};
// Integer registers.
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
uint32_t edi; // destination index
uint32_t esi; // source index
uint32_t ebp; // base pointer
uint32_t esp; // stack pointer
uint32_t eip; // instruction pointer
uint32_t eflags;
uint16_t cs; // code segment selector
uint16_t ds; // data segment selector
uint16_t es; // extra segment selector
uint16_t fs;
uint16_t gs;
uint16_t ss; // stack segment selector
// Floating-point and vector registers.
Fxsave fxsave;
// Debug registers.
uint32_t dr0;
uint32_t dr1;
uint32_t dr2;
uint32_t dr3;
uint32_t dr4; // obsolete, normally an alias for dr6
uint32_t dr5; // obsolete, normally an alias for dr7
uint32_t dr6;
uint32_t dr7;
};
//! \brief A context structure carrying x86_64 CPU state.
struct CPUContextX86_64 {
typedef CPUContextX86::X87Register X87Register;
typedef CPUContextX86::X87OrMMXRegister X87OrMMXRegister;
typedef CPUContextX86::XMMRegister XMMRegister;
struct Fxsave64 {
uint16_t fcw; // FPU control word
uint16_t fsw; // FPU status word
uint8_t ftw; // abridged FPU tag word
uint8_t reserved_1;
uint16_t fop; // FPU opcode
uint64_t fpu_ip; // FPU instruction pointer
uint64_t fpu_dp; // FPU data pointer
uint32_t mxcsr; // multimedia extensions status and control register
uint32_t mxcsr_mask; // valid bits in mxcsr
X87OrMMXRegister st_mm[8];
XMMRegister xmm[16];
uint8_t reserved_2[48];
uint8_t available[48];
};
// Integer registers.
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
uint64_t rdi; // destination index
uint64_t rsi; // source index
uint64_t rbp; // base pointer
uint64_t rsp; // stack pointer
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rip; // instruction pointer
uint64_t rflags;
uint16_t cs; // code segment selector
uint16_t fs;
uint16_t gs;
// Floating-point and vector registers.
Fxsave64 fxsave64;
// Debug registers.
uint64_t dr0;
uint64_t dr1;
uint64_t dr2;
uint64_t dr3;
uint64_t dr4; // obsolete, normally an alias for dr6
uint64_t dr5; // obsolete, normally an alias for dr7
uint64_t dr6;
uint64_t dr7;
};
//! \brief A context structure capable of carrying the context of any supported
//! CPU architecture.
struct CPUContext {
//! \brief Returns the instruction pointer value from the context structure.
//!
//! This is a CPU architecture-independent method that is capable of
//! recovering the instruction pointer from any supported CPU architectures
//! context structure.
uint64_t InstructionPointer() const;
//! \brief The CPU architecture of a context structure. This field controls
//! the expression of the union.
CPUArchitecture architecture;
union {
CPUContextX86* x86;
CPUContextX86_64* x86_64;
};
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_SNAPSHOT_CPU_CONTEXT_H_

View File

@ -0,0 +1,96 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_EXCEPTION_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_EXCEPTION_SNAPSHOT_H_
#include <stdint.h>
#include <vector>
namespace crashpad {
struct CPUContext;
//! \brief An abstract interface to a snapshot representing an exception that a
//! snapshot process sustained and triggered the snapshot being taken.
class ExceptionSnapshot {
public:
//! \brief Returns a CPUContext object corresponding to the exception threads
//! CPU context at the time of the exception.
//!
//! The caller does not take ownership of this object, it is scoped to the
//! lifetime of the ThreadSnapshot object that it was obtained from.
virtual const CPUContext* Context() const = 0;
//! \brief Returns the thread identifier of the thread that triggered the
//! exception.
//!
//! This value can be compared to ThreadSnapshot::ThreadID() to associate an
//! ExceptionSnapshot object with the ThreadSnapshot that contains a snapshot
//! of the thread that triggered the exception.
virtual uint64_t ThreadID() const = 0;
//! \brief Returns the top-level exception code identifying the exception.
//!
//! This is an operating system-specific value.
//!
//! For Mac OS X, this will be an \ref EXC_x "EXC_*" exception type, such as
//! `EXC_BAD_ACCESS`. `EXC_CRASH` will not appear here for exceptions
//! processed as `EXC_CRASH` when generated from another preceding exception:
//! the original exception code will appear instead. The exception type as it
//! was received will appear at index 0 of Codes().
virtual uint32_t Exception() const = 0;
//! \brief Returns the second-level exception code identifying the exception.
//!
//! This is an operating system-specific value.
//!
//! For Mac OS X, this will be the value of the exception code at index 0 as
//! received by a Mach exception handler. For `EXC_CRASH` exceptions generated
//! from another preceding exception, the original exception code will appear
//! here, not the code as received by the Mach exception handler. The code as
//! it was received will appear at index 1 of Codes().
virtual uint32_t ExceptionInfo() const = 0;
//! \brief Returns the address that triggered the exception.
//!
//! This may be the address that caused a fault on data access, or it may be
//! the instruction pointer that contained an offending instruction. For
//! exceptions where this value cannot be determined, it will be `0`.
//!
//! For Mac OS X, this will be the value of the exception code at index 1 as
//! received by a Mach exception handler.
virtual uint64_t ExceptionAddress() const = 0;
//! \brief Returns a series of operating system-specific exception codes.
//!
//! The precise interpretation of these codes is specific to the snapshot
//! operating system. These codes may provide a duplicate of information
//! available elsewhere, they may extend information available elsewhere, or
//! they may not be present at all. In this case, an empty vector will be
//! returned.
//!
//! For Mac OS X, this will be a vector containing the original exception type
//! and the values of `code[0]` and `code[1]` as received by a Mach exception
//! handler.
virtual const std::vector<uint64_t>& Codes() const = 0;
protected:
~ExceptionSnapshot() {}
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_EXCEPTION_SNAPSHOT_H_

View File

@ -0,0 +1,78 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_
#include <stdint.h>
#include <sys/types.h>
namespace crashpad {
//! \brief An abstract interface to a snapshot representing a region of memory
//! present in a snapshot process.
class MemorySnapshot {
public:
//! \brief An interface that MemorySnapshot clients must implement in order to
//! receive memory snapshot data.
//!
//! This callback-based model frees MemorySnapshot implementations from having
//! to deal with memory region ownership problems. When a memory snapshots
//! data is read, it will be passed to a delegate method.
class Delegate {
public:
//! \brief Called by MemorySnapshot::Read() to provide data requested by a
//! call to that method.
//!
//! \param[in] data A pointer to the data that was read. The callee does not
//! take ownership of this data. This data is only valid for the
//! duration of the call to this method.
//! \param[in] size The size of the data that was read.
//!
//! \return `true` on success, `false` on failure. MemoryDelegate::Read()
//! will use this as its own return value.
virtual bool MemorySnapshotDelegateRead(void* data, size_t size) = 0;
protected:
~Delegate() {}
};
//! \brief The base address of the memory snapshot in the snapshot process
//! address space.
virtual uint64_t Address() const = 0;
//! \brief The size of the memory snapshot.
virtual size_t Size() const = 0;
//! \brief Calls Delegate::MemorySnapshotDelegateRead(), providing it with
//! the memory snapshots data.
//!
//! Implementations do not necessarily read the memory snapshot data prior to
//! this method being called. Memory snapshot data may be loaded lazily and
//! may be discarded after being passed to the delegate. This provides clean
//! memory management without burdening a snapshot implementation with the
//! requirement that it track all memory region data simultaneously.
//!
//! \return `false` on failure, otherwise, the return value of
//! Delegate::MemorySnapshotDelegateRead(), which should be `true` on
//! success and `false` on failure.
virtual bool Read(Delegate* delegate) const = 0;
protected:
~MemorySnapshot() {}
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_H_

149
snapshot/module_snapshot.h Normal file
View File

@ -0,0 +1,149 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_MODULE_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_MODULE_SNAPSHOT_H_
#include <stdint.h>
#include <sys/types.h>
#include <map>
#include <string>
#include <vector>
#include "util/misc/uuid.h"
namespace crashpad {
//! \brief An abstract interface to a snapshot representing a code module
//! (binary image) loaded into a snapshot process.
class ModuleSnapshot {
public:
//! \brief A modules type.
enum ModuleType {
//! \brief The modules type is unknown.
kModuleTypeUnknown = 0,
//! \brief The module is a main executable.
kModuleTypeExecutable,
//! \brief The module is a shared library.
//!
//! \sa kModuleTypeLoadableModule
kModuleTypeSharedLibrary,
//! \brief The module is a loadable module.
//!
//! On some platforms, loadable modules are distinguished from shared
//! libraries. On these platforms, a shared library is a module that another
//! module links against directly, and a loadable module is not. Loadable
//! modules tend to be binary plug-ins.
kModuleTypeLoadableModule,
//! \brief The module is a dynamic loader.
//!
//! This is the module responsible for loading other modules. This is
//! normally `dyld` for Mac OS X and `ld.so` for Linux and other systems
//! using ELF.
kModuleTypeDynamicLoader,
};
//! \brief Returns the modules pathname.
virtual std::string Name() const = 0;
//! \brief Returns the base address that the module is loaded at in the
//! snapshot process.
virtual uint64_t Address() const = 0;
//! \brief Returns the size that the module occupies in the snapshot process
//! address space, starting at its base address.
//!
//! For Mac OS X snapshots, this method only reports the size of the `__TEXT`
//! segment, because segments may not be loaded contiguously.
virtual uint64_t Size() const = 0;
//! \brief Returns the modules timestamp, if known.
//!
//! The timestamp is typically the modification time of the file that provided
//! the module in `time_t` format, seconds since the POSIX epoch. If the
//! modules timestamp is unknown, this method returns `0`.
virtual time_t Timestamp() const = 0;
//! \brief Returns the modules file version in the \a version_* parameters.
//!
//! If no file version can be determined, the \a version_* parameters are set
//! to `0`.
//!
//! For Mac OS X snapshots, this is taken from the modules `LC_ID_DYLIB` load
//! command for shared libraries, and is `0` for other module types.
virtual void FileVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const = 0;
//! \brief Returns the modules source version in the \a version_* parameters.
//!
//! If no source version can be determined, the \a version_* parameters are
//! set to `0`.
//!
//! For Mac OS X snapshots, this is taken from the modules
//! `LC_SOURCE_VERSION` load command.
virtual void SourceVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const = 0;
//! \brief Returns the modules type.
virtual ModuleType GetModuleType() const = 0;
//! \brief Returns the modules UUID in the \a uuid parameter.
//!
//! A snapshot modules UUID is taken directly from the module itself. If the
//! module does not have a UUID, the \a uuid parameter will be zeroed out.
virtual void UUID(crashpad::UUID* uuid) const = 0;
//! \brief Returns diagnostic messages recorded in the module.
//!
//! This method retrieves diagnostic messages recorded in a module. These
//! messages are intended for diagnostic use, including crash analysis. A
//! module may contain multiple diagnostic messages.
//!
//! For Mac OS X snapshots, the diagnostic messages are found by interpreting
//! the modules `__DATA, __crash_info` section as
//! `crashreporter_annotations_t`. System libraries using the crash reporter
//! client interface may reference diagnostic messages in this structure.
//! Additional diagnostic messages may be found in other locations, which may
//! be module-specific. The dynamic linker (`dyld`) can provide a diagnostic
//! message at its `_error_string` symbol.
virtual std::vector<std::string> DiagnosticMessages() const = 0;
//! \brief Returns simple annotations recorded in the module.
//!
//! This method retrieves simple annotations recorded in a module. These
//! annotations are intended for diagnostic use, including crash analysis.
//! Simple annotations are structured as a sequence of key-value pairs. These
//! are referred to in Chrome as “crash keys.”
//!
//! For Mac OS X snapshots, simple annotations are found by interpreting
//! the `__DATA, __crashpad_info` section as `CrashpadInfo`. Clients can use
//! the Crashpad client interface to store annotations in this structure.
virtual std::map<std::string, std::string> SimpleAnnotations() const = 0;
protected:
~ModuleSnapshot() {}
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_MODULE_SNAPSHOT_H_

116
snapshot/process_snapshot.h Normal file
View File

@ -0,0 +1,116 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_PROCESS_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_PROCESS_SNAPSHOT_H_
#include <sys/time.h>
#include <sys/types.h>
#include <vector>
namespace crashpad {
class ExceptionSnapshot;
class ModuleSnapshot;
class SystemSnapshot;
class ThreadSnapshot;
//! \brief An abstract interface to a snapshot representing the state of a
//! process.
//!
//! This is the top-level object in a family of Snapshot objects, because it
//! gives access to a SystemSnapshot, vectors of ModuleSnapshot and
//! ThreadSnapshot objects, and possibly an ExceptionSnapshot. In turn,
//! ThreadSnapshot and ExceptionSnapshot objects both give access to CPUContext
//! objects, and ThreadSnapshot objects also give access to MemorySnapshot
//! objects corresponding to thread stacks.
class ProcessSnapshot {
public:
//! \brief Returns the snapshot process process ID.
virtual pid_t ProcessID() const = 0;
//! \brief Returns the snapshot process parent process process ID.
virtual pid_t ParentProcessID() const = 0;
//! \brief Returns the time that the snapshot was taken in \a snapshot_time.
//!
//! \param[out] snapshot_time The time that the snapshot was taken. This is
//! distinct from the time that a ProcessSnapshot object was created or
//! initialized, although it may be that time for ProcessSnapshot objects
//! representing live or recently-crashed process state.
virtual void SnapshotTime(timeval* snapshot_time) const = 0;
//! \brief Returns the time that the snapshot process was started in \a
//! start_time.
//!
//! Normally, process uptime in wall clock time can be computed as
//! SnapshotTime() ProcessStartTime(), but this cannot be guaranteed in
//! cases where the real-time clock has been set during the snapshot process
//! lifetime.
//!
//! \param[out] start_time The time that the process was started.
virtual void ProcessStartTime(timeval* start_time) const = 0;
//! \brief Returns the snapshot process CPU usage times in \a user_time and
//! \a system_time.
//!
//! \param[out] user_time The time that the process has spent executing in
//! user mode.
//! \param[out] system_time The time that the process has spent executing in
//! system (kernel) mode.
virtual void ProcessCPUTimes(timeval* user_time,
timeval* system_time) const = 0;
//! \brief Returns a SystemSnapshot reflecting the characteristics of the
//! system that ran the snapshot process at the time of the snapshot.
//!
//! \return A SystemSnapshot object. The caller does not take ownership of
//! this object, it is scoped to the lifetime of the ProcessSnapshot
//! object that it was obtained from.
virtual const SystemSnapshot* System() const = 0;
//! \brief Returns ModuleSnapshot objects reflecting the code modules (binary
//! images) loaded into the snapshot process at the time of the snapshot.
//!
//! \return A vector of ModuleSnapshot objects. The caller does not take
//! ownership of these objects, they are scoped to the lifetime of the
//! ProcessSnapshot object that they were obtained from.
virtual std::vector<const ModuleSnapshot*> Modules() const = 0;
//! \brief Returns ThreadSnapshot objects reflecting the threads (lightweight
//! processes) existing in the snapshot process at the time of the
//! snapshot.
//!
//! \return A vector of ThreadSnapshot objects. The caller does not take
//! ownership of these objects, they are scoped to the lifetime of the
//! ProcessSnapshot object that they were obtained from.
virtual std::vector<const ThreadSnapshot*> Threads() const = 0;
//! \brief Returns an ExceptionSnapshot reflecting the exception that the
//! snapshot process sustained to trigger the snapshot being taken.
//!
//! \return An ExceptionSnapshot object. The caller does not take ownership of
//! this object, it is scoped to the lifetime of the ProcessSnapshot
//! object that it was obtained from. If the snapshot is not a result of
//! an exception, returns `NULL`.
virtual const ExceptionSnapshot* Exception() const = 0;
protected:
~ProcessSnapshot() {}
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_PROCESS_SNAPSHOT_H_

41
snapshot/snapshot.gyp Normal file
View File

@ -0,0 +1,41 @@
# 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.
{
'targets': [
{
'target_name': 'snapshot',
'type': 'static_library',
'dependencies': [
'../compat/compat.gyp:compat',
'../third_party/mini_chromium/mini_chromium/base/base.gyp:base',
'../util/util.gyp:util',
],
'include_dirs': [
'..',
],
'sources': [
'cpu_architecture.h',
'cpu_context.cc',
'cpu_context.h',
'exception_snapshot.h',
'memory_snapshot.h',
'module_snapshot.h',
'process_snapshot.h',
'system_snapshot.h',
'thread_snapshot.h',
],
},
],
}

265
snapshot/system_snapshot.h Normal file
View File

@ -0,0 +1,265 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_SYSTEM_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_SYSTEM_SNAPSHOT_H_
#include <stdint.h>
#include <sys/types.h>
#include <string>
#include "snapshot/cpu_architecture.h"
namespace crashpad {
//! \brief An abstract interface to a snapshot representing the state of a
//! system, comprising an operating system, CPU architecture, and various
//! other characteristics.
class SystemSnapshot {
public:
//! \brief A systems operating system family.
enum OperatingSystem {
//! \brief The snapshot systems operating system is unknown.
kOperatingSystemUnknown = 0,
//! \brief Mac OS X.
kOperatingSystemMacOSX,
};
//! \brief A systems daylight saving time status.
//!
//! The daylight saving time status is taken partially from the systems
//! locale configuration. This determines whether daylight saving time is
//! ever observed on the system. If it is, the snapshots time
//! (ProcessSnapshot::SnapshotTime()) is used to determine whether the system
//! was observing daylight saving time at the time of the snapshot.
enum DaylightSavingTimeStatus {
//! \brief Daylight saving time is never observed on the snapshot system.
kDoesNotObserveDaylightSavingTime = 0,
//! \brief Daylight saving time is observed on the snapshot system when in
//! effect, but standard time was in effect at the time of the snapshot.
kObservingStandardTime,
//! \brief Daylight saving time is observed on the snapshot system when in
//! effect, and daylight saving time was in effect at the time of the
//! snapshot.
kObservingDaylightSavingTime,
};
//! \brief Returns the snapshot systems CPU architecture.
//!
//! In some cases, a system may be able to run processes of multiple specific
//! architecture types. For example, systems based on 64-bit architectures
//! such as x86_64 are often able to run 32-bit code of another architecture
//! in the same family, such as 32-bit x86. On these systems, this method will
//! return the architecture of the process that the snapshot is associated
//! with, provided that the SystemSnapshot object was obtained from
//! ProcessSnapshot::System(). This renders one aspect of this methods return
//! value a process attribute rather than a system attribute, but its defined
//! here rather than in ProcessSnapshot because the CPU architecture is a
//! better conceptual fit for the system abstraction alongside these other
//! related methods.
virtual CPUArchitecture GetCPUArchitecture() const = 0;
//! \brief Returns the snapshot systems CPU revision.
//!
//! For x86-family CPUs (including x86_64 and 32-bit x86), this is the CPU
//! family ID value from `cpuid 1` `eax`, adjusted to take the extended family
//! ID into account.
//!
//! \return A CPU architecture-specific value identifying the CPU revision.
virtual uint32_t CPURevision() const = 0;
//! \brief Returns the total number of CPUs present in the snapshot system.
virtual uint8_t CPUCount() const = 0;
//! \brief Returns the vendor of the snapshot systems CPUs.
//!
//! For x86-family CPUs (including x86_64 and 32-bit x86), this is the CPU
//! vendor identification string as encoded in `cpuid 0` `ebx`, `edx`, and
//! `ecx`.
//!
//! \return A string identifying the vendor of the snapshot systems CPUs.
virtual std::string CPUVendor() const = 0;
//! \brief Returns frequency information about the snapshot systems CPUs in
//! \current_hz and \a max_hz.
//!
//! \param[out] current_hz The snapshot systems CPU clock frequency in Hz at
//! the time of the snapshot.
//! \param[out] max_hz The snapshot systems maximum possible CPU clock
//! frequency.
virtual void CPUFrequency(uint64_t* current_hz, uint64_t* max_hz) const = 0;
//! \brief Returns an x86-family snapshot systems CPU signature.
//!
//! This is the family, model, and stepping ID values as encoded in `cpuid 1`
//! `eax`.
//!
//! This method must only be called when GetCPUArchitecture() indicates an
//! x86-family CPU architecture (#kCPUArchitectureX86 or
//! #kCPUArchitectureX86_64).
//!
//! \return An x86 family-specific value identifying the CPU signature.
virtual uint32_t CPUX86Signature() const = 0;
//! \brief Returns an x86-family snapshot systems CPU features.
//!
//! This is the feature information as encoded in `cpuid 1` `edx` and `ecx`.
//! `edx` is placed in the low half of the return value, and `ecx` is placed
//! in the high half.
//!
//! This method must only be called when GetCPUArchitecture() indicates an
//! x86-family CPU architecture (#kCPUArchitectureX86 or
//! #kCPUArchitectureX86_64).
//!
//! \return An x86 family-specific value identifying CPU features.
//!
//! \sa CPUX86ExtendedFeatures()
//! \sa CPUX86Leaf7Features()
virtual uint64_t CPUX86Features() const = 0;
//! \brief Returns an x86-family snapshot systems extended CPU features.
//!
//! This is the extended feature information as encoded in `cpuid 0x80000001`
//! `edx` and `ecx`. `edx` is placed in the low half of the return value, and
//! `ecx` is placed in the high half.
//!
//! This method must only be called when GetCPUArchitecture() indicates an
//! x86-family CPU architecture (#kCPUArchitectureX86 or
//! #kCPUArchitectureX86_64).
//!
//! \return An x86 family-specific value identifying extended CPU features.
//!
//! \sa CPUX86Features()
//! \sa CPUX86Leaf7Features()
virtual uint64_t CPUX86ExtendedFeatures() const = 0;
//! \brief Returns an x86-family snapshot systems “leaf 7” CPU features.
//!
//! This is the “leaf 7” feature information as encoded in `cpuid 7` `ebx`. If
//! `cpuid 7` is not supported by the snapshot CPU, this returns `0`.
//!
//! This method must only be called when GetCPUArchitecture() indicates an
//! x86-family CPU architecture (#kCPUArchitectureX86 or
//! #kCPUArchitectureX86_64).
//!
//! \return An x86 family-specific value identifying “leaf 7” CPU features.
//!
//! \sa CPUX86Features()
//! \sa CPUX86ExtendedFeatures()
virtual uint32_t CPUX86Leaf7Features() const = 0;
//! \brief Returns an x86-family snapshot systems CPUs support for the SSE
//! DAZ (“denormals are zeros”) mode.
//!
//! This determines whether the CPU supports DAZ mode at all, not whether this
//! mode is enabled for any particular thread. DAZ mode support is detected by
//! examining the DAZ bit in the `mxcsr_mask` field of the floating-point
//! context saved by `fxsave`.
//!
//! This method must only be called when GetCPUArchitecture() indicates an
//! x86-family CPU architecture (#kCPUArchitectureX86 or
//! #kCPUArchitectureX86_64).
//!
//! \return `true` if the snapshot systems CPUs support the SSE DAZ mode,
//! `false` if they do not.
virtual bool CPUX86SupportsDAZ() const = 0;
//! \brief Returns the snapshot systems operating system family.
virtual OperatingSystem GetOperatingSystem() const = 0;
//! \brief Returns whether the snapshot system runs a server variant of its
//! operating system.
virtual bool OSServer() const = 0;
//! \brief Returns the snapshot systems operating system version information
//! in \a major, \a minor, \a bugfix, and \a build.
//!
//! \param[out] major The snapshot systems operating systems first (major)
//! version number component. This would be `10` for Mac OS X 10.9.5, and
//! `6` for Windows 7 (NT 6.1) SP1 version 6.1.7601.
//! \param[out] minor The snapshot systems operating systems second (minor)
//! version number component. This would be `9` for Mac OS X 10.9.5, and
//! `1` for Windows 7 (NT 6.1) SP1 version 6.1.7601.
//! \param[out] bugfix The snapshot systems operating systems third (bugfix)
//! version number component. This would be `5` for Mac OS X 10.9.5, and
//! `7601` for Windows 7 (NT 6.1) SP1 version 6.1.7601.
//! \param[out] build A string further identifying an operating system
//! version. For Mac OS X 10.9.5, this would be `"13F34"`. For Windows,
//! this would be `"Service Pack 1"` if that service pack was installed.
//! For Linux and other Unix-like systems, this would be the kernel
//! version from `uname -srvm`, possibly with additional information
//! appended. On Android, the `ro.build.fingerprint` system property would
//! be appended.
virtual void OSVersion(int* major,
int* minor,
int* bugfix,
std::string* build) const = 0;
//! \brief Returns the snapshot systems full operating system version
//! information in string format.
//!
//! For Mac OS X, the string contains values from the operating system and
//! kernel. A Mac OS X 10.9.5 snapshot system would be identified as `"Mac OS
//! X 10.9.5 (13F34); Darwin 13.4.0 Darwin Kernel Version 13.4.0: Sun Aug 17
//! 19:50:11 PDT 2014; root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64"`.
virtual std::string OSVersionFull() const = 0;
//! \brief Returns a description of the snapshot systems hardware in string
//! format.
//!
//! For Mac OS X, the string contains the Mac model and board ID. A mid-2014
//! 15" MacBook Pro would be identified as `"MacBookPro11,3
//! (Mac-2BD1B31983FE1663)"`.
virtual std::string MachineDescription() const = 0;
//! \brief Returns the status of the NX (no-execute, or XD, execute-disable)
//! feature on the snapshot system.
//!
//! This refers to a feature that allows mapped readable pages to be marked
//! as non-executable.
//!
//! \return `true` if the snapshot system supports NX and it is enabled.
virtual bool NXEnabled() const = 0;
//! \brief Returns time zone information from the snapshot system, based on
//! its locale configuration and real-time clock.
//!
//! \param[out] dst_status Whether the location observes daylight saving time,
//! and if so, whether it or standard time is currently being observed.
//! \param[out] standard_offset_seconds The number of seconds that the
//! locations time zone is east (ahead) of UTC during standard time.
//! \param[out] daylight_offset_seconds The number of seconds that the
//! locations time zone is east (ahead) of UTC during daylight saving.
//! time.
//! \param[out] standard_name The name of the time zone while standard time is
//! being observed.
//! \param[out] daylight_name The name of the time zone while daylight saving
//! time is being observed.
virtual void TimeZone(DaylightSavingTimeStatus* observes_daylight,
int* standard_offset_seconds,
int* daylight_offset_seconds,
std::string* standard_name,
std::string* daylight_name) const = 0;
protected:
~SystemSnapshot() {}
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_SYSTEM_SNAPSHOT_H_

View File

@ -0,0 +1,69 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_THREAD_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_THREAD_SNAPSHOT_H_
#include <stdint.h>
namespace crashpad {
struct CPUContext;
class MemorySnapshot;
//! \brief An abstract interface to a snapshot representing a thread
//! (lightweight process) present in a snapshot process.
class ThreadSnapshot {
public:
//! \brief Returns a CPUContext object corresponding to the threads CPU
//! context.
//!
//! The caller does not take ownership of this object, it is scoped to the
//! lifetime of the ThreadSnapshot object that it was obtained from.
virtual const CPUContext* Context() const = 0;
//! \brief Returns a MemorySnapshot object corresponding to the memory region
//! that contains the threads stack.
//!
//! The caller does not take ownership of this object, it is scoped to the
//! lifetime of the ThreadSnapshot object that it was obtained from.
virtual const MemorySnapshot* Stack() const = 0;
//! \brief Returns the threads identifier.
//!
//! Thread identifiers are at least unique within a process, and may be unique
//! system-wide.
virtual uint64_t ThreadID() const = 0;
//! \brief Returns the threads suspend count.
//!
//! A suspend count of `0` denotes a schedulable (not suspended) thread.
virtual int SuspendCount() const = 0;
//! \brief Returns the threads priority.
//!
//! Threads with higher priorities will have higher priority values.
virtual int Priority() const = 0;
//! \brief Returns the base address of a region used to store thread-specific
//! data.
virtual uint64_t ThreadSpecificDataAddress() const = 0;
protected:
~ThreadSnapshot() {}
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_THREAD_SNAPSHOT_H_