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

Side by Side Diff: obsolete/breakpad/common/module_unittest.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 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 | « obsolete/breakpad/common/module.cc ('k') | obsolete/breakpad/common/solaris/dump_symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
31
32 // module_unittest.cc: Unit tests for google_breakpad::Module.
33
34 #include <cerrno>
35 #include <cstdio>
36 #include <cstdlib>
37 #include <cstring>
38
39 #include <algorithm>
40 #include <string>
41
42 #include "breakpad_googletest_includes.h"
43 #include "common/module.h"
44
45 using google_breakpad::Module;
46 using std::string;
47 using std::vector;
48 using testing::ContainerEq;
49
50 // Return a FILE * referring to a temporary file that will be deleted
51 // automatically when the stream is closed or the program exits.
52 FILE *checked_tmpfile() {
53 FILE *f = tmpfile();
54 if (!f) {
55 fprintf(stderr, "error creating temporary file: %s\n", strerror(errno));
56 exit(1);
57 }
58 return f;
59 }
60
61 // Read from STREAM until end of file, and return the contents as a
62 // string.
63 string checked_read(FILE *stream) {
64 string contents;
65 int c;
66 while ((c = getc(stream)) != EOF)
67 contents.push_back(c);
68 if (ferror(stream)) {
69 fprintf(stderr, "error reading temporary file contents: %s\n",
70 strerror(errno));
71 exit(1);
72 }
73 return contents;
74 }
75
76 // Apply 'fflush' to STREAM, and check for errors.
77 void checked_fflush(FILE *stream) {
78 if (fflush(stream) == EOF) {
79 fprintf(stderr, "error flushing temporary file stream: %s\n",
80 strerror(errno));
81 exit(1);
82 }
83 }
84
85 // Apply 'fclose' to STREAM, and check for errors.
86 void checked_fclose(FILE *stream) {
87 if (fclose(stream) == EOF) {
88 fprintf(stderr, "error closing temporary file stream: %s\n",
89 strerror(errno));
90 exit(1);
91 }
92 }
93
94 #define MODULE_NAME "name with spaces"
95 #define MODULE_OS "os-name"
96 #define MODULE_ARCH "architecture"
97 #define MODULE_ID "id-string"
98
99 TEST(Write, Header) {
100 FILE *f = checked_tmpfile();
101 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
102 m.Write(f);
103 checked_fflush(f);
104 rewind(f);
105 string contents = checked_read(f);
106 checked_fclose(f);
107 EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n",
108 contents.c_str());
109 }
110
111 TEST(Write, OneLineFunc) {
112 FILE *f = checked_tmpfile();
113 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
114
115 Module::File *file = m.FindFile("file_name.cc");
116 Module::Function *function = new(Module::Function);
117 function->name = "function_name";
118 function->address = 0xe165bf8023b9d9abLL;
119 function->size = 0x1e4bb0eb1cbf5b09LL;
120 function->parameter_size = 0x772beee89114358aLL;
121 Module::Line line = { 0xe165bf8023b9d9abLL, 0x1e4bb0eb1cbf5b09LL,
122 file, 67519080 };
123 function->lines.push_back(line);
124 m.AddFunction(function);
125
126 m.Write(f);
127 checked_fflush(f);
128 rewind(f);
129 string contents = checked_read(f);
130 checked_fclose(f);
131 EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
132 "FILE 0 file_name.cc\n"
133 "FUNC e165bf8023b9d9ab 1e4bb0eb1cbf5b09 772beee89114358a"
134 " function_name\n"
135 "e165bf8023b9d9ab 1e4bb0eb1cbf5b09 67519080 0\n",
136 contents.c_str());
137 }
138
139 TEST(Write, RelativeLoadAddress) {
140 FILE *f = checked_tmpfile();
141 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
142
143 m.SetLoadAddress(0x2ab698b0b6407073LL);
144
145 // Some source files. We will expect to see them in lexicographic order.
146 Module::File *file1 = m.FindFile("filename-b.cc");
147 Module::File *file2 = m.FindFile("filename-a.cc");
148
149 // A function.
150 Module::Function *function = new(Module::Function);
151 function->name = "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)";
152 function->address = 0xbec774ea5dd935f3LL;
153 function->size = 0x2922088f98d3f6fcLL;
154 function->parameter_size = 0xe5e9aa008bd5f0d0LL;
155
156 // Some source lines. The module should not sort these.
157 Module::Line line1 = { 0xbec774ea5dd935f3LL, 0x1c2be6d6c5af2611LL,
158 file1, 41676901 };
159 Module::Line line2 = { 0xdaf35bc123885c04LL, 0xcf621b8d324d0ebLL,
160 file2, 67519080 };
161 function->lines.push_back(line2);
162 function->lines.push_back(line1);
163
164 m.AddFunction(function);
165
166 // Some stack information.
167 Module::StackFrameEntry *entry = new Module::StackFrameEntry();
168 entry->address = 0x30f9e5c83323973dULL;
169 entry->size = 0x49fc9ca7c7c13dc2ULL;
170 entry->initial_rules[".cfa"] = "he was a handsome man";
171 entry->initial_rules["and"] = "what i want to know is";
172 entry->rule_changes[0x30f9e5c83323973eULL]["how"] =
173 "do you like your blueeyed boy";
174 entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = "Death";
175 m.AddStackFrameEntry(entry);
176
177 m.Write(f);
178 checked_fflush(f);
179 rewind(f);
180 string contents = checked_read(f);
181 checked_fclose(f);
182 EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
183 "FILE 0 filename-a.cc\n"
184 "FILE 1 filename-b.cc\n"
185 "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0"
186 " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n"
187 "b03cc3106d47eb91 cf621b8d324d0eb 67519080 0\n"
188 "9410dc39a798c580 1c2be6d6c5af2611 41676901 1\n"
189 "STACK CFI INIT 6434d177ce326ca 49fc9ca7c7c13dc2"
190 " .cfa: he was a handsome man"
191 " and: what i want to know is\n"
192 "STACK CFI 6434d177ce326cb"
193 " Mister: Death"
194 " how: do you like your blueeyed boy\n",
195 contents.c_str());
196 }
197
198 TEST(Write, OmitUnusedFiles) {
199 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
200
201 // Create some source files.
202 Module::File *file1 = m.FindFile("filename1");
203 m.FindFile("filename2"); // not used by any line
204 Module::File *file3 = m.FindFile("filename3");
205
206 // Create a function.
207 Module::Function *function = new(Module::Function);
208 function->name = "function_name";
209 function->address = 0x9b926d464f0b9384LL;
210 function->size = 0x4f524a4ba795e6a6LL;
211 function->parameter_size = 0xbbe8133a6641c9b7LL;
212
213 // Source files that refer to some files, but not others.
214 Module::Line line1 = { 0x595fa44ebacc1086LL, 0x1e1e0191b066c5b3LL,
215 file1, 137850127 };
216 Module::Line line2 = { 0x401ce8c8a12d25e3LL, 0x895751c41b8d2ce2LL,
217 file3, 28113549 };
218 function->lines.push_back(line1);
219 function->lines.push_back(line2);
220 m.AddFunction(function);
221
222 m.AssignSourceIds();
223
224 vector<Module::File *> vec;
225 m.GetFiles(&vec);
226 EXPECT_EQ((size_t) 3, vec.size());
227 EXPECT_STREQ("filename1", vec[0]->name.c_str());
228 EXPECT_NE(-1, vec[0]->source_id);
229 // Expect filename2 not to be used.
230 EXPECT_STREQ("filename2", vec[1]->name.c_str());
231 EXPECT_EQ(-1, vec[1]->source_id);
232 EXPECT_STREQ("filename3", vec[2]->name.c_str());
233 EXPECT_NE(-1, vec[2]->source_id);
234
235 FILE *f = checked_tmpfile();
236 m.Write(f);
237 checked_fflush(f);
238 rewind(f);
239 string contents = checked_read(f);
240 checked_fclose(f);
241 EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
242 "FILE 0 filename1\n"
243 "FILE 1 filename3\n"
244 "FUNC 9b926d464f0b9384 4f524a4ba795e6a6 bbe8133a6641c9b7"
245 " function_name\n"
246 "595fa44ebacc1086 1e1e0191b066c5b3 137850127 0\n"
247 "401ce8c8a12d25e3 895751c41b8d2ce2 28113549 1\n",
248 contents.c_str());
249 }
250
251 TEST(Construct, AddFunctions) {
252 FILE *f = checked_tmpfile();
253 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
254
255 // Two functions.
256 Module::Function *function1 = new(Module::Function);
257 function1->name = "_without_form";
258 function1->address = 0xd35024aa7ca7da5cLL;
259 function1->size = 0x200b26e605f99071LL;
260 function1->parameter_size = 0xf14ac4fed48c4a99LL;
261
262 Module::Function *function2 = new(Module::Function);
263 function2->name = "_and_void";
264 function2->address = 0x2987743d0b35b13fLL;
265 function2->size = 0xb369db048deb3010LL;
266 function2->parameter_size = 0x938e556cb5a79988LL;
267
268 // Put them in a vector.
269 vector<Module::Function *> vec;
270 vec.push_back(function1);
271 vec.push_back(function2);
272
273 m.AddFunctions(vec.begin(), vec.end());
274
275 m.Write(f);
276 checked_fflush(f);
277 rewind(f);
278 string contents = checked_read(f);
279 checked_fclose(f);
280 EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
281 "FUNC d35024aa7ca7da5c 200b26e605f99071 f14ac4fed48c4a99"
282 " _without_form\n"
283 "FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988"
284 " _and_void\n",
285 contents.c_str());
286
287 // Check that m.GetFunctions returns the functions we expect.
288 vec.clear();
289 m.GetFunctions(&vec, vec.end());
290 EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function1));
291 EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function2));
292 EXPECT_EQ((size_t) 2, vec.size());
293 }
294
295 TEST(Construct, AddFrames) {
296 FILE *f = checked_tmpfile();
297 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
298
299 // First STACK CFI entry, with no initial rules or deltas.
300 Module::StackFrameEntry *entry1 = new Module::StackFrameEntry();
301 entry1->address = 0xddb5f41285aa7757ULL;
302 entry1->size = 0x1486493370dc5073ULL;
303 m.AddStackFrameEntry(entry1);
304
305 // Second STACK CFI entry, with initial rules but no deltas.
306 Module::StackFrameEntry *entry2 = new Module::StackFrameEntry();
307 entry2->address = 0x8064f3af5e067e38ULL;
308 entry2->size = 0x0de2a5ee55509407ULL;
309 entry2->initial_rules[".cfa"] = "I think that I shall never see";
310 entry2->initial_rules["stromboli"] = "a poem lovely as a tree";
311 entry2->initial_rules["cannoli"] = "a tree whose hungry mouth is prest";
312 m.AddStackFrameEntry(entry2);
313
314 // Third STACK CFI entry, with initial rules and deltas.
315 Module::StackFrameEntry *entry3 = new Module::StackFrameEntry();
316 entry3->address = 0x5e8d0db0a7075c6cULL;
317 entry3->size = 0x1c7edb12a7aea229ULL;
318 entry3->initial_rules[".cfa"] = "Whose woods are these";
319 entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] =
320 "the village though";
321 entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
322 "he will not see me stopping here";
323 entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] =
324 "his house is in";
325 entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] =
326 "I think I know";
327 m.AddStackFrameEntry(entry3);
328
329 // Check that Write writes STACK CFI records properly.
330 m.Write(f);
331 checked_fflush(f);
332 rewind(f);
333 string contents = checked_read(f);
334 checked_fclose(f);
335 EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
336 "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n"
337 "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407"
338 " .cfa: I think that I shall never see"
339 " cannoli: a tree whose hungry mouth is prest"
340 " stromboli: a poem lovely as a tree\n"
341 "STACK CFI INIT 5e8d0db0a7075c6c 1c7edb12a7aea229"
342 " .cfa: Whose woods are these\n"
343 "STACK CFI 36682fad3763ffff"
344 " .cfa: I think I know"
345 " stromboli: his house is in\n"
346 "STACK CFI 47ceb0f63c269d7f"
347 " calzone: the village though"
348 " cannoli: he will not see me stopping here\n",
349 contents.c_str());
350
351 // Check that GetStackFrameEntries works.
352 vector<Module::StackFrameEntry *> entries;
353 m.GetStackFrameEntries(&entries);
354 ASSERT_EQ(3U, entries.size());
355 // Check first entry.
356 EXPECT_EQ(0xddb5f41285aa7757ULL, entries[0]->address);
357 EXPECT_EQ(0x1486493370dc5073ULL, entries[0]->size);
358 ASSERT_EQ(0U, entries[0]->initial_rules.size());
359 ASSERT_EQ(0U, entries[0]->rule_changes.size());
360 // Check second entry.
361 EXPECT_EQ(0x8064f3af5e067e38ULL, entries[1]->address);
362 EXPECT_EQ(0x0de2a5ee55509407ULL, entries[1]->size);
363 ASSERT_EQ(3U, entries[1]->initial_rules.size());
364 Module::RuleMap entry2_initial;
365 entry2_initial[".cfa"] = "I think that I shall never see";
366 entry2_initial["stromboli"] = "a poem lovely as a tree";
367 entry2_initial["cannoli"] = "a tree whose hungry mouth is prest";
368 EXPECT_THAT(entries[1]->initial_rules, ContainerEq(entry2_initial));
369 ASSERT_EQ(0U, entries[1]->rule_changes.size());
370 // Check third entry.
371 EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[2]->address);
372 EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[2]->size);
373 Module::RuleMap entry3_initial;
374 entry3_initial[".cfa"] = "Whose woods are these";
375 EXPECT_THAT(entries[2]->initial_rules, ContainerEq(entry3_initial));
376 Module::RuleChangeMap entry3_changes;
377 entry3_changes[0x36682fad3763ffffULL][".cfa"] = "I think I know";
378 entry3_changes[0x36682fad3763ffffULL]["stromboli"] = "his house is in";
379 entry3_changes[0x47ceb0f63c269d7fULL]["calzone"] = "the village though";
380 entry3_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
381 "he will not see me stopping here";
382 EXPECT_THAT(entries[2]->rule_changes, ContainerEq(entry3_changes));
383 }
384
385 TEST(Construct, UniqueFiles) {
386 Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
387 Module::File *file1 = m.FindFile("foo");
388 Module::File *file2 = m.FindFile(string("bar"));
389 Module::File *file3 = m.FindFile(string("foo"));
390 Module::File *file4 = m.FindFile("bar");
391 EXPECT_NE(file1, file2);
392 EXPECT_EQ(file1, file3);
393 EXPECT_EQ(file2, file4);
394 EXPECT_EQ(file1, m.FindExistingFile("foo"));
395 EXPECT_TRUE(m.FindExistingFile("baz") == NULL);
396 }
OLDNEW
« no previous file with comments | « obsolete/breakpad/common/module.cc ('k') | obsolete/breakpad/common/solaris/dump_symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698