LEFT | RIGHT |
(no file at all) | |
| 1 // Copyright (c) 2014 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 #include <sys/syscall.h> |
| 31 #include <sys/types.h> |
| 32 #include <unistd.h> |
| 33 |
| 34 #include <string> |
| 35 |
| 36 #include "breakpad_googletest_includes.h" |
| 37 #include "client/linux/handler/exception_handler.h" |
| 38 #include "client/linux/microdump_writer/microdump_writer.h" |
| 39 #include "common/linux/eintr_wrapper.h" |
| 40 #include "common/linux/ignore_ret.h" |
| 41 #include "common/scoped_ptr.h" |
| 42 #include "common/tests/auto_tempdir.h" |
| 43 #include "common/using_std_string.h" |
| 44 |
| 45 using namespace google_breakpad; |
| 46 |
| 47 // Length of a formatted GUID string = |
| 48 // sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator) |
| 49 const int kGUIDStringSize = 37; |
| 50 |
| 51 namespace { |
| 52 |
| 53 typedef testing::Test MicrodumpWriterTest; |
| 54 |
| 55 TEST(MicrodumpWriterTest, Setup) { |
| 56 int fds[2]; |
| 57 ASSERT_NE(-1, pipe(fds)); |
| 58 |
| 59 AutoTempDir temp_dir; |
| 60 string stderr_file = temp_dir.path() + "/stderr.log"; |
| 61 int err_fd = open(stderr_file.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); |
| 62 ASSERT_NE(-1, err_fd); |
| 63 |
| 64 const pid_t child = fork(); |
| 65 if (child == 0) { |
| 66 close(fds[1]); |
| 67 char b; |
| 68 IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b)))); |
| 69 close(fds[0]); |
| 70 syscall(__NR_exit); |
| 71 } |
| 72 close(fds[0]); |
| 73 |
| 74 ExceptionHandler::CrashContext context; |
| 75 memset(&context, 0, sizeof(context)); |
| 76 |
| 77 // Set a non-zero tid to avoid tripping asserts. |
| 78 context.tid = child; |
| 79 |
| 80 // Push some extra mapping to check the MappingList logic. |
| 81 const uint32_t memory_size = sysconf(_SC_PAGESIZE); |
| 82 const char* kMemoryName = "libfoo.so"; |
| 83 const uint8_t kModuleGUID[sizeof(MDGUID)] = { |
| 84 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, |
| 85 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF |
| 86 }; |
| 87 |
| 88 MappingInfo info; |
| 89 info.start_addr = memory_size; |
| 90 info.size = memory_size; |
| 91 info.offset = 42; |
| 92 strcpy(info.name, kMemoryName); |
| 93 |
| 94 MappingList mappings; |
| 95 MappingEntry mapping; |
| 96 mapping.first = info; |
| 97 memcpy(mapping.second, kModuleGUID, sizeof(MDGUID)); |
| 98 mappings.push_back(mapping); |
| 99 |
| 100 // Redirect temporarily stderr to the stderr.log file. |
| 101 int save_err = dup(STDERR_FILENO); |
| 102 ASSERT_NE(-1, save_err); |
| 103 ASSERT_NE(-1, dup2(err_fd, STDERR_FILENO)); |
| 104 |
| 105 ASSERT_TRUE(WriteMicrodump(child, &context, sizeof(context), mappings)); |
| 106 |
| 107 // Revert stderr back to the console. |
| 108 dup2(save_err, STDERR_FILENO); |
| 109 close(save_err); |
| 110 |
| 111 // Read back the stderr file and check for the microdump marker. |
| 112 fsync(err_fd); |
| 113 lseek(err_fd, 0, SEEK_SET); |
| 114 const size_t kBufSize = 64 * 1024; |
| 115 scoped_array<char> buf(new char[kBufSize]); |
| 116 ASSERT_GT(read(err_fd, buf.get(), kBufSize), 0); |
| 117 |
| 118 ASSERT_NE(static_cast<char*>(0), strstr( |
| 119 buf.get(), "-----BEGIN BREAKPAD MICRODUMP-----")); |
| 120 ASSERT_NE(static_cast<char*>(0), strstr( |
| 121 buf.get(), "-----END BREAKPAD MICRODUMP-----")); |
| 122 ASSERT_NE(static_cast<char*>(0), strstr( |
| 123 buf.get(), "M 0000000000001000 000000000000002A 0000000000001000 " |
| 124 "33221100554477668899AABBCCDDEEFF0 libfoo.so")); |
| 125 |
| 126 close(err_fd); |
| 127 close(fds[1]); |
| 128 } |
| 129 |
| 130 } // namespace |
LEFT | RIGHT |