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 3 // found in the LICENSE file. 4 5 #define _CRT_SECURE_NO_WARNINGS 6 7 #include <limits> 8 9 #include "base/command_line.h" 10 #include "base/debug/alias.h" 11 #include "base/debug/stack_trace.h" 12 #include "base/files/file_path.h" 13 #include "base/logging.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/path_service.h" 16 #include "base/posix/eintr_wrapper.h" 17 #include "base/process/kill.h" 18 #include "base/process/launch.h" 19 #include "base/process/memory.h" 20 #include "base/process/process.h" 21 #include "base/process/process_metrics.h" 22 #include "base/strings/string_number_conversions.h" 23 #include "base/strings/utf_string_conversions.h" 24 #include "base/synchronization/waitable_event.h" 25 #include "base/test/multiprocess_test.h" 26 #include "base/test/test_timeouts.h" 27 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 28 #include "base/threading/platform_thread.h" 29 #include "base/threading/thread.h" 30 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/multiprocess_func_list.h" 32 33 #if defined(OS_LINUX) 34 #include <malloc.h> 35 #include <sched.h> 36 #endif 37 #if defined(OS_POSIX) 38 #include <dlfcn.h> 39 #include <errno.h> 40 #include <fcntl.h> 41 #include <signal.h> 42 #include <sys/resource.h> 43 #include <sys/socket.h> 44 #include <sys/wait.h> 45 #endif 46 #if defined(OS_WIN) 47 #include <windows.h> 48 #include "base/win/windows_version.h" 49 #endif 50 #if defined(OS_MACOSX) 51 #include <mach/vm_param.h> 52 #include <malloc/malloc.h> 53 #include "base/mac/mac_util.h" 54 #endif 55 56 using base::FilePath; 57 58 namespace { 59 60 #if defined(OS_ANDROID) 61 const char kShellPath[] = "/system/bin/sh"; 62 const char kPosixShell[] = "sh"; 63 #else 64 const char kShellPath[] = "/bin/sh"; 65 const char kPosixShell[] = "bash"; 66 #endif 67 68 const char kSignalFileSlow[] = "SlowChildProcess.die"; 69 const char kSignalFileKill[] = "KilledChildProcess.die"; 70 71 #if defined(OS_WIN) 72 const int kExpectedStillRunningExitCode = 0x102; 73 const int kExpectedKilledExitCode = 1; 74 #else 75 const int kExpectedStillRunningExitCode = 0; 76 #endif 77 78 // Sleeps until file filename is created. 79 void WaitToDie(const char* filename) { 80 FILE* fp; 81 do { 82 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); 83 fp = fopen(filename, "r"); 84 } while (!fp); 85 fclose(fp); 86 } 87 88 // Signals children they should die now. 89 void SignalChildren(const char* filename) { 90 FILE* fp = fopen(filename, "w"); 91 fclose(fp); 92 } 93 94 // Using a pipe to the child to wait for an event was considered, but 95 // there were cases in the past where pipes caused problems (other 96 // libraries closing the fds, child deadlocking). This is a simple 97 // case, so it's not worth the risk. Using wait loops is discouraged 98 // in most instances. 99 base::TerminationStatus WaitForChildTermination(base::ProcessHandle handle, 100 int* exit_code) { 101 // Now we wait until the result is something other than STILL_RUNNING. 102 base::TerminationStatus status = base::TERMINATION_STATUS_STILL_RUNNING; 103 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(20); 104 base::TimeDelta waited; 105 do { 106 status = base::GetTerminationStatus(handle, exit_code); 107 base::PlatformThread::Sleep(kInterval); 108 waited += kInterval; 109 } while (status == base::TERMINATION_STATUS_STILL_RUNNING && 110 waited < TestTimeouts::action_max_timeout()); 111 112 return status; 113 } 114 115 } // namespace 116 117 class ProcessUtilTest : public base::MultiProcessTest { 118 public: 119 #if defined(OS_POSIX) 120 // Spawn a child process that counts how many file descriptors are open. 121 int CountOpenFDsInChild(); 122 #endif 123 // Converts the filename to a platform specific filepath. 124 // On Android files can not be created in arbitrary directories. 125 static std::string GetSignalFilePath(const char* filename); 126 }; 127 128 std::string ProcessUtilTest::GetSignalFilePath(const char* filename) { 129 #if !defined(OS_ANDROID) 130 return filename; 131 #else 132 FilePath tmp_dir; 133 PathService::Get(base::DIR_CACHE, &tmp_dir); 134 tmp_dir = tmp_dir.Append(filename); 135 return tmp_dir.value(); 136 #endif 137 } 138 139 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { 140 return 0; 141 } 142 143 // TODO(viettrungluu): This should be in a "MultiProcessTestTest". 144 TEST_F(ProcessUtilTest, SpawnChild) { 145 base::ProcessHandle handle = SpawnChild("SimpleChildProcess"); 146 ASSERT_NE(base::kNullProcessHandle, handle); 147 EXPECT_TRUE(base::WaitForSingleProcess( 148 handle, TestTimeouts::action_max_timeout())); 149 base::CloseProcessHandle(handle); 150 } 151 152 MULTIPROCESS_TEST_MAIN(SlowChildProcess) { 153 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str()); 154 return 0; 155 } 156 157 TEST_F(ProcessUtilTest, KillSlowChild) { 158 const std::string signal_file = 159 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); 160 remove(signal_file.c_str()); 161 base::ProcessHandle handle = SpawnChild("SlowChildProcess"); 162 ASSERT_NE(base::kNullProcessHandle, handle); 163 SignalChildren(signal_file.c_str()); 164 EXPECT_TRUE(base::WaitForSingleProcess( 165 handle, TestTimeouts::action_max_timeout())); 166 base::CloseProcessHandle(handle); 167 remove(signal_file.c_str()); 168 } 169 170 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058 171 TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) { 172 const std::string signal_file = 173 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow); 174 remove(signal_file.c_str()); 175 base::ProcessHandle handle = SpawnChild("SlowChildProcess"); 176 ASSERT_NE(base::kNullProcessHandle, handle); 177 178 int exit_code = 42; 179 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, 180 base::GetTerminationStatus(handle, &exit_code)); 181 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); 182 183 SignalChildren(signal_file.c_str()); 184 exit_code = 42; 185 base::TerminationStatus status = 186 WaitForChildTermination(handle, &exit_code); 187 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status); 188 EXPECT_EQ(0, exit_code); 189 base::CloseProcessHandle(handle); 190 remove(signal_file.c_str()); 191 } 192 193 #if defined(OS_WIN) 194 // TODO(cpu): figure out how to test this in other platforms. 195 TEST_F(ProcessUtilTest, GetProcId) { 196 base::ProcessId id1 = base::GetProcId(GetCurrentProcess()); 197 EXPECT_NE(0ul, id1); 198 base::ProcessHandle handle = SpawnChild("SimpleChildProcess"); 199 ASSERT_NE(base::kNullProcessHandle, handle); 200 base::ProcessId id2 = base::GetProcId(handle); 201 EXPECT_NE(0ul, id2); 202 EXPECT_NE(id1, id2); 203 base::CloseProcessHandle(handle); 204 } 205 #endif 206 207 #if !defined(OS_MACOSX) 208 // This test is disabled on Mac, since it's flaky due to ReportCrash 209 // taking a variable amount of time to parse and load the debug and 210 // symbol data for this unit test's executable before firing the 211 // signal handler. 212 // 213 // TODO(gspencer): turn this test process into a very small program 214 // with no symbols (instead of using the multiprocess testing 215 // framework) to reduce the ReportCrash overhead. 216 const char kSignalFileCrash[] = "CrashingChildProcess.die"; 217 218 MULTIPROCESS_TEST_MAIN(CrashingChildProcess) { 219 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileCrash).c_str()); 220 #if defined(OS_POSIX) 221 // Have to disable to signal handler for segv so we can get a crash 222 // instead of an abnormal termination through the crash dump handler. 223 ::signal(SIGSEGV, SIG_DFL); 224 #endif 225 // Make this process have a segmentation fault. 226 volatile int* oops = NULL; 227 *oops = 0xDEAD; 228 return 1; 229 } 230 231 // This test intentionally crashes, so we don't need to run it under 232 // AddressSanitizer. 233 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN) 234 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash 235 #else 236 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash 237 #endif 238 TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) { 239 const std::string signal_file = 240 ProcessUtilTest::GetSignalFilePath(kSignalFileCrash); 241 remove(signal_file.c_str()); 242 base::ProcessHandle handle = SpawnChild("CrashingChildProcess"); 243 ASSERT_NE(base::kNullProcessHandle, handle); 244 245 int exit_code = 42; 246 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, 247 base::GetTerminationStatus(handle, &exit_code)); 248 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); 249 250 SignalChildren(signal_file.c_str()); 251 exit_code = 42; 252 base::TerminationStatus status = 253 WaitForChildTermination(handle, &exit_code); 254 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status); 255 256 #if defined(OS_WIN) 257 EXPECT_EQ(0xc0000005, exit_code); 258 #elif defined(OS_POSIX) 259 int signaled = WIFSIGNALED(exit_code); 260 EXPECT_NE(0, signaled); 261 int signal = WTERMSIG(exit_code); 262 EXPECT_EQ(SIGSEGV, signal); 263 #endif 264 base::CloseProcessHandle(handle); 265 266 // Reset signal handlers back to "normal". 267 base::debug::EnableInProcessStackDumping(); 268 remove(signal_file.c_str()); 269 } 270 #endif // !defined(OS_MACOSX) 271 272 MULTIPROCESS_TEST_MAIN(KilledChildProcess) { 273 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileKill).c_str()); 274 #if defined(OS_WIN) 275 // Kill ourselves. 276 HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId()); 277 ::TerminateProcess(handle, kExpectedKilledExitCode); 278 #elif defined(OS_POSIX) 279 // Send a SIGKILL to this process, just like the OOM killer would. 280 ::kill(getpid(), SIGKILL); 281 #endif 282 return 1; 283 } 284 285 TEST_F(ProcessUtilTest, GetTerminationStatusKill) { 286 const std::string signal_file = 287 ProcessUtilTest::GetSignalFilePath(kSignalFileKill); 288 remove(signal_file.c_str()); 289 base::ProcessHandle handle = SpawnChild("KilledChildProcess"); 290 ASSERT_NE(base::kNullProcessHandle, handle); 291 292 int exit_code = 42; 293 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, 294 base::GetTerminationStatus(handle, &exit_code)); 295 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code); 296 297 SignalChildren(signal_file.c_str()); 298 exit_code = 42; 299 base::TerminationStatus status = 300 WaitForChildTermination(handle, &exit_code); 301 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status); 302 #if defined(OS_WIN) 303 EXPECT_EQ(kExpectedKilledExitCode, exit_code); 304 #elif defined(OS_POSIX) 305 int signaled = WIFSIGNALED(exit_code); 306 EXPECT_NE(0, signaled); 307 int signal = WTERMSIG(exit_code); 308 EXPECT_EQ(SIGKILL, signal); 309 #endif 310 base::CloseProcessHandle(handle); 311 remove(signal_file.c_str()); 312 } 313 314 // Ensure that the priority of a process is restored correctly after 315 // backgrounding and restoring. 316 // Note: a platform may not be willing or able to lower the priority of 317 // a process. The calls to SetProcessBackground should be noops then. 318 TEST_F(ProcessUtilTest, SetProcessBackgrounded) { 319 base::ProcessHandle handle = SpawnChild("SimpleChildProcess"); 320 base::Process process(handle); 321 int old_priority = process.GetPriority(); 322 #if defined(OS_WIN) 323 EXPECT_TRUE(process.SetProcessBackgrounded(true)); 324 EXPECT_TRUE(process.IsProcessBackgrounded()); 325 EXPECT_TRUE(process.SetProcessBackgrounded(false)); 326 EXPECT_FALSE(process.IsProcessBackgrounded()); 327 #else 328 process.SetProcessBackgrounded(true); 329 process.SetProcessBackgrounded(false); 330 #endif 331 int new_priority = process.GetPriority(); 332 EXPECT_EQ(old_priority, new_priority); 333 } 334 335 // Same as SetProcessBackgrounded but to this very process. It uses 336 // a different code path at least for Windows. 337 TEST_F(ProcessUtilTest, SetProcessBackgroundedSelf) { 338 base::Process process(base::Process::Current().handle()); 339 int old_priority = process.GetPriority(); 340 #if defined(OS_WIN) 341 EXPECT_TRUE(process.SetProcessBackgrounded(true)); 342 EXPECT_TRUE(process.IsProcessBackgrounded()); 343 EXPECT_TRUE(process.SetProcessBackgrounded(false)); 344 EXPECT_FALSE(process.IsProcessBackgrounded()); 345 #else 346 process.SetProcessBackgrounded(true); 347 process.SetProcessBackgrounded(false); 348 #endif 349 int new_priority = process.GetPriority(); 350 EXPECT_EQ(old_priority, new_priority); 351 } 352 353 #if defined(OS_WIN) 354 // TODO(estade): if possible, port this test. 355 TEST_F(ProcessUtilTest, GetAppOutput) { 356 // Let's create a decently long message. 357 std::string message; 358 for (int i = 0; i < 1025; i++) { // 1025 so it does not end on a kilo-byte 359 // boundary. 360 message += "Hello!"; 361 } 362 // cmd.exe's echo always adds a \r\n to its output. 363 std::string expected(message); 364 expected += "\r\n"; 365 366 FilePath cmd(L"cmd.exe"); 367 CommandLine cmd_line(cmd); 368 cmd_line.AppendArg("/c"); 369 cmd_line.AppendArg("echo " + message + ""); 370 std::string output; 371 ASSERT_TRUE(base::GetAppOutput(cmd_line, &output)); 372 EXPECT_EQ(expected, output); 373 374 // Let's make sure stderr is ignored. 375 CommandLine other_cmd_line(cmd); 376 other_cmd_line.AppendArg("/c"); 377 // http://msdn.microsoft.com/library/cc772622.aspx 378 cmd_line.AppendArg("echo " + message + " >&2"); 379 output.clear(); 380 ASSERT_TRUE(base::GetAppOutput(other_cmd_line, &output)); 381 EXPECT_EQ("", output); 382 } 383 384 // TODO(estade): if possible, port this test. 385 TEST_F(ProcessUtilTest, LaunchAsUser) { 386 base::UserTokenHandle token; 387 ASSERT_TRUE(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)); 388 base::LaunchOptions options; 389 options.as_user = token; 390 EXPECT_TRUE(base::LaunchProcess(MakeCmdLine("SimpleChildProcess"), options, 391 NULL)); 392 } 393 394 static const char kEventToTriggerHandleSwitch[] = "event-to-trigger-handle"; 395 396 MULTIPROCESS_TEST_MAIN(TriggerEventChildProcess) { 397 std::string handle_value_string = 398 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 399 kEventToTriggerHandleSwitch); 400 CHECK(!handle_value_string.empty()); 401 402 uint64 handle_value_uint64; 403 CHECK(base::StringToUint64(handle_value_string, &handle_value_uint64)); 404 // Give ownership of the handle to |event|. 405 base::WaitableEvent event(reinterpret_cast<HANDLE>(handle_value_uint64)); 406 407 event.Signal(); 408 409 return 0; 410 } 411 412 TEST_F(ProcessUtilTest, InheritSpecifiedHandles) { 413 // Manually create the event, so that it can be inheritable. 414 SECURITY_ATTRIBUTES security_attributes = {}; 415 security_attributes.nLength = static_cast<DWORD>(sizeof(security_attributes)); 416 security_attributes.lpSecurityDescriptor = NULL; 417 security_attributes.bInheritHandle = true; 418 419 // Takes ownership of the event handle. 420 base::WaitableEvent event( 421 CreateEvent(&security_attributes, true, false, NULL)); 422 base::HandlesToInheritVector handles_to_inherit; 423 handles_to_inherit.push_back(event.handle()); 424 base::LaunchOptions options; 425 options.handles_to_inherit = &handles_to_inherit; 426 427 CommandLine cmd_line = MakeCmdLine("TriggerEventChildProcess"); 428 cmd_line.AppendSwitchASCII(kEventToTriggerHandleSwitch, 429 base::Uint64ToString(reinterpret_cast<uint64>(event.handle()))); 430 431 // This functionality actually requires Vista or later. Make sure that it 432 // fails properly on XP. 433 if (base::win::GetVersion() < base::win::VERSION_VISTA) { 434 EXPECT_FALSE(base::LaunchProcess(cmd_line, options, NULL)); 435 return; 436 } 437 438 // Launch the process and wait for it to trigger the event. 439 ASSERT_TRUE(base::LaunchProcess(cmd_line, options, NULL)); 440 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); 441 } 442 #endif // defined(OS_WIN) 443 444 #if defined(OS_POSIX) 445 446 namespace { 447 448 // Returns the maximum number of files that a process can have open. 449 // Returns 0 on error. 450 int GetMaxFilesOpenInProcess() { 451 struct rlimit rlim; 452 if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { 453 return 0; 454 } 455 456 // rlim_t is a uint64 - clip to maxint. We do this since FD #s are ints 457 // which are all 32 bits on the supported platforms. 458 rlim_t max_int = static_cast<rlim_t>(std::numeric_limits<int32>::max()); 459 if (rlim.rlim_cur > max_int) { 460 return max_int; 461 } 462 463 return rlim.rlim_cur; 464 } 465 466 const int kChildPipe = 20; // FD # for write end of pipe in child process. 467 468 #if defined(OS_MACOSX) 469 470 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h> 471 #if !defined(_GUARDID_T) 472 #define _GUARDID_T 473 typedef __uint64_t guardid_t; 474 #endif // _GUARDID_T 475 476 // From .../MacOSX10.9.sdk/usr/include/sys/syscall.h 477 #if !defined(SYS_change_fdguard_np) 478 #define SYS_change_fdguard_np 444 479 #endif 480 481 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h> 482 #if !defined(GUARD_DUP) 483 #define GUARD_DUP (1u << 1) 484 #endif 485 486 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_guarded.c?txt> 487 // 488 // Atomically replaces |guard|/|guardflags| with |nguard|/|nguardflags| on |fd|. 489 int change_fdguard_np(int fd, 490 const guardid_t *guard, u_int guardflags, 491 const guardid_t *nguard, u_int nguardflags, 492 int *fdflagsp) { 493 return syscall(SYS_change_fdguard_np, fd, guard, guardflags, 494 nguard, nguardflags, fdflagsp); 495 } 496 497 // Attempt to set a file-descriptor guard on |fd|. In case of success, remove 498 // it and return |true| to indicate that it can be guarded. Returning |false| 499 // means either that |fd| is guarded by some other code, or more likely EBADF. 500 // 501 // Starting with 10.9, libdispatch began setting GUARD_DUP on a file descriptor. 502 // Unfortunately, it is spun up as part of +[NSApplication initialize], which is 503 // not really something that Chromium can avoid using on OSX. See 504 // <http://crbug.com/338157>. This function allows querying whether the file 505 // descriptor is guarded before attempting to close it. 506 bool CanGuardFd(int fd) { 507 // The syscall is first provided in 10.9/Mavericks. 508 if (!base::mac::IsOSMavericksOrLater()) 509 return true; 510 511 // Saves the original flags to reset later. 512 int original_fdflags = 0; 513 514 // This can be any value at all, it just has to match up between the two 515 // calls. 516 const guardid_t kGuard = 15; 517 518 // Attempt to change the guard. This can fail with EBADF if the file 519 // descriptor is bad, or EINVAL if the fd already has a guard set. 520 int ret = 521 change_fdguard_np(fd, NULL, 0, &kGuard, GUARD_DUP, &original_fdflags); 522 if (ret == -1) 523 return false; 524 525 // Remove the guard. It should not be possible to fail in removing the guard 526 // just added. 527 ret = change_fdguard_np(fd, &kGuard, GUARD_DUP, NULL, 0, &original_fdflags); 528 DPCHECK(ret == 0); 529 530 return true; 531 } 532 #endif // OS_MACOSX 533 534 } // namespace 535 536 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) { 537 // This child process counts the number of open FDs, it then writes that 538 // number out to a pipe connected to the parent. 539 int num_open_files = 0; 540 int write_pipe = kChildPipe; 541 int max_files = GetMaxFilesOpenInProcess(); 542 for (int i = STDERR_FILENO + 1; i < max_files; i++) { 543 #if defined(OS_MACOSX) 544 // Ignore guarded or invalid file descriptors. 545 if (!CanGuardFd(i)) 546 continue; 547 #endif 548 549 if (i != kChildPipe) { 550 int fd; 551 if ((fd = HANDLE_EINTR(dup(i))) != -1) { 552 close(fd); 553 num_open_files += 1; 554 } 555 } 556 } 557 558 int written = HANDLE_EINTR(write(write_pipe, &num_open_files, 559 sizeof(num_open_files))); 560 DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files)); 561 int ret = IGNORE_EINTR(close(write_pipe)); 562 DPCHECK(ret == 0); 563 564 return 0; 565 } 566 567 int ProcessUtilTest::CountOpenFDsInChild() { 568 int fds[2]; 569 if (pipe(fds) < 0) 570 NOTREACHED(); 571 572 base::FileHandleMappingVector fd_mapping_vec; 573 fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe)); 574 base::LaunchOptions options; 575 options.fds_to_remap = &fd_mapping_vec; 576 base::ProcessHandle handle = 577 SpawnChildWithOptions("ProcessUtilsLeakFDChildProcess", options); 578 CHECK(handle); 579 int ret = IGNORE_EINTR(close(fds[1])); 580 DPCHECK(ret == 0); 581 582 // Read number of open files in client process from pipe; 583 int num_open_files = -1; 584 ssize_t bytes_read = 585 HANDLE_EINTR(read(fds[0], &num_open_files, sizeof(num_open_files))); 586 CHECK_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files))); 587 588 #if defined(THREAD_SANITIZER) 589 // Compiler-based ThreadSanitizer makes this test slow. 590 CHECK(base::WaitForSingleProcess(handle, base::TimeDelta::FromSeconds(3))); 591 #else 592 CHECK(base::WaitForSingleProcess(handle, base::TimeDelta::FromSeconds(1))); 593 #endif 594 base::CloseProcessHandle(handle); 595 ret = IGNORE_EINTR(close(fds[0])); 596 DPCHECK(ret == 0); 597 598 return num_open_files; 599 } 600 601 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) 602 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise. 603 // The problem is 100% reproducible with both ASan and TSan. 604 // See http://crbug.com/136720. 605 #define MAYBE_FDRemapping DISABLED_FDRemapping 606 #else 607 #define MAYBE_FDRemapping FDRemapping 608 #endif 609 TEST_F(ProcessUtilTest, MAYBE_FDRemapping) { 610 int fds_before = CountOpenFDsInChild(); 611 612 // open some dummy fds to make sure they don't propagate over to the 613 // child process. 614 int dev_null = open("/dev/null", O_RDONLY); 615 int sockets[2]; 616 socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); 617 618 int fds_after = CountOpenFDsInChild(); 619 620 ASSERT_EQ(fds_after, fds_before); 621 622 int ret; 623 ret = IGNORE_EINTR(close(sockets[0])); 624 DPCHECK(ret == 0); 625 ret = IGNORE_EINTR(close(sockets[1])); 626 DPCHECK(ret == 0); 627 ret = IGNORE_EINTR(close(dev_null)); 628 DPCHECK(ret == 0); 629 } 630 631 namespace { 632 633 std::string TestLaunchProcess(const std::vector<std::string>& args, 634 const base::EnvironmentMap& env_changes, 635 const bool clear_environ, 636 const int clone_flags) { 637 base::FileHandleMappingVector fds_to_remap; 638 639 int fds[2]; 640 PCHECK(pipe(fds) == 0); 641 642 fds_to_remap.push_back(std::make_pair(fds[1], 1)); 643 base::LaunchOptions options; 644 options.wait = true; 645 options.environ = env_changes; 646 options.clear_environ = clear_environ; 647 options.fds_to_remap = &fds_to_remap; 648 #if defined(OS_LINUX) 649 options.clone_flags = clone_flags; 650 #else 651 CHECK_EQ(0, clone_flags); 652 #endif // OS_LINUX 653 EXPECT_TRUE(base::LaunchProcess(args, options, NULL)); 654 PCHECK(IGNORE_EINTR(close(fds[1])) == 0); 655 656 char buf[512]; 657 const ssize_t n = HANDLE_EINTR(read(fds[0], buf, sizeof(buf))); 658 659 PCHECK(IGNORE_EINTR(close(fds[0])) == 0); 660 661 return std::string(buf, n); 662 } 663 664 const char kLargeString[] = 665 "0123456789012345678901234567890123456789012345678901234567890123456789" 666 "0123456789012345678901234567890123456789012345678901234567890123456789" 667 "0123456789012345678901234567890123456789012345678901234567890123456789" 668 "0123456789012345678901234567890123456789012345678901234567890123456789" 669 "0123456789012345678901234567890123456789012345678901234567890123456789" 670 "0123456789012345678901234567890123456789012345678901234567890123456789" 671 "0123456789012345678901234567890123456789012345678901234567890123456789"; 672 673 } // namespace 674 675 TEST_F(ProcessUtilTest, LaunchProcess) { 676 base::EnvironmentMap env_changes; 677 std::vector<std::string> echo_base_test; 678 echo_base_test.push_back(kPosixShell); 679 echo_base_test.push_back("-c"); 680 echo_base_test.push_back("echo $BASE_TEST"); 681 682 std::vector<std::string> print_env; 683 print_env.push_back("/usr/bin/env"); 684 const int no_clone_flags = 0; 685 const bool no_clear_environ = false; 686 687 const char kBaseTest[] = "BASE_TEST"; 688 689 env_changes[kBaseTest] = "bar"; 690 EXPECT_EQ("bar\n", 691 TestLaunchProcess( 692 echo_base_test, env_changes, no_clear_environ, no_clone_flags)); 693 env_changes.clear(); 694 695 EXPECT_EQ(0, setenv(kBaseTest, "testing", 1 /* override */)); 696 EXPECT_EQ("testing\n", 697 TestLaunchProcess( 698 echo_base_test, env_changes, no_clear_environ, no_clone_flags)); 699 700 env_changes[kBaseTest] = std::string(); 701 EXPECT_EQ("\n", 702 TestLaunchProcess( 703 echo_base_test, env_changes, no_clear_environ, no_clone_flags)); 704 705 env_changes[kBaseTest] = "foo"; 706 EXPECT_EQ("foo\n", 707 TestLaunchProcess( 708 echo_base_test, env_changes, no_clear_environ, no_clone_flags)); 709 710 env_changes.clear(); 711 EXPECT_EQ(0, setenv(kBaseTest, kLargeString, 1 /* override */)); 712 EXPECT_EQ(std::string(kLargeString) + "\n", 713 TestLaunchProcess( 714 echo_base_test, env_changes, no_clear_environ, no_clone_flags)); 715 716 env_changes[kBaseTest] = "wibble"; 717 EXPECT_EQ("wibble\n", 718 TestLaunchProcess( 719 echo_base_test, env_changes, no_clear_environ, no_clone_flags)); 720 721 #if defined(OS_LINUX) 722 // Test a non-trival value for clone_flags. 723 // Don't test on Valgrind as it has limited support for clone(). 724 if (!RunningOnValgrind()) { 725 EXPECT_EQ( 726 "wibble\n", 727 TestLaunchProcess( 728 echo_base_test, env_changes, no_clear_environ, CLONE_FS | SIGCHLD)); 729 } 730 731 EXPECT_EQ( 732 "BASE_TEST=wibble\n", 733 TestLaunchProcess( 734 print_env, env_changes, true /* clear_environ */, no_clone_flags)); 735 env_changes.clear(); 736 EXPECT_EQ( 737 "", 738 TestLaunchProcess( 739 print_env, env_changes, true /* clear_environ */, no_clone_flags)); 740 #endif 741 } 742 743 TEST_F(ProcessUtilTest, GetAppOutput) { 744 std::string output; 745 746 #if defined(OS_ANDROID) 747 std::vector<std::string> argv; 748 argv.push_back("sh"); // Instead of /bin/sh, force path search to find it. 749 argv.push_back("-c"); 750 751 argv.push_back("exit 0"); 752 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output)); 753 EXPECT_STREQ("", output.c_str()); 754 755 argv[2] = "exit 1"; 756 EXPECT_FALSE(base::GetAppOutput(CommandLine(argv), &output)); 757 EXPECT_STREQ("", output.c_str()); 758 759 argv[2] = "echo foobar42"; 760 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output)); 761 EXPECT_STREQ("foobar42\n", output.c_str()); 762 #else 763 EXPECT_TRUE(base::GetAppOutput(CommandLine(FilePath("true")), &output)); 764 EXPECT_STREQ("", output.c_str()); 765 766 EXPECT_FALSE(base::GetAppOutput(CommandLine(FilePath("false")), &output)); 767 768 std::vector<std::string> argv; 769 argv.push_back("/bin/echo"); 770 argv.push_back("-n"); 771 argv.push_back("foobar42"); 772 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output)); 773 EXPECT_STREQ("foobar42", output.c_str()); 774 #endif // defined(OS_ANDROID) 775 } 776 777 // Flakes on Android, crbug.com/375840 778 #if defined(OS_ANDROID) 779 #define MAYBE_GetAppOutputRestricted DISABLED_GetAppOutputRestricted 780 #else 781 #define MAYBE_GetAppOutputRestricted GetAppOutputRestricted 782 #endif 783 TEST_F(ProcessUtilTest, MAYBE_GetAppOutputRestricted) { 784 // Unfortunately, since we can't rely on the path, we need to know where 785 // everything is. So let's use /bin/sh, which is on every POSIX system, and 786 // its built-ins. 787 std::vector<std::string> argv; 788 argv.push_back(std::string(kShellPath)); // argv[0] 789 argv.push_back("-c"); // argv[1] 790 791 // On success, should set |output|. We use |/bin/sh -c 'exit 0'| instead of 792 // |true| since the location of the latter may be |/bin| or |/usr/bin| (and we 793 // need absolute paths). 794 argv.push_back("exit 0"); // argv[2]; equivalent to "true" 795 std::string output = "abc"; 796 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100)); 797 EXPECT_STREQ("", output.c_str()); 798 799 argv[2] = "exit 1"; // equivalent to "false" 800 output = "before"; 801 EXPECT_FALSE(base::GetAppOutputRestricted(CommandLine(argv), 802 &output, 100)); 803 EXPECT_STREQ("", output.c_str()); 804 805 // Amount of output exactly equal to space allowed. 806 argv[2] = "echo 123456789"; // (the sh built-in doesn't take "-n") 807 output.clear(); 808 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10)); 809 EXPECT_STREQ("123456789\n", output.c_str()); 810 811 // Amount of output greater than space allowed. 812 output.clear(); 813 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 5)); 814 EXPECT_STREQ("12345", output.c_str()); 815 816 // Amount of output less than space allowed. 817 output.clear(); 818 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 15)); 819 EXPECT_STREQ("123456789\n", output.c_str()); 820 821 // Zero space allowed. 822 output = "abc"; 823 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 0)); 824 EXPECT_STREQ("", output.c_str()); 825 } 826 827 #if !defined(OS_MACOSX) && !defined(OS_OPENBSD) 828 // TODO(benwells): GetAppOutputRestricted should terminate applications 829 // with SIGPIPE when we have enough output. http://crbug.com/88502 830 TEST_F(ProcessUtilTest, GetAppOutputRestrictedSIGPIPE) { 831 std::vector<std::string> argv; 832 std::string output; 833 834 argv.push_back(std::string(kShellPath)); // argv[0] 835 argv.push_back("-c"); 836 #if defined(OS_ANDROID) 837 argv.push_back("while echo 12345678901234567890; do :; done"); 838 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10)); 839 EXPECT_STREQ("1234567890", output.c_str()); 840 #else 841 argv.push_back("yes"); 842 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10)); 843 EXPECT_STREQ("y\ny\ny\ny\ny\n", output.c_str()); 844 #endif 845 } 846 #endif 847 848 #if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX) && \ 849 defined(ARCH_CPU_64_BITS) 850 // Times out under AddressSanitizer on 64-bit OS X, see 851 // http://crbug.com/298197. 852 #define MAYBE_GetAppOutputRestrictedNoZombies \ 853 DISABLED_GetAppOutputRestrictedNoZombies 854 #else 855 #define MAYBE_GetAppOutputRestrictedNoZombies GetAppOutputRestrictedNoZombies 856 #endif 857 TEST_F(ProcessUtilTest, MAYBE_GetAppOutputRestrictedNoZombies) { 858 std::vector<std::string> argv; 859 860 argv.push_back(std::string(kShellPath)); // argv[0] 861 argv.push_back("-c"); // argv[1] 862 argv.push_back("echo 123456789012345678901234567890"); // argv[2] 863 864 // Run |GetAppOutputRestricted()| 300 (> default per-user processes on Mac OS 865 // 10.5) times with an output buffer big enough to capture all output. 866 for (int i = 0; i < 300; i++) { 867 std::string output; 868 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100)); 869 EXPECT_STREQ("123456789012345678901234567890\n", output.c_str()); 870 } 871 872 // Ditto, but with an output buffer too small to capture all output. 873 for (int i = 0; i < 300; i++) { 874 std::string output; 875 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10)); 876 EXPECT_STREQ("1234567890", output.c_str()); 877 } 878 } 879 880 TEST_F(ProcessUtilTest, GetAppOutputWithExitCode) { 881 // Test getting output from a successful application. 882 std::vector<std::string> argv; 883 std::string output; 884 int exit_code; 885 argv.push_back(std::string(kShellPath)); // argv[0] 886 argv.push_back("-c"); // argv[1] 887 argv.push_back("echo foo"); // argv[2]; 888 EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv), &output, 889 &exit_code)); 890 EXPECT_STREQ("foo\n", output.c_str()); 891 EXPECT_EQ(exit_code, 0); 892 893 // Test getting output from an application which fails with a specific exit 894 // code. 895 output.clear(); 896 argv[2] = "echo foo; exit 2"; 897 EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv), &output, 898 &exit_code)); 899 EXPECT_STREQ("foo\n", output.c_str()); 900 EXPECT_EQ(exit_code, 2); 901 } 902 903 TEST_F(ProcessUtilTest, GetParentProcessId) { 904 base::ProcessId ppid = base::GetParentProcessId(base::GetCurrentProcId()); 905 EXPECT_EQ(ppid, getppid()); 906 } 907 908 // TODO(port): port those unit tests. 909 bool IsProcessDead(base::ProcessHandle child) { 910 // waitpid() will actually reap the process which is exactly NOT what we 911 // want to test for. The good thing is that if it can't find the process 912 // we'll get a nice value for errno which we can test for. 913 const pid_t result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG)); 914 return result == -1 && errno == ECHILD; 915 } 916 917 TEST_F(ProcessUtilTest, DelayedTermination) { 918 base::ProcessHandle child_process = SpawnChild("process_util_test_never_die"); 919 ASSERT_TRUE(child_process); 920 base::EnsureProcessTerminated(child_process); 921 base::WaitForSingleProcess(child_process, base::TimeDelta::FromSeconds(5)); 922 923 // Check that process was really killed. 924 EXPECT_TRUE(IsProcessDead(child_process)); 925 base::CloseProcessHandle(child_process); 926 } 927 928 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) { 929 while (1) { 930 sleep(500); 931 } 932 return 0; 933 } 934 935 TEST_F(ProcessUtilTest, ImmediateTermination) { 936 base::ProcessHandle child_process = 937 SpawnChild("process_util_test_die_immediately"); 938 ASSERT_TRUE(child_process); 939 // Give it time to die. 940 sleep(2); 941 base::EnsureProcessTerminated(child_process); 942 943 // Check that process was really killed. 944 EXPECT_TRUE(IsProcessDead(child_process)); 945 base::CloseProcessHandle(child_process); 946 } 947 948 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) { 949 return 0; 950 } 951 952 #endif // defined(OS_POSIX) 953