| // Copyright (c) 2012 Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #ifndef CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ |
| #define CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ |
| |
| #include <assert.h> |
| #include <sys/types.h> |
| |
| #include <string> |
| |
| #include "client/linux/handler/microdump_extra_info.h" |
| #include "common/using_std_string.h" |
| |
| // This class describes how a crash dump should be generated, either: |
| // - Writing a full minidump to a file in a given directory (the actual path, |
| // inside the directory, is determined by this class). |
| // - Writing a full minidump to a given fd. |
| // - Writing a reduced microdump to the console (logcat on Android). |
| namespace google_breakpad { |
| |
| class MinidumpDescriptor { |
| public: |
| struct MicrodumpOnConsole {}; |
| static const MicrodumpOnConsole kMicrodumpOnConsole; |
| |
| MinidumpDescriptor() |
| : mode_(kUninitialized), |
| fd_(-1), |
| size_limit_(-1), |
| address_within_principal_mapping_(0), |
| skip_dump_if_principal_mapping_not_referenced_(false) {} |
| |
| explicit MinidumpDescriptor(const string& directory) |
| : mode_(kWriteMinidumpToFile), |
| fd_(-1), |
| directory_(directory), |
| c_path_(NULL), |
| size_limit_(-1), |
| address_within_principal_mapping_(0), |
| skip_dump_if_principal_mapping_not_referenced_(false), |
| sanitize_stacks_(false) { |
| assert(!directory.empty()); |
| } |
| |
| explicit MinidumpDescriptor(int fd) |
| : mode_(kWriteMinidumpToFd), |
| fd_(fd), |
| c_path_(NULL), |
| size_limit_(-1), |
| address_within_principal_mapping_(0), |
| skip_dump_if_principal_mapping_not_referenced_(false), |
| sanitize_stacks_(false) { |
| assert(fd != -1); |
| } |
| |
| explicit MinidumpDescriptor(const MicrodumpOnConsole&) |
| : mode_(kWriteMicrodumpToConsole), |
| fd_(-1), |
| size_limit_(-1), |
| address_within_principal_mapping_(0), |
| skip_dump_if_principal_mapping_not_referenced_(false), |
| sanitize_stacks_(false) {} |
| |
| explicit MinidumpDescriptor(const MinidumpDescriptor& descriptor); |
| MinidumpDescriptor& operator=(const MinidumpDescriptor& descriptor); |
| |
| static MinidumpDescriptor getMicrodumpDescriptor(); |
| |
| bool IsFD() const { return mode_ == kWriteMinidumpToFd; } |
| |
| int fd() const { return fd_; } |
| |
| string directory() const { return directory_; } |
| |
| const char* path() const { return c_path_; } |
| |
| bool IsMicrodumpOnConsole() const { |
| return mode_ == kWriteMicrodumpToConsole; |
| } |
| |
| // Updates the path so it is unique. |
| // Should be called from a normal context: this methods uses the heap. |
| void UpdatePath(); |
| |
| off_t size_limit() const { return size_limit_; } |
| void set_size_limit(off_t limit) { size_limit_ = limit; } |
| |
| uintptr_t address_within_principal_mapping() const { |
| return address_within_principal_mapping_; |
| } |
| void set_address_within_principal_mapping( |
| uintptr_t address_within_principal_mapping) { |
| address_within_principal_mapping_ = address_within_principal_mapping; |
| } |
| |
| bool skip_dump_if_principal_mapping_not_referenced() { |
| return skip_dump_if_principal_mapping_not_referenced_; |
| } |
| void set_skip_dump_if_principal_mapping_not_referenced( |
| bool skip_dump_if_principal_mapping_not_referenced) { |
| skip_dump_if_principal_mapping_not_referenced_ = |
| skip_dump_if_principal_mapping_not_referenced; |
| } |
| |
| bool sanitize_stacks() const { return sanitize_stacks_; } |
| void set_sanitize_stacks(bool sanitize_stacks) { |
| sanitize_stacks_ = sanitize_stacks; |
| } |
| |
| MicrodumpExtraInfo* microdump_extra_info() { |
| assert(IsMicrodumpOnConsole()); |
| return µdump_extra_info_; |
| } |
| |
| private: |
| enum DumpMode { |
| kUninitialized = 0, |
| kWriteMinidumpToFile, |
| kWriteMinidumpToFd, |
| kWriteMicrodumpToConsole |
| }; |
| |
| // Specifies the dump mode (see DumpMode). |
| DumpMode mode_; |
| |
| // The file descriptor where the minidump is generated. |
| int fd_; |
| |
| // The directory where the minidump should be generated. |
| string directory_; |
| |
| // The full path to the generated minidump. |
| string path_; |
| |
| // The C string of |path_|. Precomputed so it can be access from a compromised |
| // context. |
| const char* c_path_; |
| |
| off_t size_limit_; |
| |
| // This member points somewhere into the main module for this |
| // process (the module that is considerered interesting for the |
| // purposes of debugging crashes). |
| uintptr_t address_within_principal_mapping_; |
| |
| // If set, threads that do not reference the address range |
| // associated with |address_within_principal_mapping_| will not have their |
| // stacks logged. |
| bool skip_dump_if_principal_mapping_not_referenced_; |
| |
| // If set, stacks are sanitized to remove PII. This involves |
| // overwriting any pointer-aligned words that are not either |
| // pointers into a process mapping or small integers (+/-4096). This |
| // leaves enough information to unwind stacks, and preserve some |
| // register values, but elides strings and other program data. |
| bool sanitize_stacks_; |
| |
| // The extra microdump data (e.g. product name/version, build |
| // fingerprint, gpu fingerprint) that should be appended to the dump |
| // (microdump only). Microdumps don't have the ability of appending |
| // extra metadata after the dump is generated (as opposite to |
| // minidumps MIME fields), therefore the extra data must be provided |
| // upfront. Any memory pointed to by members of the |
| // MicrodumpExtraInfo struct must be valid for the lifetime of the |
| // process (read: the caller has to guarantee that it is stored in |
| // global static storage.) |
| MicrodumpExtraInfo microdump_extra_info_; |
| }; |
| |
| } // namespace google_breakpad |
| |
| #endif // CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ |