OLD | NEW |
---|---|
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "snapshot/minidump/process_snapshot_minidump.h" | 15 #include "snapshot/minidump/process_snapshot_minidump.h" |
16 | 16 |
17 #include <utility> | |
18 | |
19 #include "base/memory/scoped_ptr.h" | |
17 #include "util/file/file_io.h" | 20 #include "util/file/file_io.h" |
18 #include "snapshot/minidump/minidump_simple_string_dictionary_reader.h" | 21 #include "snapshot/minidump/minidump_simple_string_dictionary_reader.h" |
19 | 22 |
20 namespace crashpad { | 23 namespace crashpad { |
21 | 24 |
22 ProcessSnapshotMinidump::ProcessSnapshotMinidump() | 25 ProcessSnapshotMinidump::ProcessSnapshotMinidump() |
23 : ProcessSnapshot(), | 26 : ProcessSnapshot(), |
24 header_(), | 27 header_(), |
25 stream_directory_(), | 28 stream_directory_(), |
26 stream_map_(), | 29 stream_map_(), |
30 modules_(), | |
27 crashpad_info_(), | 31 crashpad_info_(), |
28 annotations_simple_map_(), | 32 annotations_simple_map_(), |
29 file_reader_(nullptr), | 33 file_reader_(nullptr), |
30 initialized_() { | 34 initialized_() { |
31 } | 35 } |
32 | 36 |
33 ProcessSnapshotMinidump::~ProcessSnapshotMinidump() { | 37 ProcessSnapshotMinidump::~ProcessSnapshotMinidump() { |
34 } | 38 } |
35 | 39 |
36 bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) { | 40 bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 LOG(ERROR) << "duplicate streams for type " << directory.StreamType; | 78 LOG(ERROR) << "duplicate streams for type " << directory.StreamType; |
75 return false; | 79 return false; |
76 } | 80 } |
77 | 81 |
78 stream_map_[stream_type] = &directory.Location; | 82 stream_map_[stream_type] = &directory.Location; |
79 } | 83 } |
80 | 84 |
81 INITIALIZATION_STATE_SET_VALID(initialized_); | 85 INITIALIZATION_STATE_SET_VALID(initialized_); |
82 | 86 |
83 InitializeCrashpadInfo(); | 87 InitializeCrashpadInfo(); |
88 InitializeModules(); | |
84 | 89 |
85 return true; | 90 return true; |
86 } | 91 } |
87 | 92 |
88 pid_t ProcessSnapshotMinidump::ProcessID() const { | 93 pid_t ProcessSnapshotMinidump::ProcessID() const { |
89 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 94 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
90 NOTREACHED(); | 95 NOTREACHED(); |
91 return 0; | 96 return 0; |
92 } | 97 } |
93 | 98 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 } | 144 } |
140 | 145 |
141 std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const { | 146 std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const { |
142 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 147 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
143 NOTREACHED(); | 148 NOTREACHED(); |
144 return std::vector<const ThreadSnapshot*>(); | 149 return std::vector<const ThreadSnapshot*>(); |
145 } | 150 } |
146 | 151 |
147 std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const { | 152 std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const { |
148 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 153 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
149 NOTREACHED(); | 154 std::vector<const ModuleSnapshot*> modules; |
150 return std::vector<const ModuleSnapshot*>(); | 155 for (internal::ModuleSnapshotMinidump* module : modules_) { |
156 modules.push_back(module); | |
157 } | |
158 return modules; | |
151 } | 159 } |
152 | 160 |
153 const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const { | 161 const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const { |
154 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 162 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
155 NOTREACHED(); | 163 NOTREACHED(); |
156 return nullptr; | 164 return nullptr; |
157 } | 165 } |
158 | 166 |
159 void ProcessSnapshotMinidump::InitializeCrashpadInfo() { | 167 void ProcessSnapshotMinidump::InitializeCrashpadInfo() { |
160 const auto& it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo); | 168 const auto& stream_it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo); |
161 if (it == stream_map_.end()) { | 169 if (stream_it == stream_map_.end()) { |
162 return; | 170 return; |
163 } | 171 } |
164 | 172 |
165 if (it->second->DataSize < sizeof(crashpad_info_)) { | 173 if (stream_it->second->DataSize < sizeof(crashpad_info_)) { |
166 LOG(ERROR) << "crashpad_info size mismatch"; | 174 LOG(ERROR) << "crashpad_info size mismatch"; |
167 return; | 175 return; |
168 } | 176 } |
169 | 177 |
170 if (!file_reader_->SeekSet(it->second->Rva)) { | 178 if (!file_reader_->SeekSet(stream_it->second->Rva)) { |
171 return; | 179 return; |
172 } | 180 } |
173 | 181 |
174 if (!file_reader_->ReadExactly(&crashpad_info_, sizeof(crashpad_info_))) { | 182 if (!file_reader_->ReadExactly(&crashpad_info_, sizeof(crashpad_info_))) { |
175 return; | 183 return; |
176 } | 184 } |
177 | 185 |
178 if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) { | 186 if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) { |
179 LOG(ERROR) << "crashpad_info version mismatch"; | 187 LOG(ERROR) << "crashpad_info version mismatch"; |
180 return; | 188 return; |
181 } | 189 } |
182 | 190 |
183 internal::ReadMinidumpSimpleStringDictionary( | 191 internal::ReadMinidumpSimpleStringDictionary( |
184 file_reader_, | 192 file_reader_, |
185 crashpad_info_.simple_annotations, | 193 crashpad_info_.simple_annotations, |
186 &annotations_simple_map_); | 194 &annotations_simple_map_); |
187 } | 195 } |
188 | 196 |
197 bool ProcessSnapshotMinidump::InitializeModules() { | |
198 const auto& stream_it = stream_map_.find(kMinidumpStreamTypeModuleList); | |
199 if (stream_it == stream_map_.end()) { | |
200 return true; | |
201 } | |
202 | |
203 std::map<uint32_t, MINIDUMP_LOCATION_DESCRIPTOR> module_crashpad_info_links; | |
204 InitializeModulesCrashpadInfo(&module_crashpad_info_links); | |
205 | |
206 if (stream_it->second->DataSize < sizeof(MINIDUMP_MODULE_LIST)) { | |
207 LOG(ERROR) << "module_list size mismatch"; | |
208 return false; | |
209 } | |
210 | |
211 if (!file_reader_->SeekSet(stream_it->second->Rva)) { | |
212 return false; | |
213 } | |
214 | |
215 uint32_t module_count; | |
216 if (!file_reader_->ReadExactly(&module_count, sizeof(module_count))) { | |
217 return false; | |
218 } | |
219 | |
220 if (sizeof(MINIDUMP_MODULE_LIST) + module_count * sizeof(MINIDUMP_MODULE) != | |
221 stream_it->second->DataSize) { | |
222 LOG(ERROR) << "module_list size mismatch"; | |
223 return false; | |
224 } | |
225 | |
226 for (uint32_t module_index = 0; module_index < module_count; ++module_index) { | |
227 internal::ModuleSnapshotMinidump* module = | |
Robert Sesek
2015/03/04 01:52:25
Similar to the earlier comment, it'll be easier to
| |
228 new internal::ModuleSnapshotMinidump(); | |
229 modules_.push_back(module); | |
230 | |
231 const RVA module_rva = stream_it->second->Rva + sizeof(module_count) + | |
232 module_index * sizeof(MINIDUMP_MODULE); | |
233 | |
234 const auto& module_crashpad_info_it = | |
235 module_crashpad_info_links.find(module_index); | |
236 const MINIDUMP_LOCATION_DESCRIPTOR* module_crashpad_info_location = | |
237 module_crashpad_info_it != module_crashpad_info_links.end() | |
238 ? &module_crashpad_info_it->second | |
239 : nullptr; | |
240 | |
241 if (!module->Initialize( | |
242 file_reader_, module_rva, module_crashpad_info_location)) { | |
243 delete module; | |
244 modules_.pop_back(); | |
245 return false; | |
246 } | |
247 } | |
248 | |
249 return true; | |
250 } | |
251 | |
252 void ProcessSnapshotMinidump::InitializeModulesCrashpadInfo( | |
253 std::map<uint32_t, MINIDUMP_LOCATION_DESCRIPTOR>* | |
254 module_crashpad_info_links) { | |
255 module_crashpad_info_links->clear(); | |
256 | |
257 if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) { | |
258 return; | |
259 } | |
260 | |
261 if (crashpad_info_.module_list.Rva == 0) { | |
262 return; | |
263 } | |
264 | |
265 if (crashpad_info_.module_list.DataSize < | |
266 sizeof(MinidumpModuleCrashpadInfoList)) { | |
Robert Sesek
2015/03/04 01:52:25
nit: indent +4
| |
267 LOG(ERROR) << "module_crashpad_info_list size mismatch"; | |
268 return; | |
269 } | |
270 | |
271 if (!file_reader_->SeekSet(crashpad_info_.module_list.Rva)) { | |
272 return; | |
273 } | |
274 | |
275 uint32_t crashpad_module_count; | |
276 if (!file_reader_->ReadExactly(&crashpad_module_count, | |
277 sizeof(crashpad_module_count))) { | |
278 return; | |
Robert Sesek
2015/03/04 01:52:25
Similar comment as to returning false under failur
| |
279 } | |
280 | |
281 if (crashpad_info_.module_list.DataSize != | |
282 sizeof(MinidumpModuleCrashpadInfoList) + | |
283 crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink)) { | |
284 LOG(ERROR) << "module_crashpad_info_list size mismatch"; | |
285 return; | |
286 } | |
287 | |
288 scoped_ptr<MinidumpModuleCrashpadInfoLink[]> minidump_links( | |
289 new MinidumpModuleCrashpadInfoLink[crashpad_module_count]); | |
290 if (!file_reader_->ReadExactly( | |
291 &minidump_links[0], | |
292 crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink))) { | |
293 return; | |
294 } | |
295 | |
296 for (uint32_t crashpad_module_index = 0; | |
297 crashpad_module_index < crashpad_module_count; | |
298 ++crashpad_module_index) { | |
299 const MinidumpModuleCrashpadInfoLink& minidump_link = | |
300 minidump_links[crashpad_module_index]; | |
301 if (module_crashpad_info_links->find( | |
302 minidump_link.minidump_module_list_index) != | |
303 module_crashpad_info_links->end()) { | |
304 LOG(WARNING) | |
305 << "duplicate module_crashpad_info_list minidump_module_list_index " | |
306 << minidump_link.minidump_module_list_index << ", discarding"; | |
307 } else { | |
308 module_crashpad_info_links->insert(std::make_pair( | |
309 minidump_link.minidump_module_list_index, minidump_link.location)); | |
310 } | |
311 } | |
312 } | |
313 | |
189 } // namespace crashpad | 314 } // namespace crashpad |
OLD | NEW |