1// Copyright (c) 2012 Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#ifndef CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_
31#define CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_
32
33#include <assert.h>
34#include <sys/types.h>
35
36#include <string>
37
38#include "client/linux/handler/microdump_extra_info.h"
39#include "common/using_std_string.h"
40
41// This class describes how a crash dump should be generated, either:
42// - Writing a full minidump to a file in a given directory (the actual path,
43// inside the directory, is determined by this class).
44// - Writing a full minidump to a given fd.
45// - Writing a reduced microdump to the console (logcat on Android).
46namespace google_breakpad {
47
48class MinidumpDescriptor {
49 public:
50 struct MicrodumpOnConsole {};
51 static const MicrodumpOnConsole kMicrodumpOnConsole;
52
53 MinidumpDescriptor()
54 : mode_(kUninitialized),
55 fd_(-1),
56 size_limit_(-1),
57 address_within_principal_mapping_(0),
58 skip_dump_if_principal_mapping_not_referenced_(false) {}
59
60 explicit MinidumpDescriptor(const string& directory)
61 : mode_(kWriteMinidumpToFile),
62 fd_(-1),
63 directory_(directory),
64 c_path_(NULL),
65 size_limit_(-1),
66 address_within_principal_mapping_(0),
67 skip_dump_if_principal_mapping_not_referenced_(false),
68 sanitize_stacks_(false) {
69 assert(!directory.empty());
70 }
71
72 explicit MinidumpDescriptor(int fd)
73 : mode_(kWriteMinidumpToFd),
74 fd_(fd),
75 c_path_(NULL),
76 size_limit_(-1),
77 address_within_principal_mapping_(0),
78 skip_dump_if_principal_mapping_not_referenced_(false),
79 sanitize_stacks_(false) {
80 assert(fd != -1);
81 }
82
83 explicit MinidumpDescriptor(const MicrodumpOnConsole&)
84 : mode_(kWriteMicrodumpToConsole),
85 fd_(-1),
86 size_limit_(-1),
87 address_within_principal_mapping_(0),
88 skip_dump_if_principal_mapping_not_referenced_(false),
89 sanitize_stacks_(false) {}
90
91 explicit MinidumpDescriptor(const MinidumpDescriptor& descriptor);
92 MinidumpDescriptor& operator=(const MinidumpDescriptor& descriptor);
93
94 static MinidumpDescriptor getMicrodumpDescriptor();
95
96 bool IsFD() const { return mode_ == kWriteMinidumpToFd; }
97
98 int fd() const { return fd_; }
99
100 string directory() const { return directory_; }
101
102 const char* path() const { return c_path_; }
103
104 bool IsMicrodumpOnConsole() const {
105 return mode_ == kWriteMicrodumpToConsole;
106 }
107
108 // Updates the path so it is unique.
109 // Should be called from a normal context: this methods uses the heap.
110 void UpdatePath();
111
112 off_t size_limit() const { return size_limit_; }
113 void set_size_limit(off_t limit) { size_limit_ = limit; }
114
115 uintptr_t address_within_principal_mapping() const {
116 return address_within_principal_mapping_;
117 }
118 void set_address_within_principal_mapping(
119 uintptr_t address_within_principal_mapping) {
120 address_within_principal_mapping_ = address_within_principal_mapping;
121 }
122
123 bool skip_dump_if_principal_mapping_not_referenced() {
124 return skip_dump_if_principal_mapping_not_referenced_;
125 }
126 void set_skip_dump_if_principal_mapping_not_referenced(
127 bool skip_dump_if_principal_mapping_not_referenced) {
128 skip_dump_if_principal_mapping_not_referenced_ =
129 skip_dump_if_principal_mapping_not_referenced;
130 }
131
132 bool sanitize_stacks() const { return sanitize_stacks_; }
133 void set_sanitize_stacks(bool sanitize_stacks) {
134 sanitize_stacks_ = sanitize_stacks;
135 }
136
137 MicrodumpExtraInfo* microdump_extra_info() {
138 assert(IsMicrodumpOnConsole());
139 return &microdump_extra_info_;
140 }
141
142 private:
143 enum DumpMode {
144 kUninitialized = 0,
145 kWriteMinidumpToFile,
146 kWriteMinidumpToFd,
147 kWriteMicrodumpToConsole
148 };
149
150 // Specifies the dump mode (see DumpMode).
151 DumpMode mode_;
152
153 // The file descriptor where the minidump is generated.
154 int fd_;
155
156 // The directory where the minidump should be generated.
157 string directory_;
158
159 // The full path to the generated minidump.
160 string path_;
161
162 // The C string of |path_|. Precomputed so it can be access from a compromised
163 // context.
164 const char* c_path_;
165
166 off_t size_limit_;
167
168 // This member points somewhere into the main module for this
169 // process (the module that is considerered interesting for the
170 // purposes of debugging crashes).
171 uintptr_t address_within_principal_mapping_;
172
173 // If set, threads that do not reference the address range
174 // associated with |address_within_principal_mapping_| will not have their
175 // stacks logged.
176 bool skip_dump_if_principal_mapping_not_referenced_;
177
178 // If set, stacks are sanitized to remove PII. This involves
179 // overwriting any pointer-aligned words that are not either
180 // pointers into a process mapping or small integers (+/-4096). This
181 // leaves enough information to unwind stacks, and preserve some
182 // register values, but elides strings and other program data.
183 bool sanitize_stacks_;
184
185 // The extra microdump data (e.g. product name/version, build
186 // fingerprint, gpu fingerprint) that should be appended to the dump
187 // (microdump only). Microdumps don't have the ability of appending
188 // extra metadata after the dump is generated (as opposite to
189 // minidumps MIME fields), therefore the extra data must be provided
190 // upfront. Any memory pointed to by members of the
191 // MicrodumpExtraInfo struct must be valid for the lifetime of the
192 // process (read: the caller has to guarantee that it is stored in
193 // global static storage.)
194 MicrodumpExtraInfo microdump_extra_info_;
195};
196
197} // namespace google_breakpad
198
199#endif // CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_
200