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/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/threading/thread.h"
23 #include "base/utf_string_conversions.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "testing/multiprocess_func_list.h"
37 #include <sys/resource.h>
38 #include <sys/socket.h>
44 #if defined(OS_MACOSX)
45 #include <mach/vm_param.h>
46 #include <malloc/malloc.h>
47 #include "base/process_util_unittest_mac.h"
55 const wchar_t kProcessName
[] = L
"base_unittests.exe";
57 const wchar_t kProcessName
[] = L
"base_unittests";
58 #endif // defined(OS_WIN)
60 #if defined(OS_ANDROID)
61 const char kShellPath
[] = "/system/bin/sh";
62 const char kPosixShell
[] = "sh";
64 const char kShellPath
[] = "/bin/sh";
65 const char kPosixShell
[] = "bash";
68 const char kSignalFileSlow
[] = "SlowChildProcess.die";
69 const char kSignalFileCrash
[] = "CrashingChildProcess.die";
70 const char kSignalFileKill
[] = "KilledChildProcess.die";
73 const int kExpectedStillRunningExitCode
= 0x102;
74 const int kExpectedKilledExitCode
= 1;
76 const int kExpectedStillRunningExitCode
= 0;
80 // HeapQueryInformation function pointer.
81 typedef BOOL (WINAPI
* HeapQueryFn
) \
82 (HANDLE
, HEAP_INFORMATION_CLASS
, PVOID
, SIZE_T
, PSIZE_T
);
85 // Sleeps until file filename is created.
86 void WaitToDie(const char* filename
) {
89 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
90 fp
= fopen(filename
, "r");
95 // Signals children they should die now.
96 void SignalChildren(const char* filename
) {
97 FILE* fp
= fopen(filename
, "w");
101 // Using a pipe to the child to wait for an event was considered, but
102 // there were cases in the past where pipes caused problems (other
103 // libraries closing the fds, child deadlocking). This is a simple
104 // case, so it's not worth the risk. Using wait loops is discouraged
105 // in most instances.
106 base::TerminationStatus
WaitForChildTermination(base::ProcessHandle handle
,
108 // Now we wait until the result is something other than STILL_RUNNING.
109 base::TerminationStatus status
= base::TERMINATION_STATUS_STILL_RUNNING
;
110 const base::TimeDelta kInterval
= base::TimeDelta::FromMilliseconds(20);
111 base::TimeDelta waited
;
113 status
= base::GetTerminationStatus(handle
, exit_code
);
114 base::PlatformThread::Sleep(kInterval
);
116 } while (status
== base::TERMINATION_STATUS_STILL_RUNNING
&&
117 // Waiting for more time for process termination on android devices.
118 #if defined(OS_ANDROID)
119 waited
< TestTimeouts::large_test_timeout());
121 waited
< TestTimeouts::action_max_timeout());
129 class ProcessUtilTest
: public base::MultiProcessTest
{
131 #if defined(OS_POSIX)
132 // Spawn a child process that counts how many file descriptors are open.
133 int CountOpenFDsInChild();
135 // Converts the filename to a platform specific filepath.
136 // On Android files can not be created in arbitrary directories.
137 static std::string
GetSignalFilePath(const char* filename
);
140 std::string
ProcessUtilTest::GetSignalFilePath(const char* filename
) {
141 #if !defined(OS_ANDROID)
145 PathService::Get(base::DIR_CACHE
, &tmp_dir
);
146 tmp_dir
= tmp_dir
.Append(filename
);
147 return tmp_dir
.value();
151 MULTIPROCESS_TEST_MAIN(SimpleChildProcess
) {
155 TEST_F(ProcessUtilTest
, SpawnChild
) {
156 base::ProcessHandle handle
= this->SpawnChild("SimpleChildProcess", false);
157 ASSERT_NE(base::kNullProcessHandle
, handle
);
158 EXPECT_TRUE(base::WaitForSingleProcess(
159 handle
, TestTimeouts::action_max_timeout()));
160 base::CloseProcessHandle(handle
);
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::ProcessHandle handle
= this->SpawnChild("SlowChildProcess", false);
173 ASSERT_NE(base::kNullProcessHandle
, handle
);
174 SignalChildren(signal_file
.c_str());
175 EXPECT_TRUE(base::WaitForSingleProcess(
176 handle
, TestTimeouts::action_max_timeout()));
177 base::CloseProcessHandle(handle
);
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::ProcessHandle handle
= this->SpawnChild("SlowChildProcess", false);
187 ASSERT_NE(base::kNullProcessHandle
, handle
);
190 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING
,
191 base::GetTerminationStatus(handle
, &exit_code
));
192 EXPECT_EQ(kExpectedStillRunningExitCode
, exit_code
);
194 SignalChildren(signal_file
.c_str());
196 base::TerminationStatus status
=
197 WaitForChildTermination(handle
, &exit_code
);
198 EXPECT_EQ(base::TERMINATION_STATUS_NORMAL_TERMINATION
, status
);
199 EXPECT_EQ(0, exit_code
);
200 base::CloseProcessHandle(handle
);
201 remove(signal_file
.c_str());
205 // TODO(cpu): figure out how to test this in other platforms.
206 TEST_F(ProcessUtilTest
, GetProcId
) {
207 base::ProcessId id1
= base::GetProcId(GetCurrentProcess());
209 base::ProcessHandle handle
= this->SpawnChild("SimpleChildProcess", false);
210 ASSERT_NE(base::kNullProcessHandle
, handle
);
211 base::ProcessId id2
= base::GetProcId(handle
);
214 base::CloseProcessHandle(handle
);
217 TEST_F(ProcessUtilTest
, GetModuleFromAddress
) {
218 // Since the unit tests are their own EXE, this should be
219 // equivalent to the EXE's HINSTANCE.
221 // kExpectedKilledExitCode is a constant in this file and
222 // therefore within the unit test EXE.
223 EXPECT_EQ(::GetModuleHandle(NULL
),
224 base::GetModuleFromAddress(
225 const_cast<int*>(&kExpectedKilledExitCode
)));
227 // Any address within the kernel32 module should return
228 // kernel32's HMODULE. Our only assumption here is that
229 // kernel32 is larger than 4 bytes.
230 HMODULE kernel32
= ::GetModuleHandle(L
"kernel32.dll");
231 HMODULE kernel32_from_address
=
232 base::GetModuleFromAddress(reinterpret_cast<DWORD
*>(kernel32
) + 1);
233 EXPECT_EQ(kernel32
, kernel32_from_address
);
237 #if !defined(OS_MACOSX)
238 // This test is disabled on Mac, since it's flaky due to ReportCrash
239 // taking a variable amount of time to parse and load the debug and
240 // symbol data for this unit test's executable before firing the
243 // TODO(gspencer): turn this test process into a very small program
244 // with no symbols (instead of using the multiprocess testing
245 // framework) to reduce the ReportCrash overhead.
247 MULTIPROCESS_TEST_MAIN(CrashingChildProcess
) {
248 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileCrash
).c_str());
249 #if defined(OS_POSIX)
250 // Have to disable to signal handler for segv so we can get a crash
251 // instead of an abnormal termination through the crash dump handler.
252 ::signal(SIGSEGV
, SIG_DFL
);
254 // Make this process have a segmentation fault.
255 volatile int* oops
= NULL
;
260 // This test intentionally crashes, so we don't need to run it under
262 // TODO(jschuh): crbug.com/175753 Fix this in Win64 bots.
263 #if defined(ADDRESS_SANITIZER) || (defined(OS_WIN) && defined(ARCH_CPU_X86_64))
264 #define MAYBE_GetTerminationStatusCrash DISABLED_GetTerminationStatusCrash
266 #define MAYBE_GetTerminationStatusCrash GetTerminationStatusCrash
268 TEST_F(ProcessUtilTest
, MAYBE_GetTerminationStatusCrash
) {
269 const std::string signal_file
=
270 ProcessUtilTest::GetSignalFilePath(kSignalFileCrash
);
271 remove(signal_file
.c_str());
272 base::ProcessHandle handle
= this->SpawnChild("CrashingChildProcess",
274 ASSERT_NE(base::kNullProcessHandle
, handle
);
277 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING
,
278 base::GetTerminationStatus(handle
, &exit_code
));
279 EXPECT_EQ(kExpectedStillRunningExitCode
, exit_code
);
281 SignalChildren(signal_file
.c_str());
283 base::TerminationStatus status
=
284 WaitForChildTermination(handle
, &exit_code
);
285 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_CRASHED
, status
);
288 EXPECT_EQ(0xc0000005, exit_code
);
289 #elif defined(OS_POSIX)
290 int signaled
= WIFSIGNALED(exit_code
);
291 EXPECT_NE(0, signaled
);
292 int signal
= WTERMSIG(exit_code
);
293 EXPECT_EQ(SIGSEGV
, signal
);
295 base::CloseProcessHandle(handle
);
297 // Reset signal handlers back to "normal".
298 base::debug::EnableInProcessStackDumping();
299 remove(signal_file
.c_str());
301 #endif // !defined(OS_MACOSX)
303 MULTIPROCESS_TEST_MAIN(KilledChildProcess
) {
304 WaitToDie(ProcessUtilTest::GetSignalFilePath(kSignalFileKill
).c_str());
307 HANDLE handle
= ::OpenProcess(PROCESS_ALL_ACCESS
, 0, ::GetCurrentProcessId());
308 ::TerminateProcess(handle
, kExpectedKilledExitCode
);
309 #elif defined(OS_POSIX)
310 // Send a SIGKILL to this process, just like the OOM killer would.
311 ::kill(getpid(), SIGKILL
);
316 TEST_F(ProcessUtilTest
, GetTerminationStatusKill
) {
317 const std::string signal_file
=
318 ProcessUtilTest::GetSignalFilePath(kSignalFileKill
);
319 remove(signal_file
.c_str());
320 base::ProcessHandle handle
= this->SpawnChild("KilledChildProcess",
322 ASSERT_NE(base::kNullProcessHandle
, handle
);
325 EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING
,
326 base::GetTerminationStatus(handle
, &exit_code
));
327 EXPECT_EQ(kExpectedStillRunningExitCode
, exit_code
);
329 SignalChildren(signal_file
.c_str());
331 base::TerminationStatus status
=
332 WaitForChildTermination(handle
, &exit_code
);
333 EXPECT_EQ(base::TERMINATION_STATUS_PROCESS_WAS_KILLED
, status
);
335 EXPECT_EQ(kExpectedKilledExitCode
, exit_code
);
336 #elif defined(OS_POSIX)
337 int signaled
= WIFSIGNALED(exit_code
);
338 EXPECT_NE(0, signaled
);
339 int signal
= WTERMSIG(exit_code
);
340 EXPECT_EQ(SIGKILL
, signal
);
342 base::CloseProcessHandle(handle
);
343 remove(signal_file
.c_str());
346 // Ensure that the priority of a process is restored correctly after
347 // backgrounding and restoring.
348 // Note: a platform may not be willing or able to lower the priority of
349 // a process. The calls to SetProcessBackground should be noops then.
350 TEST_F(ProcessUtilTest
, SetProcessBackgrounded
) {
351 base::ProcessHandle handle
= this->SpawnChild("SimpleChildProcess", false);
352 base::Process
process(handle
);
353 int old_priority
= process
.GetPriority();
355 EXPECT_TRUE(process
.SetProcessBackgrounded(true));
356 EXPECT_TRUE(process
.IsProcessBackgrounded());
357 EXPECT_TRUE(process
.SetProcessBackgrounded(false));
358 EXPECT_FALSE(process
.IsProcessBackgrounded());
360 process
.SetProcessBackgrounded(true);
361 process
.SetProcessBackgrounded(false);
363 int new_priority
= process
.GetPriority();
364 EXPECT_EQ(old_priority
, new_priority
);
367 // Same as SetProcessBackgrounded but to this very process. It uses
368 // a different code path at least for Windows.
369 TEST_F(ProcessUtilTest
, SetProcessBackgroundedSelf
) {
370 base::Process
process(base::Process::Current().handle());
371 int old_priority
= process
.GetPriority();
373 EXPECT_TRUE(process
.SetProcessBackgrounded(true));
374 EXPECT_TRUE(process
.IsProcessBackgrounded());
375 EXPECT_TRUE(process
.SetProcessBackgrounded(false));
376 EXPECT_FALSE(process
.IsProcessBackgrounded());
378 process
.SetProcessBackgrounded(true);
379 process
.SetProcessBackgrounded(false);
381 int new_priority
= process
.GetPriority();
382 EXPECT_EQ(old_priority
, new_priority
);
385 #if defined(OS_LINUX) || defined(OS_ANDROID)
386 TEST_F(ProcessUtilTest
, GetSystemMemoryInfo
) {
387 base::SystemMemoryInfoKB info
;
388 EXPECT_TRUE(base::GetSystemMemoryInfo(&info
));
390 // Ensure each field received a value.
391 EXPECT_GT(info
.total
, 0);
392 EXPECT_GT(info
.free
, 0);
393 EXPECT_GT(info
.buffers
, 0);
394 EXPECT_GT(info
.cached
, 0);
395 EXPECT_GT(info
.active_anon
, 0);
396 EXPECT_GT(info
.inactive_anon
, 0);
397 EXPECT_GT(info
.active_file
, 0);
398 EXPECT_GT(info
.inactive_file
, 0);
400 // All the values should be less than the total amount of memory.
401 EXPECT_LT(info
.free
, info
.total
);
402 EXPECT_LT(info
.buffers
, info
.total
);
403 EXPECT_LT(info
.cached
, info
.total
);
404 EXPECT_LT(info
.active_anon
, info
.total
);
405 EXPECT_LT(info
.inactive_anon
, info
.total
);
406 EXPECT_LT(info
.active_file
, info
.total
);
407 EXPECT_LT(info
.inactive_file
, info
.total
);
409 #if defined(OS_CHROMEOS)
410 // Chrome OS exposes shmem.
411 EXPECT_GT(info
.shmem
, 0);
412 EXPECT_LT(info
.shmem
, info
.total
);
413 // Chrome unit tests are not run on actual Chrome OS hardware, so gem_objects
414 // and gem_size cannot be tested here.
417 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
419 // TODO(estade): if possible, port these 2 tests.
421 TEST_F(ProcessUtilTest
, EnableLFH
) {
422 ASSERT_TRUE(base::EnableLowFragmentationHeap());
423 if (IsDebuggerPresent()) {
424 // Under these conditions, LFH can't be enabled. There's no point to test
426 const char* no_debug_env
= getenv("_NO_DEBUG_HEAP");
427 if (!no_debug_env
|| strcmp(no_debug_env
, "1"))
430 HMODULE kernel32
= GetModuleHandle(L
"kernel32.dll");
431 ASSERT_TRUE(kernel32
!= NULL
);
432 HeapQueryFn heap_query
= reinterpret_cast<HeapQueryFn
>(GetProcAddress(
434 "HeapQueryInformation"));
436 // On Windows 2000, the function is not exported. This is not a reason to
437 // fail but we won't be able to retrieves information about the heap, so we
439 if (heap_query
== NULL
)
442 HANDLE heaps
[1024] = { 0 };
443 unsigned number_heaps
= GetProcessHeaps(1024, heaps
);
444 EXPECT_GT(number_heaps
, 0u);
445 for (unsigned i
= 0; i
< number_heaps
; ++i
) {
448 ASSERT_NE(0, heap_query(heaps
[i
],
449 HeapCompatibilityInformation
,
453 // If flag is 0, the heap is a standard heap that does not support
454 // look-asides. If flag is 1, the heap supports look-asides. If flag is 2,
455 // the heap is a low-fragmentation heap (LFH). Note that look-asides are not
456 // supported on the LFH.
458 // We don't have any documented way of querying the HEAP_NO_SERIALIZE flag.
464 TEST_F(ProcessUtilTest
, CalcFreeMemory
) {
465 scoped_ptr
<base::ProcessMetrics
> metrics(
466 base::ProcessMetrics::CreateProcessMetrics(::GetCurrentProcess()));
467 ASSERT_TRUE(NULL
!= metrics
.get());
469 // Typical values here is ~1900 for total and ~1000 for largest. Obviously
470 // it depends in what other tests have done to this process.
471 base::FreeMBytes free_mem1
= {0};
472 EXPECT_TRUE(metrics
->CalculateFreeMemory(&free_mem1
));
473 EXPECT_LT(10u, free_mem1
.total
);
474 EXPECT_LT(10u, free_mem1
.largest
);
475 EXPECT_GT(2048u, free_mem1
.total
);
476 EXPECT_GT(2048u, free_mem1
.largest
);
477 EXPECT_GE(free_mem1
.total
, free_mem1
.largest
);
478 EXPECT_TRUE(NULL
!= free_mem1
.largest_ptr
);
480 // Allocate 20M and check again. It should have gone down.
481 const int kAllocMB
= 20;
482 scoped_ptr
<char[]> alloc(new char[kAllocMB
* 1024 * 1024]);
483 size_t expected_total
= free_mem1
.total
- kAllocMB
;
484 size_t expected_largest
= free_mem1
.largest
;
486 base::FreeMBytes free_mem2
= {0};
487 EXPECT_TRUE(metrics
->CalculateFreeMemory(&free_mem2
));
488 EXPECT_GE(free_mem2
.total
, free_mem2
.largest
);
489 EXPECT_GE(expected_total
, free_mem2
.total
);
490 EXPECT_GE(expected_largest
, free_mem2
.largest
);
491 EXPECT_TRUE(NULL
!= free_mem2
.largest_ptr
);
494 TEST_F(ProcessUtilTest
, GetAppOutput
) {
495 // Let's create a decently long message.
497 for (int i
= 0; i
< 1025; i
++) { // 1025 so it does not end on a kilo-byte
501 // cmd.exe's echo always adds a \r\n to its output.
502 std::string
expected(message
);
505 FilePath
cmd(L
"cmd.exe");
506 CommandLine
cmd_line(cmd
);
507 cmd_line
.AppendArg("/c");
508 cmd_line
.AppendArg("echo " + message
+ "");
510 ASSERT_TRUE(base::GetAppOutput(cmd_line
, &output
));
511 EXPECT_EQ(expected
, output
);
513 // Let's make sure stderr is ignored.
514 CommandLine
other_cmd_line(cmd
);
515 other_cmd_line
.AppendArg("/c");
516 // http://msdn.microsoft.com/library/cc772622.aspx
517 cmd_line
.AppendArg("echo " + message
+ " >&2");
519 ASSERT_TRUE(base::GetAppOutput(other_cmd_line
, &output
));
520 EXPECT_EQ("", output
);
523 TEST_F(ProcessUtilTest
, LaunchAsUser
) {
524 base::UserTokenHandle token
;
525 ASSERT_TRUE(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS
, &token
));
526 std::wstring cmdline
=
527 this->MakeCmdLine("SimpleChildProcess", false).GetCommandLineString();
528 base::LaunchOptions options
;
529 options
.as_user
= token
;
530 EXPECT_TRUE(base::LaunchProcess(cmdline
, options
, NULL
));
533 #endif // defined(OS_WIN)
535 #if defined(OS_MACOSX)
537 // For the following Mac tests:
538 // Note that base::EnableTerminationOnHeapCorruption() is called as part of
539 // test suite setup and does not need to be done again, else mach_override
542 #if !defined(ADDRESS_SANITIZER)
543 // The following code tests the system implementation of malloc() thus no need
544 // to test it under AddressSanitizer.
545 TEST_F(ProcessUtilTest
, MacMallocFailureDoesNotTerminate
) {
546 // Test that ENOMEM doesn't crash via CrMallocErrorBreak two ways: the exit
547 // code and lack of the error string. The number of bytes is one less than
548 // MALLOC_ABSOLUTE_MAX_SIZE, more than which the system early-returns NULL and
549 // does not call through malloc_error_break(). See the comment at
550 // EnableTerminationOnOutOfMemory() for more information.
554 base::EnableTerminationOnOutOfMemory();
556 buf
= malloc(std::numeric_limits
<size_t>::max() - (2 * PAGE_SIZE
) - 1);
558 testing::KilledBySignal(SIGTRAP
),
559 "\\*\\*\\* error: can't allocate region.*"
560 "(Terminating process due to a potential for future heap "
563 base::debug::Alias(buf
);
565 #endif // !defined(ADDRESS_SANITIZER)
567 TEST_F(ProcessUtilTest
, MacTerminateOnHeapCorruption
) {
568 // Assert that freeing an unallocated pointer will crash the process.
570 asm("" : "=r" (buf
)); // Prevent clang from being too smart.
572 // On 64 bit Macs, the malloc system automatically abort()s on heap corruption
573 // but does not output anything.
574 ASSERT_DEATH(free(buf
), "");
575 #elif defined(ADDRESS_SANITIZER)
576 // AddressSanitizer replaces malloc() and prints a different error message on
578 ASSERT_DEATH(free(buf
), "attempting free on address which "
579 "was not malloc\\(\\)-ed");
581 ASSERT_DEATH(free(buf
), "being freed.*"
582 "\\*\\*\\* set a breakpoint in malloc_error_break to debug.*"
583 "Terminating process due to a potential for future heap corruption");
584 #endif // ARCH_CPU_64_BITS || defined(ADDRESS_SANITIZER)
587 #endif // defined(OS_MACOSX)
589 #if defined(OS_POSIX)
593 // Returns the maximum number of files that a process can have open.
594 // Returns 0 on error.
595 int GetMaxFilesOpenInProcess() {
597 if (getrlimit(RLIMIT_NOFILE
, &rlim
) != 0) {
601 // rlim_t is a uint64 - clip to maxint. We do this since FD #s are ints
602 // which are all 32 bits on the supported platforms.
603 rlim_t max_int
= static_cast<rlim_t
>(std::numeric_limits
<int32
>::max());
604 if (rlim
.rlim_cur
> max_int
) {
608 return rlim
.rlim_cur
;
611 const int kChildPipe
= 20; // FD # for write end of pipe in child process.
615 MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess
) {
616 // This child process counts the number of open FDs, it then writes that
617 // number out to a pipe connected to the parent.
618 int num_open_files
= 0;
619 int write_pipe
= kChildPipe
;
620 int max_files
= GetMaxFilesOpenInProcess();
621 for (int i
= STDERR_FILENO
+ 1; i
< max_files
; i
++) {
622 if (i
!= kChildPipe
) {
624 if ((fd
= HANDLE_EINTR(dup(i
))) != -1) {
631 int written
= HANDLE_EINTR(write(write_pipe
, &num_open_files
,
632 sizeof(num_open_files
)));
633 DCHECK_EQ(static_cast<size_t>(written
), sizeof(num_open_files
));
634 int ret
= HANDLE_EINTR(close(write_pipe
));
640 int ProcessUtilTest::CountOpenFDsInChild() {
645 base::FileHandleMappingVector fd_mapping_vec
;
646 fd_mapping_vec
.push_back(std::pair
<int, int>(fds
[1], kChildPipe
));
647 base::ProcessHandle handle
= this->SpawnChild(
648 "ProcessUtilsLeakFDChildProcess", fd_mapping_vec
, false);
650 int ret
= HANDLE_EINTR(close(fds
[1]));
653 // Read number of open files in client process from pipe;
654 int num_open_files
= -1;
656 HANDLE_EINTR(read(fds
[0], &num_open_files
, sizeof(num_open_files
)));
657 CHECK_EQ(bytes_read
, static_cast<ssize_t
>(sizeof(num_open_files
)));
659 #if defined(THREAD_SANITIZER) || defined(USE_HEAPCHECKER)
660 // Compiler-based ThreadSanitizer makes this test slow.
661 CHECK(base::WaitForSingleProcess(handle
, base::TimeDelta::FromSeconds(3)));
663 CHECK(base::WaitForSingleProcess(handle
, base::TimeDelta::FromSeconds(1)));
665 base::CloseProcessHandle(handle
);
666 ret
= HANDLE_EINTR(close(fds
[0]));
669 return num_open_files
;
672 #if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
673 // ProcessUtilTest.FDRemapping is flaky when ran under xvfb-run on Precise.
674 // The problem is 100% reproducible with both ASan and TSan.
675 // See http://crbug.com/136720.
676 #define MAYBE_FDRemapping DISABLED_FDRemapping
678 #define MAYBE_FDRemapping FDRemapping
680 TEST_F(ProcessUtilTest
, MAYBE_FDRemapping
) {
681 int fds_before
= CountOpenFDsInChild();
683 // open some dummy fds to make sure they don't propagate over to the
685 int dev_null
= open("/dev/null", O_RDONLY
);
687 socketpair(AF_UNIX
, SOCK_STREAM
, 0, sockets
);
689 int fds_after
= CountOpenFDsInChild();
691 ASSERT_EQ(fds_after
, fds_before
);
694 ret
= HANDLE_EINTR(close(sockets
[0]));
696 ret
= HANDLE_EINTR(close(sockets
[1]));
698 ret
= HANDLE_EINTR(close(dev_null
));
704 std::string
TestLaunchProcess(const base::EnvironmentVector
& env_changes
,
705 const int clone_flags
) {
706 std::vector
<std::string
> args
;
707 base::FileHandleMappingVector fds_to_remap
;
709 args
.push_back(kPosixShell
);
710 args
.push_back("-c");
711 args
.push_back("echo $BASE_TEST");
714 PCHECK(pipe(fds
) == 0);
716 fds_to_remap
.push_back(std::make_pair(fds
[1], 1));
717 base::LaunchOptions options
;
719 options
.environ
= &env_changes
;
720 options
.fds_to_remap
= &fds_to_remap
;
721 #if defined(OS_LINUX)
722 options
.clone_flags
= clone_flags
;
724 CHECK_EQ(0, clone_flags
);
726 EXPECT_TRUE(base::LaunchProcess(args
, options
, NULL
));
727 PCHECK(HANDLE_EINTR(close(fds
[1])) == 0);
730 const ssize_t n
= HANDLE_EINTR(read(fds
[0], buf
, sizeof(buf
)));
733 PCHECK(HANDLE_EINTR(close(fds
[0])) == 0);
735 return std::string(buf
, n
);
738 const char kLargeString
[] =
739 "0123456789012345678901234567890123456789012345678901234567890123456789"
740 "0123456789012345678901234567890123456789012345678901234567890123456789"
741 "0123456789012345678901234567890123456789012345678901234567890123456789"
742 "0123456789012345678901234567890123456789012345678901234567890123456789"
743 "0123456789012345678901234567890123456789012345678901234567890123456789"
744 "0123456789012345678901234567890123456789012345678901234567890123456789"
745 "0123456789012345678901234567890123456789012345678901234567890123456789";
749 TEST_F(ProcessUtilTest
, LaunchProcess
) {
750 base::EnvironmentVector env_changes
;
751 const int no_clone_flags
= 0;
753 env_changes
.push_back(std::make_pair(std::string("BASE_TEST"),
754 std::string("bar")));
755 EXPECT_EQ("bar\n", TestLaunchProcess(env_changes
, no_clone_flags
));
758 EXPECT_EQ(0, setenv("BASE_TEST", "testing", 1 /* override */));
759 EXPECT_EQ("testing\n", TestLaunchProcess(env_changes
, no_clone_flags
));
761 env_changes
.push_back(
762 std::make_pair(std::string("BASE_TEST"), std::string()));
763 EXPECT_EQ("\n", TestLaunchProcess(env_changes
, no_clone_flags
));
765 env_changes
[0].second
= "foo";
766 EXPECT_EQ("foo\n", TestLaunchProcess(env_changes
, no_clone_flags
));
769 EXPECT_EQ(0, setenv("BASE_TEST", kLargeString
, 1 /* override */));
770 EXPECT_EQ(std::string(kLargeString
) + "\n",
771 TestLaunchProcess(env_changes
, no_clone_flags
));
773 env_changes
.push_back(std::make_pair(std::string("BASE_TEST"),
774 std::string("wibble")));
775 EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes
, no_clone_flags
));
777 #if defined(OS_LINUX)
778 // Test a non-trival value for clone_flags.
779 // Don't test on Valgrind as it has limited support for clone().
780 if (!RunningOnValgrind()) {
781 EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes
, CLONE_FS
| SIGCHLD
));
786 TEST_F(ProcessUtilTest
, AlterEnvironment
) {
787 const char* const empty
[] = { NULL
};
788 const char* const a2
[] = { "A=2", NULL
};
789 base::EnvironmentVector changes
;
792 e
= base::AlterEnvironment(changes
, empty
);
793 EXPECT_TRUE(e
[0] == NULL
);
796 changes
.push_back(std::make_pair(std::string("A"), std::string("1")));
797 e
= base::AlterEnvironment(changes
, empty
);
798 EXPECT_EQ(std::string("A=1"), e
[0]);
799 EXPECT_TRUE(e
[1] == NULL
);
803 changes
.push_back(std::make_pair(std::string("A"), std::string()));
804 e
= base::AlterEnvironment(changes
, empty
);
805 EXPECT_TRUE(e
[0] == NULL
);
809 e
= base::AlterEnvironment(changes
, a2
);
810 EXPECT_EQ(std::string("A=2"), e
[0]);
811 EXPECT_TRUE(e
[1] == NULL
);
815 changes
.push_back(std::make_pair(std::string("A"), std::string("1")));
816 e
= base::AlterEnvironment(changes
, a2
);
817 EXPECT_EQ(std::string("A=1"), e
[0]);
818 EXPECT_TRUE(e
[1] == NULL
);
822 changes
.push_back(std::make_pair(std::string("A"), std::string()));
823 e
= base::AlterEnvironment(changes
, a2
);
824 EXPECT_TRUE(e
[0] == NULL
);
828 TEST_F(ProcessUtilTest
, GetAppOutput
) {
831 #if defined(OS_ANDROID)
832 std::vector
<std::string
> argv
;
833 argv
.push_back("sh"); // Instead of /bin/sh, force path search to find it.
834 argv
.push_back("-c");
836 argv
.push_back("exit 0");
837 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv
), &output
));
838 EXPECT_STREQ("", output
.c_str());
841 EXPECT_FALSE(base::GetAppOutput(CommandLine(argv
), &output
));
842 EXPECT_STREQ("", output
.c_str());
844 argv
[2] = "echo foobar42";
845 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv
), &output
));
846 EXPECT_STREQ("foobar42\n", output
.c_str());
848 EXPECT_TRUE(base::GetAppOutput(CommandLine(FilePath("true")), &output
));
849 EXPECT_STREQ("", output
.c_str());
851 EXPECT_FALSE(base::GetAppOutput(CommandLine(FilePath("false")), &output
));
853 std::vector
<std::string
> argv
;
854 argv
.push_back("/bin/echo");
855 argv
.push_back("-n");
856 argv
.push_back("foobar42");
857 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv
), &output
));
858 EXPECT_STREQ("foobar42", output
.c_str());
859 #endif // defined(OS_ANDROID)
862 TEST_F(ProcessUtilTest
, GetAppOutputRestricted
) {
863 // Unfortunately, since we can't rely on the path, we need to know where
864 // everything is. So let's use /bin/sh, which is on every POSIX system, and
866 std::vector
<std::string
> argv
;
867 argv
.push_back(std::string(kShellPath
)); // argv[0]
868 argv
.push_back("-c"); // argv[1]
870 // On success, should set |output|. We use |/bin/sh -c 'exit 0'| instead of
871 // |true| since the location of the latter may be |/bin| or |/usr/bin| (and we
872 // need absolute paths).
873 argv
.push_back("exit 0"); // argv[2]; equivalent to "true"
874 std::string output
= "abc";
875 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 100));
876 EXPECT_STREQ("", output
.c_str());
878 argv
[2] = "exit 1"; // equivalent to "false"
880 EXPECT_FALSE(base::GetAppOutputRestricted(CommandLine(argv
),
882 EXPECT_STREQ("", output
.c_str());
884 // Amount of output exactly equal to space allowed.
885 argv
[2] = "echo 123456789"; // (the sh built-in doesn't take "-n")
887 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 10));
888 EXPECT_STREQ("123456789\n", output
.c_str());
890 // Amount of output greater than space allowed.
892 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 5));
893 EXPECT_STREQ("12345", output
.c_str());
895 // Amount of output less than space allowed.
897 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 15));
898 EXPECT_STREQ("123456789\n", output
.c_str());
900 // Zero space allowed.
902 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 0));
903 EXPECT_STREQ("", output
.c_str());
906 #if !defined(OS_MACOSX) && !defined(OS_OPENBSD)
907 // TODO(benwells): GetAppOutputRestricted should terminate applications
908 // with SIGPIPE when we have enough output. http://crbug.com/88502
909 TEST_F(ProcessUtilTest
, GetAppOutputRestrictedSIGPIPE
) {
910 std::vector
<std::string
> argv
;
913 argv
.push_back(std::string(kShellPath
)); // argv[0]
914 argv
.push_back("-c");
915 #if defined(OS_ANDROID)
916 argv
.push_back("while echo 12345678901234567890; do :; done");
917 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 10));
918 EXPECT_STREQ("1234567890", output
.c_str());
920 argv
.push_back("yes");
921 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 10));
922 EXPECT_STREQ("y\ny\ny\ny\ny\n", output
.c_str());
927 TEST_F(ProcessUtilTest
, GetAppOutputRestrictedNoZombies
) {
928 std::vector
<std::string
> argv
;
930 argv
.push_back(std::string(kShellPath
)); // argv[0]
931 argv
.push_back("-c"); // argv[1]
932 argv
.push_back("echo 123456789012345678901234567890"); // argv[2]
934 // Run |GetAppOutputRestricted()| 300 (> default per-user processes on Mac OS
935 // 10.5) times with an output buffer big enough to capture all output.
936 for (int i
= 0; i
< 300; i
++) {
938 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 100));
939 EXPECT_STREQ("123456789012345678901234567890\n", output
.c_str());
942 // Ditto, but with an output buffer too small to capture all output.
943 for (int i
= 0; i
< 300; i
++) {
945 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv
), &output
, 10));
946 EXPECT_STREQ("1234567890", output
.c_str());
950 TEST_F(ProcessUtilTest
, GetAppOutputWithExitCode
) {
951 // Test getting output from a successful application.
952 std::vector
<std::string
> argv
;
955 argv
.push_back(std::string(kShellPath
)); // argv[0]
956 argv
.push_back("-c"); // argv[1]
957 argv
.push_back("echo foo"); // argv[2];
958 EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv
), &output
,
960 EXPECT_STREQ("foo\n", output
.c_str());
961 EXPECT_EQ(exit_code
, 0);
963 // Test getting output from an application which fails with a specific exit
966 argv
[2] = "echo foo; exit 2";
967 EXPECT_TRUE(base::GetAppOutputWithExitCode(CommandLine(argv
), &output
,
969 EXPECT_STREQ("foo\n", output
.c_str());
970 EXPECT_EQ(exit_code
, 2);
973 TEST_F(ProcessUtilTest
, GetParentProcessId
) {
974 base::ProcessId ppid
= base::GetParentProcessId(base::GetCurrentProcId());
975 EXPECT_EQ(ppid
, getppid());
978 #if defined(OS_LINUX) || defined(OS_ANDROID)
979 TEST_F(ProcessUtilTest
, ParseProcStatCPU
) {
980 // /proc/self/stat for a process running "top".
981 const char kTopStat
[] = "960 (top) S 16230 960 16230 34818 960 "
983 "12 16 0 0 " // <- These are the goods.
984 "20 0 1 0 121946157 15077376 314 18446744073709551615 4194304 "
985 "4246868 140733983044336 18446744073709551615 140244213071219 "
986 "0 0 0 138047495 0 0 0 17 1 0 0 0 0 0";
987 EXPECT_EQ(12 + 16, base::ParseProcStatCPU(kTopStat
));
989 // cat /proc/self/stat on a random other machine I have.
990 const char kSelfStat
[] = "5364 (cat) R 5354 5364 5354 34819 5364 "
992 "0 0 0 0 " // <- No CPU, apparently.
993 "16 0 1 0 1676099790 2957312 114 4294967295 134512640 134528148 "
994 "3221224832 3221224344 3086339742 0 0 0 0 0 0 0 17 0 0 0";
996 EXPECT_EQ(0, base::ParseProcStatCPU(kSelfStat
));
999 // Disable on Android because base_unittests runs inside a Dalvik VM that
1000 // starts and stop threads (crbug.com/175563).
1001 #if !defined(OS_ANDROID)
1002 TEST_F(ProcessUtilTest
, GetNumberOfThreads
) {
1003 const base::ProcessHandle current
= base::GetCurrentProcessHandle();
1004 const int initial_threads
= base::GetNumberOfThreads(current
);
1005 ASSERT_GT(initial_threads
, 0);
1006 const int kNumAdditionalThreads
= 10;
1008 scoped_ptr
<base::Thread
> my_threads
[kNumAdditionalThreads
];
1009 for (int i
= 0; i
< kNumAdditionalThreads
; ++i
) {
1010 my_threads
[i
].reset(new base::Thread("GetNumberOfThreadsTest"));
1011 my_threads
[i
]->Start();
1012 ASSERT_EQ(base::GetNumberOfThreads(current
), initial_threads
+ 1 + i
);
1015 // The Thread destructor will stop them.
1016 ASSERT_EQ(initial_threads
, base::GetNumberOfThreads(current
));
1018 #endif // !defined(OS_ANDROID)
1020 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
1022 // TODO(port): port those unit tests.
1023 bool IsProcessDead(base::ProcessHandle child
) {
1024 // waitpid() will actually reap the process which is exactly NOT what we
1025 // want to test for. The good thing is that if it can't find the process
1026 // we'll get a nice value for errno which we can test for.
1027 const pid_t result
= HANDLE_EINTR(waitpid(child
, NULL
, WNOHANG
));
1028 return result
== -1 && errno
== ECHILD
;
1031 TEST_F(ProcessUtilTest
, DelayedTermination
) {
1032 base::ProcessHandle child_process
=
1033 SpawnChild("process_util_test_never_die", false);
1034 ASSERT_TRUE(child_process
);
1035 base::EnsureProcessTerminated(child_process
);
1036 base::WaitForSingleProcess(child_process
, base::TimeDelta::FromSeconds(5));
1038 // Check that process was really killed.
1039 EXPECT_TRUE(IsProcessDead(child_process
));
1040 base::CloseProcessHandle(child_process
);
1043 MULTIPROCESS_TEST_MAIN(process_util_test_never_die
) {
1050 TEST_F(ProcessUtilTest
, ImmediateTermination
) {
1051 base::ProcessHandle child_process
=
1052 SpawnChild("process_util_test_die_immediately", false);
1053 ASSERT_TRUE(child_process
);
1054 // Give it time to die.
1056 base::EnsureProcessTerminated(child_process
);
1058 // Check that process was really killed.
1059 EXPECT_TRUE(IsProcessDead(child_process
));
1060 base::CloseProcessHandle(child_process
);
1063 MULTIPROCESS_TEST_MAIN(process_util_test_die_immediately
) {
1067 #endif // defined(OS_POSIX)
1069 // Android doesn't implement set_new_handler, so we can't use the
1070 // OutOfMemoryTest cases.
1071 // OpenBSD does not support these tests either.
1072 // AddressSanitizer defines the malloc()/free()/etc. functions so that they
1073 // don't crash if the program is out of memory, so the OOM tests aren't supposed
1075 // TODO(vandebo) make this work on Windows too.
1076 #if !defined(OS_ANDROID) && !defined(OS_OPENBSD) && \
1077 !defined(OS_WIN) && !defined(ADDRESS_SANITIZER)
1079 #if defined(USE_TCMALLOC)
1081 int tc_set_new_mode(int mode
);
1083 #endif // defined(USE_TCMALLOC)
1085 class OutOfMemoryDeathTest
: public testing::Test
{
1087 OutOfMemoryDeathTest()
1089 // Make test size as large as possible minus a few pages so
1090 // that alignment or other rounding doesn't make it wrap.
1091 test_size_(std::numeric_limits
<std::size_t>::max() - 12 * 1024),
1092 signed_test_size_(std::numeric_limits
<ssize_t
>::max()) {
1095 #if defined(USE_TCMALLOC)
1096 virtual void SetUp() OVERRIDE
{
1100 virtual void TearDown() OVERRIDE
{
1103 #endif // defined(USE_TCMALLOC)
1105 void SetUpInDeathAssert() {
1106 // Must call EnableTerminationOnOutOfMemory() because that is called from
1107 // chrome's main function and therefore hasn't been called yet.
1108 // Since this call may result in another thread being created and death
1109 // tests shouldn't be started in a multithread environment, this call
1110 // should be done inside of the ASSERT_DEATH.
1111 base::EnableTerminationOnOutOfMemory();
1116 ssize_t signed_test_size_
;
1119 TEST_F(OutOfMemoryDeathTest
, New
) {
1121 SetUpInDeathAssert();
1122 value_
= operator new(test_size_
);
1126 TEST_F(OutOfMemoryDeathTest
, NewArray
) {
1128 SetUpInDeathAssert();
1129 value_
= new char[test_size_
];
1133 TEST_F(OutOfMemoryDeathTest
, Malloc
) {
1135 SetUpInDeathAssert();
1136 value_
= malloc(test_size_
);
1140 TEST_F(OutOfMemoryDeathTest
, Realloc
) {
1142 SetUpInDeathAssert();
1143 value_
= realloc(NULL
, test_size_
);
1147 TEST_F(OutOfMemoryDeathTest
, Calloc
) {
1149 SetUpInDeathAssert();
1150 value_
= calloc(1024, test_size_
/ 1024L);
1154 TEST_F(OutOfMemoryDeathTest
, Valloc
) {
1156 SetUpInDeathAssert();
1157 value_
= valloc(test_size_
);
1161 #if defined(OS_LINUX)
1162 TEST_F(OutOfMemoryDeathTest
, Pvalloc
) {
1164 SetUpInDeathAssert();
1165 value_
= pvalloc(test_size_
);
1169 TEST_F(OutOfMemoryDeathTest
, Memalign
) {
1171 SetUpInDeathAssert();
1172 value_
= memalign(4, test_size_
);
1176 TEST_F(OutOfMemoryDeathTest
, ViaSharedLibraries
) {
1177 // g_try_malloc is documented to return NULL on failure. (g_malloc is the
1178 // 'safe' default that crashes if allocation fails). However, since we have
1179 // hopefully overridden malloc, even g_try_malloc should fail. This tests
1180 // that the run-time symbol resolution is overriding malloc for shared
1181 // libraries as well as for our code.
1183 SetUpInDeathAssert();
1184 value_
= g_try_malloc(test_size_
);
1189 // Android doesn't implement posix_memalign().
1190 #if defined(OS_POSIX) && !defined(OS_ANDROID)
1191 TEST_F(OutOfMemoryDeathTest
, Posix_memalign
) {
1192 // Grab the return value of posix_memalign to silence a compiler warning
1193 // about unused return values. We don't actually care about the return
1194 // value, since we're asserting death.
1196 SetUpInDeathAssert();
1197 EXPECT_EQ(ENOMEM
, posix_memalign(&value_
, 8, test_size_
));
1200 #endif // defined(OS_POSIX) && !defined(OS_ANDROID)
1202 #if defined(OS_MACOSX)
1204 // Purgeable zone tests
1206 TEST_F(OutOfMemoryDeathTest
, MallocPurgeable
) {
1207 malloc_zone_t
* zone
= malloc_default_purgeable_zone();
1209 SetUpInDeathAssert();
1210 value_
= malloc_zone_malloc(zone
, test_size_
);
1214 TEST_F(OutOfMemoryDeathTest
, ReallocPurgeable
) {
1215 malloc_zone_t
* zone
= malloc_default_purgeable_zone();
1217 SetUpInDeathAssert();
1218 value_
= malloc_zone_realloc(zone
, NULL
, test_size_
);
1222 TEST_F(OutOfMemoryDeathTest
, CallocPurgeable
) {
1223 malloc_zone_t
* zone
= malloc_default_purgeable_zone();
1225 SetUpInDeathAssert();
1226 value_
= malloc_zone_calloc(zone
, 1024, test_size_
/ 1024L);
1230 TEST_F(OutOfMemoryDeathTest
, VallocPurgeable
) {
1231 malloc_zone_t
* zone
= malloc_default_purgeable_zone();
1233 SetUpInDeathAssert();
1234 value_
= malloc_zone_valloc(zone
, test_size_
);
1238 TEST_F(OutOfMemoryDeathTest
, PosixMemalignPurgeable
) {
1239 malloc_zone_t
* zone
= malloc_default_purgeable_zone();
1241 SetUpInDeathAssert();
1242 value_
= malloc_zone_memalign(zone
, 8, test_size_
);
1246 // Since these allocation functions take a signed size, it's possible that
1247 // calling them just once won't be enough to exhaust memory. In the 32-bit
1248 // environment, it's likely that these allocation attempts will fail because
1249 // not enough contiguous address space is available. In the 64-bit environment,
1250 // it's likely that they'll fail because they would require a preposterous
1251 // amount of (virtual) memory.
1253 TEST_F(OutOfMemoryDeathTest
, CFAllocatorSystemDefault
) {
1255 SetUpInDeathAssert();
1257 base::AllocateViaCFAllocatorSystemDefault(signed_test_size_
))) {}
1261 TEST_F(OutOfMemoryDeathTest
, CFAllocatorMalloc
) {
1263 SetUpInDeathAssert();
1265 base::AllocateViaCFAllocatorMalloc(signed_test_size_
))) {}
1269 TEST_F(OutOfMemoryDeathTest
, CFAllocatorMallocZone
) {
1271 SetUpInDeathAssert();
1273 base::AllocateViaCFAllocatorMallocZone(signed_test_size_
))) {}
1277 #if !defined(ARCH_CPU_64_BITS)
1279 // See process_util_unittest_mac.mm for an explanation of why this test isn't
1280 // run in the 64-bit environment.
1282 TEST_F(OutOfMemoryDeathTest
, PsychoticallyBigObjCObject
) {
1284 SetUpInDeathAssert();
1285 while ((value_
= base::AllocatePsychoticallyBigObjCObject())) {}
1289 #endif // !ARCH_CPU_64_BITS
1292 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) &&
1293 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER)