OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #ifndef CRASHPAD_MINIDUMP_MINIDUMP_WRITABLE_H_ | |
16 #define CRASHPAD_MINIDUMP_MINIDUMP_WRITABLE_H_ | |
17 | |
18 #include <dbghelp.h> | |
19 #include <stdint.h> | |
20 #include <sys/types.h> | |
21 | |
22 #include <limits> | |
23 #include <vector> | |
24 | |
25 #include "base/basictypes.h" | |
26 #include "util/file/file_writer.h" | |
27 | |
28 namespace crashpad { | |
29 namespace internal { | |
30 | |
31 //! \brief The base class for all content that might be written to a minidump | |
32 //! file. | |
33 class MinidumpWritable { | |
34 public: | |
35 //! \brief Writes an object and all of its children to a minidump file. | |
36 //! | |
37 //! Use this on the root object of a tree of MinidumpWritable objects, | |
38 //! typically on a MinidumpFileWriter object. | |
39 //! | |
40 //! \param[in] file_writer The file writer to receive the minidump file’s | |
41 //! content. | |
42 //! | |
43 //! \return `true` on success, `false` on failure, with an appropriate message | |
44 //! logged. | |
45 //! | |
46 //! \note Valid in #kStateMutable, and transitions the object and the entire | |
47 //! tree beneath it through all states to #kStateWritten. | |
48 //! | |
49 //! \note This method should rarely, if ever, be overridden. | |
50 virtual bool WriteEverything(FileWriterInterface* file_writer); | |
51 | |
52 //! \brief Registers a file offset pointer as one that should point to the | |
53 //! object on which this method is called. | |
54 //! | |
55 //! Once the file offset at which an object will be written is known (when it | |
56 //! enters #kStateWritable), registered RVA pointers will be updated. | |
57 //! | |
58 //! \param[in] rva A pointer to storage for the file offset that should | |
59 //! contain this object’s writable file offset, once it is known. | |
60 //! | |
61 //! \note Valid in #kStateFrozen or any preceding state. | |
62 // | |
63 // This is public instead of protected because objects of derived classes need | |
Robert Sesek
2014/08/01 14:38:04
Deliberately not //! ?
| |
64 // to be able to register their own pointers with distinct objects. | |
65 void RegisterRVA(RVA* rva); | |
66 | |
67 //! \brief Registers a location descriptor as one that should point to the | |
68 //! object on which this method is called. | |
69 //! | |
70 //! Once an object’s size and the file offset at it will be written is known | |
71 //! (when it enters #kStateFrozen), the relevant data in registered location | |
72 //! descriptors will be updated. | |
73 //! | |
74 //! \param[in] location_descriptor A pointer to a location descriptor that | |
75 //! should contain this object’s writable size and file offset, once they | |
76 //! are known. | |
77 //! | |
78 //! \note Valid in #kStateFrozen or any preceding state. | |
79 // | |
80 // This is public instead of protected because objects of derived classes need | |
81 // to be able to register their own pointers with distinct objects. | |
82 void RegisterLocationDescriptor( | |
83 MINIDUMP_LOCATION_DESCRIPTOR* location_descriptor); | |
84 | |
85 protected: | |
86 //! \brief Identifies the state of an object. | |
87 //! | |
88 //! Objects will normally transition through each of these states as they are | |
89 //! created, populated with data, and then written to a minidump file. | |
90 enum State { | |
91 //! \brief The object’s properties can be modified. | |
92 kStateMutable = 0, | |
93 | |
94 //! \brief The object is “frozen”. | |
95 //! | |
96 //! Its properties cannot be modified. Pointers to file offsets of other | |
97 //! structures may not yet be valid. | |
98 kStateFrozen, | |
99 | |
100 //! \brief The object is writable. | |
101 //! | |
102 //! The file offset at which it will be written is known. Pointers to file | |
103 //! offsets of other structures are valid when all objects in a tree are in | |
104 //! this state. | |
105 kStateWritable, | |
106 | |
107 //! \brief The object has been written to a minidump file. | |
108 kStateWritten, | |
109 }; | |
110 | |
111 //! \brief Identifies the phase during which an object will be written to a | |
112 //! minidump file. | |
113 enum Phase { | |
114 //! \brief Objects that are written to a minidump file “early”. | |
115 //! | |
116 //! The normal sequence is for an object to write itself and then write all | |
117 //! of its children. | |
118 kPhaseEarly = 0, | |
119 | |
120 //! \brief Objects that are written to a minidump file “late”. | |
121 //! | |
122 //! Some objects, such as those capturing memory region snapshots, are | |
123 //! written to minidump files after all other objects. This “late” phase | |
124 //! identifies such objects. This is useful to improve spatial locality in | |
125 //! in minidump files in accordance with expected access patterns: unlike | |
126 //! most other data, memory snapshots are large and the entire snapshots do | |
127 //! not need to be consulted in order to process a minidump file. | |
128 kPhaseLate, | |
129 }; | |
130 | |
131 //! \brief A size value used to signal failure by methods that return | |
132 //! `size_t`. | |
133 static const size_t kInvalidSize; | |
134 | |
135 MinidumpWritable(); | |
136 ~MinidumpWritable(); | |
Robert Sesek
2014/08/01 14:38:04
virtual?
| |
137 | |
138 //! \brief The state of the object. | |
139 State state() const { return state_; } | |
140 | |
141 //! \brief Transitions the object from #kStateMutable to #kStateFrozen. | |
142 //! | |
143 //! The default implementation marks the object as frozen and recursively | |
144 //! calls Freeze() on all of its children. Subclasses may override this method | |
145 //! to perform processing that should only be done once callers have finished | |
146 //! populating an object with data. Typically, a subclass implementation would | |
147 //! call RegisterRVA() or RegisterLocationDescriptor() on other objects as | |
148 //! appropriate, because at the time Freeze() runs, the in-memory locations of | |
149 //! RVAs and location descriptors are known and will not change for the | |
150 //! remaining duration of an object’s lifetime. | |
151 //! | |
152 //! \return `true` on success, `false` on failure, with an appropriate message | |
153 //! logged. | |
154 virtual bool Freeze(); | |
155 | |
156 //! \brief Returns the amount of space that this object will consume when | |
157 //! written to a minidump file, in bytes, not including any leading or | |
158 //! trailing padding necessary to maintain proper alignment. | |
159 //! | |
160 //! \note Valid in #kStateFrozen or any subsequent state. | |
161 virtual size_t SizeOfObject() = 0; | |
162 | |
163 //! \brief Returns the object’s desired byte-boundary alignment. | |
164 //! | |
165 //! The default implementation returns `4`. Subclasses may override this as | |
166 //! needed. | |
167 //! | |
168 //! \note Valid in #kStateFrozen or any subsequent state. | |
169 virtual size_t Alignment(); | |
170 | |
171 //! \brief Returns the object’s children. | |
172 //! | |
173 //! \note Valid in #kStateFrozen or any subsequent state. | |
174 virtual std::vector<MinidumpWritable*> Children(); | |
175 | |
176 //! \brief Returns the object’s desired write phase. | |
177 //! | |
178 //! \note Valid in any state. | |
179 virtual Phase WritePhase(); | |
180 | |
181 //! \brief Prepares the object to be written at a known file offset, | |
182 //! transitioning it from #kStateFrozen to #kStateWritable. | |
183 //! | |
184 //! This method is responsible for determining the final file offset of the | |
185 //! object, which may be increased from \a offset to meet alignment | |
186 //! requirements. It calls WillWriteAtOffsetImpl() for the benefit of | |
187 //! subclasses. It populates all RVAs and location descriptors registered with | |
188 //! it via RegisterRVA() and RegisterLocationDescriptor(). It also recurses | |
189 //! into all known children. | |
190 //! | |
191 //! \param[in] phase The phase during which the object will be written. If | |
192 //! this does not match Phase(), processing is suppressed, although | |
193 //! recursive processing will still occur on all children. This addresses | |
194 //! the case where parents and children do not write in the same phase. | |
195 //! \param[in] offset The file offset at which the object will be written. The | |
196 //! offset may need to be adjusted for alignment. | |
197 //! \param[out] write_sequence This object will append itself to this list, | |
198 //! such that on return from a recursive tree of WillWriteAtOffset() | |
199 //! calls, elements of the vector will be organized in the sequence that | |
200 //! the objects will be written to the minidump file. | |
201 //! | |
202 //! \return The file size consumed by this object and all children, including | |
203 //! any padding inserted to meet alignment requirements. On failure, | |
204 //! #kInvalidSize, with an appropriate message logged. | |
205 //! | |
206 //! \note This method cannot be overridden. Subclasses that need to perform | |
207 //! processing when an object transitions to #kStateWritable should | |
208 //! implement WillWriteAtOffsetImpl(), which is called by this method. | |
209 size_t WillWriteAtOffset(Phase phase, | |
210 off_t* offset, | |
211 std::vector<MinidumpWritable*>* write_sequence); | |
212 | |
213 //! \brief Called once an object’s writable file offset is determined, as it | |
214 //! transitions into #kStateWritable. | |
215 //! | |
216 //! Subclasses can override this method if they need to provide additional | |
217 //! processing once their writable file offset is known. Typically, this will | |
218 //! be done by subclasses that handle certain RVAs themselves instead of using | |
219 //! the RegisterRVA() interface. | |
220 //! | |
221 //! \param[in] offset The file offset at which the object will be written. The | |
222 //! value passed to this method will already have been adjusted to meet | |
223 //! alignment requirements. | |
224 //! | |
225 //! \return `true` on success, `false` on error, indicating that the minidump | |
226 //! file should not be written. | |
227 //! | |
228 //! \note Valid in #kStateFrozen. The object will transition to | |
229 //! #kStateWritable after this method returns. | |
230 virtual bool WillWriteAtOffsetImpl(off_t offset); | |
231 | |
232 //! \brief Writes the object, transitioning it from #kStateWritable to | |
233 //! #kStateWritten. | |
234 //! | |
235 //! Writes any padding necessary to meet alignment requirements, and then | |
236 //! calls WriteObject() to write the object’s content. | |
237 //! | |
238 //! \param[in] file_writer The file writer to receive the object’s content. | |
239 //! | |
240 //! \return `true` on success, `false` on error with an appropriate message | |
241 //! logged. | |
242 //! | |
243 //! \note This method cannot be overridden. Subclasses must override | |
244 //! WriteObject(). | |
245 bool WritePaddingAndObject(FileWriterInterface* file_writer); | |
246 | |
247 //! \brief Writes the object’s content. | |
248 //! | |
249 //! \param[in] file_writer The file writer to receive the object’s content. | |
250 //! | |
251 //! \return `true` on success, `false` on error, indicating that the content | |
252 //! could not be written to the minidump file. | |
253 //! | |
254 //! \note Valid in #kStateWritable. The object will transition to | |
255 //! #kStateWritten after this method returns. | |
256 virtual bool WriteObject(FileWriterInterface* file_writer) = 0; | |
257 | |
258 private: | |
259 std::vector<RVA*> registered_rvas_; | |
260 std::vector<MINIDUMP_LOCATION_DESCRIPTOR*> registered_location_descriptors_; | |
261 size_t leading_pad_bytes_; | |
262 State state_; | |
263 | |
264 DISALLOW_COPY_AND_ASSIGN(MinidumpWritable); | |
265 }; | |
266 | |
267 } // namespace internal | |
268 } // namespace crashpad | |
269 | |
270 #endif // CRASHPAD_MINIDUMP_MINIDUMP_WRITABLE_H_ | |
OLD | NEW |