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.
5 #define _CRT_SECURE_NO_WARNINGS
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/files/file_util.h"
14 #include "base/files/scoped_file.h"
15 #include "base/logging.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/path_service.h"
18 #include "base/posix/eintr_wrapper.h"
19 #include "base/process/kill.h"
20 #include "base/process/launch.h"
21 #include "base/process/memory.h"
22 #include "base/process/process.h"
23 #include "base/process/process_metrics.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/utf_string_conversions.h"
26 #include "base/synchronization/waitable_event.h"
27 #include "base/test/multiprocess_test.h"
28 #include "base/test/test_timeouts.h"
29 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
30 #include "base/threading/platform_thread.h"
31 #include "base/threading/thread.h"
32 #include "build/build_config.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34 #include "testing/multiprocess_func_list.h"
39 #include <sys/syscall.h>
47 #include <sys/resource.h>
48 #include <sys/socket.h>
49 #include <sys/types.h>
55 #include "base/win/windows_version.h"
57 #if defined(OS_MACOSX)
58 #include <mach/vm_param.h>
59 #include <malloc/malloc.h>
60 #include "base/mac/mac_util.h"
67 const char kSignalFileSlow
[] = "SlowChildProcess.die";
68 const char kSignalFileKill
[] = "KilledChildProcess.die";
71 const char kSignalFileTerm
[] = "TerminatedChildProcess.die";
73 #if defined(OS_ANDROID)
74 const char kShellPath
[] = "/system/bin/sh";
75 const char kPosixShell
[] = "sh";
77 const char kShellPath
[] = "/bin/sh";
78 const char kPosixShell
[] = "sh";
80 #endif // defined(OS_POSIX)
83 const int kExpectedStillRunningExitCode
= 0x102;
84 const int kExpectedKilledExitCode
= 1;
86 const int kExpectedStillRunningExitCode
= 0;
89 // Sleeps until file filename is created.
90 void WaitToDie(const char* filename
) {
93 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
94 fp
= fopen(filename
, "r");
99 // Signals children they should die now.
100 void SignalChildren(const char* filename
) {
101 FILE* fp
= fopen(filename
, "w");
105 // Using a pipe to the child to wait for an event was considered, but
106 // there were cases in the past where pipes caused problems (other
107 // libraries closing the fds, child deadlocking). This is a simple
108 // case, so it's not worth the risk. Using wait loops is discouraged
109 // in most instances.
110 base::TerminationStatus
WaitForChildTermination(base::ProcessHandle handle
,
112 // Now we wait until the result is something other than STILL_RUNNING.
113 base::TerminationStatus status
= base::TERMINATION_STATUS_STILL_RUNNING
;
114 const base::TimeDelta kInterval
= base::TimeDelta::FromMilliseconds(20);
115 base::TimeDelta waited
;
117 status
= base::GetTerminationStatus(handle
, exit_code
);
118 base::PlatformThread::Sleep(kInterval
);
120 } while (status
== base::TERMINATION_STATUS_STILL_RUNNING
&&
121 waited
< TestTimeouts::action_max_timeout());
128 class ProcessUtilTest
: public base::MultiProcessTest
{
130 #if defined(OS_POSIX)
131 // Spawn a child process that counts how many file descriptors are open.
132 int CountOpenFDsInChild();
134 // Converts the filename to a platform specific filepath.
135 // On Android files can not be created in arbitrary directories.
136 static std::string
GetSignalFilePath(const char* filename
);
139 std::string
ProcessUtilTest::GetSignalFilePath(const char* filename
) {
140 #if !defined(OS_ANDROID)
144 PathService::Get(base::DIR_CACHE
, &tmp_dir
);
145 tmp_dir
= tmp_dir
.Append(filename
);
146 return tmp_dir
.value();
150 MULTIPROCESS_TEST_MAIN(SimpleChildProcess
) {
154 // TODO(viettrungluu): This should be in a "MultiProcessTestTest".
155 TEST_F(ProcessUtilTest
, SpawnChild
) {
156 base::Process process
= SpawnChild("SimpleChildProcess");
157 ASSERT_TRUE(process
.IsValid());
159 EXPECT_TRUE(process
.WaitForExitWithTimeout(
160 TestTimeouts::action_max_timeout(), &exit_code
));
163 MULTIPROCESS_TEST_MAIN(SlowChildProcess
) {
164 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow
).c_str());
168 TEST_F(ProcessUtilTest
, KillSlowChild
) {
169 const std::string signal_file
=
170 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow
);
171 remove(signal_file
.c_str());
172 base::Process process
= SpawnChild("SlowChildProcess");
173 ASSERT_TRUE(process
.IsValid());
174 SignalChildren(signal_file
.c_str());
176 EXPECT_TRUE(process
.WaitForExitWithTimeout(
177 TestTimeouts::action_max_timeout(), &exit_code
));
178 remove(signal_file
.c_str());
181 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058
182 TEST_F(ProcessUtilTest
, DISABLED_GetTerminationStatusExit
) {
183 const std::string signal_file
=
184 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow
);
185 remove(signal_file
.c_str());
186 base::Process process
= SpawnChild("SlowChildProcess");
187 ASSERT_TRUE(process
.IsValid());
190 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING
,
191 base::GetTerminationStatus(process
.Handle(), &exit_code
));
192 EXPECT_EQ(kExpectedStillRunningExitCode
, exit_code
);
194 SignalChildren(signal_file
.c_str());
196 base::TerminationStatus status
=
197 WaitForChildTermination(process
.Handle(), &exit_code
);
198 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION
, status
);
199 EXPECT_EQ(0, exit_code
);
200 remove(signal_file
.c_str());
204 // TODO(cpu): figure out how to test this in other platforms.
205 TEST_F(ProcessUtilTest
, GetProcId
) {
206 base::ProcessId id1
= base::GetProcId(GetCurrentProcess());
208 base::Process process
= SpawnChild("SimpleChildProcess");
209 ASSERT_TRUE(process
.IsValid());
210 base::ProcessId id2
= process
.Pid();
216 #if !defined(OS_MACOSX)
217 // This test is disabled on Mac, since it's flaky due to ReportCrash
218 // taking a variable amount of time to parse and load the debug and
219 // symbol data for this unit test's executable before firing the
222 // TODO(gspencer): turn this test process into a very small program
223 // with no symbols (instead of using the multiprocess testing
224 // framework) to reduce the ReportCrash overhead.
225 const char kSignalFileCrash
[] = "CrashingChildProcess.die";
227 MULTIPROCESS_TEST_MAIN(CrashingChildProcess
) {
228 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileCrash
).c_str());
229 #if defined(OS_POSIX)
230 // Have to disable to signal handler for segv so we can get a crash
231 // instead of an abnormal termination through the crash dump handler.
232 ::signal(SIGSEGV
, SIG_DFL
);
234 // Make this process have a segmentation fault.
235 volatile int* oops
= NULL
;
240 // This test intentionally crashes, so we don't need to run it under
242 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
243 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash
245 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash
247 TEST_F(ProcessUtilTest
, MAYBE_GetTerminationStatusCrash
) {
248 const std::string signal_file
=
249 ProcessUtilTest::GetSignalFilePath(kSignalFileCrash
);
250 remove(signal_file
.c_str());
251 base::Process process
= SpawnChild("CrashingChildProcess");
252 ASSERT_TRUE(process
.IsValid());
255 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING
,
256 base::GetTerminationStatus(process
.Handle(), &exit_code
));
257 EXPECT_EQ(kExpectedStillRunningExitCode
, exit_code
);
259 SignalChildren(signal_file
.c_str());
261 base::TerminationStatus status
=
262 WaitForChildTermination(process
.Handle(), &exit_code
);
263 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED
, status
);
266 EXPECT_EQ(0xc0000005, exit_code
);
267 #elif defined(OS_POSIX)
268 int signaled
= WIFSIGNALED(exit_code
);
269 EXPECT_NE(0, signaled
);
270 int signal
= WTERMSIG(exit_code
);
271 EXPECT_EQ(SIGSEGV
, signal
);
274 // Reset signal handlers back to "normal".
275 base::debug::EnableInProcessStackDumping();
276 remove(signal_file
.c_str());
278 #endif // !defined(OS_MACOSX)
280 MULTIPROCESS_TEST_MAIN(KilledChildProcess
) {
281 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileKill
).c_str());
284 HANDLE handle
= ::OpenProcess(PROCESS_ALL_ACCESS
, 0, ::GetCurrentProcessId());
285 ::TerminateProcess(handle
, kExpectedKilledExitCode
);
286 #elif defined(OS_POSIX)
287 // Send a SIGKILL to this process, just like the OOM killer would.
288 ::kill(getpid(), SIGKILL
);
293 #if defined(OS_POSIX)
294 MULTIPROCESS_TEST_MAIN(TerminatedChildProcess
) {
295 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileTerm
).c_str());
296 // Send a SIGTERM to this process.
297 ::kill(getpid(), SIGTERM
);
302 TEST_F(ProcessUtilTest
, GetTerminationStatusSigKill
) {
303 const std::string signal_file
=
304 ProcessUtilTest::GetSignalFilePath(kSignalFileKill
);
305 remove(signal_file
.c_str());
306 base::Process process
= SpawnChild("KilledChildProcess");
307 ASSERT_TRUE(process
.IsValid());
310 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING
,
311 base::GetTerminationStatus(process
.Handle(), &exit_code
));
312 EXPECT_EQ(kExpectedStillRunningExitCode
, exit_code
);
314 SignalChildren(signal_file
.c_str());
316 base::TerminationStatus status
=
317 WaitForChildTermination(process
.Handle(), &exit_code
);
318 #if defined(OS_CHROMEOS)
319 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM
, status
);
321 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED
, status
);
325 EXPECT_EQ(kExpectedKilledExitCode
, exit_code
);
326 #elif defined(OS_POSIX)
327 int signaled
= WIFSIGNALED(exit_code
);
328 EXPECT_NE(0, signaled
);
329 int signal
= WTERMSIG(exit_code
);
330 EXPECT_EQ(SIGKILL
, signal
);
332 remove(signal_file
.c_str());
335 #if defined(OS_POSIX)
336 TEST_F(ProcessUtilTest
, GetTerminationStatusSigTerm
) {
337 const std::string signal_file
=
338 ProcessUtilTest::GetSignalFilePath(kSignalFileTerm
);
339 remove(signal_file
.c_str());
340 base::Process process
= SpawnChild("TerminatedChildProcess");
341 ASSERT_TRUE(process
.IsValid());
344 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING
,
345 base::GetTerminationStatus(process
.Handle(), &exit_code
));
346 EXPECT_EQ(kExpectedStillRunningExitCode
, exit_code
);
348 SignalChildren(signal_file
.c_str());
350 base::TerminationStatus status
=
351 WaitForChildTermination(process
.Handle(), &exit_code
);
352 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED
, status
);
354 int signaled
= WIFSIGNALED(exit_code
);
355 EXPECT_NE(0, signaled
);
356 int signal
= WTERMSIG(exit_code
);
357 EXPECT_EQ(SIGTERM
, signal
);
358 remove(signal_file
.c_str());
363 // TODO(estade): if possible, port this test.
364 TEST_F(ProcessUtilTest
, GetAppOutput
) {
365 // Let's create a decently long message.
367 for (int i
= 0; i
< 1025; i
++) { // 1025 so it does not end on a kilo-byte
371 // cmd.exe's echo always adds a \r\n to its output.
372 std::string
expected(message
);
375 FilePath
cmd(L
"cmd.exe");
376 base::CommandLine
cmd_line(cmd
);
377 cmd_line
.AppendArg("/c");
378 cmd_line
.AppendArg("echo " + message
+ "");
380 ASSERT_TRUE(base::GetAppOutput(cmd_line
, &output
));
381 EXPECT_EQ(expected
, output
);
383 // Let's make sure stderr is ignored.
384 base::CommandLine
other_cmd_line(cmd
);
385 other_cmd_line
.AppendArg("/c");
386 // http://msdn.microsoft.com/library/cc772622.aspx
387 cmd_line
.AppendArg("echo " + message
+ " >&2");
389 ASSERT_TRUE(base::GetAppOutput(other_cmd_line
, &output
));
390 EXPECT_EQ("", output
);
393 // TODO(estade): if possible, port this test.
394 TEST_F(ProcessUtilTest
, LaunchAsUser
) {
395 base::UserTokenHandle token
;
396 ASSERT_TRUE(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS
, &token
));
397 base::LaunchOptions options
;
398 options
.as_user
= token
;
399 EXPECT_TRUE(base::LaunchProcess(MakeCmdLine("SimpleChildProcess"),
403 static const char kEventToTriggerHandleSwitch
[] = "event-to-trigger-handle";
405 MULTIPROCESS_TEST_MAIN(TriggerEventChildProcess
) {
406 std::string handle_value_string
=
407 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
408 kEventToTriggerHandleSwitch
);
409 CHECK(!handle_value_string
.empty());
411 uint64 handle_value_uint64
;
412 CHECK(base::StringToUint64(handle_value_string
, &handle_value_uint64
));
413 // Give ownership of the handle to |event|.
414 base::WaitableEvent
event(base::win::ScopedHandle(
415 reinterpret_cast<HANDLE
>(handle_value_uint64
)));
422 TEST_F(ProcessUtilTest
, InheritSpecifiedHandles
) {
423 // Manually create the event, so that it can be inheritable.
424 SECURITY_ATTRIBUTES security_attributes
= {};
425 security_attributes
.nLength
= static_cast<DWORD
>(sizeof(security_attributes
));
426 security_attributes
.lpSecurityDescriptor
= NULL
;
427 security_attributes
.bInheritHandle
= true;
429 // Takes ownership of the event handle.
430 base::WaitableEvent
event(base::win::ScopedHandle(
431 CreateEvent(&security_attributes
, true, false, NULL
)));
432 base::HandlesToInheritVector handles_to_inherit
;
433 handles_to_inherit
.push_back(event
.handle());
434 base::LaunchOptions options
;
435 options
.handles_to_inherit
= &handles_to_inherit
;
437 base::CommandLine cmd_line
= MakeCmdLine("TriggerEventChildProcess");
438 cmd_line
.AppendSwitchASCII(kEventToTriggerHandleSwitch
,
439 base::Uint64ToString(reinterpret_cast<uint64
>(event
.handle())));
441 // This functionality actually requires Vista or later. Make sure that it
442 // fails properly on XP.
443 if (base::win::GetVersion() < base::win::VERSION_VISTA
) {
444 EXPECT_FALSE(base::LaunchProcess(cmd_line
, options
).IsValid());
448 // Launch the process and wait for it to trigger the event.
449 ASSERT_TRUE(base::LaunchProcess(cmd_line
, options
).IsValid());
450 EXPECT_TRUE(event
.TimedWait(TestTimeouts::action_max_timeout()));
452 #endif // defined(OS_WIN)
454 #if defined(OS_POSIX)
458 // Returns the maximum number of files that a process can have open.
459 // Returns 0 on error.
460 int GetMaxFilesOpenInProcess() {
462 if (getrlimit(RLIMIT_NOFILE
, &rlim
) != 0) {
466 // rlim_t is a uint64 - clip to maxint. We do this since FD #s are ints
467 // which are all 32 bits on the supported platforms.
468 rlim_t max_int
= static_cast<rlim_t
>(std::numeric_limits
<int32
>::max());
469 if (rlim
.rlim_cur
> max_int
) {
473 return rlim
.rlim_cur
;
476 const int kChildPipe
= 20; // FD # for write end of pipe in child process.
478 #if defined(OS_MACOSX)
480 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h>
481 #if !defined(_GUARDID_T)
483 typedef __uint64_t guardid_t
;
486 // From .../MacOSX10.9.sdk/usr/include/sys/syscall.h
487 #if !defined(SYS_change_fdguard_np)
488 #define SYS_change_fdguard_np 444
491 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/sys/guarded.h>
492 #if !defined(GUARD_DUP)
493 #define GUARD_DUP (1u << 1)
496 // <http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_guarded.c?txt>
498 // Atomically replaces |guard|/|guardflags| with |nguard|/|nguardflags| on |fd|.
499 int change_fdguard_np(int fd
,
500 const guardid_t
*guard
, u_int guardflags
,
501 const guardid_t
*nguard
, u_int nguardflags
,
503 return syscall(SYS_change_fdguard_np
, fd
, guard
, guardflags
,
504 nguard
, nguardflags
, fdflagsp
);
507 // Attempt to set a file-descriptor guard on |fd|. In case of success, remove
508 // it and return |true| to indicate that it can be guarded. Returning |false|
509 // means either that |fd| is guarded by some other code, or more likely EBADF.
511 // Starting with 10.9, libdispatch began setting GUARD_DUP on a file descriptor.
512 // Unfortunately, it is spun up as part of +[NSApplication initialize], which is
513 // not really something that Chromium can avoid using on OSX. See
514 // <http://crbug.com/338157>. This function allows querying whether the file
515 // descriptor is guarded before attempting to close it.
516 bool CanGuardFd(int fd
) {
517 // The syscall is first provided in 10.9/Mavericks.
518 if (!base::mac::IsOSMavericksOrLater())
521 // Saves the original flags to reset later.
522 int original_fdflags
= 0;
524 // This can be any value at all, it just has to match up between the two
526 const guardid_t kGuard
= 15;
528 // Attempt to change the guard. This can fail with EBADF if the file
529 // descriptor is bad, or EINVAL if the fd already has a guard set.
531 change_fdguard_np(fd
, NULL
, 0, &kGuard
, GUARD_DUP
, &original_fdflags
);
535 // Remove the guard. It should not be possible to fail in removing the guard
537 ret
= change_fdguard_np(fd
, &kGuard
, GUARD_DUP
, NULL
, 0, &original_fdflags
);
546 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess
) {
547 // This child process counts the number of open FDs, it then writes that
548 // number out to a pipe connected to the parent.
549 int num_open_files
= 0;
550 int write_pipe
= kChildPipe
;
551 int max_files
= GetMaxFilesOpenInProcess();
552 for (int i
= STDERR_FILENO
+ 1; i
< max_files
; i
++) {
553 #if defined(OS_MACOSX)
554 // Ignore guarded or invalid file descriptors.
559 if (i
!= kChildPipe
) {
561 if ((fd
= HANDLE_EINTR(dup(i
))) != -1) {
568 int written
= HANDLE_EINTR(write(write_pipe
, &num_open_files
,
569 sizeof(num_open_files
)));
570 DCHECK_EQ(static_cast<size_t>(written
), sizeof(num_open_files
));
571 int ret
= IGNORE_EINTR(close(write_pipe
));
577 int ProcessUtilTest::CountOpenFDsInChild() {
582 base::FileHandleMappingVector fd_mapping_vec
;
583 fd_mapping_vec
.push_back(std::pair
<int, int>(fds
[1], kChildPipe
));
584 base::LaunchOptions options
;
585 options
.fds_to_remap
= &fd_mapping_vec
;
586 base::Process process
=
587 SpawnChildWithOptions("ProcessUtilsLeakFDChildProcess", options
);
588 CHECK(process
.IsValid());
589 int ret
= IGNORE_EINTR(close(fds
[1]));
592 // Read number of open files in client process from pipe;
593 int num_open_files
= -1;
595 HANDLE_EINTR(read(fds
[0], &num_open_files
, sizeof(num_open_files
)));
596 CHECK_EQ(bytes_read
, static_cast<ssize_t
>(sizeof(num_open_files
)));
598 #if defined(THREAD_SANITIZER)
599 // Compiler-based ThreadSanitizer makes this test slow.
600 base::TimeDelta timeout
= base::TimeDelta::FromSeconds(3);
602 base::TimeDelta timeout
= base::TimeDelta::FromSeconds(1);
605 CHECK(process
.WaitForExitWithTimeout(timeout
, &exit_code
));
606 ret
= IGNORE_EINTR(close(fds
[0]));
609 return num_open_files
;
612 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
613 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise.
614 // The problem is 100% reproducible with both ASan and TSan.
615 // See http://crbug.com/136720.
616 #define MAYBE_FDRemapping DISABLED_FDRemapping
618 #define MAYBE_FDRemapping FDRemapping
620 TEST_F(ProcessUtilTest
, MAYBE_FDRemapping
) {
621 int fds_before
= CountOpenFDsInChild();
623 // open some dummy fds to make sure they don't propagate over to the
625 int dev_null
= open("/dev/null", O_RDONLY
);
627 socketpair(AF_UNIX
, SOCK_STREAM
, 0, sockets
);
629 int fds_after
= CountOpenFDsInChild();
631 ASSERT_EQ(fds_after
, fds_before
);
634 ret
= IGNORE_EINTR(close(sockets
[0]));
636 ret
= IGNORE_EINTR(close(sockets
[1]));
638 ret
= IGNORE_EINTR(close(dev_null
));
644 std::string
TestLaunchProcess(const std::vector
<std::string
>& args
,
645 const base::EnvironmentMap
& env_changes
,
646 const bool clear_environ
,
647 const int clone_flags
) {
648 base::FileHandleMappingVector fds_to_remap
;
651 PCHECK(pipe(fds
) == 0);
653 fds_to_remap
.push_back(std::make_pair(fds
[1], 1));
654 base::LaunchOptions options
;
656 options
.environ
= env_changes
;
657 options
.clear_environ
= clear_environ
;
658 options
.fds_to_remap
= &fds_to_remap
;
659 #if defined(OS_LINUX)
660 options
.clone_flags
= clone_flags
;
662 CHECK_EQ(0, clone_flags
);
664 EXPECT_TRUE(base::LaunchProcess(args
, options
).IsValid());
665 PCHECK(IGNORE_EINTR(close(fds
[1])) == 0);
668 const ssize_t n
= HANDLE_EINTR(read(fds
[0], buf
, sizeof(buf
)));
670 PCHECK(IGNORE_EINTR(close(fds
[0])) == 0);
672 return std::string(buf
, n
);
675 const char kLargeString
[] =
676 "0123456789012345678901234567890123456789012345678901234567890123456789"
677 "0123456789012345678901234567890123456789012345678901234567890123456789"
678 "0123456789012345678901234567890123456789012345678901234567890123456789"
679 "0123456789012345678901234567890123456789012345678901234567890123456789"
680 "0123456789012345678901234567890123456789012345678901234567890123456789"
681 "0123456789012345678901234567890123456789012345678901234567890123456789"
682 "0123456789012345678901234567890123456789012345678901234567890123456789";
686 TEST_F(ProcessUtilTest
, LaunchProcess
) {
687 base::EnvironmentMap env_changes
;
688 std::vector
<std::string
> echo_base_test
;
689 echo_base_test
.push_back(kPosixShell
);
690 echo_base_test
.push_back("-c");
691 echo_base_test
.push_back("echo $BASE_TEST");
693 std::vector
<std::string
> print_env
;
694 print_env
.push_back("/usr/bin/env");
695 const int no_clone_flags
= 0;
696 const bool no_clear_environ
= false;
698 const char kBaseTest
[] = "BASE_TEST";
700 env_changes
[kBaseTest
] = "bar";
703 echo_base_test
, env_changes
, no_clear_environ
, no_clone_flags
));
706 EXPECT_EQ(0, setenv(kBaseTest
, "testing", 1 /* override */));
707 EXPECT_EQ("testing\n",
709 echo_base_test
, env_changes
, no_clear_environ
, no_clone_flags
));
711 env_changes
[kBaseTest
] = std::string();
714 echo_base_test
, env_changes
, no_clear_environ
, no_clone_flags
));
716 env_changes
[kBaseTest
] = "foo";
719 echo_base_test
, env_changes
, no_clear_environ
, no_clone_flags
));
722 EXPECT_EQ(0, setenv(kBaseTest
, kLargeString
, 1 /* override */));
723 EXPECT_EQ(std::string(kLargeString
) + "\n",
725 echo_base_test
, env_changes
, no_clear_environ
, no_clone_flags
));
727 env_changes
[kBaseTest
] = "wibble";
728 EXPECT_EQ("wibble\n",
730 echo_base_test
, env_changes
, no_clear_environ
, no_clone_flags
));
732 #if defined(OS_LINUX)
733 // Test a non-trival value for clone_flags.
734 // Don't test on Valgrind as it has limited support for clone().
735 if (!RunningOnValgrind()) {
736 EXPECT_EQ("wibble\n", TestLaunchProcess(echo_base_test
, env_changes
,
737 no_clear_environ
, CLONE_FS
));
741 "BASE_TEST=wibble\n",
743 print_env
, env_changes
, true /* clear_environ */, no_clone_flags
));
748 print_env
, env_changes
, true /* clear_environ */, no_clone_flags
));
752 TEST_F(ProcessUtilTest
, GetAppOutput
) {
755 #if defined(OS_ANDROID)
756 std::vector
<std::string
> argv
;
757 argv
.push_back("sh"); // Instead of /bin/sh, force path search to find it.
758 argv
.push_back("-c");
760 argv
.push_back("exit 0");
761 EXPECT_TRUE(base::GetAppOutput(base::CommandLine(argv
), &output
));
762 EXPECT_STREQ("", output
.c_str());
765 EXPECT_FALSE(base::GetAppOutput(base::CommandLine(argv
), &output
));
766 EXPECT_STREQ("", output
.c_str());
768 argv
[2] = "echo foobar42";
769 EXPECT_TRUE(base::GetAppOutput(base::CommandLine(argv
), &output
));
770 EXPECT_STREQ("foobar42\n", output
.c_str());
772 EXPECT_TRUE(base::GetAppOutput(base::CommandLine(FilePath("true")),
774 EXPECT_STREQ("", output
.c_str());
776 EXPECT_FALSE(base::GetAppOutput(base::CommandLine(FilePath("false")),
779 std::vector
<std::string
> argv
;
780 argv
.push_back("/bin/echo");
781 argv
.push_back("-n");
782 argv
.push_back("foobar42");
783 EXPECT_TRUE(base::GetAppOutput(base::CommandLine(argv
), &output
));
784 EXPECT_STREQ("foobar42", output
.c_str());
785 #endif // defined(OS_ANDROID)
788 // Flakes on Android, crbug.com/375840
789 #if defined(OS_ANDROID)
790 #define MAYBE_GetAppOutputRestricted DISABLED_GetAppOutputRestricted
792 #define MAYBE_GetAppOutputRestricted GetAppOutputRestricted
794 TEST_F(ProcessUtilTest
, MAYBE_GetAppOutputRestricted
) {
795 // Unfortunately, since we can't rely on the path, we need to know where
796 // everything is. So let's use /bin/sh, which is on every POSIX system, and
798 std::vector
<std::string
> argv
;
799 argv
.push_back(std::string(kShellPath
)); // argv[0]
800 argv
.push_back("-c"); // argv[1]
802 // On success, should set |output|. We use |/bin/sh -c 'exit 0'| instead of
803 // |true| since the location of the latter may be |/bin| or |/usr/bin| (and we
804 // need absolute paths).
805 argv
.push_back("exit 0"); // argv[2]; equivalent to "true"
806 std::string output
= "abc";
807 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
809 EXPECT_STREQ("", output
.c_str());
811 argv
[2] = "exit 1"; // equivalent to "false"
813 EXPECT_FALSE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
815 EXPECT_STREQ("", output
.c_str());
817 // Amount of output exactly equal to space allowed.
818 argv
[2] = "echo 123456789"; // (the sh built-in doesn't take "-n")
820 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
822 EXPECT_STREQ("123456789\n", output
.c_str());
824 // Amount of output greater than space allowed.
826 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
828 EXPECT_STREQ("12345", output
.c_str());
830 // Amount of output less than space allowed.
832 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
834 EXPECT_STREQ("123456789\n", output
.c_str());
836 // Zero space allowed.
838 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
840 EXPECT_STREQ("", output
.c_str());
843 #if !defined(OS_MACOSX) && !defined(OS_OPENBSD)
844 // TODO(benwells): GetAppOutputRestricted should terminate applications
845 // with SIGPIPE when we have enough output. http://crbug.com/88502
846 TEST_F(ProcessUtilTest
, GetAppOutputRestrictedSIGPIPE
) {
847 std::vector
<std::string
> argv
;
850 argv
.push_back(std::string(kShellPath
)); // argv[0]
851 argv
.push_back("-c");
852 #if defined(OS_ANDROID)
853 argv
.push_back("while echo 12345678901234567890; do :; done");
854 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
856 EXPECT_STREQ("1234567890", output
.c_str());
858 argv
.push_back("yes");
859 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
861 EXPECT_STREQ("y\ny\ny\ny\ny\n", output
.c_str());
866 #if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX) && \
867 defined(ARCH_CPU_64_BITS)
868 // Times out under AddressSanitizer on 64-bit OS X, see
869 // http://crbug.com/298197.
870 #define MAYBE_GetAppOutputRestrictedNoZombies \
871 DISABLED_GetAppOutputRestrictedNoZombies
873 #define MAYBE_GetAppOutputRestrictedNoZombies GetAppOutputRestrictedNoZombies
875 TEST_F(ProcessUtilTest
, MAYBE_GetAppOutputRestrictedNoZombies
) {
876 std::vector
<std::string
> argv
;
878 argv
.push_back(std::string(kShellPath
)); // argv[0]
879 argv
.push_back("-c"); // argv[1]
880 argv
.push_back("echo 123456789012345678901234567890"); // argv[2]
882 // Run |GetAppOutputRestricted()| 300 (> default per-user processes on Mac OS
883 // 10.5) times with an output buffer big enough to capture all output.
884 for (int i
= 0; i
< 300; i
++) {
886 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
888 EXPECT_STREQ("123456789012345678901234567890\n", output
.c_str());
891 // Ditto, but with an output buffer too small to capture all output.
892 for (int i
= 0; i
< 300; i
++) {
894 EXPECT_TRUE(base::GetAppOutputRestricted(base::CommandLine(argv
), &output
,
896 EXPECT_STREQ("1234567890", output
.c_str());
900 TEST_F(ProcessUtilTest
, GetAppOutputWithExitCode
) {
901 // Test getting output from a successful application.
902 std::vector
<std::string
> argv
;
905 argv
.push_back(std::string(kShellPath
)); // argv[0]
906 argv
.push_back("-c"); // argv[1]
907 argv
.push_back("echo foo"); // argv[2];
908 EXPECT_TRUE(base::GetAppOutputWithExitCode(base::CommandLine(argv
), &output
,
910 EXPECT_STREQ("foo\n", output
.c_str());
911 EXPECT_EQ(exit_code
, 0);
913 // Test getting output from an application which fails with a specific exit
916 argv
[2] = "echo foo; exit 2";
917 EXPECT_TRUE(base::GetAppOutputWithExitCode(base::CommandLine(argv
), &output
,
919 EXPECT_STREQ("foo\n", output
.c_str());
920 EXPECT_EQ(exit_code
, 2);
923 TEST_F(ProcessUtilTest
, GetParentProcessId
) {
924 base::ProcessId ppid
= base::GetParentProcessId(base::GetCurrentProcId());
925 EXPECT_EQ(ppid
, getppid());
928 // TODO(port): port those unit tests.
929 bool IsProcessDead(base::ProcessHandle child
) {
930 // waitpid() will actually reap the process which is exactly NOT what we
931 // want to test for. The good thing is that if it can't find the process
932 // we'll get a nice value for errno which we can test for.
933 const pid_t result
= HANDLE_EINTR(waitpid(child
, NULL
, WNOHANG
));
934 return result
== -1 && errno
== ECHILD
;
937 TEST_F(ProcessUtilTest
, DelayedTermination
) {
938 base::Process child_process
= SpawnChild("process_util_test_never_die");
939 ASSERT_TRUE(child_process
.IsValid());
940 base::EnsureProcessTerminated(child_process
.Duplicate());
942 child_process
.WaitForExitWithTimeout(base::TimeDelta::FromSeconds(5),
945 // Check that process was really killed.
946 EXPECT_TRUE(IsProcessDead(child_process
.Handle()));
949 MULTIPROCESS_TEST_MAIN(process_util_test_never_die
) {
956 TEST_F(ProcessUtilTest
, ImmediateTermination
) {
957 base::Process child_process
= SpawnChild("process_util_test_die_immediately");
958 ASSERT_TRUE(child_process
.IsValid());
959 // Give it time to die.
961 base::EnsureProcessTerminated(child_process
.Duplicate());
963 // Check that process was really killed.
964 EXPECT_TRUE(IsProcessDead(child_process
.Handle()));
967 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately
) {
971 #if !defined(OS_ANDROID)
972 const char kPipeValue
= '\xcc';
974 class ReadFromPipeDelegate
: public base::LaunchOptions::PreExecDelegate
{
976 explicit ReadFromPipeDelegate(int fd
) : fd_(fd
) {}
977 ~ReadFromPipeDelegate() override
{}
978 void RunAsyncSafe() override
{
980 RAW_CHECK(HANDLE_EINTR(read(fd_
, &c
, 1)) == 1);
981 RAW_CHECK(IGNORE_EINTR(close(fd_
)) == 0);
982 RAW_CHECK(c
== kPipeValue
);
987 DISALLOW_COPY_AND_ASSIGN(ReadFromPipeDelegate
);
990 TEST_F(ProcessUtilTest
, PreExecHook
) {
992 ASSERT_EQ(0, pipe(pipe_fds
));
994 base::ScopedFD
read_fd(pipe_fds
[0]);
995 base::ScopedFD
write_fd(pipe_fds
[1]);
996 base::FileHandleMappingVector fds_to_remap
;
997 fds_to_remap
.push_back(std::make_pair(read_fd
.get(), read_fd
.get()));
999 ReadFromPipeDelegate
read_from_pipe_delegate(read_fd
.get());
1000 base::LaunchOptions options
;
1001 options
.fds_to_remap
= &fds_to_remap
;
1002 options
.pre_exec_delegate
= &read_from_pipe_delegate
;
1003 base::Process
process(SpawnChildWithOptions("SimpleChildProcess", options
));
1004 ASSERT_TRUE(process
.IsValid());
1007 ASSERT_EQ(1, HANDLE_EINTR(write(write_fd
.get(), &kPipeValue
, 1)));
1010 EXPECT_TRUE(process
.WaitForExit(&exit_code
));
1011 EXPECT_EQ(0, exit_code
);
1013 #endif // !defined(OS_ANDROID)
1015 #endif // defined(OS_POSIX)
1017 #if defined(OS_LINUX)
1018 const int kSuccess
= 0;
1020 MULTIPROCESS_TEST_MAIN(CheckPidProcess
) {
1021 const pid_t kInitPid
= 1;
1022 const pid_t pid
= syscall(__NR_getpid
);
1023 CHECK(pid
== kInitPid
);
1024 CHECK(getpid() == pid
);
1028 #if defined(CLONE_NEWUSER) && defined(CLONE_NEWPID)
1029 TEST_F(ProcessUtilTest
, CloneFlags
) {
1030 if (RunningOnValgrind() ||
1031 !base::PathExists(FilePath("/proc/self/ns/user")) ||
1032 !base::PathExists(FilePath("/proc/self/ns/pid"))) {
1033 // User or PID namespaces are not supported.
1037 base::LaunchOptions options
;
1038 options
.clone_flags
= CLONE_NEWUSER
| CLONE_NEWPID
;
1040 base::Process
process(SpawnChildWithOptions("CheckPidProcess", options
));
1041 ASSERT_TRUE(process
.IsValid());
1044 EXPECT_TRUE(process
.WaitForExit(&exit_code
));
1045 EXPECT_EQ(kSuccess
, exit_code
);
1049 TEST(ForkWithFlagsTest
, UpdatesPidCache
) {
1050 // The libc clone function, which allows ForkWithFlags to keep the pid cache
1051 // up to date, does not work on Valgrind.
1052 if (RunningOnValgrind()) {
1056 // Warm up the libc pid cache, if there is one.
1057 ASSERT_EQ(syscall(__NR_getpid
), getpid());
1061 base::ForkWithFlags(SIGCHLD
| CLONE_CHILD_SETTID
, nullptr, &ctid
);
1063 // In child. Check both the raw getpid syscall and the libc getpid wrapper
1064 // (which may rely on a pid cache).
1065 RAW_CHECK(syscall(__NR_getpid
) == ctid
);
1066 RAW_CHECK(getpid() == ctid
);
1072 ASSERT_EQ(pid
, HANDLE_EINTR(waitpid(pid
, &status
, 0)));
1073 ASSERT_TRUE(WIFEXITED(status
));
1074 EXPECT_EQ(kSuccess
, WEXITSTATUS(status
));
1077 MULTIPROCESS_TEST_MAIN(CheckCwdProcess
) {
1078 base::FilePath expected
;
1079 CHECK(base::GetTempDir(&expected
));
1080 base::FilePath actual
;
1081 CHECK(base::GetCurrentDirectory(&actual
));
1082 CHECK(actual
== expected
);
1086 TEST_F(ProcessUtilTest
, CurrentDirectory
) {
1087 // TODO(rickyz): Add support for passing arguments to multiprocess children,
1088 // then create a special directory for this test.
1089 base::FilePath tmp_dir
;
1090 ASSERT_TRUE(base::GetTempDir(&tmp_dir
));
1092 base::LaunchOptions options
;
1093 options
.current_directory
= tmp_dir
;
1095 base::Process
process(SpawnChildWithOptions("CheckCwdProcess", options
));
1096 ASSERT_TRUE(process
.IsValid());
1099 EXPECT_TRUE(process
.WaitForExit(&exit_code
));
1100 EXPECT_EQ(kSuccess
, exit_code
);
1103 TEST_F(ProcessUtilTest
, InvalidCurrentDirectory
) {
1104 base::LaunchOptions options
;
1105 options
.current_directory
= base::FilePath("/dev/null");
1107 base::Process
process(SpawnChildWithOptions("SimpleChildProcess", options
));
1108 ASSERT_TRUE(process
.IsValid());
1110 int exit_code
= kSuccess
;
1111 EXPECT_TRUE(process
.WaitForExit(&exit_code
));
1112 EXPECT_NE(kSuccess
, exit_code
);