| 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 #define _CRT_SECURE_NO_WARNINGS | 5 #define _CRT_SECURE_NO_WARNINGS |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 waited += kInterval; | 105 waited += kInterval; |
| 106 } while (status == base::TERMINATION_STATUS_STILL_RUNNING && | 106 } while (status == base::TERMINATION_STATUS_STILL_RUNNING && |
| 107 waited.InMilliseconds() < TestTimeouts::action_max_timeout_ms()); | 107 waited.InMilliseconds() < TestTimeouts::action_max_timeout_ms()); |
| 108 | 108 |
| 109 return status; | 109 return status; |
| 110 } | 110 } |
| 111 | 111 |
| 112 } // namespace | 112 } // namespace |
| 113 | 113 |
| 114 class ProcessUtilTest : public base::MultiProcessTest { | 114 class ProcessUtilTest : public base::MultiProcessTest { |
| 115 public: |
| 115 #if defined(OS_POSIX) | 116 #if defined(OS_POSIX) |
| 116 public: | |
| 117 // Spawn a child process that counts how many file descriptors are open. | 117 // Spawn a child process that counts how many file descriptors are open. |
| 118 int CountOpenFDsInChild(); | 118 int CountOpenFDsInChild(); |
| 119 #endif | 119 #endif |
| 120 // Converts the filename to a platform specific filepath. |
| 121 // On Android files can not be created in arbitrary directories. |
| 122 static std::string GetSignalFilePath(const char* filename); |
| 120 }; | 123 }; |
| 121 | 124 |
| 125 std::string ProcessUtilTest::GetSignalFilePath(const char* filename) { |
| 126 #if !defined(OS_ANDROID) |
| 127 return filename; |
| 128 #else |
| 129 FilePath tmp_dir; |
| 130 PathService::Get(base::DIR_CACHE, &tmp_dir); |
| 131 tmp_dir = tmp_dir.Append(filename); |
| 132 return tmp_dir.value(); |
| 133 #endif |
| 134 } |
| 135 |
| 122 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { | 136 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { |
| 123 return 0; | 137 return 0; |
| 124 } | 138 } |
| 125 | 139 |
| 126 TEST_F(ProcessUtilTest, SpawnChild) { | 140 TEST_F(ProcessUtilTest, SpawnChild) { |
| 127 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); | 141 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); |
| 128 ASSERT_NE(base::kNullProcessHandle, handle); | 142 ASSERT_NE(base::kNullProcessHandle, handle); |
| 129 EXPECT_TRUE(base::WaitForSingleProcess( | 143 EXPECT_TRUE(base::WaitForSingleProcess( |
| 130 handle, TestTimeouts::action_max_timeout_ms())); | 144 handle, TestTimeouts::action_max_timeout_ms())); |
| 131 base::CloseProcessHandle(handle); | 145 base::CloseProcessHandle(handle); |
| 132 } | 146 } |
| 133 | 147 |
| 134 MULTIPROCESS_TEST_MAIN(SlowChildProcess) { | 148 MULTIPROCESS_TEST_MAIN(SlowChildProcess) { |
| 135 WaitToDie(kSignalFileSlow); | 149 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str()); |
| 136 return 0; | 150 return 0; |
| 137 } | 151 } |
| 138 | 152 |
| 139 TEST_F(ProcessUtilTest, KillSlowChild) { | 153 TEST_F(ProcessUtilTest, KillSlowChild) { |
| 140 remove(kSignalFileSlow); | 154 const std::string signal_file = |
| 155 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); |
| 156 remove(signal_file.c_str()); |
| 141 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false); | 157 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false); |
| 142 ASSERT_NE(base::kNullProcessHandle, handle); | 158 ASSERT_NE(base::kNullProcessHandle, handle); |
| 143 SignalChildren(kSignalFileSlow); | 159 SignalChildren(signal_file.c_str()); |
| 144 EXPECT_TRUE(base::WaitForSingleProcess( | 160 EXPECT_TRUE(base::WaitForSingleProcess( |
| 145 handle, TestTimeouts::action_max_timeout_ms())); | 161 handle, TestTimeouts::action_max_timeout_ms())); |
| 146 base::CloseProcessHandle(handle); | 162 base::CloseProcessHandle(handle); |
| 147 remove(kSignalFileSlow); | 163 remove(signal_file.c_str()); |
| 148 } | 164 } |
| 149 | 165 |
| 150 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058 | 166 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058 |
| 151 TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) { | 167 TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) { |
| 152 remove(kSignalFileSlow); | 168 const std::string signal_file = |
| 169 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); |
| 170 remove(signal_file.c_str()); |
| 153 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false); | 171 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false); |
| 154 ASSERT_NE(base::kNullProcessHandle, handle); | 172 ASSERT_NE(base::kNullProcessHandle, handle); |
| 155 | 173 |
| 156 int exit_code = 42; | 174 int exit_code = 42; |
| 157 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 175 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, |
| 158 base::GetTerminationStatus(handle, &exit_code)); | 176 base::GetTerminationStatus(handle, &exit_code)); |
| 159 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 177 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 160 | 178 |
| 161 SignalChildren(kSignalFileSlow); | 179 SignalChildren(signal_file.c_str()); |
| 162 exit_code = 42; | 180 exit_code = 42; |
| 163 base::TerminationStatus status = | 181 base::TerminationStatus status = |
| 164 WaitForChildTermination(handle, &exit_code); | 182 WaitForChildTermination(handle, &exit_code); |
| 165 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status); | 183 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status); |
| 166 EXPECT_EQ(0, exit_code); | 184 EXPECT_EQ(0, exit_code); |
| 167 base::CloseProcessHandle(handle); | 185 base::CloseProcessHandle(handle); |
| 168 remove(kSignalFileSlow); | 186 remove(signal_file.c_str()); |
| 169 } | 187 } |
| 170 | 188 |
| 171 #if defined(OS_WIN) | 189 #if defined(OS_WIN) |
| 172 // TODO(cpu): figure out how to test this in other platforms. | 190 // TODO(cpu): figure out how to test this in other platforms. |
| 173 TEST_F(ProcessUtilTest, GetProcId) { | 191 TEST_F(ProcessUtilTest, GetProcId) { |
| 174 base::ProcessId id1 = base::GetProcId(GetCurrentProcess()); | 192 base::ProcessId id1 = base::GetProcId(GetCurrentProcess()); |
| 175 EXPECT_NE(0ul, id1); | 193 EXPECT_NE(0ul, id1); |
| 176 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); | 194 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); |
| 177 ASSERT_NE(base::kNullProcessHandle, handle); | 195 ASSERT_NE(base::kNullProcessHandle, handle); |
| 178 base::ProcessId id2 = base::GetProcId(handle); | 196 base::ProcessId id2 = base::GetProcId(handle); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 205 // This test is disabled on Mac, since it's flaky due to ReportCrash | 223 // This test is disabled on Mac, since it's flaky due to ReportCrash |
| 206 // taking a variable amount of time to parse and load the debug and | 224 // taking a variable amount of time to parse and load the debug and |
| 207 // symbol data for this unit test's executable before firing the | 225 // symbol data for this unit test's executable before firing the |
| 208 // signal handler. | 226 // signal handler. |
| 209 // | 227 // |
| 210 // TODO(gspencer): turn this test process into a very small program | 228 // TODO(gspencer): turn this test process into a very small program |
| 211 // with no symbols (instead of using the multiprocess testing | 229 // with no symbols (instead of using the multiprocess testing |
| 212 // framework) to reduce the ReportCrash overhead. | 230 // framework) to reduce the ReportCrash overhead. |
| 213 | 231 |
| 214 MULTIPROCESS_TEST_MAIN(CrashingChildProcess) { | 232 MULTIPROCESS_TEST_MAIN(CrashingChildProcess) { |
| 215 WaitToDie(kSignalFileCrash); | 233 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileCrash).c_str()); |
| 216 #if defined(OS_POSIX) | 234 #if defined(OS_POSIX) |
| 217 // Have to disable to signal handler for segv so we can get a crash | 235 // Have to disable to signal handler for segv so we can get a crash |
| 218 // instead of an abnormal termination through the crash dump handler. | 236 // instead of an abnormal termination through the crash dump handler. |
| 219 ::signal(SIGSEGV, SIG_DFL); | 237 ::signal(SIGSEGV, SIG_DFL); |
| 220 #endif | 238 #endif |
| 221 // Make this process have a segmentation fault. | 239 // Make this process have a segmentation fault. |
| 222 volatile int* oops = NULL; | 240 volatile int* oops = NULL; |
| 223 *oops = 0xDEAD; | 241 *oops = 0xDEAD; |
| 224 return 1; | 242 return 1; |
| 225 } | 243 } |
| 226 | 244 |
| 227 // This test intentionally crashes, so we don't need to run it under | 245 // This test intentionally crashes, so we don't need to run it under |
| 228 // AddressSanitizer. | 246 // AddressSanitizer. |
| 229 #if defined(ADDRESS_SANITIZER) | 247 #if defined(ADDRESS_SANITIZER) |
| 230 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash | 248 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash |
| 231 #else | 249 #else |
| 232 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash | 250 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash |
| 233 #endif | 251 #endif |
| 234 TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) { | 252 TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) { |
| 235 remove(kSignalFileCrash); | 253 const std::string signal_file = |
| 254 ProcessUtilTest::GetSignalFilePath(kSignalFileCrash); |
| 255 remove(signal_file.c_str()); |
| 236 base::ProcessHandle handle = this->SpawnChild("CrashingChildProcess", | 256 base::ProcessHandle handle = this->SpawnChild("CrashingChildProcess", |
| 237 false); | 257 false); |
| 238 ASSERT_NE(base::kNullProcessHandle, handle); | 258 ASSERT_NE(base::kNullProcessHandle, handle); |
| 239 | 259 |
| 240 int exit_code = 42; | 260 int exit_code = 42; |
| 241 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 261 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, |
| 242 base::GetTerminationStatus(handle, &exit_code)); | 262 base::GetTerminationStatus(handle, &exit_code)); |
| 243 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 263 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 244 | 264 |
| 245 SignalChildren(kSignalFileCrash); | 265 SignalChildren(signal_file.c_str()); |
| 246 exit_code = 42; | 266 exit_code = 42; |
| 247 base::TerminationStatus status = | 267 base::TerminationStatus status = |
| 248 WaitForChildTermination(handle, &exit_code); | 268 WaitForChildTermination(handle, &exit_code); |
| 249 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status); | 269 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status); |
| 250 | 270 |
| 251 #if defined(OS_WIN) | 271 #if defined(OS_WIN) |
| 252 EXPECT_EQ(0xc0000005, exit_code); | 272 EXPECT_EQ(0xc0000005, exit_code); |
| 253 #elif defined(OS_POSIX) | 273 #elif defined(OS_POSIX) |
| 254 int signaled = WIFSIGNALED(exit_code); | 274 int signaled = WIFSIGNALED(exit_code); |
| 255 EXPECT_NE(0, signaled); | 275 EXPECT_NE(0, signaled); |
| 256 int signal = WTERMSIG(exit_code); | 276 int signal = WTERMSIG(exit_code); |
| 257 EXPECT_EQ(SIGSEGV, signal); | 277 EXPECT_EQ(SIGSEGV, signal); |
| 258 #endif | 278 #endif |
| 259 base::CloseProcessHandle(handle); | 279 base::CloseProcessHandle(handle); |
| 260 | 280 |
| 261 // Reset signal handlers back to "normal". | 281 // Reset signal handlers back to "normal". |
| 262 base::EnableInProcessStackDumping(); | 282 base::EnableInProcessStackDumping(); |
| 263 remove(kSignalFileCrash); | 283 remove(signal_file.c_str()); |
| 264 } | 284 } |
| 265 #endif // !defined(OS_MACOSX) | 285 #endif // !defined(OS_MACOSX) |
| 266 | 286 |
| 267 MULTIPROCESS_TEST_MAIN(KilledChildProcess) { | 287 MULTIPROCESS_TEST_MAIN(KilledChildProcess) { |
| 268 WaitToDie(kSignalFileKill); | 288 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileKill).c_str()); |
| 269 #if defined(OS_WIN) | 289 #if defined(OS_WIN) |
| 270 // Kill ourselves. | 290 // Kill ourselves. |
| 271 HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId()); | 291 HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId()); |
| 272 ::TerminateProcess(handle, kExpectedKilledExitCode); | 292 ::TerminateProcess(handle, kExpectedKilledExitCode); |
| 273 #elif defined(OS_POSIX) | 293 #elif defined(OS_POSIX) |
| 274 // Send a SIGKILL to this process, just like the OOM killer would. | 294 // Send a SIGKILL to this process, just like the OOM killer would. |
| 275 ::kill(getpid(), SIGKILL); | 295 ::kill(getpid(), SIGKILL); |
| 276 #endif | 296 #endif |
| 277 return 1; | 297 return 1; |
| 278 } | 298 } |
| 279 | 299 |
| 280 TEST_F(ProcessUtilTest, GetTerminationStatusKill) { | 300 TEST_F(ProcessUtilTest, GetTerminationStatusKill) { |
| 281 remove(kSignalFileKill); | 301 const std::string signal_file = |
| 302 ProcessUtilTest::GetSignalFilePath(kSignalFileKill); |
| 303 remove(signal_file.c_str()); |
| 282 base::ProcessHandle handle = this->SpawnChild("KilledChildProcess", | 304 base::ProcessHandle handle = this->SpawnChild("KilledChildProcess", |
| 283 false); | 305 false); |
| 284 ASSERT_NE(base::kNullProcessHandle, handle); | 306 ASSERT_NE(base::kNullProcessHandle, handle); |
| 285 | 307 |
| 286 int exit_code = 42; | 308 int exit_code = 42; |
| 287 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, | 309 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, |
| 288 base::GetTerminationStatus(handle, &exit_code)); | 310 base::GetTerminationStatus(handle, &exit_code)); |
| 289 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); | 311 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); |
| 290 | 312 |
| 291 SignalChildren(kSignalFileKill); | 313 SignalChildren(signal_file.c_str()); |
| 292 exit_code = 42; | 314 exit_code = 42; |
| 293 base::TerminationStatus status = | 315 base::TerminationStatus status = |
| 294 WaitForChildTermination(handle, &exit_code); | 316 WaitForChildTermination(handle, &exit_code); |
| 295 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); | 317 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); |
| 296 #if defined(OS_WIN) | 318 #if defined(OS_WIN) |
| 297 EXPECT_EQ(kExpectedKilledExitCode, exit_code); | 319 EXPECT_EQ(kExpectedKilledExitCode, exit_code); |
| 298 #elif defined(OS_POSIX) | 320 #elif defined(OS_POSIX) |
| 299 int signaled = WIFSIGNALED(exit_code); | 321 int signaled = WIFSIGNALED(exit_code); |
| 300 EXPECT_NE(0, signaled); | 322 EXPECT_NE(0, signaled); |
| 301 int signal = WTERMSIG(exit_code); | 323 int signal = WTERMSIG(exit_code); |
| 302 EXPECT_EQ(SIGKILL, signal); | 324 EXPECT_EQ(SIGKILL, signal); |
| 303 #endif | 325 #endif |
| 304 base::CloseProcessHandle(handle); | 326 base::CloseProcessHandle(handle); |
| 305 remove(kSignalFileKill); | 327 remove(signal_file.c_str()); |
| 306 } | 328 } |
| 307 | 329 |
| 308 // Ensure that the priority of a process is restored correctly after | 330 // Ensure that the priority of a process is restored correctly after |
| 309 // backgrounding and restoring. | 331 // backgrounding and restoring. |
| 310 // Note: a platform may not be willing or able to lower the priority of | 332 // Note: a platform may not be willing or able to lower the priority of |
| 311 // a process. The calls to SetProcessBackground should be noops then. | 333 // a process. The calls to SetProcessBackground should be noops then. |
| 312 TEST_F(ProcessUtilTest, SetProcessBackgrounded) { | 334 TEST_F(ProcessUtilTest, SetProcessBackgrounded) { |
| 313 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); | 335 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); |
| 314 base::Process process(handle); | 336 base::Process process(handle); |
| 315 int old_priority = process.GetPriority(); | 337 int old_priority = process.GetPriority(); |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 SetUpInDeathAssert(); | 1206 SetUpInDeathAssert(); |
| 1185 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {} | 1207 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {} |
| 1186 }, ""); | 1208 }, ""); |
| 1187 } | 1209 } |
| 1188 | 1210 |
| 1189 #endif // !ARCH_CPU_64_BITS | 1211 #endif // !ARCH_CPU_64_BITS |
| 1190 #endif // OS_MACOSX | 1212 #endif // OS_MACOSX |
| 1191 | 1213 |
| 1192 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && | 1214 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && |
| 1193 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER) | 1215 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER) |
| OLD | NEW |