crashpad/minidump/minidump_extensions.h

539 lines
19 KiB
C
Raw Normal View History

// Copyright 2014 The Crashpad Authors
//
// 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_MINIDUMP_MINIDUMP_EXTENSIONS_H_
#define CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_
#include <windows.h>
#include <dbghelp.h>
#include <stdint.h>
#include <winnt.h>
#include "base/compiler_specific.h"
#include "build/build_config.h"
#include "util/misc/pdb_structures.h"
#include "util/misc/uuid.h"
#if defined(COMPILER_MSVC)
// C4200 is "nonstandard extension used : zero-sized array in struct/union".
// We would like to globally disable this warning, but unfortunately, the
// compiler is buggy and only supports disabling it with a pragma, so we can't
// disable it with other silly warnings in the build files. See:
// https://connect.microsoft.com/VisualStudio/feedback/details/1114440
#pragma warning(push)
#pragma warning(disable: 4200)
#define PACKED
#pragma pack(push, 1)
#else
#define PACKED __attribute__((packed))
#endif // COMPILER_MSVC
namespace crashpad {
//! \brief Minidump stream type values for MINIDUMP_DIRECTORY::StreamType. Each
//! stream structure has a corresponding stream type value to identify it.
//!
//! \sa MINIDUMP_STREAM_TYPE
enum MinidumpStreamType : uint32_t {
//! \brief The stream type for MINIDUMP_THREAD_LIST.
//!
//! \sa ThreadListStream
kMinidumpStreamTypeThreadList = ThreadListStream,
//! \brief The stream type for MINIDUMP_MODULE_LIST.
//!
//! \sa ModuleListStream
kMinidumpStreamTypeModuleList = ModuleListStream,
//! \brief The stream type for MINIDUMP_MEMORY_LIST.
//!
//! \sa MemoryListStream
kMinidumpStreamTypeMemoryList = MemoryListStream,
//! \brief The stream type for MINIDUMP_EXCEPTION_STREAM.
//!
//! \sa ExceptionStream
kMinidumpStreamTypeException = ExceptionStream,
//! \brief The stream type for MINIDUMP_SYSTEM_INFO.
//!
//! \sa SystemInfoStream
kMinidumpStreamTypeSystemInfo = SystemInfoStream,
//! \brief The stream type for MINIDUMP_HANDLE_DATA_STREAM.
//!
//! \sa HandleDataStream
kMinidumpStreamTypeHandleData = HandleDataStream,
//! \brief The stream type for MINIDUMP_UNLOADED_MODULE_LIST.
//!
//! \sa UnloadedModuleListStream
kMinidumpStreamTypeUnloadedModuleList = UnloadedModuleListStream,
//! \brief The stream type for MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
//! MINIDUMP_MISC_INFO_3, and MINIDUMP_MISC_INFO_4.
//!
//! \sa MiscInfoStream
kMinidumpStreamTypeMiscInfo = MiscInfoStream,
//! \brief The stream type for MINIDUMP_MEMORY_INFO_LIST.
//!
//! \sa MemoryInfoListStream
kMinidumpStreamTypeMemoryInfoList = MemoryInfoListStream,
//! \brief The stream type for MINIDUMP_THREAD_NAME_LIST.
//!
//! \sa ThreadNamesStream
kMinidumpStreamTypeThreadNameList = ThreadNamesStream,
//! \brief The last reserved minidump stream.
//!
//! \sa MemoryInfoListStream
kMinidumpStreamTypeLastReservedStream = LastReservedStream,
// 0x4350 = "CP"
//! \brief The stream type for MinidumpCrashpadInfo.
kMinidumpStreamTypeCrashpadInfo = 0x43500001,
//! \brief The last reserved crashpad stream.
kMinidumpStreamTypeCrashpadLastReservedStream = 0x4350ffff,
};
//! \brief A variable-length UTF-8-encoded string carried within a minidump
//! file.
//!
//! \sa MINIDUMP_STRING
struct ALIGNAS(4) PACKED MinidumpUTF8String {
// The field names do not conform to typical style, they match the names used
// in MINIDUMP_STRING. This makes it easier to operate on MINIDUMP_STRING (for
// UTF-16 strings) and MinidumpUTF8String using templates.
//! \brief The length of the #Buffer field in bytes, not including the `NUL`
//! terminator.
//!
//! \note This field is interpreted as a byte count, not a count of Unicode
//! code points.
uint32_t Length;
//! \brief The string, encoded in UTF-8, and terminated with a `NUL` byte.
uint8_t Buffer[0];
};
//! \brief A variable-length array of bytes carried within a minidump file.
//! The data have no intrinsic type and should be interpreted according
//! to their referencing context.
struct ALIGNAS(4) PACKED MinidumpByteArray {
//! \brief The length of the #data field.
uint32_t length;
//! \brief The bytes of data.
uint8_t data[0];
};
//! \brief CPU type values for MINIDUMP_SYSTEM_INFO::ProcessorArchitecture.
//!
//! \sa \ref PROCESSOR_ARCHITECTURE_x "PROCESSOR_ARCHITECTURE_*"
enum MinidumpCPUArchitecture : uint16_t {
//! \brief 32-bit x86.
//!
//! These systems identify their CPUs generically as “x86” or “ia32”, or with
//! more specific names such as “i386”, “i486”, “i586”, and “i686”.
kMinidumpCPUArchitectureX86 = PROCESSOR_ARCHITECTURE_INTEL,
kMinidumpCPUArchitectureMIPS = PROCESSOR_ARCHITECTURE_MIPS,
kMinidumpCPUArchitectureAlpha = PROCESSOR_ARCHITECTURE_ALPHA,
//! \brief 32-bit PowerPC.
//!
//! These systems identify their CPUs generically as “ppc”, or with more
//! specific names such as “ppc6xx”, “ppc7xx”, and “ppc74xx”.
kMinidumpCPUArchitecturePPC = PROCESSOR_ARCHITECTURE_PPC,
kMinidumpCPUArchitectureSHx = PROCESSOR_ARCHITECTURE_SHX,
//! \brief 32-bit ARM.
//!
//! These systems identify their CPUs generically as “arm”, or with more
//! specific names such as “armv6” and “armv7”.
kMinidumpCPUArchitectureARM = PROCESSOR_ARCHITECTURE_ARM,
kMinidumpCPUArchitectureIA64 = PROCESSOR_ARCHITECTURE_IA64,
kMinidumpCPUArchitectureAlpha64 = PROCESSOR_ARCHITECTURE_ALPHA64,
kMinidumpCPUArchitectureMSIL = PROCESSOR_ARCHITECTURE_MSIL,
//! \brief 64-bit x86.
//!
//! These systems identify their CPUs as “x86_64”, “amd64”, or “x64”.
kMinidumpCPUArchitectureAMD64 = PROCESSOR_ARCHITECTURE_AMD64,
//! \brief A 32-bit x86 process running on IA-64 (Itanium).
//!
//! \note This value is not used in minidump files for 32-bit x86 processes
//! running on a 64-bit-capable x86 CPU and operating system. In that
//! configuration, #kMinidumpCPUArchitectureX86 is used instead.
kMinidumpCPUArchitectureX86Win64 = PROCESSOR_ARCHITECTURE_IA32_ON_WIN64,
kMinidumpCPUArchitectureNeutral = PROCESSOR_ARCHITECTURE_NEUTRAL,
//! \brief 64-bit ARM.
//!
//! These systems identify their CPUs generically as “arm64” or “aarch64”, or
//! with more specific names such as “armv8”.
//!
//! \sa #kMinidumpCPUArchitectureARM64Breakpad
kMinidumpCPUArchitectureARM64 = PROCESSOR_ARCHITECTURE_ARM64,
kMinidumpCPUArchitectureARM32Win64 = PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64,
kMinidumpCPUArchitectureSPARC = 0x8001,
//! \brief 64-bit PowerPC.
//!
//! These systems identify their CPUs generically as “ppc64”, or with more
//! specific names such as “ppc970”.
kMinidumpCPUArchitecturePPC64 = 0x8002,
//! \brief Used by Breakpad for 64-bit ARM.
//!
//! \deprecated Use #kMinidumpCPUArchitectureARM64 instead.
kMinidumpCPUArchitectureARM64Breakpad = 0x8003,
//! \brief Used by Breakpad for 64-bit RISC-V.
kMinidumpCPUArchitectureRISCV64Breakpad = 0x8006,
//! \brief Unknown CPU architecture.
kMinidumpCPUArchitectureUnknown = PROCESSOR_ARCHITECTURE_UNKNOWN,
};
//! \brief Operating system type values for MINIDUMP_SYSTEM_INFO::ProductType.
//!
//! \sa \ref VER_NT_x "VER_NT_*"
enum MinidumpOSType : uint8_t {
//! \brief A “desktop” or “workstation” system.
kMinidumpOSTypeWorkstation = VER_NT_WORKSTATION,
//! \brief A “domain controller” system. Windows-specific.
kMinidumpOSTypeDomainController = VER_NT_DOMAIN_CONTROLLER,
//! \brief A “server” system.
kMinidumpOSTypeServer = VER_NT_SERVER,
};
//! \brief Operating system family values for MINIDUMP_SYSTEM_INFO::PlatformId.
//!
//! \sa \ref VER_PLATFORM_x "VER_PLATFORM_*"
enum MinidumpOS : uint32_t {
//! \brief Windows 3.1.
kMinidumpOSWin32s = VER_PLATFORM_WIN32s,
//! \brief Windows 95, Windows 98, and Windows Me.
kMinidumpOSWin32Windows = VER_PLATFORM_WIN32_WINDOWS,
//! \brief Windows NT, Windows 2000, and later.
kMinidumpOSWin32NT = VER_PLATFORM_WIN32_NT,
kMinidumpOSUnix = 0x8000,
//! \brief macOS, Darwin for traditional systems.
kMinidumpOSMacOSX = 0x8101,
//! \brief iOS, Darwin for mobile devices.
kMinidumpOSIOS = 0x8102,
//! \brief Linux, not including Android.
kMinidumpOSLinux = 0x8201,
kMinidumpOSSolaris = 0x8202,
//! \brief Android.
kMinidumpOSAndroid = 0x8203,
kMinidumpOSPS3 = 0x8204,
//! \brief Native Client (NaCl).
kMinidumpOSNaCl = 0x8205,
//! \brief Fuchsia.
kMinidumpOSFuchsia = 0x8206,
//! \brief Unknown operating system.
kMinidumpOSUnknown = 0xffffffff,
};
//! \brief A list of ::RVA pointers.
struct ALIGNAS(4) PACKED MinidumpRVAList {
//! \brief The number of children present in the #children array.
uint32_t count;
//! \brief Pointers to other structures in the minidump file.
RVA children[0];
};
//! \brief A key-value pair.
struct ALIGNAS(4) PACKED MinidumpSimpleStringDictionaryEntry {
//! \brief ::RVA of a MinidumpUTF8String containing the key of a key-value
//! pair.
RVA key;
//! \brief ::RVA of a MinidumpUTF8String containing the value of a key-value
//! pair.
RVA value;
};
//! \brief A list of key-value pairs.
struct ALIGNAS(4) PACKED MinidumpSimpleStringDictionary {
//! \brief The number of key-value pairs present.
uint32_t count;
//! \brief A list of MinidumpSimpleStringDictionaryEntry entries.
MinidumpSimpleStringDictionaryEntry entries[0];
};
//! \brief A typed annotation object.
struct ALIGNAS(4) PACKED MinidumpAnnotation {
//! \brief ::RVA of a MinidumpUTF8String containing the name of the
//! annotation.
RVA name;
//! \brief The type of data stored in the \a value of the annotation. This
//! may correspond to an \a Annotation::Type or it may be user-defined.
uint16_t type;
//! \brief This field is always `0`.
uint16_t reserved;
//! \brief ::RVA of a MinidumpByteArray to the data for the annotation.
RVA value;
};
//! \brief A list of annotation objects.
struct ALIGNAS(4) PACKED MinidumpAnnotationList {
//! \brief The number of annotation objects present.
uint32_t count;
//! \brief A list of MinidumpAnnotation objects.
MinidumpAnnotation objects[0];
};
//! \brief Additional Crashpad-specific information about a module carried
//! within a minidump file.
//!
//! This structure augments the information provided by MINIDUMP_MODULE. The
//! minidump file must contain a module list stream
//! (::kMinidumpStreamTypeModuleList) in order for this structure to appear.
//!
//! This structure is versioned. When changing this structure, leave the
//! existing structure intact so that earlier parsers will be able to understand
//! the fields they are aware of, and make additions at the end of the
//! structure. Revise #kVersion and document each fields validity based on
//! #version, so that newer parsers will be able to determine whether the added
//! fields are valid or not.
//!
doc: Fix all Doxygen warnings, cleaning up some generated documentation This makes Doxygen’s output more actionable by setting QUIET = YES to suppress verbose progress spew, and WARN_IF_UNDOCUMENTED = NO to prevent warnings for undocumented classes and members from being generated. The latter is too noisy, producing 721 warnings in the current codebase. The remaining warnings produced by Doxygen were useful and actionable. They fell into two categories: abuses of Doxygen’s markup syntax, and missing (or misspelled) parameter documentation. In a small number of cases, pass-through parameters had intentionally been left undocumented. In these cases, they are now given blank \param descriptions. This is not optimal, but there doesn’t appear to be any other way to tell Doxygen to allow a single parameter to be undocumented. Some tricky Doxygen errors were resolved by asking it to not enter directiores that we do not provide documentation in (such as the “on-platform” compat directories, compat/mac and compat/win, as well as compat/non_cxx11_lib) while allowing it to enter the “off-platform” directories that we do document (compat/non_mac and compat/non_win). A Doxygen run (doc/support/generate_doxygen.sh) now produces no output at all. It would produce warnings if any were triggered. Not directly related, but still relevant to documentation, doc/support/generate.sh is updated to remove temporary removals of now-extinct files and directories. doc/appengine/README is updated so that a consistent path to “goapp” is used throughout the file. Change-Id: I300730c04de4d3340551ea3086ca70cc5ff862d1 Reviewed-on: https://chromium-review.googlesource.com/408812 Reviewed-by: Robert Sesek <rsesek@chromium.org>
2016-11-08 14:23:09 -05:00
//! \sa MinidumpModuleCrashpadInfoList
struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfo {
//! \brief The structures currently-defined version number.
//!
//! \sa version
static constexpr uint32_t kVersion = 1;
//! \brief The structures version number.
//!
//! Readers can use this field to determine which other fields in the
//! structure are valid. Upon encountering a value greater than #kVersion, a
//! reader should assume that the structures layout is compatible with the
//! structure defined as having value #kVersion.
//!
//! Writers may produce values less than #kVersion in this field if there is
//! no need for any fields present in later versions.
uint32_t version;
//! \brief A MinidumpRVAList pointing to MinidumpUTF8String objects. The
//! module controls the data that appears here.
//!
//! These strings correspond to ModuleSnapshot::AnnotationsVector() and do not
//! duplicate anything in #simple_annotations or #annotation_objects.
//!
//! This field is present when #version is at least `1`.
MINIDUMP_LOCATION_DESCRIPTOR list_annotations;
//! \brief A MinidumpSimpleStringDictionary pointing to strings interpreted as
//! key-value pairs. The module controls the data that appears here.
//!
//! These key-value pairs correspond to
//! ModuleSnapshot::AnnotationsSimpleMap() and do not duplicate anything in
//! #list_annotations or #annotation_objects.
//!
//! This field is present when #version is at least `1`.
MINIDUMP_LOCATION_DESCRIPTOR simple_annotations;
//! \brief A MinidumpAnnotationList object containing the annotation objects
//! stored within the module. The module controls the data that appears
//! here.
//!
//! These key-value pairs correspond to ModuleSnapshot::AnnotationObjects()
//! and do not duplicate anything in #list_annotations or #simple_annotations.
//!
//! This field may be present when #version is at least `1`.
MINIDUMP_LOCATION_DESCRIPTOR annotation_objects;
};
2015-03-04 10:53:34 -05:00
//! \brief A link between a MINIDUMP_MODULE structure and additional
//! Crashpad-specific information about a module carried within a minidump
//! file.
struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfoLink {
//! \brief A link to a MINIDUMP_MODULE structure in the module list stream.
//!
//! This field is an index into MINIDUMP_MODULE_LIST::Modules. This fields
//! value must be in the range of MINIDUMP_MODULE_LIST::NumberOfEntries.
uint32_t minidump_module_list_index;
//! \brief A link to a MinidumpModuleCrashpadInfo structure.
//!
//! MinidumpModuleCrashpadInfo structures are accessed indirectly through
//! MINIDUMP_LOCATION_DESCRIPTOR pointers to allow for future growth of the
//! MinidumpModuleCrashpadInfo structure.
MINIDUMP_LOCATION_DESCRIPTOR location;
};
//! \brief Additional Crashpad-specific information about modules carried within
//! a minidump file.
//!
//! This structure augments the information provided by
//! MINIDUMP_MODULE_LIST. The minidump file must contain a module list stream
//! (::kMinidumpStreamTypeModuleList) in order for this structure to appear.
//!
//! MinidumpModuleCrashpadInfoList::count may be less than the value of
//! MINIDUMP_MODULE_LIST::NumberOfModules because not every MINIDUMP_MODULE
//! structure carried within the minidump file will necessarily have
//! Crashpad-specific information provided by a MinidumpModuleCrashpadInfo
//! structure.
2015-03-04 10:53:34 -05:00
struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfoList {
//! \brief The number of children present in the #modules array.
uint32_t count;
//! \brief Crashpad-specific information about modules, along with links to
//! MINIDUMP_MODULE structures that contain module information
//! traditionally carried within minidump files.
MinidumpModuleCrashpadInfoLink modules[0];
};
//! \brief Additional Crashpad-specific information carried within a minidump
//! file.
//!
//! This structure is versioned. When changing this structure, leave the
//! existing structure intact so that earlier parsers will be able to understand
//! the fields they are aware of, and make additions at the end of the
//! structure. Revise #kVersion and document each fields validity based on
//! #version, so that newer parsers will be able to determine whether the added
//! fields are valid or not.
struct ALIGNAS(4) PACKED MinidumpCrashpadInfo {
// UUID has a constructor, which makes it non-POD, which makes this structure
// non-POD. In order for the default constructor to zero-initialize other
// members, an explicit constructor must be provided.
MinidumpCrashpadInfo()
: version(),
report_id(),
client_id(),
simple_annotations(),
module_list(),
reserved(),
address_mask() {}
//! \brief The structures currently-defined version number.
//!
//! \sa version
static constexpr uint32_t kVersion = 1;
//! \brief The structures version number.
//!
//! Readers can use this field to determine which other fields in the
//! structure are valid. Upon encountering a value greater than #kVersion, a
//! reader should assume that the structures layout is compatible with the
//! structure defined as having value #kVersion.
//!
//! Writers may produce values less than #kVersion in this field if there is
//! no need for any fields present in later versions.
uint32_t version;
//! \brief A %UUID identifying an individual crash report.
//!
//! This provides a stable identifier for a crash even as the report is
//! converted to different formats, provided that all formats support storing
//! a crash report ID.
//!
//! If no identifier is available, this field will contain zeroes.
//!
//! This field is present when #version is at least `1`.
UUID report_id;
//! \brief A %UUID identifying the client that crashed.
//!
//! Client identification is within the scope of the application, but it is
//! expected that the identifier will be unique for an instance of Crashpad
//! monitoring an application or set of applications for a user. The
//! identifier shall remain stable over time.
//!
//! If no identifier is available, this field will contain zeroes.
//!
//! This field is present when #version is at least `1`.
UUID client_id;
//! \brief A MinidumpSimpleStringDictionary pointing to strings interpreted as
//! key-value pairs.
//!
//! These key-value pairs correspond to
//! ProcessSnapshot::AnnotationsSimpleMap().
//!
//! This field is present when #version is at least `1`.
MINIDUMP_LOCATION_DESCRIPTOR simple_annotations;
doc: Fix all Doxygen warnings, cleaning up some generated documentation This makes Doxygen’s output more actionable by setting QUIET = YES to suppress verbose progress spew, and WARN_IF_UNDOCUMENTED = NO to prevent warnings for undocumented classes and members from being generated. The latter is too noisy, producing 721 warnings in the current codebase. The remaining warnings produced by Doxygen were useful and actionable. They fell into two categories: abuses of Doxygen’s markup syntax, and missing (or misspelled) parameter documentation. In a small number of cases, pass-through parameters had intentionally been left undocumented. In these cases, they are now given blank \param descriptions. This is not optimal, but there doesn’t appear to be any other way to tell Doxygen to allow a single parameter to be undocumented. Some tricky Doxygen errors were resolved by asking it to not enter directiores that we do not provide documentation in (such as the “on-platform” compat directories, compat/mac and compat/win, as well as compat/non_cxx11_lib) while allowing it to enter the “off-platform” directories that we do document (compat/non_mac and compat/non_win). A Doxygen run (doc/support/generate_doxygen.sh) now produces no output at all. It would produce warnings if any were triggered. Not directly related, but still relevant to documentation, doc/support/generate.sh is updated to remove temporary removals of now-extinct files and directories. doc/appengine/README is updated so that a consistent path to “goapp” is used throughout the file. Change-Id: I300730c04de4d3340551ea3086ca70cc5ff862d1 Reviewed-on: https://chromium-review.googlesource.com/408812 Reviewed-by: Robert Sesek <rsesek@chromium.org>
2016-11-08 14:23:09 -05:00
//! \brief A pointer to a MinidumpModuleCrashpadInfoList structure.
//!
//! This field is present when #version is at least `1`.
MINIDUMP_LOCATION_DESCRIPTOR module_list;
//! \brief This field is always `0`.
uint32_t reserved;
//! \brief A mask indicating the range of valid addresses for a pointer.
//!
//! ARM64 supports MTE, TBI and PAC masking, generally in the upper bits of
//! a pointer. This mask can be used by LLDB to mimic ptrauth_strip and strip
//! the pointer authentication codes. To recover `pointer` in userland on
//! Darwin, `pointer & (~mask)`. In the case of code running in high memory,
//! where bit 55 is set (indicating that all of the high bits should be set
//! to 1), `pointer | mask`. See ABIMacOSX_arm64::FixAddress for more details
//! here:
//! https://github.com/llvm/llvm-project/blob/001d18664f8bcf63af64f10688809f7681dfbf0b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp#L817-L830
//!
//! If the platform does not support pointer authentication, or the range of
//! valid addressees for a pointer was inaccessible, this field will be 0 and
//! should be ignored.
//!
//! This field is present when #version is at least `1`, if the size of the
//! structure is large enough to accommodate it.
uint64_t address_mask;
};
#if defined(COMPILER_MSVC)
#pragma pack(pop)
#pragma warning(pop) // C4200
#endif // COMPILER_MSVC
#undef PACKED
} // namespace crashpad
#endif // CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_