process_util_unittest.cc revision 201ade2fbba22bfb27ae029f4d23fca6ded109a0
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#define _CRT_SECURE_NO_WARNINGS 6 7#include <limits> 8 9#include "base/command_line.h" 10#include "base/eintr_wrapper.h" 11#include "base/file_path.h" 12#include "base/logging.h" 13#include "base/path_service.h" 14#include "base/platform_thread.h" 15#include "base/process_util.h" 16#include "base/scoped_ptr.h" 17#include "base/test/multiprocess_test.h" 18#include "base/utf_string_conversions.h" 19#include "testing/gtest/include/gtest/gtest.h" 20#include "testing/multiprocess_func_list.h" 21 22#if defined(OS_LINUX) 23#include <errno.h> 24#include <malloc.h> 25#include <glib.h> 26#endif 27#if defined(OS_POSIX) 28#include <dlfcn.h> 29#include <fcntl.h> 30#include <sys/resource.h> 31#include <sys/socket.h> 32#endif 33#if defined(OS_WIN) 34#include <windows.h> 35#endif 36#if defined(OS_MACOSX) 37#include <malloc/malloc.h> 38#include "base/process_util_unittest_mac.h" 39#endif 40 41namespace { 42 43#if defined(OS_WIN) 44const wchar_t* const kProcessName = L"base_unittests.exe"; 45#else 46const wchar_t* const kProcessName = L"base_unittests"; 47#endif // defined(OS_WIN) 48 49// Sleeps until file filename is created. 50void WaitToDie(const char* filename) { 51 FILE *fp; 52 do { 53 PlatformThread::Sleep(10); 54 fp = fopen(filename, "r"); 55 } while (!fp); 56 fclose(fp); 57} 58 59// Signals children they should die now. 60void SignalChildren(const char* filename) { 61 FILE *fp = fopen(filename, "w"); 62 fclose(fp); 63} 64 65} // namespace 66 67class ProcessUtilTest : public base::MultiProcessTest { 68#if defined(OS_POSIX) 69 public: 70 // Spawn a child process that counts how many file descriptors are open. 71 int CountOpenFDsInChild(); 72#endif 73}; 74 75MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { 76 return 0; 77} 78 79TEST_F(ProcessUtilTest, SpawnChild) { 80 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); 81 ASSERT_NE(base::kNullProcessHandle, handle); 82 EXPECT_TRUE(base::WaitForSingleProcess(handle, 5000)); 83 base::CloseProcessHandle(handle); 84} 85 86MULTIPROCESS_TEST_MAIN(SlowChildProcess) { 87 WaitToDie("SlowChildProcess.die"); 88 return 0; 89} 90 91TEST_F(ProcessUtilTest, KillSlowChild) { 92 remove("SlowChildProcess.die"); 93 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false); 94 ASSERT_NE(base::kNullProcessHandle, handle); 95 SignalChildren("SlowChildProcess.die"); 96 EXPECT_TRUE(base::WaitForSingleProcess(handle, 5000)); 97 base::CloseProcessHandle(handle); 98 remove("SlowChildProcess.die"); 99} 100 101TEST_F(ProcessUtilTest, DidProcessCrash) { 102 remove("SlowChildProcess.die"); 103 base::ProcessHandle handle = this->SpawnChild("SlowChildProcess", false); 104 ASSERT_NE(base::kNullProcessHandle, handle); 105 106 bool child_exited = true; 107 EXPECT_FALSE(base::DidProcessCrash(&child_exited, handle)); 108 EXPECT_FALSE(child_exited); 109 110 SignalChildren("SlowChildProcess.die"); 111 EXPECT_TRUE(base::WaitForSingleProcess(handle, 5000)); 112 113 EXPECT_FALSE(base::DidProcessCrash(&child_exited, handle)); 114 base::CloseProcessHandle(handle); 115 remove("SlowChildProcess.die"); 116} 117 118// Ensure that the priority of a process is restored correctly after 119// backgrounding and restoring. 120// Note: a platform may not be willing or able to lower the priority of 121// a process. The calls to SetProcessBackground should be noops then. 122TEST_F(ProcessUtilTest, SetProcessBackgrounded) { 123 base::ProcessHandle handle = this->SpawnChild("SimpleChildProcess", false); 124 base::Process process(handle); 125 int old_priority = process.GetPriority(); 126 process.SetProcessBackgrounded(true); 127 process.SetProcessBackgrounded(false); 128 int new_priority = process.GetPriority(); 129 EXPECT_EQ(old_priority, new_priority); 130} 131 132// TODO(estade): if possible, port these 2 tests. 133#if defined(OS_WIN) 134TEST_F(ProcessUtilTest, EnableLFH) { 135 ASSERT_TRUE(base::EnableLowFragmentationHeap()); 136 if (IsDebuggerPresent()) { 137 // Under these conditions, LFH can't be enabled. There's no point to test 138 // anything. 139 const char* no_debug_env = getenv("_NO_DEBUG_HEAP"); 140 if (!no_debug_env || strcmp(no_debug_env, "1")) 141 return; 142 } 143 HANDLE heaps[1024] = { 0 }; 144 unsigned number_heaps = GetProcessHeaps(1024, heaps); 145 EXPECT_GT(number_heaps, 0u); 146 for (unsigned i = 0; i < number_heaps; ++i) { 147 ULONG flag = 0; 148 SIZE_T length; 149 ASSERT_NE(0, HeapQueryInformation(heaps[i], 150 HeapCompatibilityInformation, 151 &flag, 152 sizeof(flag), 153 &length)); 154 // If flag is 0, the heap is a standard heap that does not support 155 // look-asides. If flag is 1, the heap supports look-asides. If flag is 2, 156 // the heap is a low-fragmentation heap (LFH). Note that look-asides are not 157 // supported on the LFH. 158 159 // We don't have any documented way of querying the HEAP_NO_SERIALIZE flag. 160 EXPECT_LE(flag, 2u); 161 EXPECT_NE(flag, 1u); 162 } 163} 164 165TEST_F(ProcessUtilTest, CalcFreeMemory) { 166 scoped_ptr<base::ProcessMetrics> metrics( 167 base::ProcessMetrics::CreateProcessMetrics(::GetCurrentProcess())); 168 ASSERT_TRUE(NULL != metrics.get()); 169 170 // Typical values here is ~1900 for total and ~1000 for largest. Obviously 171 // it depends in what other tests have done to this process. 172 base::FreeMBytes free_mem1 = {0}; 173 EXPECT_TRUE(metrics->CalculateFreeMemory(&free_mem1)); 174 EXPECT_LT(10u, free_mem1.total); 175 EXPECT_LT(10u, free_mem1.largest); 176 EXPECT_GT(2048u, free_mem1.total); 177 EXPECT_GT(2048u, free_mem1.largest); 178 EXPECT_GE(free_mem1.total, free_mem1.largest); 179 EXPECT_TRUE(NULL != free_mem1.largest_ptr); 180 181 // Allocate 20M and check again. It should have gone down. 182 const int kAllocMB = 20; 183 scoped_array<char> alloc(new char[kAllocMB * 1024 * 1024]); 184 size_t expected_total = free_mem1.total - kAllocMB; 185 size_t expected_largest = free_mem1.largest; 186 187 base::FreeMBytes free_mem2 = {0}; 188 EXPECT_TRUE(metrics->CalculateFreeMemory(&free_mem2)); 189 EXPECT_GE(free_mem2.total, free_mem2.largest); 190 EXPECT_GE(expected_total, free_mem2.total); 191 EXPECT_GE(expected_largest, free_mem2.largest); 192 EXPECT_TRUE(NULL != free_mem2.largest_ptr); 193} 194 195TEST_F(ProcessUtilTest, GetAppOutput) { 196 // Let's create a decently long message. 197 std::string message; 198 for (int i = 0; i < 1025; i++) { // 1025 so it does not end on a kilo-byte 199 // boundary. 200 message += "Hello!"; 201 } 202 203 FilePath python_runtime; 204 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &python_runtime)); 205 python_runtime = python_runtime.Append(FILE_PATH_LITERAL("third_party")) 206 .Append(FILE_PATH_LITERAL("python_26")) 207 .Append(FILE_PATH_LITERAL("python.exe")); 208 209 CommandLine cmd_line(python_runtime); 210 cmd_line.AppendArg("-c"); 211 cmd_line.AppendArg("import sys; sys.stdout.write('" + message + "');"); 212 std::string output; 213 ASSERT_TRUE(base::GetAppOutput(cmd_line, &output)); 214 EXPECT_EQ(message, output); 215 216 // Let's make sure stderr is ignored. 217 CommandLine other_cmd_line(python_runtime); 218 other_cmd_line.AppendArg("-c"); 219 other_cmd_line.AppendArg("import sys; sys.stderr.write('Hello!');"); 220 output.clear(); 221 ASSERT_TRUE(base::GetAppOutput(other_cmd_line, &output)); 222 EXPECT_EQ("", output); 223} 224 225TEST_F(ProcessUtilTest, LaunchAsUser) { 226 base::UserTokenHandle token; 227 ASSERT_TRUE(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)); 228 std::wstring cmdline = 229 this->MakeCmdLine("SimpleChildProcess", false).command_line_string(); 230 EXPECT_TRUE(base::LaunchAppAsUser(token, cmdline, false, NULL)); 231} 232 233#endif // defined(OS_WIN) 234 235#if defined(OS_POSIX) 236 237namespace { 238 239// Returns the maximum number of files that a process can have open. 240// Returns 0 on error. 241int GetMaxFilesOpenInProcess() { 242 struct rlimit rlim; 243 if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { 244 return 0; 245 } 246 247 // rlim_t is a uint64 - clip to maxint. We do this since FD #s are ints 248 // which are all 32 bits on the supported platforms. 249 rlim_t max_int = static_cast<rlim_t>(std::numeric_limits<int32>::max()); 250 if (rlim.rlim_cur > max_int) { 251 return max_int; 252 } 253 254 return rlim.rlim_cur; 255} 256 257const int kChildPipe = 20; // FD # for write end of pipe in child process. 258 259} // namespace 260 261MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) { 262 // This child process counts the number of open FDs, it then writes that 263 // number out to a pipe connected to the parent. 264 int num_open_files = 0; 265 int write_pipe = kChildPipe; 266 int max_files = GetMaxFilesOpenInProcess(); 267 for (int i = STDERR_FILENO + 1; i < max_files; i++) { 268 if (i != kChildPipe) { 269 int fd; 270 if ((fd = HANDLE_EINTR(dup(i))) != -1) { 271 close(fd); 272 num_open_files += 1; 273 } 274 } 275 } 276 277 int written = HANDLE_EINTR(write(write_pipe, &num_open_files, 278 sizeof(num_open_files))); 279 DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files)); 280 int ret = HANDLE_EINTR(close(write_pipe)); 281 DPCHECK(ret == 0); 282 283 return 0; 284} 285 286int ProcessUtilTest::CountOpenFDsInChild() { 287 int fds[2]; 288 if (pipe(fds) < 0) 289 NOTREACHED(); 290 291 base::file_handle_mapping_vector fd_mapping_vec; 292 fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe)); 293 base::ProcessHandle handle = this->SpawnChild( 294 "ProcessUtilsLeakFDChildProcess", fd_mapping_vec, false); 295 CHECK(handle); 296 int ret = HANDLE_EINTR(close(fds[1])); 297 DPCHECK(ret == 0); 298 299 // Read number of open files in client process from pipe; 300 int num_open_files = -1; 301 ssize_t bytes_read = 302 HANDLE_EINTR(read(fds[0], &num_open_files, sizeof(num_open_files))); 303 CHECK_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files))); 304 305 CHECK(base::WaitForSingleProcess(handle, 1000)); 306 base::CloseProcessHandle(handle); 307 ret = HANDLE_EINTR(close(fds[0])); 308 DPCHECK(ret == 0); 309 310 return num_open_files; 311} 312 313TEST_F(ProcessUtilTest, FDRemapping) { 314 int fds_before = CountOpenFDsInChild(); 315 316 // open some dummy fds to make sure they don't propagate over to the 317 // child process. 318 int dev_null = open("/dev/null", O_RDONLY); 319 int sockets[2]; 320 socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); 321 322 int fds_after = CountOpenFDsInChild(); 323 324 ASSERT_EQ(fds_after, fds_before); 325 326 int ret; 327 ret = HANDLE_EINTR(close(sockets[0])); 328 DPCHECK(ret == 0); 329 ret = HANDLE_EINTR(close(sockets[1])); 330 DPCHECK(ret == 0); 331 ret = HANDLE_EINTR(close(dev_null)); 332 DPCHECK(ret == 0); 333} 334 335namespace { 336 337std::string TestLaunchApp(const base::environment_vector& env_changes) { 338 std::vector<std::string> args; 339 base::file_handle_mapping_vector fds_to_remap; 340 base::ProcessHandle handle; 341 342 args.push_back("bash"); 343 args.push_back("-c"); 344 args.push_back("echo $BASE_TEST"); 345 346 int fds[2]; 347 PCHECK(pipe(fds) == 0); 348 349 fds_to_remap.push_back(std::make_pair(fds[1], 1)); 350 EXPECT_TRUE(base::LaunchApp(args, env_changes, fds_to_remap, 351 true /* wait for exit */, &handle)); 352 PCHECK(close(fds[1]) == 0); 353 354 char buf[512]; 355 const ssize_t n = HANDLE_EINTR(read(fds[0], buf, sizeof(buf))); 356 PCHECK(n > 0); 357 return std::string(buf, n); 358} 359 360const char kLargeString[] = 361 "0123456789012345678901234567890123456789012345678901234567890123456789" 362 "0123456789012345678901234567890123456789012345678901234567890123456789" 363 "0123456789012345678901234567890123456789012345678901234567890123456789" 364 "0123456789012345678901234567890123456789012345678901234567890123456789" 365 "0123456789012345678901234567890123456789012345678901234567890123456789" 366 "0123456789012345678901234567890123456789012345678901234567890123456789" 367 "0123456789012345678901234567890123456789012345678901234567890123456789"; 368 369} // namespace 370 371TEST_F(ProcessUtilTest, LaunchApp) { 372 base::environment_vector env_changes; 373 374 env_changes.push_back(std::make_pair(std::string("BASE_TEST"), 375 std::string("bar"))); 376 EXPECT_EQ("bar\n", TestLaunchApp(env_changes)); 377 env_changes.clear(); 378 379 EXPECT_EQ(0, setenv("BASE_TEST", "testing", 1 /* override */)); 380 EXPECT_EQ("testing\n", TestLaunchApp(env_changes)); 381 382 env_changes.push_back(std::make_pair(std::string("BASE_TEST"), 383 std::string(""))); 384 EXPECT_EQ("\n", TestLaunchApp(env_changes)); 385 386 env_changes[0].second = "foo"; 387 EXPECT_EQ("foo\n", TestLaunchApp(env_changes)); 388 389 env_changes.clear(); 390 EXPECT_EQ(0, setenv("BASE_TEST", kLargeString, 1 /* override */)); 391 EXPECT_EQ(std::string(kLargeString) + "\n", TestLaunchApp(env_changes)); 392 393 env_changes.push_back(std::make_pair(std::string("BASE_TEST"), 394 std::string("wibble"))); 395 EXPECT_EQ("wibble\n", TestLaunchApp(env_changes)); 396} 397 398TEST_F(ProcessUtilTest, AlterEnvironment) { 399 const char* const empty[] = { NULL }; 400 const char* const a2[] = { "A=2", NULL }; 401 base::environment_vector changes; 402 char** e; 403 404 e = base::AlterEnvironment(changes, empty); 405 EXPECT_TRUE(e[0] == NULL); 406 delete[] e; 407 408 changes.push_back(std::make_pair(std::string("A"), std::string("1"))); 409 e = base::AlterEnvironment(changes, empty); 410 EXPECT_EQ(std::string("A=1"), e[0]); 411 EXPECT_TRUE(e[1] == NULL); 412 delete[] e; 413 414 changes.clear(); 415 changes.push_back(std::make_pair(std::string("A"), std::string(""))); 416 e = base::AlterEnvironment(changes, empty); 417 EXPECT_TRUE(e[0] == NULL); 418 delete[] e; 419 420 changes.clear(); 421 e = base::AlterEnvironment(changes, a2); 422 EXPECT_EQ(std::string("A=2"), e[0]); 423 EXPECT_TRUE(e[1] == NULL); 424 delete[] e; 425 426 changes.clear(); 427 changes.push_back(std::make_pair(std::string("A"), std::string("1"))); 428 e = base::AlterEnvironment(changes, a2); 429 EXPECT_EQ(std::string("A=1"), e[0]); 430 EXPECT_TRUE(e[1] == NULL); 431 delete[] e; 432 433 changes.clear(); 434 changes.push_back(std::make_pair(std::string("A"), std::string(""))); 435 e = base::AlterEnvironment(changes, a2); 436 EXPECT_TRUE(e[0] == NULL); 437 delete[] e; 438} 439 440TEST_F(ProcessUtilTest, GetAppOutput) { 441 std::string output; 442 EXPECT_TRUE(base::GetAppOutput(CommandLine(FilePath("true")), &output)); 443 EXPECT_STREQ("", output.c_str()); 444 445 EXPECT_FALSE(base::GetAppOutput(CommandLine(FilePath("false")), &output)); 446 447 std::vector<std::string> argv; 448 argv.push_back("/bin/echo"); 449 argv.push_back("-n"); 450 argv.push_back("foobar42"); 451 EXPECT_TRUE(base::GetAppOutput(CommandLine(argv), &output)); 452 EXPECT_STREQ("foobar42", output.c_str()); 453} 454 455TEST_F(ProcessUtilTest, GetAppOutputRestricted) { 456 // Unfortunately, since we can't rely on the path, we need to know where 457 // everything is. So let's use /bin/sh, which is on every POSIX system, and 458 // its built-ins. 459 std::vector<std::string> argv; 460 argv.push_back("/bin/sh"); // argv[0] 461 argv.push_back("-c"); // argv[1] 462 463 // On success, should set |output|. We use |/bin/sh -c 'exit 0'| instead of 464 // |true| since the location of the latter may be |/bin| or |/usr/bin| (and we 465 // need absolute paths). 466 argv.push_back("exit 0"); // argv[2]; equivalent to "true" 467 std::string output = "abc"; 468 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100)); 469 EXPECT_STREQ("", output.c_str()); 470 471 argv[2] = "exit 1"; // equivalent to "false" 472 output = "before"; 473 EXPECT_FALSE(base::GetAppOutputRestricted(CommandLine(argv), 474 &output, 100)); 475 EXPECT_STREQ("", output.c_str()); 476 477 // Amount of output exactly equal to space allowed. 478 argv[2] = "echo 123456789"; // (the sh built-in doesn't take "-n") 479 output.clear(); 480 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10)); 481 EXPECT_STREQ("123456789\n", output.c_str()); 482 483 // Amount of output greater than space allowed. 484 output.clear(); 485 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 5)); 486 EXPECT_STREQ("12345", output.c_str()); 487 488 // Amount of output less than space allowed. 489 output.clear(); 490 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 15)); 491 EXPECT_STREQ("123456789\n", output.c_str()); 492 493 // Zero space allowed. 494 output = "abc"; 495 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 0)); 496 EXPECT_STREQ("", output.c_str()); 497} 498 499TEST_F(ProcessUtilTest, GetAppOutputRestrictedNoZombies) { 500 std::vector<std::string> argv; 501 argv.push_back("/bin/sh"); // argv[0] 502 argv.push_back("-c"); // argv[1] 503 argv.push_back("echo 123456789012345678901234567890"); // argv[2] 504 505 // Run |GetAppOutputRestricted()| 300 (> default per-user processes on Mac OS 506 // 10.5) times with an output buffer big enough to capture all output. 507 for (int i = 0; i < 300; i++) { 508 std::string output; 509 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 100)); 510 EXPECT_STREQ("123456789012345678901234567890\n", output.c_str()); 511 } 512 513 // Ditto, but with an output buffer too small to capture all output. 514 for (int i = 0; i < 300; i++) { 515 std::string output; 516 EXPECT_TRUE(base::GetAppOutputRestricted(CommandLine(argv), &output, 10)); 517 EXPECT_STREQ("1234567890", output.c_str()); 518 } 519} 520 521#if defined(OS_LINUX) 522TEST_F(ProcessUtilTest, GetParentProcessId) { 523 base::ProcessId ppid = base::GetParentProcessId(base::GetCurrentProcId()); 524 EXPECT_EQ(ppid, getppid()); 525} 526 527TEST_F(ProcessUtilTest, ParseProcStatCPU) { 528 // /proc/self/stat for a process running "top". 529 const char kTopStat[] = "960 (top) S 16230 960 16230 34818 960 " 530 "4202496 471 0 0 0 " 531 "12 16 0 0 " // <- These are the goods. 532 "20 0 1 0 121946157 15077376 314 18446744073709551615 4194304 " 533 "4246868 140733983044336 18446744073709551615 140244213071219 " 534 "0 0 0 138047495 0 0 0 17 1 0 0 0 0 0"; 535 EXPECT_EQ(12 + 16, base::ParseProcStatCPU(kTopStat)); 536 537 // cat /proc/self/stat on a random other machine I have. 538 const char kSelfStat[] = "5364 (cat) R 5354 5364 5354 34819 5364 " 539 "0 142 0 0 0 " 540 "0 0 0 0 " // <- No CPU, apparently. 541 "16 0 1 0 1676099790 2957312 114 4294967295 134512640 134528148 " 542 "3221224832 3221224344 3086339742 0 0 0 0 0 0 0 17 0 0 0"; 543 544 EXPECT_EQ(0, base::ParseProcStatCPU(kSelfStat)); 545} 546#endif 547 548#endif // defined(OS_POSIX) 549 550// TODO(vandebo) make this work on Windows too. 551#if !defined(OS_WIN) 552 553#if defined(USE_TCMALLOC) 554extern "C" { 555int tc_set_new_mode(int mode); 556} 557#endif // defined(USE_TCMALLOC) 558 559class OutOfMemoryDeathTest : public testing::Test { 560 public: 561 OutOfMemoryDeathTest() 562 : value_(NULL), 563 // Make test size as large as possible minus a few pages so 564 // that alignment or other rounding doesn't make it wrap. 565 test_size_(std::numeric_limits<std::size_t>::max() - 12 * 1024), 566 signed_test_size_(std::numeric_limits<ssize_t>::max()) { 567 } 568 569 virtual void SetUp() { 570#if defined(USE_TCMALLOC) 571 tc_set_new_mode(1); 572 } 573 574 virtual void TearDown() { 575 tc_set_new_mode(0); 576#endif // defined(USE_TCMALLOC) 577 } 578 579 void SetUpInDeathAssert() { 580 // Must call EnableTerminationOnOutOfMemory() because that is called from 581 // chrome's main function and therefore hasn't been called yet. 582 // Since this call may result in another thread being created and death 583 // tests shouldn't be started in a multithread environment, this call 584 // should be done inside of the ASSERT_DEATH. 585 base::EnableTerminationOnOutOfMemory(); 586 } 587 588 void* value_; 589 size_t test_size_; 590 ssize_t signed_test_size_; 591}; 592 593TEST_F(OutOfMemoryDeathTest, New) { 594 ASSERT_DEATH({ 595 SetUpInDeathAssert(); 596 value_ = operator new(test_size_); 597 }, ""); 598} 599 600TEST_F(OutOfMemoryDeathTest, NewArray) { 601 ASSERT_DEATH({ 602 SetUpInDeathAssert(); 603 value_ = new char[test_size_]; 604 }, ""); 605} 606 607TEST_F(OutOfMemoryDeathTest, Malloc) { 608 ASSERT_DEATH({ 609 SetUpInDeathAssert(); 610 value_ = malloc(test_size_); 611 }, ""); 612} 613 614TEST_F(OutOfMemoryDeathTest, Realloc) { 615 ASSERT_DEATH({ 616 SetUpInDeathAssert(); 617 value_ = realloc(NULL, test_size_); 618 }, ""); 619} 620 621TEST_F(OutOfMemoryDeathTest, Calloc) { 622 ASSERT_DEATH({ 623 SetUpInDeathAssert(); 624 value_ = calloc(1024, test_size_ / 1024L); 625 }, ""); 626} 627 628TEST_F(OutOfMemoryDeathTest, Valloc) { 629 ASSERT_DEATH({ 630 SetUpInDeathAssert(); 631 value_ = valloc(test_size_); 632 }, ""); 633} 634 635#if defined(OS_LINUX) 636TEST_F(OutOfMemoryDeathTest, Pvalloc) { 637 ASSERT_DEATH({ 638 SetUpInDeathAssert(); 639 value_ = pvalloc(test_size_); 640 }, ""); 641} 642 643TEST_F(OutOfMemoryDeathTest, Memalign) { 644 ASSERT_DEATH({ 645 SetUpInDeathAssert(); 646 value_ = memalign(4, test_size_); 647 }, ""); 648} 649 650TEST_F(OutOfMemoryDeathTest, ViaSharedLibraries) { 651 // g_try_malloc is documented to return NULL on failure. (g_malloc is the 652 // 'safe' default that crashes if allocation fails). However, since we have 653 // hopefully overridden malloc, even g_try_malloc should fail. This tests 654 // that the run-time symbol resolution is overriding malloc for shared 655 // libraries as well as for our code. 656 ASSERT_DEATH({ 657 SetUpInDeathAssert(); 658 value_ = g_try_malloc(test_size_); 659 }, ""); 660} 661#endif // OS_LINUX 662 663#if defined(OS_POSIX) 664TEST_F(OutOfMemoryDeathTest, Posix_memalign) { 665 typedef int (*memalign_t)(void **, size_t, size_t); 666#if defined(OS_MACOSX) 667 // posix_memalign only exists on >= 10.6. Use dlsym to grab it at runtime 668 // because it may not be present in the SDK used for compilation. 669 memalign_t memalign = 670 reinterpret_cast<memalign_t>(dlsym(RTLD_DEFAULT, "posix_memalign")); 671#else 672 memalign_t memalign = posix_memalign; 673#endif // OS_* 674 if (memalign) { 675 // Grab the return value of posix_memalign to silence a compiler warning 676 // about unused return values. We don't actually care about the return 677 // value, since we're asserting death. 678 ASSERT_DEATH({ 679 SetUpInDeathAssert(); 680 EXPECT_EQ(ENOMEM, memalign(&value_, 8, test_size_)); 681 }, ""); 682 } 683} 684#endif // OS_POSIX 685 686#if defined(OS_MACOSX) 687 688// Purgeable zone tests (if it exists) 689 690TEST_F(OutOfMemoryDeathTest, MallocPurgeable) { 691 malloc_zone_t* zone = base::GetPurgeableZone(); 692 if (zone) 693 ASSERT_DEATH({ 694 SetUpInDeathAssert(); 695 value_ = malloc_zone_malloc(zone, test_size_); 696 }, ""); 697} 698 699TEST_F(OutOfMemoryDeathTest, ReallocPurgeable) { 700 malloc_zone_t* zone = base::GetPurgeableZone(); 701 if (zone) 702 ASSERT_DEATH({ 703 SetUpInDeathAssert(); 704 value_ = malloc_zone_realloc(zone, NULL, test_size_); 705 }, ""); 706} 707 708TEST_F(OutOfMemoryDeathTest, CallocPurgeable) { 709 malloc_zone_t* zone = base::GetPurgeableZone(); 710 if (zone) 711 ASSERT_DEATH({ 712 SetUpInDeathAssert(); 713 value_ = malloc_zone_calloc(zone, 1024, test_size_ / 1024L); 714 }, ""); 715} 716 717TEST_F(OutOfMemoryDeathTest, VallocPurgeable) { 718 malloc_zone_t* zone = base::GetPurgeableZone(); 719 if (zone) 720 ASSERT_DEATH({ 721 SetUpInDeathAssert(); 722 value_ = malloc_zone_valloc(zone, test_size_); 723 }, ""); 724} 725 726TEST_F(OutOfMemoryDeathTest, PosixMemalignPurgeable) { 727 malloc_zone_t* zone = base::GetPurgeableZone(); 728 729 typedef void* (*zone_memalign_t)(malloc_zone_t*, size_t, size_t); 730 // malloc_zone_memalign only exists on >= 10.6. Use dlsym to grab it at 731 // runtime because it may not be present in the SDK used for compilation. 732 zone_memalign_t zone_memalign = 733 reinterpret_cast<zone_memalign_t>( 734 dlsym(RTLD_DEFAULT, "malloc_zone_memalign")); 735 736 if (zone && zone_memalign) { 737 ASSERT_DEATH({ 738 SetUpInDeathAssert(); 739 value_ = zone_memalign(zone, 8, test_size_); 740 }, ""); 741 } 742} 743 744// Since these allocation functions take a signed size, it's possible that 745// calling them just once won't be enough to exhaust memory. In the 32-bit 746// environment, it's likely that these allocation attempts will fail because 747// not enough contiguous address space is availble. In the 64-bit environment, 748// it's likely that they'll fail because they would require a preposterous 749// amount of (virtual) memory. 750 751TEST_F(OutOfMemoryDeathTest, CFAllocatorSystemDefault) { 752 ASSERT_DEATH({ 753 SetUpInDeathAssert(); 754 while ((value_ = 755 base::AllocateViaCFAllocatorSystemDefault(signed_test_size_))) {} 756 }, ""); 757} 758 759TEST_F(OutOfMemoryDeathTest, CFAllocatorMalloc) { 760 ASSERT_DEATH({ 761 SetUpInDeathAssert(); 762 while ((value_ = 763 base::AllocateViaCFAllocatorMalloc(signed_test_size_))) {} 764 }, ""); 765} 766 767TEST_F(OutOfMemoryDeathTest, CFAllocatorMallocZone) { 768 ASSERT_DEATH({ 769 SetUpInDeathAssert(); 770 while ((value_ = 771 base::AllocateViaCFAllocatorMallocZone(signed_test_size_))) {} 772 }, ""); 773} 774 775#if !defined(ARCH_CPU_64_BITS) 776 777// See process_util_unittest_mac.mm for an explanation of why this test isn't 778// run in the 64-bit environment. 779 780TEST_F(OutOfMemoryDeathTest, PsychoticallyBigObjCObject) { 781 ASSERT_DEATH({ 782 SetUpInDeathAssert(); 783 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {} 784 }, ""); 785} 786 787#endif // !ARCH_CPU_64_BITS 788#endif // OS_MACOSX 789 790#endif // !defined(OS_WIN) 791