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

Side by Side Diff: snapshot/minidump/process_snapshot_minidump_test.cc

Issue 972383002: snapshot: Add a minimal ModuleSnapshotMinidump and accessor from ProcessSnapshotMinidump (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Add NOTREACHED() comments Created 5 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
« no previous file with comments | « snapshot/minidump/process_snapshot_minidump.cc ('k') | snapshot/snapshot.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <string.h> 17 #include <string.h>
18 #include <windows.h> 18 #include <windows.h>
19 #include <dbghelp.h> 19 #include <dbghelp.h>
20 20
21 #include "base/memory/scoped_ptr.h" 21 #include "base/memory/scoped_ptr.h"
22 #include "gtest/gtest.h" 22 #include "gtest/gtest.h"
23 #include "snapshot/module_snapshot.h"
23 #include "util/file/string_file.h" 24 #include "util/file/string_file.h"
24 25
25 namespace crashpad { 26 namespace crashpad {
26 namespace test { 27 namespace test {
27 namespace { 28 namespace {
28 29
29 TEST(ProcessSnapshotMinidump, EmptyFile) { 30 TEST(ProcessSnapshotMinidump, EmptyFile) {
30 StringFile string_file; 31 StringFile string_file;
31 ProcessSnapshotMinidump process_snapshot; 32 ProcessSnapshotMinidump process_snapshot;
32 33
(...skipping 17 matching lines...) Expand all
50 MINIDUMP_HEADER header = {}; 51 MINIDUMP_HEADER header = {};
51 header.Signature = MINIDUMP_SIGNATURE; 52 header.Signature = MINIDUMP_SIGNATURE;
52 header.Version = MINIDUMP_VERSION; 53 header.Version = MINIDUMP_VERSION;
53 54
54 EXPECT_TRUE(string_file.Write(&header, sizeof(header))); 55 EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
55 56
56 ProcessSnapshotMinidump process_snapshot; 57 ProcessSnapshotMinidump process_snapshot;
57 EXPECT_TRUE(process_snapshot.Initialize(&string_file)); 58 EXPECT_TRUE(process_snapshot.Initialize(&string_file));
58 } 59 }
59 60
61 // Writes |string| to |writer| as a MinidumpUTF8String, and returns the file
62 // offst of the beginning of the string.
63 RVA WriteString(FileWriterInterface* writer, const std::string& string) {
64 RVA rva = static_cast<RVA>(writer->SeekGet());
65
66 uint32_t string_size = string.size();
67 EXPECT_TRUE(writer->Write(&string_size, sizeof(string_size)));
68
69 // Include the trailing NUL character.
70 EXPECT_TRUE(writer->Write(string.c_str(), string.size() + 1));
71
72 return rva;
73 }
74
75 // Writes |dictionary| to |writer| as a MinidumpSimpleStringDictionary, and
76 // populates |location| with a location descriptor identifying what was written.
77 void WriteMinidumpSimpleStringDictionary(
78 MINIDUMP_LOCATION_DESCRIPTOR* location,
79 FileWriterInterface* writer,
80 const std::map<std::string, std::string>& dictionary) {
81 std::vector<MinidumpSimpleStringDictionaryEntry> entries;
82 for (const auto& it : dictionary) {
83 MinidumpSimpleStringDictionaryEntry entry;
84 entry.key = WriteString(writer, it.first);
85 entry.value = WriteString(writer, it.second);
86 entries.push_back(entry);
87 }
88
89 location->Rva = static_cast<RVA>(writer->SeekGet());
90
91 const uint32_t simple_string_dictionary_entries = entries.size();
92 EXPECT_TRUE(writer->Write(&simple_string_dictionary_entries,
93 sizeof(simple_string_dictionary_entries)));
94 for (const MinidumpSimpleStringDictionaryEntry& entry : entries) {
95 EXPECT_TRUE(writer->Write(&entry, sizeof(entry)));
96 }
97
98 location->DataSize =
99 sizeof(simple_string_dictionary_entries) +
100 entries.size() * sizeof(MinidumpSimpleStringDictionaryEntry);
101 }
102
103 // Writes |strings| to |writer| as a MinidumpRVAList referencing
104 // MinidumpUTF8String objects, and populates |location| with a location
105 // descriptor identifying what was written.
106 void WriteMinidumpStringList(MINIDUMP_LOCATION_DESCRIPTOR* location,
107 FileWriterInterface* writer,
108 const std::vector<std::string>& strings) {
109 std::vector<RVA> rvas;
110 for (const std::string& string : strings) {
111 rvas.push_back(WriteString(writer, string));
112 }
113
114 location->Rva = static_cast<RVA>(writer->SeekGet());
115
116 const uint32_t string_list_entries = rvas.size();
117 EXPECT_TRUE(writer->Write(&string_list_entries, sizeof(string_list_entries)));
118 for (RVA rva : rvas) {
119 EXPECT_TRUE(writer->Write(&rva, sizeof(rva)));
120 }
121
122 location->DataSize = sizeof(string_list_entries) + rvas.size() * sizeof(RVA);
123 }
124
60 TEST(ProcessSnapshotMinidump, AnnotationsSimpleMap) { 125 TEST(ProcessSnapshotMinidump, AnnotationsSimpleMap) {
61 StringFile string_file; 126 StringFile string_file;
62 127
63 MINIDUMP_HEADER header = {}; 128 MINIDUMP_HEADER header = {};
64 EXPECT_TRUE(string_file.Write(&header, sizeof(header))); 129 EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
65 130
66 MinidumpSimpleStringDictionaryEntry entry0 = {};
67 entry0.key = static_cast<RVA>(string_file.SeekGet());
68 const char kKey0[] = "the first key";
69 uint32_t string_size = strlen(kKey0);
70 EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
71 EXPECT_TRUE(string_file.Write(kKey0, sizeof(kKey0)));
72
73 entry0.value = static_cast<RVA>(string_file.SeekGet());
74 const char kValue0[] = "THE FIRST VALUE EVER!";
75 string_size = strlen(kValue0);
76 EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
77 EXPECT_TRUE(string_file.Write(kValue0, sizeof(kValue0)));
78
79 MinidumpSimpleStringDictionaryEntry entry1 = {};
80 entry1.key = static_cast<RVA>(string_file.SeekGet());
81 const char kKey1[] = "2key";
82 string_size = strlen(kKey1);
83 EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
84 EXPECT_TRUE(string_file.Write(kKey1, sizeof(kKey1)));
85
86 entry1.value = static_cast<RVA>(string_file.SeekGet());
87 const char kValue1[] = "a lowly second value";
88 string_size = strlen(kValue1);
89 EXPECT_TRUE(string_file.Write(&string_size, sizeof(string_size)));
90 EXPECT_TRUE(string_file.Write(kValue1, sizeof(kValue1)));
91
92 MinidumpCrashpadInfo crashpad_info = {}; 131 MinidumpCrashpadInfo crashpad_info = {};
93 crashpad_info.version = MinidumpCrashpadInfo::kVersion; 132 crashpad_info.version = MinidumpCrashpadInfo::kVersion;
94 133
95 crashpad_info.simple_annotations.Rva = 134 std::map<std::string, std::string> dictionary;
96 static_cast<RVA>(string_file.SeekGet()); 135 dictionary["the first key"] = "THE FIRST VALUE EVER!";
97 uint32_t simple_string_dictionary_entries = 2; 136 dictionary["2key"] = "a lowly second value";
98 EXPECT_TRUE(string_file.Write(&simple_string_dictionary_entries, 137 WriteMinidumpSimpleStringDictionary(
99 sizeof(simple_string_dictionary_entries))); 138 &crashpad_info.simple_annotations, &string_file, dictionary);
100 EXPECT_TRUE(string_file.Write(&entry0, sizeof(entry0)));
101 EXPECT_TRUE(string_file.Write(&entry1, sizeof(entry1)));
102 crashpad_info.simple_annotations.DataSize =
103 simple_string_dictionary_entries *
104 sizeof(MinidumpSimpleStringDictionaryEntry);
105 139
106 MINIDUMP_DIRECTORY crashpad_info_directory = {}; 140 MINIDUMP_DIRECTORY crashpad_info_directory = {};
107 crashpad_info_directory.StreamType = kMinidumpStreamTypeCrashpadInfo; 141 crashpad_info_directory.StreamType = kMinidumpStreamTypeCrashpadInfo;
108 crashpad_info_directory.Location.Rva = 142 crashpad_info_directory.Location.Rva =
109 static_cast<RVA>(string_file.SeekGet()); 143 static_cast<RVA>(string_file.SeekGet());
110 EXPECT_TRUE(string_file.Write(&crashpad_info, sizeof(crashpad_info))); 144 EXPECT_TRUE(string_file.Write(&crashpad_info, sizeof(crashpad_info)));
111 crashpad_info_directory.Location.DataSize = sizeof(crashpad_info); 145 crashpad_info_directory.Location.DataSize = sizeof(crashpad_info);
112 146
113 header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet()); 147 header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet());
114 EXPECT_TRUE(string_file.Write(&crashpad_info_directory, 148 EXPECT_TRUE(string_file.Write(&crashpad_info_directory,
115 sizeof(crashpad_info_directory))); 149 sizeof(crashpad_info_directory)));
116 150
117 header.Signature = MINIDUMP_SIGNATURE; 151 header.Signature = MINIDUMP_SIGNATURE;
118 header.Version = MINIDUMP_VERSION; 152 header.Version = MINIDUMP_VERSION;
119 header.NumberOfStreams = 1; 153 header.NumberOfStreams = 1;
120 EXPECT_TRUE(string_file.SeekSet(0)); 154 EXPECT_TRUE(string_file.SeekSet(0));
121 EXPECT_TRUE(string_file.Write(&header, sizeof(header))); 155 EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
122 156
123 ProcessSnapshotMinidump process_snapshot; 157 ProcessSnapshotMinidump process_snapshot;
124 EXPECT_TRUE(process_snapshot.Initialize(&string_file)); 158 EXPECT_TRUE(process_snapshot.Initialize(&string_file));
125 159
126 const auto annotations_simple_map = process_snapshot.AnnotationsSimpleMap(); 160 const auto annotations_simple_map = process_snapshot.AnnotationsSimpleMap();
127 EXPECT_EQ(2u, annotations_simple_map.size()); 161 EXPECT_EQ(dictionary, annotations_simple_map);
162 }
128 163
129 auto it = annotations_simple_map.find(kKey0); 164 TEST(ProcessSnapshotMinidump, Modules) {
130 ASSERT_NE(it, annotations_simple_map.end()); 165 StringFile string_file;
131 EXPECT_EQ(kValue0, it->second);
132 166
133 it = annotations_simple_map.find(kKey1); 167 MINIDUMP_HEADER header = {};
134 ASSERT_NE(it, annotations_simple_map.end()); 168 EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
135 EXPECT_EQ(kValue1, it->second); 169
170 MINIDUMP_MODULE minidump_module = {};
171 uint32_t minidump_module_count = 3;
172
173 MINIDUMP_DIRECTORY minidump_module_list_directory = {};
174 minidump_module_list_directory.StreamType = kMinidumpStreamTypeModuleList;
175 minidump_module_list_directory.Location.DataSize =
176 sizeof(MINIDUMP_MODULE_LIST) +
177 minidump_module_count * sizeof(MINIDUMP_MODULE);
178 minidump_module_list_directory.Location.Rva =
179 static_cast<RVA>(string_file.SeekGet());
180
181 EXPECT_TRUE(
182 string_file.Write(&minidump_module_count, sizeof(minidump_module_count)));
183 for (uint32_t minidump_module_index = 0;
184 minidump_module_index < minidump_module_count;
185 ++minidump_module_index) {
186 EXPECT_TRUE(string_file.Write(&minidump_module, sizeof(minidump_module)));
187 }
188
189 MinidumpModuleCrashpadInfo crashpad_module_0 = {};
190 crashpad_module_0.version = MinidumpModuleCrashpadInfo::kVersion;
191 std::map<std::string, std::string> dictionary_0;
192 dictionary_0["ptype"] = "browser";
193 dictionary_0["pid"] = "12345";
194 WriteMinidumpSimpleStringDictionary(
195 &crashpad_module_0.simple_annotations, &string_file, dictionary_0);
196
197 MinidumpModuleCrashpadInfoLink crashpad_module_0_link = {};
198 crashpad_module_0_link.minidump_module_list_index = 0;
199 crashpad_module_0_link.location.DataSize = sizeof(crashpad_module_0);
200 crashpad_module_0_link.location.Rva = static_cast<RVA>(string_file.SeekGet());
201 EXPECT_TRUE(string_file.Write(&crashpad_module_0, sizeof(crashpad_module_0)));
202
203 MinidumpModuleCrashpadInfo crashpad_module_2 = {};
204 crashpad_module_2.version = MinidumpModuleCrashpadInfo::kVersion;
205 std::map<std::string, std::string> dictionary_2;
206 dictionary_2["fakemodule"] = "yes";
207 WriteMinidumpSimpleStringDictionary(
208 &crashpad_module_2.simple_annotations, &string_file, dictionary_2);
209
210 std::vector<std::string> list_annotations_2;
211 list_annotations_2.push_back("first string");
212 list_annotations_2.push_back("last string");
213 WriteMinidumpStringList(
214 &crashpad_module_2.list_annotations, &string_file, list_annotations_2);
215
216 MinidumpModuleCrashpadInfoLink crashpad_module_2_link = {};
217 crashpad_module_2_link.minidump_module_list_index = 2;
218 crashpad_module_2_link.location.DataSize = sizeof(crashpad_module_2);
219 crashpad_module_2_link.location.Rva = static_cast<RVA>(string_file.SeekGet());
220 EXPECT_TRUE(string_file.Write(&crashpad_module_2, sizeof(crashpad_module_2)));
221
222 MinidumpCrashpadInfo crashpad_info = {};
223 crashpad_info.version = MinidumpCrashpadInfo::kVersion;
224
225 uint32_t crashpad_module_count = 2;
226
227 crashpad_info.module_list.DataSize =
228 sizeof(MinidumpModuleCrashpadInfoList) +
229 crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink);
230 crashpad_info.module_list.Rva = static_cast<RVA>(string_file.SeekGet());
231
232 EXPECT_TRUE(
233 string_file.Write(&crashpad_module_count, sizeof(crashpad_module_count)));
234 EXPECT_TRUE(string_file.Write(&crashpad_module_0_link,
235 sizeof(crashpad_module_0_link)));
236 EXPECT_TRUE(string_file.Write(&crashpad_module_2_link,
237 sizeof(crashpad_module_2_link)));
238
239 MINIDUMP_DIRECTORY crashpad_info_directory = {};
240 crashpad_info_directory.StreamType = kMinidumpStreamTypeCrashpadInfo;
241 crashpad_info_directory.Location.DataSize = sizeof(crashpad_info);
242 crashpad_info_directory.Location.Rva =
243 static_cast<RVA>(string_file.SeekGet());
244 EXPECT_TRUE(string_file.Write(&crashpad_info, sizeof(crashpad_info)));
245
246 header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet());
247 EXPECT_TRUE(string_file.Write(&minidump_module_list_directory,
248 sizeof(minidump_module_list_directory)));
249 EXPECT_TRUE(string_file.Write(&crashpad_info_directory,
250 sizeof(crashpad_info_directory)));
251
252 header.Signature = MINIDUMP_SIGNATURE;
253 header.Version = MINIDUMP_VERSION;
254 header.NumberOfStreams = 2;
255 EXPECT_TRUE(string_file.SeekSet(0));
256 EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
257
258 ProcessSnapshotMinidump process_snapshot;
259 EXPECT_TRUE(process_snapshot.Initialize(&string_file));
260
261 std::vector<const ModuleSnapshot*> modules = process_snapshot.Modules();
262 ASSERT_EQ(minidump_module_count, modules.size());
263
264 auto annotations_simple_map = modules[0]->AnnotationsSimpleMap();
265 EXPECT_EQ(dictionary_0, annotations_simple_map);
266
267 auto annotations_vector = modules[0]->AnnotationsVector();
268 EXPECT_TRUE(annotations_vector.empty());
269
270 annotations_simple_map = modules[1]->AnnotationsSimpleMap();
271 EXPECT_TRUE(annotations_simple_map.empty());
272
273 annotations_vector = modules[1]->AnnotationsVector();
274 EXPECT_TRUE(annotations_vector.empty());
275
276 annotations_simple_map = modules[2]->AnnotationsSimpleMap();
277 EXPECT_EQ(dictionary_2, annotations_simple_map);
278
279 annotations_vector = modules[2]->AnnotationsVector();
280 EXPECT_EQ(list_annotations_2, annotations_vector);
136 } 281 }
137 282
138 } // namespace 283 } // namespace
139 } // namespace test 284 } // namespace test
140 } // namespace crashpad 285 } // namespace crashpad
OLDNEW
« no previous file with comments | « snapshot/minidump/process_snapshot_minidump.cc ('k') | snapshot/snapshot.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698