OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <fcntl.h> | 5 #include <fcntl.h> |
6 #include <poll.h> | 6 #include <poll.h> |
7 #include <signal.h> | 7 #include <signal.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include <sys/resource.h> | 9 #include <sys/resource.h> |
10 #include <sys/time.h> | 10 #include <sys/time.h> |
(...skipping 25 matching lines...) Expand all Loading... |
36 if (task_d != 0 || task_stat.st_nlink < 3) | 36 if (task_d != 0 || task_stat.st_nlink < 3) |
37 return -1; | 37 return -1; |
38 const int num_threads = task_stat.st_nlink - 2; | 38 const int num_threads = task_stat.st_nlink - 2; |
39 return num_threads; | 39 return num_threads; |
40 } | 40 } |
41 | 41 |
42 } // namespace | 42 } // namespace |
43 | 43 |
44 namespace sandbox { | 44 namespace sandbox { |
45 | 45 |
46 extern bool kAllowForkWithThreads; | |
47 | |
48 bool IsAndroid() { | 46 bool IsAndroid() { |
49 #if defined(OS_ANDROID) | 47 #if defined(OS_ANDROID) |
50 return true; | 48 return true; |
51 #else | 49 #else |
52 return false; | 50 return false; |
53 #endif | 51 #endif |
54 } | 52 } |
55 | 53 |
56 bool IsArchitectureArm() { | 54 bool IsArchitectureArm() { |
57 #if defined(ARCH_CPU_ARM_FAMILY) | 55 #if defined(ARCH_CPU_ARM_FAMILY) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // there is a way to delay the start of the thread | 120 // there is a way to delay the start of the thread |
123 // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19). | 121 // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19). |
124 const int kNumExpectedThreads = 2; | 122 const int kNumExpectedThreads = 2; |
125 #endif | 123 #endif |
126 | 124 |
127 // The kernel is at liberty to wake a thread id futex before updating /proc. | 125 // The kernel is at liberty to wake a thread id futex before updating /proc. |
128 // If another test running in the same process has stopped a thread, it may | 126 // If another test running in the same process has stopped a thread, it may |
129 // appear as still running in /proc. | 127 // appear as still running in /proc. |
130 // We poll /proc, with an exponential back-off. At most, we'll sleep around | 128 // We poll /proc, with an exponential back-off. At most, we'll sleep around |
131 // 2^iterations nanoseconds in nanosleep(). | 129 // 2^iterations nanoseconds in nanosleep(). |
132 if (!kAllowForkWithThreads) { | 130 for (unsigned int iteration = 0; iteration < 30; iteration++) { |
133 for (unsigned int iteration = 0; iteration < 30; iteration++) { | 131 struct timespec ts = {0, 1L << iteration /* nanoseconds */}; |
134 struct timespec ts = {0, 1L << iteration /* nanoseconds */}; | 132 PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts))); |
135 PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts))); | 133 num_threads = CountThreads(); |
136 num_threads = CountThreads(); | 134 if (kNumExpectedThreads == num_threads) |
137 if (kNumExpectedThreads == num_threads) | 135 break; |
138 break; | |
139 } | |
140 } | 136 } |
141 | 137 |
142 const std::string multiple_threads_error = | 138 ASSERT_EQ(kNumExpectedThreads, num_threads) |
143 "Running sandbox tests with multiple threads " | 139 << "Running sandbox tests with multiple threads " |
144 "is not supported and will make the tests flaky."; | 140 << "is not supported and will make the tests flaky."; |
145 if (!kAllowForkWithThreads) { | |
146 ASSERT_EQ(kNumExpectedThreads, num_threads) << multiple_threads_error; | |
147 } else { | |
148 if (kNumExpectedThreads != num_threads) | |
149 LOG(ERROR) << multiple_threads_error; | |
150 } | |
151 | |
152 int fds[2]; | 141 int fds[2]; |
153 ASSERT_EQ(0, pipe(fds)); | 142 ASSERT_EQ(0, pipe(fds)); |
154 // Check that our pipe is not on one of the standard file descriptor. | 143 // Check that our pipe is not on one of the standard file descriptor. |
155 SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2); | 144 SANDBOX_ASSERT(fds[0] > 2 && fds[1] > 2); |
156 | 145 |
157 pid_t pid; | 146 pid_t pid; |
158 ASSERT_LE(0, (pid = fork())); | 147 ASSERT_LE(0, (pid = fork())); |
159 if (!pid) { | 148 if (!pid) { |
160 // In child process | 149 // In child process |
161 // Redirect stderr to our pipe. This way, we can capture all error | 150 // Redirect stderr to our pipe. This way, we can capture all error |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 fflush(stderr); | 281 fflush(stderr); |
293 _exit(kExitWithAssertionFailure); | 282 _exit(kExitWithAssertionFailure); |
294 } | 283 } |
295 | 284 |
296 void UnitTests::IgnoreThisTest() { | 285 void UnitTests::IgnoreThisTest() { |
297 fflush(stderr); | 286 fflush(stderr); |
298 _exit(kIgnoreThisTest); | 287 _exit(kIgnoreThisTest); |
299 } | 288 } |
300 | 289 |
301 } // namespace | 290 } // namespace |
OLD | NEW |