| // 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 <memory> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "snapshot/annotation_snapshot.h" |
| #include "snapshot/memory_snapshot.h" |
| #include "util/misc/uuid.h" |
| #include "util/numeric/checked_range.h" |
| |
| namespace crashpad { |
| |
| class MemorySnapshot; |
| |
| //! \brief Information describing a custom user data stream in a minidump. |
| class UserMinidumpStream { |
| public: |
| //! \brief Constructs a UserMinidumpStream, takes ownership of \a memory. |
| UserMinidumpStream(uint32_t stream_type, MemorySnapshot* memory) |
| : memory_(memory), stream_type_(stream_type) {} |
| |
| const MemorySnapshot* memory() const { return memory_.get(); } |
| uint32_t stream_type() const { return stream_type_; } |
| |
| private: |
| //! \brief The memory representing the custom minidump stream. |
| std::unique_ptr<MemorySnapshot> memory_; |
| |
| //! \brief The stream type that the minidump stream will be tagged with. |
| uint32_t stream_type_; |
| |
| DISALLOW_COPY_AND_ASSIGN(UserMinidumpStream); |
| }; |
| |
| //! \brief An abstract interface to a snapshot representing a code module |
| //! (binary image) loaded into a snapshot process. |
| class ModuleSnapshot { |
| public: |
| virtual ~ModuleSnapshot() {} |
| |
| //! \brief A module’s type. |
| enum ModuleType { |
| //! \brief The module’s 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 macOS and `ld.so` for Linux and other systems using |
| //! ELF. |
| kModuleTypeDynamicLoader, |
| }; |
| |
| //! \brief Returns the module’s 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 macOS 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 module’s 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 |
| //! module’s timestamp is unknown, this method returns `0`. |
| virtual time_t Timestamp() const = 0; |
| |
| //! \brief Returns the module’s file version in the \a version_* parameters. |
| //! |
| //! If no file version can be determined, the \a version_* parameters are set |
| //! to `0`. |
| //! |
| //! For macOS snapshots, this is taken from the module’s `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 module’s source version in the \a version_* parameters. |
| //! |
| //! If no source version can be determined, the \a version_* parameters are |
| //! set to `0`. |
| //! |
| //! For macOS snapshots, this is taken from the module’s `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 module’s type. |
| virtual ModuleType GetModuleType() const = 0; |
| |
| //! \brief Returns the module’s UUID in the \a uuid parameter, and the age of |
| //! that UUID in \a age. |
| //! |
| //! A snapshot module’s UUID is taken directly from the module itself. If the |
| //! module does not have a UUID, the \a uuid parameter will be zeroed out. |
| //! |
| //! \a age is the number of times the UUID has been reused. This occurs on |
| //! Windows with incremental linking. On other platforms \a age will always be |
| //! `0`. |
| //! |
| //! \sa BuildID() |
| //! \sa DebugFileName() |
| virtual void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const = 0; |
| |
| //! \brief Returns the module’s debug file info name. |
| //! |
| //! On Windows, this references the PDB file, which contains symbol |
| //! information held separately from the module itself. On other platforms, |
| //! this is normally the basename of the module, because the debug info file’s |
| //! name is not relevant even in split-debug scenarios. |
| //! |
| //! \sa UUIDAndAge() |
| virtual std::string DebugFileName() const = 0; |
| |
| //! \brief Returns the module’s build ID. |
| //! |
| //! On ELF platforms, the build ID is a variable-length byte stream that |
| //! identifies a library uniquely, and is usually used to look up its debug |
| //! symbols when stored separately. This will return an empty vector if it is |
| //! unsupported. |
| //! |
| //! BuildID() and UUIDAndAge() are never available in the same place. When |
| //! UUIDAndAge() is unavailable, it will be filled out with the contents of |
| //! BuildID() (either 0-padded or truncated) and age will be zero. |
| //! |
| //! \sa UUIDAndAge() |
| virtual std::vector<uint8_t> BuildID() const = 0; |
| |
| //! \brief Returns string annotations recorded in the module. |
| //! |
| //! This method retrieves annotations recorded in a module. These annotations |
| //! are intended for diagnostic use, including crash analysis. A module may |
| //! contain multiple annotations, so they are returned in a vector. |
| //! |
| //! For macOS snapshots, these annotations are found by interpreting the |
| //! module’s `__DATA,__crash_info` section as `crashreporter_annotations_t`. |
| //! System libraries using the crash reporter client interface may reference |
| //! annotations in this structure. Additional annotations messages may be |
| //! found in other locations, which may be module-specific. The dynamic linker |
| //! (`dyld`) can provide an annotation at its `_error_string` symbol. |
| //! |
| //! The annotations returned by this method do not duplicate those returned by |
| //! AnnotationsSimpleMap() or AnnotationObjects(). |
| virtual std::vector<std::string> AnnotationsVector() const = 0; |
| |
| //! \brief Returns key-value string annotations recorded in the module. |
| //! |
| //! This method retrieves 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, where all |
| //! keys and values are strings. These are referred to in Chrome as “crash |
| //! keys.” |
| //! |
| //! For macOS snapshots, these 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. Most |
| //! annotations under the client’s direct control will be retrievable by this |
| //! method. For clients such as Chrome, this includes the process type. |
| //! |
| //! The annotations returned by this method do not duplicate those returned by |
| //! AnnotationsVector() or AnnotationObjects(). Additional annotations related |
| //! to the process, system, or snapshot producer may be obtained by calling |
| //! ProcessSnapshot::AnnotationsSimpleMap(). |
| virtual std::map<std::string, std::string> AnnotationsSimpleMap() const = 0; |
| |
| //! \brief Returns the typed annotation objects recorded in the module. |
| //! |
| //! This method retrieves annotations recorded in a module. These annotations |
| //! are intended for diagnostic use, including crash analysis. Annotation |
| //! objects are strongly-typed name-value pairs. The names are not unique. |
| //! |
| //! For macOS snapshots, these 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. Most |
| //! annotations under the client’s direct control will be retrievable by this |
| //! method. For clients such as Chrome, this includes the process type. |
| //! |
| //! The annotations returned by this method do not duplicate those returned by |
| //! AnnotationsVector() or AnnotationsSimpleMap(). |
| virtual std::vector<AnnotationSnapshot> AnnotationObjects() const = 0; |
| |
| //! \brief Returns a set of extra memory ranges specified in the module as |
| //! being desirable to include in the crash dump. |
| virtual std::set<CheckedRange<uint64_t>> ExtraMemoryRanges() const = 0; |
| |
| //! \brief Returns a list of custom minidump stream specified in the module to |
| //! be included in the crash dump. |
| //! |
| //! \return The caller does not take ownership of the returned objects, they |
| //! are scoped to the lifetime of the ModuleSnapshot object that they were |
| //! obtained from. |
| virtual std::vector<const UserMinidumpStream*> CustomMinidumpStreams() |
| const = 0; |
| }; |
| |
| } // namespace crashpad |
| |
| #endif // CRASHPAD_SNAPSHOT_MODULE_SNAPSHOT_H_ |