diff --git a/compat/compat.gyp b/compat/compat.gyp index d88e5511..54dc8571 100644 --- a/compat/compat.gyp +++ b/compat/compat.gyp @@ -32,6 +32,7 @@ 'mac/mach/mach.h', 'mac/mach-o/loader.h', 'mac/servers/bootstrap.h', + 'non_mac/mach/mach.h', 'non_win/dbghelp.h', 'non_win/minwinbase.h', 'non_win/timezoneapi.h', diff --git a/compat/non_mac/mach/mach.h b/compat/non_mac/mach/mach.h new file mode 100644 index 00000000..d7cc4905 --- /dev/null +++ b/compat/non_mac/mach/mach.h @@ -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. + +#ifndef CRASHPAD_COMPAT_NON_MAC_MACH_MACH_H_ +#define CRASHPAD_COMPAT_NON_MAC_MACH_MACH_H_ + +//! \file + +// + +//! \anchor EXC_x +//! \name EXC_* +//! +//! \brief Mach exception type definitions. +//! \{ +#define EXC_BAD_ACCESS 1 +#define EXC_BAD_INSTRUCTION 2 +#define EXC_ARITHMETIC 3 +#define EXC_EMULATION 4 +#define EXC_SOFTWARE 5 +#define EXC_BREAKPOINT 6 +#define EXC_SYSCALL 7 +#define EXC_MACH_SYSCALL 8 +#define EXC_RPC_ALERT 9 +#define EXC_CRASH 10 +#define EXC_RESOURCE 11 +#define EXC_GUARD 12 +//! \} + +#endif // CRASHPAD_COMPAT_NON_MAC_MACH_MACH_H_ diff --git a/compat/non_win/dbghelp.h b/compat/non_win/dbghelp.h index 85cf4ccb..389544bd 100644 --- a/compat/non_win/dbghelp.h +++ b/compat/non_win/dbghelp.h @@ -404,19 +404,18 @@ struct __attribute__((packed, aligned(4))) MINIDUMP_EXCEPTION { //! \brief The top-level exception code identifying the exception, in //! operating system-specific values. //! - //! For Mac OS X minidumps, this will be a value of - //! crashpad::MinidumpExceptionCodeMac, which corresponds to an `EXC_*` - //! exception type. `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 #ExceptionInformation. + //! For Mac OS X minidumps, 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 #ExceptionInformation. //! //! \note This field is named ExceptionCode, but what is known as the //! “exception code” on Mac OS X/Mach is actually stored in the //! #ExceptionFlags field of a minidump file. //! - //! \todo Document the possible values by OS. There should be OS-specific - //! enums in minidump_extensions.h. + //! \todo Document the possible values by OS. There may be OS-specific enums + //! in minidump_extensions.h. uint32_t ExceptionCode; //! \brief Additional exception flags that further identify the exception, in @@ -429,8 +428,8 @@ struct __attribute__((packed, aligned(4))) MINIDUMP_EXCEPTION { //! exception handler. The code as it was received will appear at index 1 of //! #ExceptionInformation. //! - //! \todo Document the possible values by OS. There should be OS-specific - //! enums in minidump_extensions.h. + //! \todo Document the possible values by OS. There may be OS-specific enums + //! in minidump_extensions.h. uint32_t ExceptionFlags; //! \brief An address, in the address space of the process that this minidump diff --git a/minidump/minidump.gyp b/minidump/minidump.gyp index 6d44486b..7f4bc5d1 100644 --- a/minidump/minidump.gyp +++ b/minidump/minidump.gyp @@ -29,6 +29,7 @@ '..', ], 'sources': [ + 'minidump_extensions.h', 'minidump_writable.cc', 'minidump_writable.h', ], diff --git a/minidump/minidump_extensions.h b/minidump/minidump_extensions.h new file mode 100644 index 00000000..5799e53b --- /dev/null +++ b/minidump/minidump_extensions.h @@ -0,0 +1,340 @@ +// 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_MINIDUMP_MINIDUMP_EXTENSIONS_H_ +#define CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_ + +#include +#include +#include + +#include "util/misc/uuid.h" + +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 { + //! \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_MISC_INFO, MINIDUMP_MISC_INFO_2, + //! MINIDUMP_MISC_INFO_3, and MINIDUMP_MISC_INFO_4. + //! + //! \sa MiscInfoStream + kMinidumpStreamTypeMiscInfo = MiscInfoStream, + + // 0x4350 = "CP" + + //! \brief The stream type for MinidumpCrashpadInfo. + kMinidumpStreamTypeCrashpadInfo = 0x43500001, +}; + +//! \brief A variable-length UTF-8-encoded string carried within a minidump +//! file. +//! +//! \sa MINIDUMP_STRING +struct __attribute__((packed, aligned(4))) 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 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, + + kMinidumpCPUArchitectureX86Win64 = PROCESSOR_ARCHITECTURE_IA32_ON_WIN64, + kMinidumpCPUArchitectureNeutral = PROCESSOR_ARCHITECTURE_NEUTRAL, + 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 64-bit ARM. + //! + //! These systems identify their CPUs generically as “arm64” or “aarch64”, or + //! with more specific names such as “armv8”. + kMinidumpCPUArchitectureARM64 = 0x8003, + + //! \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 Mac OS X, 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 Unknown operating system. + kMinidumpOSUnknown = 0xffffffff, +}; + +//! \brief A CodeView record linking to a `.pdb` 2.0 file. +//! +//! This format provides an indirect link to debugging data by referencing an +//! external `.pdb` file by its name, timestamp, and age. This structure may be +//! pointed to by MINIDUMP_MODULE::CvRecord. It has been superseded by +//! MinidumpModuleCodeViewRecordPDB70. +//! +//! For more information about this structure and format, see Matching +//! Debug Information, PDB Files, and Undocumented +//! Windows 2000 Secrets, Windows 2000 Debugging Support/Microsoft Symbol +//! File Internals/CodeView Subsections. +//! +//! \sa IMAGE_DEBUG_MISC +struct MinidumpModuleCodeViewRecordPDB20 { + //! \brief The magic number identifying this structure version, stored in + //! #signature. + //! + //! In a hex dump, this will appear as “NB10” when produced by a little-endian + //! machine. + static const uint32_t kSignature = '01BN'; + + //! \brief The magic number identifying this structure version, the value of + //! #kSignature. + uint32_t signature; + + //! \brief The offset to CodeView data. + //! + //! In this structure, this field always has the value `0` because no CodeView + //! data is present, there is only a link to CodeView data stored in an + //! external file. + uint32_t offset; + + //! \brief The time that the `.pdb` file was created, in `time_t` format, the + //! number of seconds since the POSIX epoch. + uint32_t timestamp; + + //! \brief The revision of the `.pdb` file. + //! + //! A `.pdb` file’s age indicates incremental changes to it. When a `.pdb` + //! file is created, it has age `1`, and subsequent updates increase this + //! value. + uint32_t age; + + //! \brief The path or file name of the `.pdb` file associated with the + //! module. + //! + //! This is a NUL-terminated string. On Windows, it will be encoded in the + //! code page of the system that linked the module. On other operating + //! systems, UTF-8 may be used. + uint8_t pdb_name[1]; +}; + +//! \brief A CodeView record linking to a `.pdb` 7.0 file. +//! +//! This format provides an indirect link to debugging data by referencing an +//! external `.pdb` file by its name, %UUID, and age. This structure may be +//! pointed to by MINIDUMP_MODULE::CvRecord. +//! +//! For more information about this structure and format, see Matching +//! Debug Information, PDB Files. +//! +//! \sa MinidumpModuleCodeViewRecordPDB20 +//! \sa IMAGE_DEBUG_MISC +struct MinidumpModuleCodeViewRecordPDB70 { + //! \brief The magic number identifying this structure version, stored in + //! #signature. + //! + //! In a hex dump, this will appear as “RSDS” when produced by a little-endian + //! machine. + static const uint32_t kSignature = 'SDSR'; + + //! \brief The magic number identifying this structure version, the value of + //! #kSignature. + uint32_t signature; + + //! \brief The `.pdb` file’s unique identifier. + UUID uuid; + + //! \brief The revision of the `.pdb` file. + //! + //! A `.pdb` file’s age indicates incremental changes to it. When a `.pdb` + //! file is created, it has age `1`, and subsequent updates increase this + //! value. + uint32_t age; + + //! \brief The path or file name of the `.pdb` file associated with the + //! module. + //! + //! This is a NUL-terminated string. On Windows, it will be encoded in the + //! code page of the system that linked the module. On other operating + //! systems, UTF-8 may be used. + uint8_t pdb_name[1]; +}; + +//! \brief A key-value pair. +struct __attribute__((packed, aligned(4))) 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 __attribute__((packed, aligned(4))) MinidumpSimpleStringDictionary { + //! \brief The number of key-value pairs present. + uint32_t count; + + //! \brief A list of MinidumpSimpleStringDictionaryEntry entries. + MinidumpSimpleStringDictionaryEntry entries[0]; +}; + +//! \brief Additional Crashpad-specific information carried within a minidump +//! file. +struct __attribute__((packed, aligned(4))) MinidumpCrashpadInfo { + //! \brief The size of the entire structure, in bytes. + //! + //! \sa version + uint32_t size; + + //! \brief The structure’s version number. This can be used to determine which + //! other fields in the structure are valid. + //! + //! \sa size + uint32_t version; + + //! \brief A MinidumpSimpleStringDictionary pointing to strings interpreted as + //! key-value pairs. The process that crashed controlled the data that + //! appears here. + //! + //! If MINIDUMP_LOCATION_DESCRIPTOR::DataSize is `0`, no key-value pairs are + //! present, and MINIDUMP_LOCATION_DESCRIPTOR::Rva should not be consulted. + //! + //! This field is present when #version is at least `1`. + MINIDUMP_LOCATION_DESCRIPTOR simple_annotations; +}; + +} // namespace crashpad + +#endif // CRASHPAD_MINIDUMP_MINIDUMP_EXTENSIONS_H_