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). |
46 | namespace google_breakpad { |
47 | |
48 | class 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* () { |
138 | assert(IsMicrodumpOnConsole()); |
139 | return µdump_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 ; |
195 | }; |
196 | |
197 | } // namespace google_breakpad |
198 | |
199 | #endif // CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ |
200 | |