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