| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #define _CRT_SECURE_NO_WARNINGS | 5 #define _CRT_SECURE_NO_WARNINGS |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/eintr_wrapper.h" | 10 #include "base/eintr_wrapper.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 #if defined(OS_WIN) | 66 #if defined(OS_WIN) |
| 67 const int kExpectedStillRunningExitCode = 0x102; | 67 const int kExpectedStillRunningExitCode = 0x102; |
| 68 const int kExpectedKilledExitCode = 1; | 68 const int kExpectedKilledExitCode = 1; |
| 69 #else | 69 #else |
| 70 const int kExpectedStillRunningExitCode = 0; | 70 const int kExpectedStillRunningExitCode = 0; |
| 71 #endif | 71 #endif |
| 72 | 72 |
| 73 // Sleeps until file filename is created. | 73 // Sleeps until file filename is created. |
| 74 void WaitToDie(const char* filename) { | 74 void WaitToDie(const char* filename) { |
| 75 FILE *fp; | 75 FILE* fp; |
| 76 do { | 76 do { |
| 77 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); | 77 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); |
| 78 fp = fopen(filename, "r"); | 78 fp = fopen(filename, "r"); |
| 79 } while (!fp); | 79 } while (!fp); |
| 80 fclose(fp); | 80 fclose(fp); |
| 81 } | 81 } |
| 82 | 82 |
| 83 // Signals children they should die now. | 83 // Signals children they should die now. |
| 84 void SignalChildren(const char* filename) { | 84 void SignalChildren(const char* filename) { |
| 85 FILE *fp = fopen(filename, "w"); | 85 FILE* fp = fopen(filename, "w"); |
| 86 fclose(fp); | 86 fclose(fp); |
| 87 } | 87 } |
| 88 | 88 |
| 89 // Using a pipe to the child to wait for an event was considered, but | 89 // Using a pipe to the child to wait for an event was considered, but |
| 90 // there were cases in the past where pipes caused problems (other | 90 // there were cases in the past where pipes caused problems (other |
| 91 // libraries closing the fds, child deadlocking). This is a simple | 91 // libraries closing the fds, child deadlocking). This is a simple |
| 92 // case, so it's not worth the risk. Using wait loops is discouraged | 92 // case, so it's not worth the risk. Using wait loops is discouraged |
| 93 // in most instances. | 93 // in most instances. |
| 94 base::TerminationStatus WaitForChildTermination(base::ProcessHandle handle, | 94 base::TerminationStatus WaitForChildTermination(base::ProcessHandle handle, |
| 95 int* exit_code) { | 95 int* exit_code) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 EXPECT_NE(0, signaled); | 253 EXPECT_NE(0, signaled); |
| 254 int signal = WTERMSIG(exit_code); | 254 int signal = WTERMSIG(exit_code); |
| 255 EXPECT_EQ(SIGSEGV, signal); | 255 EXPECT_EQ(SIGSEGV, signal); |
| 256 #endif | 256 #endif |
| 257 base::CloseProcessHandle(handle); | 257 base::CloseProcessHandle(handle); |
| 258 | 258 |
| 259 // Reset signal handlers back to "normal". | 259 // Reset signal handlers back to "normal". |
| 260 base::EnableInProcessStackDumping(); | 260 base::EnableInProcessStackDumping(); |
| 261 remove(kSignalFileCrash); | 261 remove(kSignalFileCrash); |
| 262 } | 262 } |
| 263 #endif // !defined(OS_MACOSX) | 263 #endif // !defined(OS_MACOSX) |
| 264 | 264 |
| 265 MULTIPROCESS_TEST_MAIN(KilledChildProcess) { | 265 MULTIPROCESS_TEST_MAIN(KilledChildProcess) { |
| 266 WaitToDie(kSignalFileKill); | 266 WaitToDie(kSignalFileKill); |
| 267 #if defined(OS_WIN) | 267 #if defined(OS_WIN) |
| 268 // Kill ourselves. | 268 // Kill ourselves. |
| 269 HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId()); | 269 HANDLE handle = ::OpenProcess(PROCESS_ALL_ACCESS, 0, ::GetCurrentProcessId()); |
| 270 ::TerminateProcess(handle, kExpectedKilledExitCode); | 270 ::TerminateProcess(handle, kExpectedKilledExitCode); |
| 271 #elif defined(OS_POSIX) | 271 #elif defined(OS_POSIX) |
| 272 // Send a SIGKILL to this process, just like the OOM killer would. | 272 // Send a SIGKILL to this process, just like the OOM killer would. |
| 273 ::kill(getpid(), SIGKILL); | 273 ::kill(getpid(), SIGKILL); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 DPCHECK(ret == 0); | 511 DPCHECK(ret == 0); |
| 512 | 512 |
| 513 return 0; | 513 return 0; |
| 514 } | 514 } |
| 515 | 515 |
| 516 int ProcessUtilTest::CountOpenFDsInChild() { | 516 int ProcessUtilTest::CountOpenFDsInChild() { |
| 517 int fds[2]; | 517 int fds[2]; |
| 518 if (pipe(fds) < 0) | 518 if (pipe(fds) < 0) |
| 519 NOTREACHED(); | 519 NOTREACHED(); |
| 520 | 520 |
| 521 base::file_handle_mapping_vector fd_mapping_vec; | 521 base::FileHandleMappingVector fd_mapping_vec; |
| 522 fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe)); | 522 fd_mapping_vec.push_back(std::pair<int, int>(fds[1], kChildPipe)); |
| 523 base::ProcessHandle handle = this->SpawnChild( | 523 base::ProcessHandle handle = this->SpawnChild( |
| 524 "ProcessUtilsLeakFDChildProcess", fd_mapping_vec, false); | 524 "ProcessUtilsLeakFDChildProcess", fd_mapping_vec, false); |
| 525 CHECK(handle); | 525 CHECK(handle); |
| 526 int ret = HANDLE_EINTR(close(fds[1])); | 526 int ret = HANDLE_EINTR(close(fds[1])); |
| 527 DPCHECK(ret == 0); | 527 DPCHECK(ret == 0); |
| 528 | 528 |
| 529 // Read number of open files in client process from pipe; | 529 // Read number of open files in client process from pipe; |
| 530 int num_open_files = -1; | 530 int num_open_files = -1; |
| 531 ssize_t bytes_read = | 531 ssize_t bytes_read = |
| (...skipping 25 matching lines...) Expand all Loading... |
| 557 ret = HANDLE_EINTR(close(sockets[0])); | 557 ret = HANDLE_EINTR(close(sockets[0])); |
| 558 DPCHECK(ret == 0); | 558 DPCHECK(ret == 0); |
| 559 ret = HANDLE_EINTR(close(sockets[1])); | 559 ret = HANDLE_EINTR(close(sockets[1])); |
| 560 DPCHECK(ret == 0); | 560 DPCHECK(ret == 0); |
| 561 ret = HANDLE_EINTR(close(dev_null)); | 561 ret = HANDLE_EINTR(close(dev_null)); |
| 562 DPCHECK(ret == 0); | 562 DPCHECK(ret == 0); |
| 563 } | 563 } |
| 564 | 564 |
| 565 namespace { | 565 namespace { |
| 566 | 566 |
| 567 std::string TestLaunchProcess(const base::environment_vector& env_changes, | 567 std::string TestLaunchProcess(const base::EnvironmentVector& env_changes, |
| 568 const int clone_flags) { | 568 const int clone_flags) { |
| 569 std::vector<std::string> args; | 569 std::vector<std::string> args; |
| 570 base::file_handle_mapping_vector fds_to_remap; | 570 base::FileHandleMappingVector fds_to_remap; |
| 571 | 571 |
| 572 args.push_back(kPosixShell); | 572 args.push_back(kPosixShell); |
| 573 args.push_back("-c"); | 573 args.push_back("-c"); |
| 574 args.push_back("echo $BASE_TEST"); | 574 args.push_back("echo $BASE_TEST"); |
| 575 | 575 |
| 576 int fds[2]; | 576 int fds[2]; |
| 577 PCHECK(pipe(fds) == 0); | 577 PCHECK(pipe(fds) == 0); |
| 578 | 578 |
| 579 fds_to_remap.push_back(std::make_pair(fds[1], 1)); | 579 fds_to_remap.push_back(std::make_pair(fds[1], 1)); |
| 580 base::LaunchOptions options; | 580 base::LaunchOptions options; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 603 "0123456789012345678901234567890123456789012345678901234567890123456789" | 603 "0123456789012345678901234567890123456789012345678901234567890123456789" |
| 604 "0123456789012345678901234567890123456789012345678901234567890123456789" | 604 "0123456789012345678901234567890123456789012345678901234567890123456789" |
| 605 "0123456789012345678901234567890123456789012345678901234567890123456789" | 605 "0123456789012345678901234567890123456789012345678901234567890123456789" |
| 606 "0123456789012345678901234567890123456789012345678901234567890123456789" | 606 "0123456789012345678901234567890123456789012345678901234567890123456789" |
| 607 "0123456789012345678901234567890123456789012345678901234567890123456789" | 607 "0123456789012345678901234567890123456789012345678901234567890123456789" |
| 608 "0123456789012345678901234567890123456789012345678901234567890123456789"; | 608 "0123456789012345678901234567890123456789012345678901234567890123456789"; |
| 609 | 609 |
| 610 } // namespace | 610 } // namespace |
| 611 | 611 |
| 612 TEST_F(ProcessUtilTest, LaunchProcess) { | 612 TEST_F(ProcessUtilTest, LaunchProcess) { |
| 613 base::environment_vector env_changes; | 613 base::EnvironmentVector env_changes; |
| 614 const int no_clone_flags = 0; | 614 const int no_clone_flags = 0; |
| 615 | 615 |
| 616 env_changes.push_back(std::make_pair(std::string("BASE_TEST"), | 616 env_changes.push_back(std::make_pair(std::string("BASE_TEST"), |
| 617 std::string("bar"))); | 617 std::string("bar"))); |
| 618 EXPECT_EQ("bar\n", TestLaunchProcess(env_changes, no_clone_flags)); | 618 EXPECT_EQ("bar\n", TestLaunchProcess(env_changes, no_clone_flags)); |
| 619 env_changes.clear(); | 619 env_changes.clear(); |
| 620 | 620 |
| 621 EXPECT_EQ(0, setenv("BASE_TEST", "testing", 1 /* override */)); | 621 EXPECT_EQ(0, setenv("BASE_TEST", "testing", 1 /* override */)); |
| 622 EXPECT_EQ("testing\n", TestLaunchProcess(env_changes, no_clone_flags)); | 622 EXPECT_EQ("testing\n", TestLaunchProcess(env_changes, no_clone_flags)); |
| 623 | 623 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 642 // Don't test on Valgrind as it has limited support for clone(). | 642 // Don't test on Valgrind as it has limited support for clone(). |
| 643 if (!RunningOnValgrind()) { | 643 if (!RunningOnValgrind()) { |
| 644 EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes, CLONE_FS | SIGCHLD)); | 644 EXPECT_EQ("wibble\n", TestLaunchProcess(env_changes, CLONE_FS | SIGCHLD)); |
| 645 } | 645 } |
| 646 #endif | 646 #endif |
| 647 } | 647 } |
| 648 | 648 |
| 649 TEST_F(ProcessUtilTest, AlterEnvironment) { | 649 TEST_F(ProcessUtilTest, AlterEnvironment) { |
| 650 const char* const empty[] = { NULL }; | 650 const char* const empty[] = { NULL }; |
| 651 const char* const a2[] = { "A=2", NULL }; | 651 const char* const a2[] = { "A=2", NULL }; |
| 652 base::environment_vector changes; | 652 base::EnvironmentVector changes; |
| 653 char** e; | 653 char** e; |
| 654 | 654 |
| 655 e = base::AlterEnvironment(changes, empty); | 655 e = base::AlterEnvironment(changes, empty); |
| 656 EXPECT_TRUE(e[0] == NULL); | 656 EXPECT_TRUE(e[0] == NULL); |
| 657 delete[] e; | 657 delete[] e; |
| 658 | 658 |
| 659 changes.push_back(std::make_pair(std::string("A"), std::string("1"))); | 659 changes.push_back(std::make_pair(std::string("A"), std::string("1"))); |
| 660 e = base::AlterEnvironment(changes, empty); | 660 e = base::AlterEnvironment(changes, empty); |
| 661 EXPECT_EQ(std::string("A=1"), e[0]); | 661 EXPECT_EQ(std::string("A=1"), e[0]); |
| 662 EXPECT_TRUE(e[1] == NULL); | 662 EXPECT_TRUE(e[1] == NULL); |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 SetUpInDeathAssert(); | 1150 SetUpInDeathAssert(); |
| 1151 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {} | 1151 while ((value_ = base::AllocatePsychoticallyBigObjCObject())) {} |
| 1152 }, ""); | 1152 }, ""); |
| 1153 } | 1153 } |
| 1154 | 1154 |
| 1155 #endif // !ARCH_CPU_64_BITS | 1155 #endif // !ARCH_CPU_64_BITS |
| 1156 #endif // OS_MACOSX | 1156 #endif // OS_MACOSX |
| 1157 | 1157 |
| 1158 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && | 1158 #endif // !defined(OS_ANDROID) && !defined(OS_OPENBSD) && |
| 1159 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER) | 1159 // !defined(OS_WIN) && !defined(ADDRESS_SANITIZER) |
| OLD | NEW |