Chromium Code Reviews| Index: util/mach/exception_ports_test.cc |
| diff --git a/util/mach/exception_ports_test.cc b/util/mach/exception_ports_test.cc |
| index 43fb025757a32c706dc1abca830147d17938bb40..6fc23c4c7e971446920dfb526bd3a3548e89dda1 100644 |
| --- a/util/mach/exception_ports_test.cc |
| +++ b/util/mach/exception_ports_test.cc |
| @@ -107,6 +107,12 @@ void TestGetExceptionPorts(const ExceptionPorts& exception_ports, |
| class TestExceptionPorts : public MachMultiprocess, |
| public UniversalMachExcServer::Interface { |
| public: |
| + // Which entities to set exception ports for. |
| + enum SetOn { |
| + kSetOnTaskOnly = 0, |
| + kSetOnTaskAndThreads, |
| + }; |
| + |
| // Where to call ExceptionPorts::SetExceptionPort() from. |
| enum SetType { |
| // Call it from the child process on itself. |
| @@ -116,12 +122,6 @@ class TestExceptionPorts : public MachMultiprocess, |
| kSetOutOfProcess, |
| }; |
| - // Which entities to set exception ports for. |
| - enum SetOn { |
| - kSetOnTaskOnly = 0, |
| - kSetOnTaskAndThreads, |
| - }; |
| - |
| // Which thread in the child process is expected to crash. |
| enum WhoCrashes { |
| kNobodyCrashes = 0, |
| @@ -129,16 +129,16 @@ class TestExceptionPorts : public MachMultiprocess, |
| kOtherThreadCrashes, |
| }; |
| - TestExceptionPorts(SetType set_type, SetOn set_on, WhoCrashes who_crashes) |
| + TestExceptionPorts(SetOn set_on, SetType set_type, WhoCrashes who_crashes) |
| : MachMultiprocess(), |
| UniversalMachExcServer::Interface(), |
| - set_type_(set_type), |
| set_on_(set_on), |
| + set_type_(set_type), |
| who_crashes_(who_crashes), |
| handled_(false) {} |
| - SetType set_type() const { return set_type_; } |
| SetOn set_on() const { return set_on_; } |
| + SetType set_type() const { return set_type_; } |
| WhoCrashes who_crashes() const { return who_crashes_; } |
| // UniversalMachExcServer::Interface: |
| @@ -191,10 +191,8 @@ class TestExceptionPorts : public MachMultiprocess, |
| int signal; |
| ExcCrashRecoverOriginalException(code[0], nullptr, &signal); |
| - // The child crashed with a division by zero, which shows up as SIGFPE. |
| - // This was chosen because it’s unlikely to be generated by testing or |
| - // assertion failures. |
| - EXPECT_EQ(SIGFPE, signal); |
| + // The child crashed with __builtin_trap(), which shows up as SIGILL. |
| + EXPECT_EQ(SIGILL, signal); |
| SetExpectedChildTermination(kTerminationSignal, signal); |
| } |
| @@ -326,10 +324,9 @@ class TestExceptionPorts : public MachMultiprocess, |
| return nullptr; |
| } |
| - // Crashes by performing a division by zero. The assignment is present to |
| - // avoid optimizing zero_ out entirely by making it appear that its value |
| - // might change. |
| - static void Crash() { zero_ = 1 / zero_; } |
| + static void Crash() { |
| + __builtin_trap(); |
| + } |
| // The parent object. |
| TestExceptionPorts* test_exception_ports_; // weak |
| @@ -345,11 +342,6 @@ class TestExceptionPorts : public MachMultiprocess, |
| // child can test its exception ports and possibly crash, as appropriate. |
| Semaphore crash_semaphore_; |
| - // Always zero. Crash() divides by this in order to trigger a crash. This is |
| - // structured as a static volatile int to ward off aggressive compiler |
| - // optimizations. |
| - static volatile int zero_; |
| - |
| DISALLOW_COPY_AND_ASSIGN(Child); |
| }; |
| @@ -447,13 +439,14 @@ class TestExceptionPorts : public MachMultiprocess, |
| if (who_crashes_ != kNobodyCrashes) { |
| UniversalMachExcServer universal_mach_exc_server(this); |
| + const mach_msg_timeout_t kTimeoutMs = 50; |
| kern_return_t kr = |
| MachMessageServer::Run(&universal_mach_exc_server, |
| local_port, |
| MACH_MSG_OPTION_NONE, |
| MachMessageServer::kOneShot, |
| MachMessageServer::kReceiveLargeError, |
| - kMachMessageTimeoutWaitIndefinitely); |
| + kTimeoutMs); |
| EXPECT_EQ(KERN_SUCCESS, kr) |
| << MachErrorMessage(kr, "MachMessageServer::Run"); |
| @@ -471,8 +464,8 @@ class TestExceptionPorts : public MachMultiprocess, |
| child.Run(); |
| } |
| - SetType set_type_; |
| SetOn set_on_; |
| + SetType set_type_; |
| WhoCrashes who_crashes_; |
| // true if an exception message was handled. |
| @@ -481,66 +474,103 @@ class TestExceptionPorts : public MachMultiprocess, |
| DISALLOW_COPY_AND_ASSIGN(TestExceptionPorts); |
| }; |
| -volatile int TestExceptionPorts::Child::zero_ = 0; |
| +TEST(ExceptionPorts, TaskExceptionPorts_SetInProcess_NoCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskOnly, |
| + TestExceptionPorts::kSetInProcess, |
| + TestExceptionPorts::kNobodyCrashes); |
| + test_exception_ports.Run(); |
| +} |
| -TEST(ExceptionPorts, TaskAndThreadExceptionPorts) { |
| - struct Testcase { |
| - TestExceptionPorts::SetType set_type; |
| - TestExceptionPorts::SetOn set_on; |
| - TestExceptionPorts::WhoCrashes who_crashes; |
| - }; |
| - const Testcase kTestcases[] = { |
| - {TestExceptionPorts::kSetInProcess, |
| - TestExceptionPorts::kSetOnTaskOnly, |
| - TestExceptionPorts::kNobodyCrashes}, |
| - {TestExceptionPorts::kSetInProcess, |
| - TestExceptionPorts::kSetOnTaskOnly, |
| - TestExceptionPorts::kMainThreadCrashes}, |
| - {TestExceptionPorts::kSetInProcess, |
| - TestExceptionPorts::kSetOnTaskOnly, |
| - TestExceptionPorts::kOtherThreadCrashes}, |
| - {TestExceptionPorts::kSetInProcess, |
| - TestExceptionPorts::kSetOnTaskAndThreads, |
| - TestExceptionPorts::kNobodyCrashes}, |
| - {TestExceptionPorts::kSetInProcess, |
| - TestExceptionPorts::kSetOnTaskAndThreads, |
| - TestExceptionPorts::kMainThreadCrashes}, |
| - {TestExceptionPorts::kSetInProcess, |
| - TestExceptionPorts::kSetOnTaskAndThreads, |
| - TestExceptionPorts::kOtherThreadCrashes}, |
| - {TestExceptionPorts::kSetOutOfProcess, |
| - TestExceptionPorts::kSetOnTaskOnly, |
| - TestExceptionPorts::kNobodyCrashes}, |
| - {TestExceptionPorts::kSetOutOfProcess, |
| - TestExceptionPorts::kSetOnTaskOnly, |
| - TestExceptionPorts::kMainThreadCrashes}, |
| - {TestExceptionPorts::kSetOutOfProcess, |
| - TestExceptionPorts::kSetOnTaskOnly, |
| - TestExceptionPorts::kOtherThreadCrashes}, |
| - {TestExceptionPorts::kSetOutOfProcess, |
| - TestExceptionPorts::kSetOnTaskAndThreads, |
| - TestExceptionPorts::kNobodyCrashes}, |
| - {TestExceptionPorts::kSetOutOfProcess, |
| - TestExceptionPorts::kSetOnTaskAndThreads, |
| - TestExceptionPorts::kMainThreadCrashes}, |
| - {TestExceptionPorts::kSetOutOfProcess, |
| - TestExceptionPorts::kSetOnTaskAndThreads, |
| - TestExceptionPorts::kOtherThreadCrashes}, |
| - }; |
| +TEST(ExceptionPorts, TaskExceptionPorts_SetInProcess_MainThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskOnly, |
| + TestExceptionPorts::kSetInProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
| + test_exception_ports.Run(); |
| +} |
| - for (size_t index = 0; index < arraysize(kTestcases); ++index) { |
| - const Testcase& testcase = kTestcases[index]; |
| - SCOPED_TRACE( |
| - base::StringPrintf("index %zu, set_type %d, set_on %d, who_crashes %d", |
| - index, |
| - testcase.set_type, |
| - testcase.set_on, |
| - testcase.who_crashes)); |
| - |
| - TestExceptionPorts test_exception_ports( |
| - testcase.set_type, testcase.set_on, testcase.who_crashes); |
| - test_exception_ports.Run(); |
| - } |
| +TEST(ExceptionPorts, TaskExceptionPorts_SetInProcess_OtherThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskOnly, |
| + TestExceptionPorts::kSetInProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
|
Robert Sesek
2015/03/10 14:53:48
kOtherThreadCrashes
|
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SetInProcess_NoCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskAndThreads, |
| + TestExceptionPorts::kSetInProcess, |
| + TestExceptionPorts::kNobodyCrashes); |
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SetInProcess_MainThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskAndThreads, |
| + TestExceptionPorts::kSetInProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, |
| + TaskAndThreadExceptionPorts_SetInProcess_OtherThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskAndThreads, |
| + TestExceptionPorts::kSetInProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, TaskExceptionPorts_SetOutOfProcess_NoCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskOnly, |
| + TestExceptionPorts::kSetOutOfProcess, |
| + TestExceptionPorts::kNobodyCrashes); |
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, TaskExceptionPorts_SetOutOfProcess_MainThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskOnly, |
| + TestExceptionPorts::kSetOutOfProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, TaskExceptionPorts_SetOutOfProcess_OtherThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskOnly, |
| + TestExceptionPorts::kSetOutOfProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
|
Robert Sesek
2015/03/10 14:53:49
kOtherThreadCrashes
|
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SetOutOfProcess_NoCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskAndThreads, |
| + TestExceptionPorts::kSetOutOfProcess, |
| + TestExceptionPorts::kNobodyCrashes); |
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, |
| + TaskAndThreadExceptionPorts_SetOutOfProcess_MainThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskAndThreads, |
| + TestExceptionPorts::kSetOutOfProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
| + test_exception_ports.Run(); |
| +} |
| + |
| +TEST(ExceptionPorts, |
| + TaskAndThreadExceptionPorts_SetOutOfProcess_OtherThreadCrash) { |
| + TestExceptionPorts test_exception_ports( |
| + TestExceptionPorts::kSetOnTaskAndThreads, |
| + TestExceptionPorts::kSetOutOfProcess, |
| + TestExceptionPorts::kMainThreadCrashes); |
|
Robert Sesek
2015/03/10 14:53:48
kOtherThreadCrashes
|
| + test_exception_ports.Run(); |
| } |
| TEST(ExceptionPorts, HostExceptionPorts) { |