Fix iOS build for XCode 4.6.
[chromium-blink-merge.git] / base / process_util_unittest.cc
blob4c1eff438c12554d440c70788b1a7cb9114f4d4b
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
7 #include <limits>
9 #include "base/command_line.h"
10 #include "base/debug/alias.h"
11 #include "base/debug/stack_trace.h"
12 #include "base/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_util.h"
18 #include "base/test/multiprocess_test.h"
19 #include "base/test/test_timeouts.h"
20 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
21 #include "base/threading/platform_thread.h"
22 #include "base/utf_string_conversions.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "testing/multiprocess_func_list.h"
26 #if defined(OS_LINUX)
27 #include <malloc.h>
28 #include <glib.h>
29 #include <sched.h>
30 #endif
31 #if defined(OS_POSIX)
32 #include <errno.h>
33 #include <dlfcn.h>
34 #include <fcntl.h>
35 #include <signal.h>
36 #include <sys/resource.h>
37 #include <sys/socket.h>
38 #include <sys/wait.h>
39 #endif
40 #if defined(OS_WIN)
41 #include <windows.h>
42 #endif
43 #if defined(OS_MACOSX)
44 #include <mach/vm_param.h>
45 #include <malloc/malloc.h>
46 #include "base/process_util_unittest_mac.h"
47 #endif
49 namespace {
51 #if defined(OS_WIN)
52 const wchar_t kProcessName[] = L"base_unittests.exe";
53 #else
54 const wchar_t kProcessName[] = L"base_unittests";
55 #endif // defined(OS_WIN)
57 #if defined(OS_ANDROID)
58 const char kShellPath[] = "/system/bin/sh";
59 const char kPosixShell[] = "sh";
60 #else
61 const char kShellPath[] = "/bin/sh";
62 const char kPosixShell[] = "bash";
63 #endif
65 const char kSignalFileSlow[] = "SlowChildProcess.die";
66 const char kSignalFileCrash[] = "CrashingChildProcess.die";
67 const char kSignalFileKill[] = "KilledChildProcess.die";
69 #if defined(OS_WIN)
70 const int kExpectedStillRunningExitCode = 0x102;
71 const int kExpectedKilledExitCode = 1;
72 #else
73 const int kExpectedStillRunningExitCode = 0;
74 #endif
76 #if defined(OS_WIN)
77 // HeapQueryInformation function pointer.
78 typedef BOOL (WINAPI* HeapQueryFn) \
79 (HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T);
80 #endif
82 // Sleeps until file filename is created.
83 void WaitToDie(const char* filename) {
84 FILE* fp;
85 do {
86 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
87 fp = fopen(filename, "r");
88 } while (!fp);
89 fclose(fp);
92 // Signals children they should die now.
93 void SignalChildren(const char* filename) {
94 FILE* fp = fopen(filename, "w");
95 fclose(fp);
98 // Using a pipe to the child to wait for an event was considered, but
99 // there were cases in the past where pipes caused problems (other
100 // libraries closing the fds, child deadlocking). This is a simple
101 // case, so it's not worth the risk. Using wait loops is discouraged
102 // in most instances.
103 base::TerminationStatus WaitForChildTermination(base::ProcessHandle handle,
104 int* exit_code) {
105 // Now we wait until the result is something other than STILL_RUNNING.
106 base::TerminationStatus status = base::TERMINATION_STATUS_STILL_RUNNING;
107 const base::TimeDelta kInterval = base::TimeDelta::FromMilliseconds(20);
108 base::TimeDelta waited;
109 do {
110 status = base::GetTerminationStatus(handle, exit_code);
111 base::PlatformThread::Sleep(kInterval);
112 waited += kInterval;
113 } while (status == base::TERMINATION_STATUS_STILL_RUNNING &&
114 // Waiting for more time for process termination on android devices.
115 #if defined(OS_ANDROID)
116 waited < TestTimeouts::large_test_timeout());
117 #else
118 waited < TestTimeouts::action_max_timeout());
119 #endif
121 return status;
124 } // namespace
126 class ProcessUtilTest : public base::MultiProcessTest {
127 public:
128 #if defined(OS_POSIX)
129 // Spawn a child process that counts how many file descriptors are open.
130 int CountOpenFDsInChild();
131 #endif
132 // Converts the filename to a platform specific filepath.
133 // On Android files can not be created in arbitrary directories.
134 static std::string GetSignalFilePath(const char* filename);
137 std::string ProcessUtilTest::GetSignalFilePath(const char* filename) {
138 #if !defined(OS_ANDROID)
139 return filename;
140 #else
141 FilePath tmp_dir;
142 PathService::Get(base::DIR_CACHE, &tmp_dir);
143 tmp_dir = tmp_dir.Append(filename);
144 return tmp_dir.value();
145 #endif
148 MULTIPROCESS_TEST_MAIN(SimpleChildProcess) {
149 return 0;
152 TEST_F(ProcessUtilTest, SpawnChild) {
153 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false);
154 ASSERT_NE(base::kNullProcessHandle, handle);
155 EXPECT_TRUE(base::WaitForSingleProcess(
156 handle, TestTimeouts::action_max_timeout()));
157 base::CloseProcessHandle(handle);
160 MULTIPROCESS_TEST_MAIN(SlowChildProcess) {
161 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileSlow).c_str());
162 return 0;
165 TEST_F(ProcessUtilTest, KillSlowChild) {
166 const std::string signal_file =
167 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow);
168 remove(signal_file.c_str());
169 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false);
170 ASSERT_NE(base::kNullProcessHandle, handle);
171 SignalChildren(signal_file.c_str());
172 EXPECT_TRUE(base::WaitForSingleProcess(
173 handle, TestTimeouts::action_max_timeout()));
174 base::CloseProcessHandle(handle);
175 remove(signal_file.c_str());
178 // Times out on Linux and Win, flakes on other platforms, http://crbug.com/95058
179 TEST_F(ProcessUtilTest, DISABLED_GetTerminationStatusExit) {
180 const std::string signal_file =
181 ProcessUtilTest::GetSignalFilePath(kSignalFileSlow);
182 remove(signal_file.c_str());
183 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false);
184 ASSERT_NE(base::kNullProcessHandle, handle);
186 int exit_code = 42;
187 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING,
188 base::GetTerminationStatus(handle, &exit_code));
189 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
191 SignalChildren(signal_file.c_str());
192 exit_code = 42;
193 base::TerminationStatus status =
194 WaitForChildTermination(handle, &exit_code);
195 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION, status);
196 EXPECT_EQ(0, exit_code);
197 base::CloseProcessHandle(handle);
198 remove(signal_file.c_str());
201 #if defined(OS_WIN)
202 // TODO(cpu): figure out how to test this in other platforms.
203 TEST_F(ProcessUtilTest, GetProcId) {
204 base::ProcessId id1 = base::GetProcId(GetCurrentProcess());
205 EXPECT_NE(0ul, id1);
206 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false);
207 ASSERT_NE(base::kNullProcessHandle, handle);
208 base::ProcessId id2 = base::GetProcId(handle);
209 EXPECT_NE(0ul, id2);
210 EXPECT_NE(id1, id2);
211 base::CloseProcessHandle(handle);
214 TEST_F(ProcessUtilTest, GetModuleFromAddress) {
215 // Since the unit tests are their own EXE, this should be
216 // equivalent to the EXE's HINSTANCE.
218 // kExpectedKilledExitCode is a constant in this file and
219 // therefore within the unit test EXE.
220 EXPECT_EQ(::GetModuleHandle(NULL),
221 base::GetModuleFromAddress(
222 const_cast<int*>(&kExpectedKilledExitCode)));
224 // Any address within the kernel32 module should return
225 // kernel32's HMODULE. Our only assumption here is that
226 // kernel32 is larger than 4 bytes.
227 HMODULE kernel32 = ::GetModuleHandle(L"kernel32.dll");
228 HMODULE kernel32_from_address =
229 base::GetModuleFromAddress(reinterpret_cast<DWORD*>(kernel32) + 1);
230 EXPECT_EQ(kernel32, kernel32_from_address);
232 #endif
234 #if !defined(OS_MACOSX)
235 // This test is disabled on Mac, since it's flaky due to ReportCrash
236 // taking a variable amount of time to parse and load the debug and
237 // symbol data for this unit test's executable before firing the
238 // signal handler.
240 // TODO(gspencer): turn this test process into a very small program
241 // with no symbols (instead of using the multiprocess testing
242 // framework) to reduce the ReportCrash overhead.
244 MULTIPROCESS_TEST_MAIN(CrashingChildProcess) {
245 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileCrash).c_str());
246 #if defined(OS_POSIX)
247 // Have to disable to signal handler for segv so we can get a crash
248 // instead of an abnormal termination through the crash dump handler.
249 ::signal(SIGSEGV, SIG_DFL);
250 #endif
251 // Make this process have a segmentation fault.
252 volatile int* oops = NULL;
253 *oops = 0xDEAD;
254 return 1;
257 // This test intentionally crashes, so we don't need to run it under
258 // AddressSanitizer.
259 #if defined(ADDRESS_SANITIZER)
260 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash
261 #else
262 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash
263 #endif
264 TEST_F(ProcessUtilTest, MAYBE_GetTerminationStatusCrash) {
265 const std::string signal_file =
266 ProcessUtilTest::GetSignalFilePath(kSignalFileCrash);
267 remove(signal_file.c_str());
268 base::ProcessHandle handle = this->SpawnChild("CrashingChildProcess",
269 false);
270 ASSERT_NE(base::kNullProcessHandle, handle);
272 int exit_code = 42;
273 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING,
274 base::GetTerminationStatus(handle, &exit_code));
275 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
277 SignalChildren(signal_file.c_str());
278 exit_code = 42;
279 base::TerminationStatus status =
280 WaitForChildTermination(handle, &exit_code);
281 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED, status);
283 #if defined(OS_WIN)
284 EXPECT_EQ(0xc0000005, exit_code);
285 #elif defined(OS_POSIX)
286 int signaled = WIFSIGNALED(exit_code);
287 EXPECT_NE(0, signaled);
288 int signal = WTERMSIG(exit_code);
289 EXPECT_EQ(SIGSEGV, signal);
290 #endif
291 base::CloseProcessHandle(handle);
293 // Reset signal handlers back to "normal".
294 base::debug::EnableInProcessStackDumping();
295 remove(signal_file.c_str());
297 #endif // !defined(OS_MACOSX)
299 MULTIPROCESS_TEST_MAIN(KilledChildProcess) {
300 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileKill).c_str());
301 #if defined(OS_WIN)
302 // Kill ourselves.
303 HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId());
304 ::TerminateProcess(handle, kExpectedKilledExitCode);
305 #elif defined(OS_POSIX)
306 // Send a SIGKILL to this process, just like the OOM killer would.
307 ::kill(getpid(), SIGKILL);
308 #endif
309 return 1;
312 TEST_F(ProcessUtilTest, GetTerminationStatusKill) {
313 const std::string signal_file =
314 ProcessUtilTest::GetSignalFilePath(kSignalFileKill);
315 remove(signal_file.c_str());
316 base::ProcessHandle handle = this->SpawnChild("KilledChildProcess",
317 false);
318 ASSERT_NE(base::kNullProcessHandle, handle);
320 int exit_code = 42;
321 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING,
322 base::GetTerminationStatus(handle, &exit_code));
323 EXPECT_EQ(kExpectedStillRunningExitCode, exit_code);
325 SignalChildren(signal_file.c_str());
326 exit_code = 42;
327 base::TerminationStatus status =
328 WaitForChildTermination(handle, &exit_code);
329 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED, status);
330 #if defined(OS_WIN)
331 EXPECT_EQ(kExpectedKilledExitCode, exit_code);
332 #elif defined(OS_POSIX)
333 int signaled = WIFSIGNALED(exit_code);
334 EXPECT_NE(0, signaled);
335 int signal = WTERMSIG(exit_code);
336 EXPECT_EQ(SIGKILL, signal);
337 #endif
338 base::CloseProcessHandle(handle);
339 remove(signal_file.c_str());
342 // Ensure that the priority of a process is restored correctly after
343 // backgrounding and restoring.
344 // Note: a platform may not be willing or able to lower the priority of
345 // a process. The calls to SetProcessBackground should be noops then.
346 TEST_F(ProcessUtilTest, SetProcessBackgrounded) {
347 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false);
348 base::Process process(handle);
349 int old_priority = process.GetPriority();
350 #if defined(OS_WIN)
351 EXPECT_TRUE(process.SetProcessBackgrounded(true));
352 EXPECT_TRUE(process.IsProcessBackgrounded());
353 EXPECT_TRUE(process.SetProcessBackgrounded(false));
354 EXPECT_FALSE(process.IsProcessBackgrounded());
355 #else
356 process.SetProcessBackgrounded(true);
357 process.SetProcessBackgrounded(false);
358 #endif
359 int new_priority = process.GetPriority();
360 EXPECT_EQ(old_priority, new_priority);
363 // Same as SetProcessBackgrounded but to this very process. It uses
364 // a different code path at least for Windows.
365 TEST_F(ProcessUtilTest, SetProcessBackgroundedSelf) {
366 base::Process process(base::Process::Current().handle());
367 int old_priority = process.GetPriority();
368 #if defined(OS_WIN)
369 EXPECT_TRUE(process.SetProcessBackgrounded(true));
370 EXPECT_TRUE(process.IsProcessBackgrounded());
371 EXPECT_TRUE(process.SetProcessBackgrounded(false));
372 EXPECT_FALSE(process.IsProcessBackgrounded());
373 #else
374 process.SetProcessBackgrounded(true);
375 process.SetProcessBackgrounded(false);
376 #endif
377 int new_priority = process.GetPriority();
378 EXPECT_EQ(old_priority, new_priority);
381 // TODO(estade): if possible, port these 2 tests.
382 #if defined(OS_WIN)
383 TEST_F(ProcessUtilTest, EnableLFH) {
384 ASSERT_TRUE(base::EnableLowFragmentationHeap());
385 if (IsDebuggerPresent()) {
386 // Under these conditions, LFH can't be enabled. There's no point to test
387 // anything.
388 const char* no_debug_env = getenv("_NO_DEBUG_HEAP");
389 if (!no_debug_env || strcmp(no_debug_env, "1"))
390 return;
392 HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
393 ASSERT_TRUE(kernel32 != NULL);
394 HeapQueryFn heap_query = reinterpret_cast<HeapQueryFn>(GetProcAddress(
395 kernel32,
396 "HeapQueryInformation"));
398 // On Windows 2000, the function is not exported. This is not a reason to
399 // fail but we won't be able to retrieves information about the heap, so we
400 // should stop here.
401 if (heap_query == NULL)
402 return;
404 HANDLE heaps[1024] = { 0 };
405 unsigned number_heaps = GetProcessHeaps(1024, heaps);
406 EXPECT_GT(number_heaps, 0u);
407 for (unsigned i = 0; i < number_heaps; ++i) {
408 ULONG flag = 0;
409 SIZE_T length;
410 ASSERT_NE(0, heap_query(heaps[i],
411 HeapCompatibilityInformation,
412 &flag,
413 sizeof(flag),
414 &length));
415 // If flag is 0, the heap is a standard heap that does not support
416 // look-asides. If flag is 1, the heap supports look-asides. If flag is 2,
417 // the heap is a low-fragmentation heap (LFH). Note that look-asides are not
418 // supported on the LFH.
420 // We don't have any documented way of querying the HEAP_NO_SERIALIZE flag.
421 EXPECT_LE(flag, 2u);
422 EXPECT_NE(flag, 1u);
426 TEST_F(ProcessUtilTest, CalcFreeMemory) {
427 scoped_ptr<base::ProcessMetrics> metrics(
428 base::ProcessMetrics::CreateProcessMetrics(::GetCurrentProcess()));
429 ASSERT_TRUE(NULL != metrics.get());
431 // Typical values here is ~1900 for total and ~1000 for largest. Obviously
432 // it depends in what other tests have done to this process.
433 base::FreeMBytes free_mem1 = {0};
434 EXPECT_TRUE(metrics->CalculateFreeMemory(&free_mem1));
435 EXPECT_LT(10u, free_mem1.total);
436 EXPECT_LT(10u, free_mem1.largest);
437 EXPECT_GT(2048u, free_mem1.total);
438 EXPECT_GT(2048u, free_mem1.largest);
439 EXPECT_GE(free_mem1.total, free_mem1.largest);
440 EXPECT_TRUE(NULL != free_mem1.largest_ptr);
442 // Allocate 20M and check again. It should have gone down.
443 const int kAllocMB = 20;
444 scoped_array<char> alloc(new char[kAllocMB * 1024 * 1024]);
445 size_t expected_total = free_mem1.total - kAllocMB;
446 size_t expected_largest = free_mem1.largest;
448 base::FreeMBytes free_mem2 = {0};
449 EXPECT_TRUE(metrics->CalculateFreeMemory(&free_mem2));
450 EXPECT_GE(free_mem2.total, free_mem2.largest);
451 EXPECT_GE(expected_total, free_mem2.total);
452 EXPECT_GE(expected_largest, free_mem2.largest);
453 EXPECT_TRUE(NULL != free_mem2.largest_ptr);
456 TEST_F(ProcessUtilTest, GetAppOutput) {
457 // Let's create a decently long message.
458 std::string message;
459 for (int i = 0; i < 1025; i++) { // 1025 so it does not end on a kilo-byte
460 // boundary.
461 message += "Hello!";
463 // cmd.exe's echo always adds a \r\n to its output.
464 std::string expected(message);
465 expected += "\r\n";
467 FilePath cmd(L"cmd.exe");
468 CommandLine cmd_line(cmd);
469 cmd_line.AppendArg("/c");
470 cmd_line.AppendArg("echo " + message + "");
471 std::string output;
472 ASSERT_TRUE(base::GetAppOutput(cmd_line, &output));
473 EXPECT_EQ(expected, output);
475 // Let's make sure stderr is ignored.
476 CommandLine other_cmd_line(cmd);
477 other_cmd_line.AppendArg("/c");
478 // http://msdn.microsoft.com/library/cc772622.aspx
479 cmd_line.AppendArg("echo " + message + " >&2");
480 output.clear();
481 ASSERT_TRUE(base::GetAppOutput(other_cmd_line, &output));
482 EXPECT_EQ("", output);
485 TEST_F(ProcessUtilTest, LaunchAsUser) {
486 base::UserTokenHandle token;
487 ASSERT_TRUE(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token));
488 std::wstring cmdline =
489 this->MakeCmdLine("SimpleChildProcess", false).GetCommandLineString();
490 base::LaunchOptions options;
491 options.as_user = token;
492 EXPECT_TRUE(base::LaunchProcess(cmdline, options, NULL));
495 #endif // defined(OS_WIN)
497 #if defined(OS_MACOSX)
499 // For the following Mac tests:
500 // Note that base::EnableTerminationOnHeapCorruption() is called as part of
501 // test suite setup and does not need to be done again, else mach_override
502 // will fail.
504 #if !defined(ADDRESS_SANITIZER)
505 // The following code tests the system implementation of malloc() thus no need
506 // to test it under AddressSanitizer.
507 TEST_F(ProcessUtilTest, MacMallocFailureDoesNotTerminate) {
508 // Install the OOM killer.
509 base::EnableTerminationOnOutOfMemory();
511 // Test that ENOMEM doesn't crash via CrMallocErrorBreak two ways: the exit
512 // code and lack of the error string. The number of bytes is one less than
513 // MALLOC_ABSOLUTE_MAX_SIZE, more than which the system early-returns NULL and
514 // does not call through malloc_error_break(). See the comment at
515 // EnableTerminationOnOutOfMemory() for more information.
516 void* buf = NULL;
517 ASSERT_EXIT(
518 buf = malloc(std::numeric_limits<size_t>::max() - (2 * PAGE_SIZE) - 1),
519 testing::KilledBySignal(SIGTRAP),
520 "\\*\\*\\* error: can't allocate region.*"
521 "(Terminating process due to a potential for future heap "
522 "corruption){0}");
524 base::debug::Alias(buf);
526 #endif // !defined(ADDRESS_SANITIZER)
528 TEST_F(ProcessUtilTest, MacTerminateOnHeapCorruption) {
529 // Assert that freeing an unallocated pointer will crash the process.
530 char buf[3];
531 asm("" : "=r" (buf)); // Prevent clang from being too smart.
532 #if !defined(ADDRESS_SANITIZER)
533 ASSERT_DEATH(free(buf), "being freed.*"
534 "\\*\\*\\* set a breakpoint in malloc_error_break to debug.*"
535 "Terminating process due to a potential for future heap corruption");
536 #else
537 // AddressSanitizer replaces malloc() and prints a different error message on
538 // heap corruption.
539 ASSERT_DEATH(free(buf), "attempting free on address which "
540 "was not malloc\\(\\)-ed");
541 #endif // !defined(ADDRESS_SANITIZER)
544 #endif // defined(OS_MACOSX)
546 #if defined(OS_POSIX)
548 namespace {
550 // Returns the maximum number of files that a process can have open.
551 // Returns 0 on error.
552 int GetMaxFilesOpenInProcess() {
553 struct rlimit rlim;
554 if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
555 return 0;
558 // rlim_t is a uint64 - clip to maxint. We do this since FD #s are ints
559 // which are all 32 bits on the supported platforms.
560 rlim_t max_int = static_cast<rlim_t>(std::numeric_limits<int32>::max());
561 if (rlim.rlim_cur > max_int) {
562 return max_int;
565 return rlim.rlim_cur;
568 const int kChildPipe = 20; // FD # for write end of pipe in child process.
570 } // namespace
572 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) {
573 // This child process counts the number of open FDs, it then writes that
574 // number out to a pipe connected to the parent.
575 int num_open_files = 0;
576 int write_pipe = kChildPipe;
577 int max_files = GetMaxFilesOpenInProcess();
578 for (int i = STDERR_FILENO + 1; i < max_files; i++) {
579 if (i != kChildPipe) {
580 int fd;
581 if ((fd = HANDLE_EINTR(dup(i))) != -1) {
582 close(fd);
583 num_open_files += 1;
588 int written = HANDLE_EINTR(write(write_pipe, &num_open_files,
589 sizeof(num_open_files)));
590 DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files));
591 int ret = HANDLE_EINTR(close(write_pipe));
592 DPCHECK(ret == 0);
594 return 0;
597 int ProcessUtilTest::CountOpenFDsInChild() {
598 int fds[2];
599 if (pipe(fds) < 0)
600 NOTREACHED();
602 base::FileHandleMappingVector fd_mapping_vec;
603 fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe));
604 base::ProcessHandle handle = this->SpawnChild(
605 "ProcessUtilsLeakFDChildProcess", fd_mapping_vec, false);
606 CHECK(handle);
607 int ret = HANDLE_EINTR(close(fds[1]));
608 DPCHECK(ret == 0);
610 // Read number of open files in client process from pipe;
611 int num_open_files = -1;
612 ssize_t bytes_read =
613 HANDLE_EINTR(read(fds[0], &num_open_files, sizeof(num_open_files)));
614 CHECK_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files)));
616 #if defined(THREAD_SANITIZER)
617 // Compiler-based ThreadSanitizer makes this test slow.
618 CHECK(base::WaitForSingleProcess(handle, base::TimeDelta::FromSeconds(3)));
619 #else
620 CHECK(base::WaitForSingleProcess(handle, base::TimeDelta::FromSeconds(1)));
621 #endif
622 base::CloseProcessHandle(handle);
623 ret = HANDLE_EINTR(close(fds[0]));
624 DPCHECK(ret == 0);
626 return num_open_files;
629 TEST_F(ProcessUtilTest, FDRemapping) {
630 int fds_before = CountOpenFDsInChild();
632 // open some dummy fds to make sure they don't propagate over to the
633 // child process.
634 int dev_null = open("/dev/null", O_RDONLY);
635 int sockets[2];
636 socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
638 int fds_after = CountOpenFDsInChild();
640 ASSERT_EQ(fds_after, fds_before);
642 int ret;
643 ret = HANDLE_EINTR(close(sockets[0]));
644 DPCHECK(ret == 0);
645 ret = HANDLE_EINTR(close(sockets[1]));
646 DPCHECK(ret == 0);
647 ret = HANDLE_EINTR(close(dev_null));
648 DPCHECK(ret == 0);
651 namespace {
653 std::string TestLaunchProcess(const base::EnvironmentVector& env_changes,
654 const int clone_flags) {
655 std::vector<std::string> args;
656 base::FileHandleMappingVector fds_to_remap;
658 args.push_back(kPosixShell);
659 args.push_back("-c");
660 args.push_back("echo $BASE_TEST");
662 int fds[2];
663 PCHECK(pipe(fds) == 0);
665 fds_to_remap.push_back(std::make_pair(fds[1], 1));
666 base::LaunchOptions options;
667 options.wait = true;
668 options.environ = &env_changes;
669 options.fds_to_remap = &fds_to_remap;
670 #if defined(OS_LINUX)
671 options.clone_flags = clone_flags;
672 #else
673 CHECK_EQ(0, clone_flags);
674 #endif // OS_LINUX
675 EXPECT_TRUE(base::LaunchProcess(args, options, NULL));
676 PCHECK(HANDLE_EINTR(close(fds[1])) == 0);
678 char buf[512];
679 const ssize_t n = HANDLE_EINTR(read(fds[0], buf, sizeof(buf)));
680 PCHECK(n > 0);
682 PCHECK(HANDLE_EINTR(close(fds[0])) == 0);
684 return std::string(buf, n);
687 const char kLargeString[] =
688 "0123456789012345678901234567890123456789012345678901234567890123456789"
689 "0123456789012345678901234567890123456789012345678901234567890123456789"
690 "0123456789012345678901234567890123456789012345678901234567890123456789"
691 "0123456789012345678901234567890123456789012345678901234567890123456789"
692 "0123456789012345678901234567890123456789012345678901234567890123456789"
693 "0123456789012345678901234567890123456789012345678901234567890123456789"
694 "0123456789012345678901234567890123456789012345678901234567890123456789";
696 } // namespace
698 TEST_F(ProcessUtilTest, LaunchProcess) {
699 base::EnvironmentVector env_changes;
700 const int no_clone_flags = 0;
702 env_changes.push_back(std::make_pair(std::string("BASE_TEST"),
703 std::string("bar")));
704 EXPECT_EQ("bar\n", TestLaunchProcess(env_changes, no_clone_flags));
705 env_changes.clear();
707 EXPECT_EQ(0, setenv("BASE_TEST", "testing", 1 /* override */));
708 EXPECT_EQ("testing\n", TestLaunchProcess(env_changes, no_clone_flags));
710 env_changes.push_back(std::make_pair(std::string("BASE_TEST"),
711 std::string("")));
712 EXPECT_EQ("\n", TestLaunchProcess(env_changes, no_clone_flags));
714 env_changes[0].second = "foo";
715 EXPECT_EQ("foo\n", TestLaunchProcess(env_changes, no_clone_flags));
717 env_changes.clear();
718 EXPECT_EQ(0, setenv("BASE_TEST", kLargeString, 1 /* override */));
719 EXPECT_EQ(std::string(kLargeString) + "\n",
720 TestLaunchProcess(env_changes, no_clone_flags));
722 env_changes.push_back(std::make_pair(std::string("BASE_TEST"),
723 std::string("wibble")));
724 EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes, no_clone_flags));
726 #if defined(OS_LINUX)
727 // Test a non-trival value for clone_flags.
728 // Don't test on Valgrind as it has limited support for clone().
729 if (!RunningOnValgrind()) {
730 EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes, CLONE_FS | SIGCHLD));
732 #endif
735 TEST_F(ProcessUtilTest, AlterEnvironment) {
736 const char* const empty[] = { NULL };
737 const char* const a2[] = { "A=2", NULL };
738 base::EnvironmentVector changes;
739 char** e;
741 e = base::AlterEnvironment(changes, empty);
742 EXPECT_TRUE(e[0] == NULL);
743 delete[] e;
745 changes.push_back(std::make_pair(std::string("A"), std::string("1")));
746 e = base::AlterEnvironment(changes, empty);
747 EXPECT_EQ(std::string("A=1"), e[0]);
748 EXPECT_TRUE(e[1] == NULL);
749 delete[] e;
751 changes.clear();
752 changes.push_back(std::make_pair(std::string("A"), std::string("")));
753 e = base::AlterEnvironment(changes, empty);
754 EXPECT_TRUE(e[0] == NULL);
755 delete[] e;
757 changes.clear();
758 e = base::AlterEnvironment(changes, a2);
759 EXPECT_EQ(std::string("A=2"), e[0]);
760 EXPECT_TRUE(e[1] == NULL);
761 delete[] e;
763 changes.clear();
764 changes.push_back(std::make_pair(std::string("A"), std::string("1")));
765 e = base::AlterEnvironment(changes, a2);
766 EXPECT_EQ(std::string("A=1"), e[0]);
767 EXPECT_TRUE(e[1] == NULL);
768 delete[] e;
770 changes.clear();
771 changes.push_back(std::make_pair(std::string("A"), std::string("")));
772 e = base::AlterEnvironment(changes, a2);
773 EXPECT_TRUE(e[0] == NULL);
774 delete[] e;
777 TEST_F(ProcessUtilTest, GetAppOutput) {
778 std::string output;
780 #if defined(OS_ANDROID)
781 std::vector<std::string> argv;
782 argv.push_back("sh"); // Instead of /bin/sh, force path search to find it.
783 argv.push_back("-c");
785 argv.push_back("exit 0");
786 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output));
787 EXPECT_STREQ("", output.c_str());
789 argv[2] = "exit 1";
790 EXPECT_FALSE(base::GetAppOutput(CommandLine(argv), &output));
791 EXPECT_STREQ("", output.c_str());
793 argv[2] = "echo foobar42";
794 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output));
795 EXPECT_STREQ("foobar42\n", output.c_str());
796 #else
797 EXPECT_TRUE(base::GetAppOutput(CommandLine(FilePath("true")), &output));
798 EXPECT_STREQ("", output.c_str());
800 EXPECT_FALSE(base::GetAppOutput(CommandLine(FilePath("false")), &output));
802 std::vector<std::string> argv;
803 argv.push_back("/bin/echo");
804 argv.push_back("-n");
805 argv.push_back("foobar42");
806 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output));
807 EXPECT_STREQ("foobar42", output.c_str());
808 #endif // defined(OS_ANDROID)
811 TEST_F(ProcessUtilTest, GetAppOutputRestricted) {
812 // Unfortunately, since we can't rely on the path, we need to know where
813 // everything is. So let's use /bin/sh, which is on every POSIX system, and
814 // its built-ins.
815 std::vector<std::string> argv;
816 argv.push_back(std::string(kShellPath)); // argv[0]
817 argv.push_back("-c"); // argv[1]
819 // On success, should set |output|. We use |/bin/sh -c 'exit 0'| instead of
820 // |true| since the location of the latter may be |/bin| or |/usr/bin| (and we
821 // need absolute paths).
822 argv.push_back("exit 0"); // argv[2]; equivalent to "true"
823 std::string output = "abc";
824 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100));
825 EXPECT_STREQ("", output.c_str());
827 argv[2] = "exit 1"; // equivalent to "false"
828 output = "before";
829 EXPECT_FALSE(base::GetAppOutputRestricted(CommandLine(argv),
830 &output, 100));
831 EXPECT_STREQ("", output.c_str());
833 // Amount of output exactly equal to space allowed.
834 argv[2] = "echo 123456789"; // (the sh built-in doesn't take "-n")
835 output.clear();
836 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
837 EXPECT_STREQ("123456789\n", output.c_str());
839 // Amount of output greater than space allowed.
840 output.clear();
841 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 5));
842 EXPECT_STREQ("12345", output.c_str());
844 // Amount of output less than space allowed.
845 output.clear();
846 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 15));
847 EXPECT_STREQ("123456789\n", output.c_str());
849 // Zero space allowed.
850 output = "abc";
851 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 0));
852 EXPECT_STREQ("", output.c_str());
855 #if !defined(OS_MACOSX) && !defined(OS_OPENBSD)
856 // TODO(benwells): GetAppOutputRestricted should terminate applications
857 // with SIGPIPE when we have enough output. http://crbug.com/88502
858 TEST_F(ProcessUtilTest, GetAppOutputRestrictedSIGPIPE) {
859 std::vector<std::string> argv;
860 std::string output;
862 argv.push_back(std::string(kShellPath)); // argv[0]
863 argv.push_back("-c");
864 #if defined(OS_ANDROID)
865 argv.push_back("while echo 12345678901234567890; do :; done");
866 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
867 EXPECT_STREQ("1234567890", output.c_str());
868 #else
869 argv.push_back("yes");
870 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
871 EXPECT_STREQ("y\ny\ny\ny\ny\n", output.c_str());
872 #endif
874 #endif
876 TEST_F(ProcessUtilTest, GetAppOutputRestrictedNoZombies) {
877 std::vector<std::string> argv;
879 argv.push_back(std::string(kShellPath)); // argv[0]
880 argv.push_back("-c"); // argv[1]
881 argv.push_back("echo 123456789012345678901234567890"); // argv[2]
883 // Run |GetAppOutputRestricted()| 300 (> default per-user processes on Mac OS
884 // 10.5) times with an output buffer big enough to capture all output.
885 for (int i = 0; i < 300; i++) {
886 std::string output;
887 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100));
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++) {
893 std::string output;
894 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10));
895 EXPECT_STREQ("1234567890", output.c_str());
899 TEST_F(ProcessUtilTest, GetAppOutputWithExitCode) {
900 // Test getting output from a successful application.
901 std::vector<std::string> argv;
902 std::string output;
903 int exit_code;
904 argv.push_back(std::string(kShellPath)); // argv[0]
905 argv.push_back("-c"); // argv[1]
906 argv.push_back("echo foo"); // argv[2];
907 EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv), &output,
908 &exit_code));
909 EXPECT_STREQ("foo\n", output.c_str());
910 EXPECT_EQ(exit_code, 0);
912 // Test getting output from an application which fails with a specific exit
913 // code.
914 output.clear();
915 argv[2] = "echo foo; exit 2";
916 EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv), &output,
917 &exit_code));
918 EXPECT_STREQ("foo\n", output.c_str());
919 EXPECT_EQ(exit_code, 2);
922 TEST_F(ProcessUtilTest, GetParentProcessId) {
923 base::ProcessId ppid = base::GetParentProcessId(base::GetCurrentProcId());
924 EXPECT_EQ(ppid, getppid());
927 #if defined(OS_LINUX) || defined(OS_ANDROID)
928 TEST_F(ProcessUtilTest, ParseProcStatCPU) {
929 // /proc/self/stat for a process running "top".
930 const char kTopStat[] = "960 (top) S 16230 960 16230 34818 960 "
931 "4202496 471 0 0 0 "
932 "12 16 0 0 " // <- These are the goods.
933 "20 0 1 0 121946157 15077376 314 18446744073709551615 4194304 "
934 "4246868 140733983044336 18446744073709551615 140244213071219 "
935 "0 0 0 138047495 0 0 0 17 1 0 0 0 0 0";
936 EXPECT_EQ(12 + 16, base::ParseProcStatCPU(kTopStat));
938 // cat /proc/self/stat on a random other machine I have.
939 const char kSelfStat[] = "5364 (cat) R 5354 5364 5354 34819 5364 "
940 "0 142 0 0 0 "
941 "0 0 0 0 " // <- No CPU, apparently.
942 "16 0 1 0 1676099790 2957312 114 4294967295 134512640 134528148 "
943 "3221224832 3221224344 3086339742 0 0 0 0 0 0 0 17 0 0 0";
945 EXPECT_EQ(0, base::ParseProcStatCPU(kSelfStat));
947 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
949 // TODO(port): port those unit tests.
950 bool IsProcessDead(base::ProcessHandle child) {
951 // waitpid() will actually reap the process which is exactly NOT what we
952 // want to test for. The good thing is that if it can't find the process
953 // we'll get a nice value for errno which we can test for.
954 const pid_t result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG));
955 return result == -1 && errno == ECHILD;
958 TEST_F(ProcessUtilTest, DelayedTermination) {
959 base::ProcessHandle child_process =
960 SpawnChild("process_util_test_never_die", false);
961 ASSERT_TRUE(child_process);
962 base::EnsureProcessTerminated(child_process);
963 base::WaitForSingleProcess(child_process, base::TimeDelta::FromSeconds(5));
965 // Check that process was really killed.
966 EXPECT_TRUE(IsProcessDead(child_process));
967 base::CloseProcessHandle(child_process);
970 MULTIPROCESS_TEST_MAIN(process_util_test_never_die) {
971 while (1) {
972 sleep(500);
974 return 0;
977 TEST_F(ProcessUtilTest, ImmediateTermination) {
978 base::ProcessHandle child_process =
979 SpawnChild("process_util_test_die_immediately", false);
980 ASSERT_TRUE(child_process);
981 // Give it time to die.
982 sleep(2);
983 base::EnsureProcessTerminated(child_process);
985 // Check that process was really killed.
986 EXPECT_TRUE(IsProcessDead(child_process));
987 base::CloseProcessHandle(child_process);
990 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately) {
991 return 0;
994 #endif // defined(OS_POSIX)
996 // Android doesn't implement set_new_handler, so we can't use the
997 // OutOfMemoryTest cases.
998 // OpenBSD does not support these tests either.
999 // AddressSanitizer defines the malloc()/free()/etc. functions so that they
1000 // don't crash if the program is out of memory, so the OOM tests aren't supposed
1001 // to work.
1002 // TODO(vandebo) make this work on Windows too.
1003 #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && \
1004 !defined(OS_WIN) && !defined(ADDRESS_SANITIZER)
1006 #if defined(USE_TCMALLOC)
1007 extern "C" {
1008 int tc_set_new_mode(int mode);
1010 #endif // defined(USE_TCMALLOC)
1012 class OutOfMemoryDeathTest : public testing::Test {
1013 public:
1014 OutOfMemoryDeathTest()
1015 : value_(NULL),
1016 // Make test size as large as possible minus a few pages so
1017 // that alignment or other rounding doesn't make it wrap.
1018 test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024),
1019 signed_test_size_(std::numeric_limits<ssize_t>::max()) {
1022 #if defined(USE_TCMALLOC)
1023 virtual void SetUp() OVERRIDE {
1024 tc_set_new_mode(1);
1027 virtual void TearDown() OVERRIDE {
1028 tc_set_new_mode(0);
1030 #endif // defined(USE_TCMALLOC)
1032 void SetUpInDeathAssert() {
1033 // Must call EnableTerminationOnOutOfMemory() because that is called from
1034 // chrome's main function and therefore hasn't been called yet.
1035 // Since this call may result in another thread being created and death
1036 // tests shouldn't be started in a multithread environment, this call
1037 // should be done inside of the ASSERT_DEATH.
1038 base::EnableTerminationOnOutOfMemory();
1041 void* value_;
1042 size_t test_size_;
1043 ssize_t signed_test_size_;
1046 TEST_F(OutOfMemoryDeathTest, New) {
1047 ASSERT_DEATH({
1048 SetUpInDeathAssert();
1049 value_ = operator new(test_size_);
1050 }, "");
1053 TEST_F(OutOfMemoryDeathTest, NewArray) {
1054 ASSERT_DEATH({
1055 SetUpInDeathAssert();
1056 value_ = new char[test_size_];
1057 }, "");
1060 TEST_F(OutOfMemoryDeathTest, Malloc) {
1061 ASSERT_DEATH({
1062 SetUpInDeathAssert();
1063 value_ = malloc(test_size_);
1064 }, "");
1067 TEST_F(OutOfMemoryDeathTest, Realloc) {
1068 ASSERT_DEATH({
1069 SetUpInDeathAssert();
1070 value_ = realloc(NULL, test_size_);
1071 }, "");
1074 TEST_F(OutOfMemoryDeathTest, Calloc) {
1075 ASSERT_DEATH({
1076 SetUpInDeathAssert();
1077 value_ = calloc(1024, test_size_ / 1024L);
1078 }, "");
1081 TEST_F(OutOfMemoryDeathTest, Valloc) {
1082 ASSERT_DEATH({
1083 SetUpInDeathAssert();
1084 value_ = valloc(test_size_);
1085 }, "");
1088 #if defined(OS_LINUX)
1089 TEST_F(OutOfMemoryDeathTest, Pvalloc) {
1090 ASSERT_DEATH({
1091 SetUpInDeathAssert();
1092 value_ = pvalloc(test_size_);
1093 }, "");
1096 TEST_F(OutOfMemoryDeathTest, Memalign) {
1097 ASSERT_DEATH({
1098 SetUpInDeathAssert();
1099 value_ = memalign(4, test_size_);
1100 }, "");
1103 TEST_F(OutOfMemoryDeathTest, ViaSharedLibraries) {
1104 // g_try_malloc is documented to return NULL on failure. (g_malloc is the
1105 // 'safe' default that crashes if allocation fails). However, since we have
1106 // hopefully overridden malloc, even g_try_malloc should fail. This tests
1107 // that the run-time symbol resolution is overriding malloc for shared
1108 // libraries as well as for our code.
1109 ASSERT_DEATH({
1110 SetUpInDeathAssert();
1111 value_ = g_try_malloc(test_size_);
1112 }, "");
1114 #endif // OS_LINUX
1116 // Android doesn't implement posix_memalign().
1117 #if defined(OS_POSIX) && !defined(OS_ANDROID)
1118 TEST_F(OutOfMemoryDeathTest, Posix_memalign) {
1119 // Grab the return value of posix_memalign to silence a compiler warning
1120 // about unused return values. We don't actually care about the return
1121 // value, since we're asserting death.
1122 ASSERT_DEATH({
1123 SetUpInDeathAssert();
1124 EXPECT_EQ(ENOMEM, posix_memalign(&value_, 8, test_size_));
1125 }, "");
1127 #endif // defined(OS_POSIX) && !defined(OS_ANDROID)
1129 #if defined(OS_MACOSX)
1131 // Purgeable zone tests
1133 TEST_F(OutOfMemoryDeathTest, MallocPurgeable) {
1134 malloc_zone_t* zone = malloc_default_purgeable_zone();
1135 ASSERT_DEATH({
1136 SetUpInDeathAssert();
1137 value_ = malloc_zone_malloc(zone, test_size_);
1138 }, "");
1141 TEST_F(OutOfMemoryDeathTest, ReallocPurgeable) {
1142 malloc_zone_t* zone = malloc_default_purgeable_zone();
1143 ASSERT_DEATH({
1144 SetUpInDeathAssert();
1145 value_ = malloc_zone_realloc(zone, NULL, test_size_);
1146 }, "");
1149 TEST_F(OutOfMemoryDeathTest, CallocPurgeable) {
1150 malloc_zone_t* zone = malloc_default_purgeable_zone();
1151 ASSERT_DEATH({
1152 SetUpInDeathAssert();
1153 value_ = malloc_zone_calloc(zone, 1024, test_size_ / 1024L);
1154 }, "");
1157 TEST_F(OutOfMemoryDeathTest, VallocPurgeable) {
1158 malloc_zone_t* zone = malloc_default_purgeable_zone();
1159 ASSERT_DEATH({
1160 SetUpInDeathAssert();
1161 value_ = malloc_zone_valloc(zone, test_size_);
1162 }, "");
1165 TEST_F(OutOfMemoryDeathTest, PosixMemalignPurgeable) {
1166 malloc_zone_t* zone = malloc_default_purgeable_zone();
1167 ASSERT_DEATH({
1168 SetUpInDeathAssert();
1169 value_ = malloc_zone_memalign(zone, 8, test_size_);
1170 }, "");
1173 // Since these allocation functions take a signed size, it's possible that
1174 // calling them just once won't be enough to exhaust memory. In the 32-bit
1175 // environment, it's likely that these allocation attempts will fail because
1176 // not enough contiguous address space is available. In the 64-bit environment,
1177 // it's likely that they'll fail because they would require a preposterous
1178 // amount of (virtual) memory.
1180 TEST_F(OutOfMemoryDeathTest, CFAllocatorSystemDefault) {
1181 ASSERT_DEATH({
1182 SetUpInDeathAssert();
1183 while ((value_ =
1184 base::AllocateViaCFAllocatorSystemDefault(signed_test_size_))) {}
1185 }, "");
1188 TEST_F(OutOfMemoryDeathTest, CFAllocatorMalloc) {
1189 ASSERT_DEATH({
1190 SetUpInDeathAssert();
1191 while ((value_ =
1192 base::AllocateViaCFAllocatorMalloc(signed_test_size_))) {}
1193 }, "");
1196 TEST_F(OutOfMemoryDeathTest, CFAllocatorMallocZone) {
1197 ASSERT_DEATH({
1198 SetUpInDeathAssert();
1199 while ((value_ =
1200 base::AllocateViaCFAllocatorMallocZone(signed_test_size_))) {}
1201 }, "");
1204 #if !defined(ARCH_CPU_64_BITS)
1206 // See process_util_unittest_mac.mm for an explanation of why this test isn't
1207 // run in the 64-bit environment.
1209 TEST_F(OutOfMemoryDeathTest, PsychoticallyBigObjCObject) {
1210 ASSERT_DEATH({
1211 SetUpInDeathAssert();
1212 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {}
1213 }, "");
1216 #endif // !ARCH_CPU_64_BITS
1217 #endif // OS_MACOSX
1219 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) &&
1220 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER)