diff options
author | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-07-06 17:05:59 +0000 |
---|---|---|
committer | ted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2011-07-06 17:05:59 +0000 |
commit | 3ca4a120de8ec3f35e972e4b23f527bb8f65c479 (patch) | |
tree | 0186b36bf01d54c7700c00c3c2cec21fbb382268 /src/common/module_unittest.cc | |
parent | Dump PUBLIC + CFI records from libraries without debug info on Linux, use .dy... (diff) | |
download | breakpad-3ca4a120de8ec3f35e972e4b23f527bb8f65c479.tar.xz |
Add some unit tests for Linux WriteSymbolFile
This patch adds synth_elf::{StringTable,SymbolTable,ELF} classes to
produce in-memory ELF files to properly test the Linux symbol dumping
code. It also uses those classes to add some basic tests for
the WriteSymbolFile function.
R=jimb at http://breakpad.appspot.com/277001/show
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@794 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/module_unittest.cc')
-rw-r--r-- | src/common/module_unittest.cc | 136 |
1 files changed, 32 insertions, 104 deletions
diff --git a/src/common/module_unittest.cc b/src/common/module_unittest.cc index 63ad5056..4972bbe8 100644 --- a/src/common/module_unittest.cc +++ b/src/common/module_unittest.cc @@ -37,6 +37,7 @@ #include <string.h> #include <algorithm> +#include <sstream> #include <string> #include "breakpad_googletest_includes.h" @@ -44,53 +45,10 @@ using google_breakpad::Module; using std::string; +using std::stringstream; 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. -static 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. -static 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. -static 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. -static void checked_fclose(FILE *stream) { - if (fclose(stream) == EOF) { - fprintf(stderr, "error closing temporary file stream: %s\n", - strerror(errno)); - exit(1); - } -} - static Module::Function *generate_duplicate_function(const string &name) { const Module::Address DUP_ADDRESS = 0xd35402aac7a7ad5cLL; const Module::Address DUP_SIZE = 0x200b26e605f99071LL; @@ -110,19 +68,16 @@ static Module::Function *generate_duplicate_function(const string &name) { #define MODULE_ID "id-string" TEST(Write, Header) { - FILE *f = checked_tmpfile(); + stringstream s; 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); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n", contents.c_str()); } TEST(Write, OneLineFunc) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module::File *file = m.FindFile("file_name.cc"); @@ -136,11 +91,8 @@ TEST(Write, OneLineFunc) { function->lines.push_back(line); m.AddFunction(function); - m.Write(f); - checked_fflush(f); - rewind(f); - string contents = checked_read(f); - checked_fclose(f); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" "FILE 0 file_name.cc\n" "FUNC e165bf8023b9d9ab 1e4bb0eb1cbf5b09 772beee89114358a" @@ -150,7 +102,7 @@ TEST(Write, OneLineFunc) { } TEST(Write, RelativeLoadAddress) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); // Some source files. We will expect to see them in lexicographic order. @@ -189,11 +141,8 @@ TEST(Write, RelativeLoadAddress) { // the module must work fine. m.SetLoadAddress(0x2ab698b0b6407073LL); - m.Write(f); - checked_fflush(f); - rewind(f); - string contents = checked_read(f); - checked_fclose(f); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" "FILE 0 filename-a.cc\n" "FILE 1 filename-b.cc\n" @@ -247,12 +196,9 @@ TEST(Write, OmitUnusedFiles) { 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); + stringstream s; + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" "FILE 0 filename1\n" "FILE 1 filename3\n" @@ -264,7 +210,7 @@ TEST(Write, OmitUnusedFiles) { } TEST(Construct, AddFunctions) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); // Two functions. @@ -287,11 +233,8 @@ TEST(Construct, AddFunctions) { m.AddFunctions(vec.begin(), vec.end()); - m.Write(f); - checked_fflush(f); - rewind(f); - string contents = checked_read(f); - checked_fclose(f); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" "FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988" " _and_void\n" @@ -308,7 +251,7 @@ TEST(Construct, AddFunctions) { } TEST(Construct, AddFrames) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); // First STACK CFI entry, with no initial rules or deltas. @@ -342,11 +285,8 @@ TEST(Construct, AddFrames) { 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); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n" "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407" @@ -411,7 +351,7 @@ TEST(Construct, UniqueFiles) { } TEST(Construct, DuplicateFunctions) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); // Two functions. @@ -421,11 +361,8 @@ TEST(Construct, DuplicateFunctions) { m.AddFunction(function1); m.AddFunction(function2); - m.Write(f); - checked_fflush(f); - rewind(f); - string contents = checked_read(f); - checked_fclose(f); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99" " _without_form\n", @@ -433,7 +370,7 @@ TEST(Construct, DuplicateFunctions) { } TEST(Construct, FunctionsWithSameAddress) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); // Two functions. @@ -443,11 +380,8 @@ TEST(Construct, FunctionsWithSameAddress) { m.AddFunction(function1); m.AddFunction(function2); - m.Write(f); - checked_fflush(f); - rewind(f); - string contents = checked_read(f); - checked_fclose(f); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n" "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99" " _and_void\n" @@ -459,7 +393,7 @@ TEST(Construct, FunctionsWithSameAddress) { // Externs should be written out as PUBLIC records, sorted by // address. TEST(Construct, Externs) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); // Two externs. @@ -473,11 +407,8 @@ TEST(Construct, Externs) { m.AddExtern(extern1); m.AddExtern(extern2); - m.Write(f); - checked_fflush(f); - rewind(f); - string contents = checked_read(f); - checked_fclose(f); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " " MODULE_ID " " MODULE_NAME "\n" @@ -489,7 +420,7 @@ TEST(Construct, Externs) { // Externs with the same address should only keep the first entry // added. TEST(Construct, DuplicateExterns) { - FILE *f = checked_tmpfile(); + stringstream s; Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); // Two externs. @@ -503,11 +434,8 @@ TEST(Construct, DuplicateExterns) { m.AddExtern(extern1); m.AddExtern(extern2); - m.Write(f); - checked_fflush(f); - rewind(f); - string contents = checked_read(f); - checked_fclose(f); + m.Write(s); + string contents = s.str(); EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " " MODULE_ID " " MODULE_NAME "\n" |