| Index: experimental/visual_studio_plugin/third_party/breakpad/common/module_unittest.cc
|
| diff --git a/experimental/visual_studio_plugin/third_party/breakpad/common/module_unittest.cc b/experimental/visual_studio_plugin/third_party/breakpad/common/module_unittest.cc
|
| deleted file mode 100644
|
| index 079034113119de30e01e037a3753c55e690a1543..0000000000000000000000000000000000000000
|
| --- a/experimental/visual_studio_plugin/third_party/breakpad/common/module_unittest.cc
|
| +++ /dev/null
|
| @@ -1,396 +0,0 @@
|
| -// Copyright (c) 2010 Google Inc.
|
| -// All rights reserved.
|
| -//
|
| -// Redistribution and use in source and binary forms, with or without
|
| -// modification, are permitted provided that the following conditions are
|
| -// met:
|
| -//
|
| -// * Redistributions of source code must retain the above copyright
|
| -// notice, this list of conditions and the following disclaimer.
|
| -// * Redistributions in binary form must reproduce the above
|
| -// copyright notice, this list of conditions and the following disclaimer
|
| -// in the documentation and/or other materials provided with the
|
| -// distribution.
|
| -// * Neither the name of Google Inc. nor the names of its
|
| -// contributors may be used to endorse or promote products derived from
|
| -// this software without specific prior written permission.
|
| -//
|
| -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| -
|
| -// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
|
| -
|
| -// module_unittest.cc: Unit tests for google_breakpad::Module.
|
| -
|
| -#include <cerrno>
|
| -#include <cstdio>
|
| -#include <cstdlib>
|
| -#include <cstring>
|
| -
|
| -#include <algorithm>
|
| -#include <string>
|
| -
|
| -#include "breakpad_googletest_includes.h"
|
| -#include "common/module.h"
|
| -
|
| -using google_breakpad::Module;
|
| -using std::string;
|
| -using std::vector;
|
| -using testing::ContainerEq;
|
| -
|
| -// Return a FILE * referring to a temporary file that will be deleted
|
| -// automatically when the stream is closed or the program exits.
|
| -FILE *checked_tmpfile() {
|
| - FILE *f = tmpfile();
|
| - if (!f) {
|
| - fprintf(stderr, "error creating temporary file: %s\n", strerror(errno));
|
| - exit(1);
|
| - }
|
| - return f;
|
| -}
|
| -
|
| -// Read from STREAM until end of file, and return the contents as a
|
| -// string.
|
| -string checked_read(FILE *stream) {
|
| - string contents;
|
| - int c;
|
| - while ((c = getc(stream)) != EOF)
|
| - contents.push_back(c);
|
| - if (ferror(stream)) {
|
| - fprintf(stderr, "error reading temporary file contents: %s\n",
|
| - strerror(errno));
|
| - exit(1);
|
| - }
|
| - return contents;
|
| -}
|
| -
|
| -// Apply 'fflush' to STREAM, and check for errors.
|
| -void checked_fflush(FILE *stream) {
|
| - if (fflush(stream) == EOF) {
|
| - fprintf(stderr, "error flushing temporary file stream: %s\n",
|
| - strerror(errno));
|
| - exit(1);
|
| - }
|
| -}
|
| -
|
| -// Apply 'fclose' to STREAM, and check for errors.
|
| -void checked_fclose(FILE *stream) {
|
| - if (fclose(stream) == EOF) {
|
| - fprintf(stderr, "error closing temporary file stream: %s\n",
|
| - strerror(errno));
|
| - exit(1);
|
| - }
|
| -}
|
| -
|
| -#define MODULE_NAME "name with spaces"
|
| -#define MODULE_OS "os-name"
|
| -#define MODULE_ARCH "architecture"
|
| -#define MODULE_ID "id-string"
|
| -
|
| -TEST(Write, Header) {
|
| - FILE *f = checked_tmpfile();
|
| - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
|
| - m.Write(f);
|
| - checked_fflush(f);
|
| - rewind(f);
|
| - string contents = checked_read(f);
|
| - checked_fclose(f);
|
| - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n",
|
| - contents.c_str());
|
| -}
|
| -
|
| -TEST(Write, OneLineFunc) {
|
| - FILE *f = checked_tmpfile();
|
| - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
|
| -
|
| - Module::File *file = m.FindFile("file_name.cc");
|
| - Module::Function *function = new(Module::Function);
|
| - function->name = "function_name";
|
| - function->address = 0xe165bf8023b9d9abLL;
|
| - function->size = 0x1e4bb0eb1cbf5b09LL;
|
| - function->parameter_size = 0x772beee89114358aLL;
|
| - Module::Line line = { 0xe165bf8023b9d9abLL, 0x1e4bb0eb1cbf5b09LL,
|
| - file, 67519080 };
|
| - function->lines.push_back(line);
|
| - m.AddFunction(function);
|
| -
|
| - m.Write(f);
|
| - checked_fflush(f);
|
| - rewind(f);
|
| - string contents = checked_read(f);
|
| - checked_fclose(f);
|
| - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
|
| - "FILE 0 file_name.cc\n"
|
| - "FUNC e165bf8023b9d9ab 1e4bb0eb1cbf5b09 772beee89114358a"
|
| - " function_name\n"
|
| - "e165bf8023b9d9ab 1e4bb0eb1cbf5b09 67519080 0\n",
|
| - contents.c_str());
|
| -}
|
| -
|
| -TEST(Write, RelativeLoadAddress) {
|
| - FILE *f = checked_tmpfile();
|
| - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
|
| -
|
| - m.SetLoadAddress(0x2ab698b0b6407073LL);
|
| -
|
| - // Some source files. We will expect to see them in lexicographic order.
|
| - Module::File *file1 = m.FindFile("filename-b.cc");
|
| - Module::File *file2 = m.FindFile("filename-a.cc");
|
| -
|
| - // A function.
|
| - Module::Function *function = new(Module::Function);
|
| - function->name = "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)";
|
| - function->address = 0xbec774ea5dd935f3LL;
|
| - function->size = 0x2922088f98d3f6fcLL;
|
| - function->parameter_size = 0xe5e9aa008bd5f0d0LL;
|
| -
|
| - // Some source lines. The module should not sort these.
|
| - Module::Line line1 = { 0xbec774ea5dd935f3LL, 0x1c2be6d6c5af2611LL,
|
| - file1, 41676901 };
|
| - Module::Line line2 = { 0xdaf35bc123885c04LL, 0xcf621b8d324d0ebLL,
|
| - file2, 67519080 };
|
| - function->lines.push_back(line2);
|
| - function->lines.push_back(line1);
|
| -
|
| - m.AddFunction(function);
|
| -
|
| - // Some stack information.
|
| - Module::StackFrameEntry *entry = new Module::StackFrameEntry();
|
| - entry->address = 0x30f9e5c83323973dULL;
|
| - entry->size = 0x49fc9ca7c7c13dc2ULL;
|
| - entry->initial_rules[".cfa"] = "he was a handsome man";
|
| - entry->initial_rules["and"] = "what i want to know is";
|
| - entry->rule_changes[0x30f9e5c83323973eULL]["how"] =
|
| - "do you like your blueeyed boy";
|
| - entry->rule_changes[0x30f9e5c83323973eULL]["Mister"] = "Death";
|
| - m.AddStackFrameEntry(entry);
|
| -
|
| - m.Write(f);
|
| - checked_fflush(f);
|
| - rewind(f);
|
| - string contents = checked_read(f);
|
| - checked_fclose(f);
|
| - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
|
| - "FILE 0 filename-a.cc\n"
|
| - "FILE 1 filename-b.cc\n"
|
| - "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0"
|
| - " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n"
|
| - "b03cc3106d47eb91 cf621b8d324d0eb 67519080 0\n"
|
| - "9410dc39a798c580 1c2be6d6c5af2611 41676901 1\n"
|
| - "STACK CFI INIT 6434d177ce326ca 49fc9ca7c7c13dc2"
|
| - " .cfa: he was a handsome man"
|
| - " and: what i want to know is\n"
|
| - "STACK CFI 6434d177ce326cb"
|
| - " Mister: Death"
|
| - " how: do you like your blueeyed boy\n",
|
| - contents.c_str());
|
| -}
|
| -
|
| -TEST(Write, OmitUnusedFiles) {
|
| - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
|
| -
|
| - // Create some source files.
|
| - Module::File *file1 = m.FindFile("filename1");
|
| - m.FindFile("filename2"); // not used by any line
|
| - Module::File *file3 = m.FindFile("filename3");
|
| -
|
| - // Create a function.
|
| - Module::Function *function = new(Module::Function);
|
| - function->name = "function_name";
|
| - function->address = 0x9b926d464f0b9384LL;
|
| - function->size = 0x4f524a4ba795e6a6LL;
|
| - function->parameter_size = 0xbbe8133a6641c9b7LL;
|
| -
|
| - // Source files that refer to some files, but not others.
|
| - Module::Line line1 = { 0x595fa44ebacc1086LL, 0x1e1e0191b066c5b3LL,
|
| - file1, 137850127 };
|
| - Module::Line line2 = { 0x401ce8c8a12d25e3LL, 0x895751c41b8d2ce2LL,
|
| - file3, 28113549 };
|
| - function->lines.push_back(line1);
|
| - function->lines.push_back(line2);
|
| - m.AddFunction(function);
|
| -
|
| - m.AssignSourceIds();
|
| -
|
| - vector<Module::File *> vec;
|
| - m.GetFiles(&vec);
|
| - EXPECT_EQ((size_t) 3, vec.size());
|
| - EXPECT_STREQ("filename1", vec[0]->name.c_str());
|
| - EXPECT_NE(-1, vec[0]->source_id);
|
| - // Expect filename2 not to be used.
|
| - EXPECT_STREQ("filename2", vec[1]->name.c_str());
|
| - EXPECT_EQ(-1, vec[1]->source_id);
|
| - EXPECT_STREQ("filename3", vec[2]->name.c_str());
|
| - EXPECT_NE(-1, vec[2]->source_id);
|
| -
|
| - FILE *f = checked_tmpfile();
|
| - m.Write(f);
|
| - checked_fflush(f);
|
| - rewind(f);
|
| - string contents = checked_read(f);
|
| - checked_fclose(f);
|
| - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
|
| - "FILE 0 filename1\n"
|
| - "FILE 1 filename3\n"
|
| - "FUNC 9b926d464f0b9384 4f524a4ba795e6a6 bbe8133a6641c9b7"
|
| - " function_name\n"
|
| - "595fa44ebacc1086 1e1e0191b066c5b3 137850127 0\n"
|
| - "401ce8c8a12d25e3 895751c41b8d2ce2 28113549 1\n",
|
| - contents.c_str());
|
| -}
|
| -
|
| -TEST(Construct, AddFunctions) {
|
| - FILE *f = checked_tmpfile();
|
| - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
|
| -
|
| - // Two functions.
|
| - Module::Function *function1 = new(Module::Function);
|
| - function1->name = "_without_form";
|
| - function1->address = 0xd35024aa7ca7da5cLL;
|
| - function1->size = 0x200b26e605f99071LL;
|
| - function1->parameter_size = 0xf14ac4fed48c4a99LL;
|
| -
|
| - Module::Function *function2 = new(Module::Function);
|
| - function2->name = "_and_void";
|
| - function2->address = 0x2987743d0b35b13fLL;
|
| - function2->size = 0xb369db048deb3010LL;
|
| - function2->parameter_size = 0x938e556cb5a79988LL;
|
| -
|
| - // Put them in a vector.
|
| - vector<Module::Function *> vec;
|
| - vec.push_back(function1);
|
| - vec.push_back(function2);
|
| -
|
| - m.AddFunctions(vec.begin(), vec.end());
|
| -
|
| - m.Write(f);
|
| - checked_fflush(f);
|
| - rewind(f);
|
| - string contents = checked_read(f);
|
| - checked_fclose(f);
|
| - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
|
| - "FUNC d35024aa7ca7da5c 200b26e605f99071 f14ac4fed48c4a99"
|
| - " _without_form\n"
|
| - "FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988"
|
| - " _and_void\n",
|
| - contents.c_str());
|
| -
|
| - // Check that m.GetFunctions returns the functions we expect.
|
| - vec.clear();
|
| - m.GetFunctions(&vec, vec.end());
|
| - EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function1));
|
| - EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function2));
|
| - EXPECT_EQ((size_t) 2, vec.size());
|
| -}
|
| -
|
| -TEST(Construct, AddFrames) {
|
| - FILE *f = checked_tmpfile();
|
| - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
|
| -
|
| - // First STACK CFI entry, with no initial rules or deltas.
|
| - Module::StackFrameEntry *entry1 = new Module::StackFrameEntry();
|
| - entry1->address = 0xddb5f41285aa7757ULL;
|
| - entry1->size = 0x1486493370dc5073ULL;
|
| - m.AddStackFrameEntry(entry1);
|
| -
|
| - // Second STACK CFI entry, with initial rules but no deltas.
|
| - Module::StackFrameEntry *entry2 = new Module::StackFrameEntry();
|
| - entry2->address = 0x8064f3af5e067e38ULL;
|
| - entry2->size = 0x0de2a5ee55509407ULL;
|
| - entry2->initial_rules[".cfa"] = "I think that I shall never see";
|
| - entry2->initial_rules["stromboli"] = "a poem lovely as a tree";
|
| - entry2->initial_rules["cannoli"] = "a tree whose hungry mouth is prest";
|
| - m.AddStackFrameEntry(entry2);
|
| -
|
| - // Third STACK CFI entry, with initial rules and deltas.
|
| - Module::StackFrameEntry *entry3 = new Module::StackFrameEntry();
|
| - entry3->address = 0x5e8d0db0a7075c6cULL;
|
| - entry3->size = 0x1c7edb12a7aea229ULL;
|
| - entry3->initial_rules[".cfa"] = "Whose woods are these";
|
| - entry3->rule_changes[0x47ceb0f63c269d7fULL]["calzone"] =
|
| - "the village though";
|
| - entry3->rule_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
|
| - "he will not see me stopping here";
|
| - entry3->rule_changes[0x36682fad3763ffffULL]["stromboli"] =
|
| - "his house is in";
|
| - entry3->rule_changes[0x36682fad3763ffffULL][".cfa"] =
|
| - "I think I know";
|
| - m.AddStackFrameEntry(entry3);
|
| -
|
| - // Check that Write writes STACK CFI records properly.
|
| - m.Write(f);
|
| - checked_fflush(f);
|
| - rewind(f);
|
| - string contents = checked_read(f);
|
| - checked_fclose(f);
|
| - EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
|
| - "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n"
|
| - "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407"
|
| - " .cfa: I think that I shall never see"
|
| - " cannoli: a tree whose hungry mouth is prest"
|
| - " stromboli: a poem lovely as a tree\n"
|
| - "STACK CFI INIT 5e8d0db0a7075c6c 1c7edb12a7aea229"
|
| - " .cfa: Whose woods are these\n"
|
| - "STACK CFI 36682fad3763ffff"
|
| - " .cfa: I think I know"
|
| - " stromboli: his house is in\n"
|
| - "STACK CFI 47ceb0f63c269d7f"
|
| - " calzone: the village though"
|
| - " cannoli: he will not see me stopping here\n",
|
| - contents.c_str());
|
| -
|
| - // Check that GetStackFrameEntries works.
|
| - vector<Module::StackFrameEntry *> entries;
|
| - m.GetStackFrameEntries(&entries);
|
| - ASSERT_EQ(3U, entries.size());
|
| - // Check first entry.
|
| - EXPECT_EQ(0xddb5f41285aa7757ULL, entries[0]->address);
|
| - EXPECT_EQ(0x1486493370dc5073ULL, entries[0]->size);
|
| - ASSERT_EQ(0U, entries[0]->initial_rules.size());
|
| - ASSERT_EQ(0U, entries[0]->rule_changes.size());
|
| - // Check second entry.
|
| - EXPECT_EQ(0x8064f3af5e067e38ULL, entries[1]->address);
|
| - EXPECT_EQ(0x0de2a5ee55509407ULL, entries[1]->size);
|
| - ASSERT_EQ(3U, entries[1]->initial_rules.size());
|
| - Module::RuleMap entry2_initial;
|
| - entry2_initial[".cfa"] = "I think that I shall never see";
|
| - entry2_initial["stromboli"] = "a poem lovely as a tree";
|
| - entry2_initial["cannoli"] = "a tree whose hungry mouth is prest";
|
| - EXPECT_THAT(entries[1]->initial_rules, ContainerEq(entry2_initial));
|
| - ASSERT_EQ(0U, entries[1]->rule_changes.size());
|
| - // Check third entry.
|
| - EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[2]->address);
|
| - EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[2]->size);
|
| - Module::RuleMap entry3_initial;
|
| - entry3_initial[".cfa"] = "Whose woods are these";
|
| - EXPECT_THAT(entries[2]->initial_rules, ContainerEq(entry3_initial));
|
| - Module::RuleChangeMap entry3_changes;
|
| - entry3_changes[0x36682fad3763ffffULL][".cfa"] = "I think I know";
|
| - entry3_changes[0x36682fad3763ffffULL]["stromboli"] = "his house is in";
|
| - entry3_changes[0x47ceb0f63c269d7fULL]["calzone"] = "the village though";
|
| - entry3_changes[0x47ceb0f63c269d7fULL]["cannoli"] =
|
| - "he will not see me stopping here";
|
| - EXPECT_THAT(entries[2]->rule_changes, ContainerEq(entry3_changes));
|
| -}
|
| -
|
| -TEST(Construct, UniqueFiles) {
|
| - Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
|
| - Module::File *file1 = m.FindFile("foo");
|
| - Module::File *file2 = m.FindFile(string("bar"));
|
| - Module::File *file3 = m.FindFile(string("foo"));
|
| - Module::File *file4 = m.FindFile("bar");
|
| - EXPECT_NE(file1, file2);
|
| - EXPECT_EQ(file1, file3);
|
| - EXPECT_EQ(file2, file4);
|
| - EXPECT_EQ(file1, m.FindExistingFile("foo"));
|
| - EXPECT_TRUE(m.FindExistingFile("baz") == NULL);
|
| -}
|
|
|