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 56using base::FilePath; 57 58namespace { 59 60#if defined(OS_ANDROID) 61const char kShellPath[] = "/system/bin/sh"; 62const char kPosixShell[] = "sh"; 63#else 64const char kShellPath[] = "/bin/sh"; 65const char kPosixShell[] = "bash"; 66#endif 67 68const char kSignalFileSlow[] = "SlowChildProcess.die"; 69const char kSignalFileKill[] = "KilledChildProcess.die"; 70 71#if defined(OS_WIN) 72const int kExpectedStillRunningExitCode = 0x102; 73const int kExpectedKilledExitCode = 1; 74#else 75const int kExpectedStillRunningExitCode = 0; 76#endif 77 78// Sleeps until file filename is created. 79void 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. 89void 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. 99base::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 117class 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 128std::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 139MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { 140 return 0; 141} 142 143// TODO(viettrungluu): This should be in a "MultiProcessTestTest". 144TEST_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 152MULTIPROCESS_TEST_MAIN(SlowChildProcess) { 153 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str()); 154 return 0; 155} 156 157TEST_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 171TEST_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. 195TEST_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. 216const char kSignalFileCrash[] = "CrashingChildProcess.die"; 217 218MULTIPROCESS_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 238TEST_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 272MULTIPROCESS_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 285TEST_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. 318TEST_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. 337TEST_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. 355TEST_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. 385TEST_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 394static const char kEventToTriggerHandleSwitch[] = "event-to-trigger-handle"; 395 396MULTIPROCESS_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 412TEST_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 446namespace { 447 448// Returns the maximum number of files that a process can have open. 449// Returns 0 on error. 450int 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 466const 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 473typedef __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|. 489int 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. 506bool 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 536MULTIPROCESS_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 567int 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 609TEST_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 631namespace { 632 633std::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 664const char kLargeString[] = 665 "0123456789012345678901234567890123456789012345678901234567890123456789" 666 "0123456789012345678901234567890123456789012345678901234567890123456789" 667 "0123456789012345678901234567890123456789012345678901234567890123456789" 668 "0123456789012345678901234567890123456789012345678901234567890123456789" 669 "0123456789012345678901234567890123456789012345678901234567890123456789" 670 "0123456789012345678901234567890123456789012345678901234567890123456789" 671 "0123456789012345678901234567890123456789012345678901234567890123456789"; 672 673} // namespace 674 675TEST_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 743TEST_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 783TEST_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 830TEST_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 857TEST_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 880TEST_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 903TEST_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. 909bool 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 917TEST_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 928MULTIPROCESS_TEST_MAIN(process_util_test_never_die) { 929 while (1) { 930 sleep(500); 931 } 932 return 0; 933} 934 935TEST_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 948MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) { 949 return 0; 950} 951 952#endif // defined(OS_POSIX) 953