Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: third_party/crashpad/crashpad/minidump/minidump_file_writer.cc

Issue 2773813002: Update Crashpad to 8e37886d418dd042c3c7bfadac99214739ee4d98 (Closed)
Patch Set: Update Crashpad to 8e37886d418dd042c3c7bfadac99214739ee4d98 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 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,
(...skipping 11 matching lines...) Expand all
22 #include "minidump/minidump_exception_writer.h" 22 #include "minidump/minidump_exception_writer.h"
23 #include "minidump/minidump_handle_writer.h" 23 #include "minidump/minidump_handle_writer.h"
24 #include "minidump/minidump_memory_info_writer.h" 24 #include "minidump/minidump_memory_info_writer.h"
25 #include "minidump/minidump_memory_writer.h" 25 #include "minidump/minidump_memory_writer.h"
26 #include "minidump/minidump_misc_info_writer.h" 26 #include "minidump/minidump_misc_info_writer.h"
27 #include "minidump/minidump_module_writer.h" 27 #include "minidump/minidump_module_writer.h"
28 #include "minidump/minidump_system_info_writer.h" 28 #include "minidump/minidump_system_info_writer.h"
29 #include "minidump/minidump_thread_id_map.h" 29 #include "minidump/minidump_thread_id_map.h"
30 #include "minidump/minidump_thread_writer.h" 30 #include "minidump/minidump_thread_writer.h"
31 #include "minidump/minidump_unloaded_module_writer.h" 31 #include "minidump/minidump_unloaded_module_writer.h"
32 #include "minidump/minidump_user_extension_stream_data_source.h"
32 #include "minidump/minidump_user_stream_writer.h" 33 #include "minidump/minidump_user_stream_writer.h"
33 #include "minidump/minidump_writer_util.h" 34 #include "minidump/minidump_writer_util.h"
34 #include "snapshot/exception_snapshot.h" 35 #include "snapshot/exception_snapshot.h"
35 #include "snapshot/module_snapshot.h" 36 #include "snapshot/module_snapshot.h"
36 #include "snapshot/process_snapshot.h" 37 #include "snapshot/process_snapshot.h"
37 #include "util/file/file_writer.h" 38 #include "util/file/file_writer.h"
38 #include "util/numeric/safe_assignment.h" 39 #include "util/numeric/safe_assignment.h"
39 40
40 namespace crashpad { 41 namespace crashpad {
41 42
(...skipping 25 matching lines...) Expand all
67 // done by MinidumpMiscInfoWriter::InitializeFromSnapshot(). Handling both 68 // done by MinidumpMiscInfoWriter::InitializeFromSnapshot(). Handling both
68 // timestamps in the same way allows the highest-fidelity computation of 69 // timestamps in the same way allows the highest-fidelity computation of
69 // process uptime as the difference between the two values. 70 // process uptime as the difference between the two values.
70 timeval snapshot_time; 71 timeval snapshot_time;
71 process_snapshot->SnapshotTime(&snapshot_time); 72 process_snapshot->SnapshotTime(&snapshot_time);
72 SetTimestamp(snapshot_time.tv_sec); 73 SetTimestamp(snapshot_time.tv_sec);
73 74
74 const SystemSnapshot* system_snapshot = process_snapshot->System(); 75 const SystemSnapshot* system_snapshot = process_snapshot->System();
75 auto system_info = base::WrapUnique(new MinidumpSystemInfoWriter()); 76 auto system_info = base::WrapUnique(new MinidumpSystemInfoWriter());
76 system_info->InitializeFromSnapshot(system_snapshot); 77 system_info->InitializeFromSnapshot(system_snapshot);
77 AddStream(std::move(system_info)); 78 bool add_stream_result = AddStream(std::move(system_info));
79 DCHECK(add_stream_result);
78 80
79 auto misc_info = base::WrapUnique(new MinidumpMiscInfoWriter()); 81 auto misc_info = base::WrapUnique(new MinidumpMiscInfoWriter());
80 misc_info->InitializeFromSnapshot(process_snapshot); 82 misc_info->InitializeFromSnapshot(process_snapshot);
81 AddStream(std::move(misc_info)); 83 add_stream_result = AddStream(std::move(misc_info));
84 DCHECK(add_stream_result);
82 85
83 auto memory_list = base::WrapUnique(new MinidumpMemoryListWriter()); 86 auto memory_list = base::WrapUnique(new MinidumpMemoryListWriter());
84 auto thread_list = base::WrapUnique(new MinidumpThreadListWriter()); 87 auto thread_list = base::WrapUnique(new MinidumpThreadListWriter());
85 thread_list->SetMemoryListWriter(memory_list.get()); 88 thread_list->SetMemoryListWriter(memory_list.get());
86 MinidumpThreadIDMap thread_id_map; 89 MinidumpThreadIDMap thread_id_map;
87 thread_list->InitializeFromSnapshot(process_snapshot->Threads(), 90 thread_list->InitializeFromSnapshot(process_snapshot->Threads(),
88 &thread_id_map); 91 &thread_id_map);
89 AddStream(std::move(thread_list)); 92 add_stream_result = AddStream(std::move(thread_list));
93 DCHECK(add_stream_result);
90 94
91 const ExceptionSnapshot* exception_snapshot = process_snapshot->Exception(); 95 const ExceptionSnapshot* exception_snapshot = process_snapshot->Exception();
92 if (exception_snapshot) { 96 if (exception_snapshot) {
93 auto exception = base::WrapUnique(new MinidumpExceptionWriter()); 97 auto exception = base::WrapUnique(new MinidumpExceptionWriter());
94 exception->InitializeFromSnapshot(exception_snapshot, thread_id_map); 98 exception->InitializeFromSnapshot(exception_snapshot, thread_id_map);
95 AddStream(std::move(exception)); 99 add_stream_result = AddStream(std::move(exception));
100 DCHECK(add_stream_result);
96 } 101 }
97 102
98 auto module_list = base::WrapUnique(new MinidumpModuleListWriter()); 103 auto module_list = base::WrapUnique(new MinidumpModuleListWriter());
99 module_list->InitializeFromSnapshot(process_snapshot->Modules()); 104 module_list->InitializeFromSnapshot(process_snapshot->Modules());
100 AddStream(std::move(module_list)); 105 add_stream_result = AddStream(std::move(module_list));
101 106 DCHECK(add_stream_result);
102 for (const auto& module : process_snapshot->Modules()) {
103 for (const UserMinidumpStream* stream : module->CustomMinidumpStreams()) {
104 auto user_stream = base::WrapUnique(new MinidumpUserStreamWriter());
105 user_stream->InitializeFromSnapshot(stream);
106 AddStream(std::move(user_stream));
107 }
108 }
109 107
110 auto unloaded_modules = process_snapshot->UnloadedModules(); 108 auto unloaded_modules = process_snapshot->UnloadedModules();
111 if (!unloaded_modules.empty()) { 109 if (!unloaded_modules.empty()) {
112 auto unloaded_module_list = 110 auto unloaded_module_list =
113 base::WrapUnique(new MinidumpUnloadedModuleListWriter()); 111 base::WrapUnique(new MinidumpUnloadedModuleListWriter());
114 unloaded_module_list->InitializeFromSnapshot(unloaded_modules); 112 unloaded_module_list->InitializeFromSnapshot(unloaded_modules);
115 AddStream(std::move(unloaded_module_list)); 113 add_stream_result = AddStream(std::move(unloaded_module_list));
114 DCHECK(add_stream_result);
116 } 115 }
117 116
118 auto crashpad_info = base::WrapUnique(new MinidumpCrashpadInfoWriter()); 117 auto crashpad_info = base::WrapUnique(new MinidumpCrashpadInfoWriter());
119 crashpad_info->InitializeFromSnapshot(process_snapshot); 118 crashpad_info->InitializeFromSnapshot(process_snapshot);
120 119
121 // Since the MinidumpCrashpadInfo stream is an extension, it’s safe to not add 120 // Since the MinidumpCrashpadInfo stream is an extension, it’s safe to not add
122 // it to the minidump file if it wouldn’t carry any useful information. 121 // it to the minidump file if it wouldn’t carry any useful information.
123 if (crashpad_info->IsUseful()) { 122 if (crashpad_info->IsUseful()) {
124 AddStream(std::move(crashpad_info)); 123 add_stream_result = AddStream(std::move(crashpad_info));
124 DCHECK(add_stream_result);
125 } 125 }
126 126
127 std::vector<const MemoryMapRegionSnapshot*> memory_map_snapshot = 127 std::vector<const MemoryMapRegionSnapshot*> memory_map_snapshot =
128 process_snapshot->MemoryMap(); 128 process_snapshot->MemoryMap();
129 if (!memory_map_snapshot.empty()) { 129 if (!memory_map_snapshot.empty()) {
130 auto memory_info_list = 130 auto memory_info_list =
131 base::WrapUnique(new MinidumpMemoryInfoListWriter()); 131 base::WrapUnique(new MinidumpMemoryInfoListWriter());
132 memory_info_list->InitializeFromSnapshot(memory_map_snapshot); 132 memory_info_list->InitializeFromSnapshot(memory_map_snapshot);
133 AddStream(std::move(memory_info_list)); 133 add_stream_result = AddStream(std::move(memory_info_list));
134 DCHECK(add_stream_result);
134 } 135 }
135 136
136 std::vector<HandleSnapshot> handles_snapshot = process_snapshot->Handles(); 137 std::vector<HandleSnapshot> handles_snapshot = process_snapshot->Handles();
137 if (!handles_snapshot.empty()) { 138 if (!handles_snapshot.empty()) {
138 auto handle_data_writer = base::WrapUnique(new MinidumpHandleDataWriter()); 139 auto handle_data_writer = base::WrapUnique(new MinidumpHandleDataWriter());
139 handle_data_writer->InitializeFromSnapshot(handles_snapshot); 140 handle_data_writer->InitializeFromSnapshot(handles_snapshot);
140 AddStream(std::move(handle_data_writer)); 141 add_stream_result = AddStream(std::move(handle_data_writer));
142 DCHECK(add_stream_result);
141 } 143 }
142 144
143 memory_list->AddFromSnapshot(process_snapshot->ExtraMemory()); 145 memory_list->AddFromSnapshot(process_snapshot->ExtraMemory());
144 if (exception_snapshot) 146 if (exception_snapshot) {
145 memory_list->AddFromSnapshot(exception_snapshot->ExtraMemory()); 147 memory_list->AddFromSnapshot(exception_snapshot->ExtraMemory());
148 }
146 149
147 AddStream(std::move(memory_list)); 150 // These user streams must be added last. Otherwise, a user stream with the
151 // same type as a well-known stream could preempt the well-known stream. As it
152 // stands now, earlier-discovered user streams can still preempt
153 // later-discovered ones. The well-known memory list stream is added after
154 // these user streams, but only with a check here to avoid adding a user
155 // stream that would preempt the memory list stream.
156 for (const auto& module : process_snapshot->Modules()) {
157 for (const UserMinidumpStream* stream : module->CustomMinidumpStreams()) {
158 if (stream->stream_type() == kMinidumpStreamTypeMemoryList) {
159 LOG(WARNING) << "discarding duplicate stream of type "
160 << stream->stream_type();
161 continue;
162 }
163 auto user_stream = base::WrapUnique(new MinidumpUserStreamWriter());
164 user_stream->InitializeFromSnapshot(stream);
165 AddStream(std::move(user_stream));
166 }
167 }
168
169 // The memory list stream should be added last. This keeps the “extra memory”
170 // at the end so that if the minidump file is truncated, other, more critical
171 // data is more likely to be preserved. Note that non-“extra” memory regions
172 // will not have to ride at the end of the file. Thread stack memory, for
173 // example, exists as a children of threads, and appears alongside them in the
174 // file, despite also being mentioned by the memory list stream.
175 add_stream_result = AddStream(std::move(memory_list));
176 DCHECK(add_stream_result);
148 } 177 }
149 178
150 void MinidumpFileWriter::SetTimestamp(time_t timestamp) { 179 void MinidumpFileWriter::SetTimestamp(time_t timestamp) {
151 DCHECK_EQ(state(), kStateMutable); 180 DCHECK_EQ(state(), kStateMutable);
152 181
153 internal::MinidumpWriterUtil::AssignTimeT(&header_.TimeDateStamp, timestamp); 182 internal::MinidumpWriterUtil::AssignTimeT(&header_.TimeDateStamp, timestamp);
154 } 183 }
155 184
156 void MinidumpFileWriter::AddStream( 185 bool MinidumpFileWriter::AddStream(
157 std::unique_ptr<internal::MinidumpStreamWriter> stream) { 186 std::unique_ptr<internal::MinidumpStreamWriter> stream) {
158 DCHECK_EQ(state(), kStateMutable); 187 DCHECK_EQ(state(), kStateMutable);
159 188
160 MinidumpStreamType stream_type = stream->StreamType(); 189 MinidumpStreamType stream_type = stream->StreamType();
161 190
162 auto rv = stream_types_.insert(stream_type); 191 auto rv = stream_types_.insert(stream_type);
163 CHECK(rv.second) << "stream_type " << stream_type << " already present"; 192 if (!rv.second) {
193 LOG(WARNING) << "discarding duplicate stream of type " << stream_type;
194 return false;
195 }
164 196
165 streams_.push_back(stream.release()); 197 streams_.push_back(stream.release());
166 198
167 DCHECK_EQ(streams_.size(), stream_types_.size()); 199 DCHECK_EQ(streams_.size(), stream_types_.size());
200 return true;
201 }
202
203 bool MinidumpFileWriter::AddUserExtensionStream(
204 std::unique_ptr<MinidumpUserExtensionStreamDataSource>
205 user_extension_stream_data) {
206 DCHECK_EQ(state(), kStateMutable);
207
208 auto user_stream = base::WrapUnique(new MinidumpUserStreamWriter());
209 user_stream->InitializeFromBuffer(user_extension_stream_data->stream_type(),
210 user_extension_stream_data->buffer(),
211 user_extension_stream_data->buffer_size());
212
213 return AddStream(std::move(user_stream));
168 } 214 }
169 215
170 bool MinidumpFileWriter::WriteEverything(FileWriterInterface* file_writer) { 216 bool MinidumpFileWriter::WriteEverything(FileWriterInterface* file_writer) {
171 DCHECK_EQ(state(), kStateMutable); 217 DCHECK_EQ(state(), kStateMutable);
172 218
173 FileOffset start_offset = file_writer->Seek(0, SEEK_CUR); 219 FileOffset start_offset = file_writer->Seek(0, SEEK_CUR);
174 if (start_offset < 0) { 220 if (start_offset < 0) {
175 return false; 221 return false;
176 } 222 }
177 223
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 for (internal::MinidumpStreamWriter* stream : streams_) { 311 for (internal::MinidumpStreamWriter* stream : streams_) {
266 iov.iov_base = stream->DirectoryListEntry(); 312 iov.iov_base = stream->DirectoryListEntry();
267 iov.iov_len = sizeof(MINIDUMP_DIRECTORY); 313 iov.iov_len = sizeof(MINIDUMP_DIRECTORY);
268 iovecs.push_back(iov); 314 iovecs.push_back(iov);
269 } 315 }
270 316
271 return file_writer->WriteIoVec(&iovecs); 317 return file_writer->WriteIoVec(&iovecs);
272 } 318 }
273 319
274 } // namespace crashpad 320 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698