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

Side by Side Diff: src/client/linux/minidump_writer/linux_dumper_unittest.cc

Issue 543125: Port linux_syscall_support and linux_dumper to support Linux ARM. Unit tests... (Closed) Base URL: http://google-breakpad.googlecode.com/svn/trunk/
Patch Set: '' Created 10 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009, Google Inc. 1 // Copyright (c) 2009, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 10 matching lines...) Expand all
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 29
30 #include <unistd.h> 30 #include <unistd.h>
31 #include <signal.h>
32 #include <sys/types.h>
31 33
34 #include "breakpad_googletest_includes.h"
35 #include "common/linux/memory.h"
32 #include "client/linux/minidump_writer/linux_dumper.h" 36 #include "client/linux/minidump_writer/linux_dumper.h"
33 #include "breakpad_googletest_includes.h"
34 37
35 using namespace google_breakpad; 38 using namespace google_breakpad;
36 39
37 namespace { 40 namespace {
38 typedef testing::Test LinuxDumperTest; 41 typedef testing::Test LinuxDumperTest;
39 } 42 }
40 43
41 TEST(LinuxDumperTest, Setup) { 44 TEST(LinuxDumperTest, Setup) {
42 LinuxDumper dumper(getpid()); 45 LinuxDumper dumper(getpid());
43 } 46 }
44 47
45 TEST(LinuxDumperTest, FindMappings) { 48 TEST(LinuxDumperTest, FindMappings) {
46 LinuxDumper dumper(getpid()); 49 LinuxDumper dumper(getpid());
47 ASSERT_TRUE(dumper.Init()); 50 ASSERT_TRUE(dumper.Init());
48 51
49 ASSERT_TRUE(dumper.FindMapping(reinterpret_cast<void*>(getpid))); 52 ASSERT_TRUE(dumper.FindMapping(reinterpret_cast<void*>(getpid)));
50 ASSERT_TRUE(dumper.FindMapping(reinterpret_cast<void*>(printf))); 53 ASSERT_TRUE(dumper.FindMapping(reinterpret_cast<void*>(printf)));
51 ASSERT_FALSE(dumper.FindMapping(NULL)); 54 ASSERT_FALSE(dumper.FindMapping(NULL));
52 } 55 }
53 56
54 TEST(LinuxDumperTest, ThreadList) { 57 TEST(LinuxDumperTest, ThreadList) {
55 LinuxDumper dumper(getpid()); 58 LinuxDumper dumper(getpid());
56 ASSERT_TRUE(dumper.Init()); 59 ASSERT_TRUE(dumper.Init());
57 60
58 ASSERT_GE(dumper.threads().size(), 1); 61 ASSERT_GE(dumper.threads().size(), (size_t)1);
59 bool found = false; 62 bool found = false;
60 for (size_t i = 0; i < dumper.threads().size(); ++i) { 63 for (size_t i = 0; i < dumper.threads().size(); ++i) {
61 if (dumper.threads()[i] == getpid()) { 64 if (dumper.threads()[i] == getpid()) {
62 found = true; 65 found = true;
63 break; 66 break;
64 } 67 }
65 } 68 }
66 } 69 }
67 70
71 TEST(LinuxDumperTest, VerifyStackReadWithMultipleThreads) {
72 static const int kNumberOfThreadsInHelperProgram = 5;
73 char kNumberOfThreadsArgument[2];
74 sprintf(kNumberOfThreadsArgument, "%d", kNumberOfThreadsInHelperProgram);
awong 2010/02/08 20:52:55 Can you use StrintPrintf instead (if you have it)?
75 pid_t child_pid = fork();
76 if (child_pid == 0) {
77 // Set the number of threads
78 execl("./linux_dumper_unittest_helper",
79 "linux_dumper_unittest_helper",
80 kNumberOfThreadsArgument,
81 NULL);
82 // Kill if we get here.
83 printf("Errno from exec: %d", errno);
84 FAIL() << "Exec failed: " << strerror(errno);
85 }
86 // The sleep is flaky, but prevents us from reading
87 // the child process before all threads have been created.
88 sleep(1);
89 LinuxDumper dumper(child_pid);
90 EXPECT_TRUE(dumper.Init());
91 EXPECT_EQ((size_t)kNumberOfThreadsInHelperProgram, dumper.threads().size());
92 EXPECT_TRUE(dumper.ThreadsSuspend());
93
94 ThreadInfo one_thread;
95 for(size_t i = 0; i < dumper.threads().size(); ++i) {
96 EXPECT_TRUE(dumper.ThreadInfoGet(dumper.threads()[i], &one_thread));
97 // We know the threads are in a function which has allocated exactly
98 // one word off the stack to store its thread id.
99 #if defined(__ARM_EABI__)
100 void* process_tid_location = (void *)(one_thread.regs.uregs[11] - 8);
101 #elif defined(__i386)
102 void* process_tid_location = (void *)(one_thread.regs.ebp - 4);
103 #elif defined(__x86_64)
104 void* process_tid_location = (void *)(one_thread.regs.ebp - 8);
Ted Mielczarek 2010/02/05 17:04:07 This should be one_thread.regs.rbp. Also, this tes
105 #else
106 #error Platform not supported!
107 #endif
108 pid_t one_thread_id;
109 dumper.CopyFromProcess(&one_thread_id,
110 dumper.threads()[i],
111 process_tid_location,
112 4);
113 EXPECT_EQ(dumper.threads()[i], one_thread_id);
114 }
115 kill(child_pid, SIGKILL);
116 }
117
68 TEST(LinuxDumperTest, BuildProcPath) { 118 TEST(LinuxDumperTest, BuildProcPath) {
69 const pid_t pid = getpid(); 119 const pid_t pid = getpid();
70 LinuxDumper dumper(pid); 120 LinuxDumper dumper(pid);
71 121
72 char maps_path[256] = "dummymappath"; 122 char maps_path[256] = "dummymappath";
73 char maps_path_expected[256]; 123 char maps_path_expected[256];
74 snprintf(maps_path_expected, sizeof(maps_path_expected), 124 snprintf(maps_path_expected, sizeof(maps_path_expected),
75 "/proc/%d/maps", pid); 125 "/proc/%d/maps", pid);
76 dumper.BuildProcPath(maps_path, pid, "maps"); 126 dumper.BuildProcPath(maps_path, pid, "maps");
77 ASSERT_STREQ(maps_path, maps_path_expected); 127 ASSERT_STREQ(maps_path, maps_path_expected);
78 128
79 // In release mode, we expect BuildProcPath to handle the invalid 129 // In release mode, we expect BuildProcPath to handle the invalid
80 // parameters correctly and fill map_path with an empty 130 // parameters correctly and fill map_path with an empty
81 // NULL-terminated string. 131 // NULL-terminated string.
82 #ifdef NDEBUG 132 #ifdef NDEBUG
83 snprintf(maps_path, sizeof(maps_path), "dummymappath"); 133 snprintf(maps_path, sizeof(maps_path), "dummymappath");
84 dumper.BuildProcPath(maps_path, 0, "maps"); 134 dumper.BuildProcPath(maps_path, 0, "maps");
85 EXPECT_STREQ(maps_path, ""); 135 EXPECT_STREQ(maps_path, "");
86 136
87 snprintf(maps_path, sizeof(maps_path), "dummymappath"); 137 snprintf(maps_path, sizeof(maps_path), "dummymappath");
88 dumper.BuildProcPath(maps_path, getpid(), ""); 138 dumper.BuildProcPath(maps_path, getpid(), "");
89 EXPECT_STREQ(maps_path, ""); 139 EXPECT_STREQ(maps_path, "");
90 140
91 snprintf(maps_path, sizeof(maps_path), "dummymappath"); 141 snprintf(maps_path, sizeof(maps_path), "dummymappath");
92 dumper.BuildProcPath(maps_path, getpid(), NULL); 142 dumper.BuildProcPath(maps_path, getpid(), NULL);
93 EXPECT_STREQ(maps_path, ""); 143 EXPECT_STREQ(maps_path, "");
94 #endif 144 #endif
95 } 145 }
96 146
147 #if !defined(__ARM_EABI__)
97 TEST(LinuxDumperTest, MappingsIncludeLinuxGate) { 148 TEST(LinuxDumperTest, MappingsIncludeLinuxGate) {
98 LinuxDumper dumper(getpid()); 149 LinuxDumper dumper(getpid());
99 ASSERT_TRUE(dumper.Init()); 150 ASSERT_TRUE(dumper.Init());
100 151
101 void* linux_gate_loc = dumper.FindBeginningOfLinuxGateSharedLibrary(getpid()); 152 void* linux_gate_loc = dumper.FindBeginningOfLinuxGateSharedLibrary(getpid());
102 if (linux_gate_loc) { 153 ASSERT_TRUE(linux_gate_loc);
103 bool found_linux_gate = false; 154 bool found_linux_gate = false;
104 155
105 const wasteful_vector<MappingInfo*> mappings = dumper.mappings(); 156 const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
106 const MappingInfo* mapping; 157 const MappingInfo* mapping;
107 for (unsigned i = 0; i < mappings.size(); ++i) { 158 for (unsigned i = 0; i < mappings.size(); ++i) {
108 mapping = mappings[i]; 159 mapping = mappings[i];
109 if (!strcmp(mapping->name, kLinuxGateLibraryName)) { 160 if (!strcmp(mapping->name, kLinuxGateLibraryName)) {
110 found_linux_gate = true; 161 found_linux_gate = true;
111 break; 162 break;
112 }
113 } 163 }
114 EXPECT_TRUE(found_linux_gate);
115 EXPECT_EQ(linux_gate_loc, reinterpret_cast<void*>(mapping->start_addr));
116 EXPECT_EQ(0, memcmp(linux_gate_loc, ELFMAG, SELFMAG));
117 } 164 }
165 EXPECT_TRUE(found_linux_gate);
166 EXPECT_EQ(linux_gate_loc, reinterpret_cast<void*>(mapping->start_addr));
167 EXPECT_EQ(0, memcmp(linux_gate_loc, ELFMAG, SELFMAG));
118 } 168 }
169 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698