| 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..8948eae791668123ced9510c5a824d1f09d91a26 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::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::kOtherThreadCrashes);
|
| + 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::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::kOtherThreadCrashes);
|
| + test_exception_ports.Run();
|
| }
|
|
|
| TEST(ExceptionPorts, HostExceptionPorts) {
|
|
|