// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/mach/exception_ports.h"

#include <mach/mach.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>

#include "base/check.h"
#include "base/mac/mach_logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/macros.h"
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/mac/mach_errors.h"
#include "test/mac/mach_multiprocess.h"
#include "util/file/file_io.h"
#include "util/mach/exc_server_variants.h"
#include "util/mach/exception_types.h"
#include "util/mach/mach_extensions.h"
#include "util/mach/mach_message.h"
#include "util/mach/mach_message_server.h"
#include "util/misc/scoped_forbid_return.h"
#include "util/synchronization/semaphore.h"

namespace crashpad {
namespace test {
namespace {

// Calls GetExceptionPorts() on its |exception_ports| argument to look up the
// EXC_MASK_CRASH handler. If |expect_port| is not MACH_PORT_NULL, it expects to
// find a handler for this mask whose port matches |expect_port| and whose
// behavior matches |expect_behavior| exactly. In this case, if
// |expect_behavior| is a state-carrying behavior, the looked-up thread state
// flavor is expected to be MACHINE_THREAD_STATE, otherwise, it is expected to
// be THREAD_STATE_NONE. If |expect_port| is MACH_PORT_NULL, no handler for
// EXC_MASK_CRASH is expected to be found.
//
// A second GetExceptionPorts() lookup is also performed on a wider exception
// mask, EXC_MASK_ALL | EXC_MASK_CRASH. The EXC_MASK_CRASH handler’s existence
// and properties from this second lookup are validated in the same way.
//
// This function uses Google Test EXPECT_* and ASSERT_* macros to perform its
// validation.
void TestGetExceptionPorts(const ExceptionPorts& exception_ports,
                           mach_port_t expect_port,
                           exception_behavior_t expect_behavior) {
  constexpr exception_mask_t kExceptionMask = EXC_MASK_CRASH;

  thread_state_flavor_t expect_flavor = (expect_behavior == EXCEPTION_DEFAULT)
                                            ? THREAD_STATE_NONE
                                            : MACHINE_THREAD_STATE;

  ExceptionPorts::ExceptionHandlerVector crash_handler;
  ASSERT_TRUE(
      exception_ports.GetExceptionPorts(kExceptionMask, &crash_handler));

  if (expect_port != MACH_PORT_NULL) {
    ASSERT_EQ(crash_handler.size(), 1u);

    EXPECT_EQ(crash_handler[0].mask, kExceptionMask);
    EXPECT_EQ(crash_handler[0].port, expect_port);
    EXPECT_EQ(crash_handler[0].behavior, expect_behavior);
    EXPECT_EQ(crash_handler[0].flavor, expect_flavor);
  } else {
    EXPECT_TRUE(crash_handler.empty());
  }

  ExceptionPorts::ExceptionHandlerVector handlers;
  ASSERT_TRUE(exception_ports.GetExceptionPorts(ExcMaskValid(), &handlers));

  EXPECT_GE(handlers.size(), crash_handler.size());
  bool found = false;
  for (const ExceptionPorts::ExceptionHandler& handler : handlers) {
    if ((handler.mask & kExceptionMask) != 0) {
      EXPECT_FALSE(found);
      found = true;
      EXPECT_EQ(handler.port, expect_port);
      EXPECT_EQ(handler.behavior, expect_behavior);
      EXPECT_EQ(handler.flavor, expect_flavor);
    }
  }

  if (expect_port != MACH_PORT_NULL) {
    EXPECT_TRUE(found);
  } else {
    EXPECT_FALSE(found);
  }
}

class TestExceptionPorts : public MachMultiprocess,
                           public UniversalMachExcServer::Interface {
 public:
  // Whether to call SetExceptionPort or SwapExceptionPorts.
  enum SetOrSwap {
    kSetExceptionPort = 0,
    kSwapExceptionPorts,
  };

  // 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.
    kSetInProcess = 0,

    // Call it from the parent process on the child.
    kSetOutOfProcess,
  };

  // Which thread in the child process is expected to crash.
  enum WhoCrashes {
    kNobodyCrashes = 0,
    kMainThreadCrashes,
    kOtherThreadCrashes,
  };

  TestExceptionPorts(SetOrSwap set_or_swap,
                     SetOn set_on,
                     SetType set_type,
                     WhoCrashes who_crashes)
      : MachMultiprocess(),
        UniversalMachExcServer::Interface(),
        set_or_swap_(set_or_swap),
        set_on_(set_on),
        set_type_(set_type),
        who_crashes_(who_crashes),
        handled_(false) {
    if (who_crashes_ != kNobodyCrashes) {
      SetExpectedChildTerminationBuiltinTrap();
    }
  }

  SetOrSwap set_or_swap() const { return set_or_swap_; }
  SetOn set_on() const { return set_on_; }
  SetType set_type() const { return set_type_; }
  WhoCrashes who_crashes() const { return who_crashes_; }

  // UniversalMachExcServer::Interface:

  virtual kern_return_t CatchMachException(
      exception_behavior_t behavior,
      exception_handler_t exception_port,
      thread_t thread,
      task_t task,
      exception_type_t exception,
      const mach_exception_data_type_t* code,
      mach_msg_type_number_t code_count,
      thread_state_flavor_t* flavor,
      ConstThreadState old_state,
      mach_msg_type_number_t old_state_count,
      thread_state_t new_state,
      mach_msg_type_number_t* new_state_count,
      const mach_msg_trailer_t* trailer,
      bool* destroy_complex_request) override {
    *destroy_complex_request = true;

    EXPECT_FALSE(handled_);
    handled_ = true;

    // To be able to distinguish between which handler was actually triggered,
    // the different handlers are registered with different behavior values.
    exception_behavior_t expect_behavior;
    if (set_on_ == kSetOnTaskOnly) {
      expect_behavior = EXCEPTION_DEFAULT;
    } else if (who_crashes_ == kMainThreadCrashes) {
      expect_behavior = EXCEPTION_STATE;
    } else if (who_crashes_ == kOtherThreadCrashes) {
      expect_behavior = EXCEPTION_STATE_IDENTITY;
    } else {
      NOTREACHED();
      expect_behavior = 0;
    }

    EXPECT_EQ(behavior, expect_behavior);

    EXPECT_EQ(exception_port, LocalPort());

    EXPECT_EQ(exception, EXC_CRASH);
    EXPECT_EQ(code_count, 2u);

    // The exception and code_count checks above would ideally use ASSERT_EQ so
    // that the next conditional would not be necessary, but ASSERT_* requires a
    // function returning type void, and the interface dictates otherwise here.
    if (exception == EXC_CRASH && code_count >= 1) {
      int signal;
      ExcCrashRecoverOriginalException(code[0], nullptr, &signal);

#if defined(ARCH_CPU_X86_FAMILY)
      constexpr int kBuiltinTrapSignal = SIGILL;
#elif defined(ARCH_CPU_ARM64)
      constexpr int kBuiltinTrapSignal = SIGTRAP;
#else
#error Port
#endif
      EXPECT_EQ(signal, kBuiltinTrapSignal);
    }

    EXPECT_EQ(AuditPIDFromMachMessageTrailer(trailer), 0);

    ExcServerCopyState(
        behavior, old_state, old_state_count, new_state, new_state_count);
    return ExcServerSuccessfulReturnValue(exception, behavior, false);
  }

 private:
  class Child {
   public:
    explicit Child(TestExceptionPorts* test_exception_ports)
        : test_exception_ports_(test_exception_ports),
          thread_(),
          init_semaphore_(0),
          crash_semaphore_(0) {}

    ~Child() {}

    void Run() {
      ExceptionPorts self_task_ports(ExceptionPorts::kTargetTypeTask,
                                     TASK_NULL);
      ExceptionPorts self_thread_ports(ExceptionPorts::kTargetTypeThread,
                                       THREAD_NULL);

      mach_port_t remote_port = test_exception_ports_->RemotePort();

      // Set the task’s and this thread’s exception ports, if appropriate.
      if (test_exception_ports_->set_type() == kSetInProcess) {
        switch (test_exception_ports_->set_or_swap()) {
          case kSetExceptionPort: {
            ASSERT_TRUE(self_task_ports.SetExceptionPort(EXC_MASK_CRASH,
                                                         remote_port,
                                                         EXCEPTION_DEFAULT,
                                                         THREAD_STATE_NONE));

            if (test_exception_ports_->set_on() == kSetOnTaskAndThreads) {
              ASSERT_TRUE(
                  self_thread_ports.SetExceptionPort(EXC_MASK_CRASH,
                                                     remote_port,
                                                     EXCEPTION_STATE,
                                                     MACHINE_THREAD_STATE));
            }

            break;
          }

          case kSwapExceptionPorts: {
            ExceptionPorts::ExceptionHandlerVector old_handlers;
            ASSERT_TRUE(self_task_ports.SwapExceptionPorts(EXC_MASK_CRASH,
                                                           remote_port,
                                                           EXCEPTION_DEFAULT,
                                                           THREAD_STATE_NONE,
                                                           &old_handlers));

            if (test_exception_ports_->set_on() == kSetOnTaskAndThreads) {
              ASSERT_TRUE(
                  self_thread_ports.SwapExceptionPorts(EXC_MASK_CRASH,
                                                       remote_port,
                                                       EXCEPTION_STATE,
                                                       MACHINE_THREAD_STATE,
                                                       &old_handlers));
            }

            break;
          }

          default: {
            NOTREACHED();
          }
        }
      }

      int rv_int = pthread_create(&thread_, nullptr, ThreadMainThunk, this);
      ASSERT_EQ(rv_int, 0);

      // Wait for the new thread to be ready.
      init_semaphore_.Wait();

      // Tell the parent process that everything is set up.
      char c = '\0';
      CheckedWriteFile(test_exception_ports_->WritePipeHandle(), &c, 1);

      // Wait for the parent process to say that its end is set up.
      CheckedReadFileExactly(test_exception_ports_->ReadPipeHandle(), &c, 1);
      EXPECT_EQ(c, '\0');

      // Regardless of where ExceptionPorts::SetExceptionPort() ran,
      // ExceptionPorts::GetExceptionPorts() can always be tested in-process.
      {
        SCOPED_TRACE("task");
        TestGetExceptionPorts(self_task_ports, remote_port, EXCEPTION_DEFAULT);
      }

      {
        SCOPED_TRACE("main_thread");
        mach_port_t thread_handler =
            (test_exception_ports_->set_on() == kSetOnTaskAndThreads)
                ? remote_port
                : MACH_PORT_NULL;
        TestGetExceptionPorts(
            self_thread_ports, thread_handler, EXCEPTION_STATE);
      }

      // Let the other thread know it’s safe to proceed.
      crash_semaphore_.Signal();

      // If this thread is the one that crashes, do it.
      if (test_exception_ports_->who_crashes() == kMainThreadCrashes) {
        Crash();
      }

      // Reap the other thread.
      rv_int = pthread_join(thread_, nullptr);
      ASSERT_EQ(rv_int, 0);
    }

   private:
    // Calls ThreadMain().
    static void* ThreadMainThunk(void* argument) {
      Child* self = reinterpret_cast<Child*>(argument);
      return self->ThreadMain();
    }

    // Runs the “other” thread.
    void* ThreadMain() {
      ExceptionPorts self_thread_ports(ExceptionPorts::kTargetTypeThread,
                                       THREAD_NULL);
      mach_port_t remote_port = test_exception_ports_->RemotePort();

      // Set this thread’s exception handler, if appropriate.
      if (test_exception_ports_->set_type() == kSetInProcess &&
          test_exception_ports_->set_on() == kSetOnTaskAndThreads) {
        switch (test_exception_ports_->set_or_swap()) {
          case kSetExceptionPort: {
            CHECK(self_thread_ports.SetExceptionPort(EXC_MASK_CRASH,
                                                     remote_port,
                                                     EXCEPTION_STATE_IDENTITY,
                                                     MACHINE_THREAD_STATE));
            break;
          }
          case kSwapExceptionPorts: {
            ExceptionPorts::ExceptionHandlerVector old_handlers;
            CHECK(self_thread_ports.SwapExceptionPorts(EXC_MASK_CRASH,
                                                       remote_port,
                                                       EXCEPTION_STATE_IDENTITY,
                                                       MACHINE_THREAD_STATE,
                                                       &old_handlers));
            break;
          }
          default: {
            NOTREACHED();
          }
        }
      }

      // Let the main thread know that this thread is ready.
      init_semaphore_.Signal();

      // Wait for the main thread to signal that it’s safe to proceed.
      crash_semaphore_.Wait();

      // Regardless of where ExceptionPorts::SetExceptionPort() ran,
      // ExceptionPorts::GetExceptionPorts() can always be tested in-process.
      {
        SCOPED_TRACE("other_thread");
        mach_port_t thread_handler =
            (test_exception_ports_->set_on() == kSetOnTaskAndThreads)
                ? remote_port
                : MACH_PORT_NULL;
        TestGetExceptionPorts(
            self_thread_ports, thread_handler, EXCEPTION_STATE_IDENTITY);
      }

      // If this thread is the one that crashes, do it.
      if (test_exception_ports_->who_crashes() == kOtherThreadCrashes) {
        Crash();
      }

      return nullptr;
    }

    static void Crash() {
      __builtin_trap();
    }

    // The parent object.
    TestExceptionPorts* test_exception_ports_;  // weak

    // The “other” thread.
    pthread_t thread_;

    // The main thread waits on this for the other thread to start up and
    // perform its own initialization.
    Semaphore init_semaphore_;

    // The child thread waits on this for the parent thread to indicate that the
    // child can test its exception ports and possibly crash, as appropriate.
    Semaphore crash_semaphore_;

    DISALLOW_COPY_AND_ASSIGN(Child);
  };

  // MachMultiprocess:

  void MachMultiprocessParent() override {
    // Wait for the child process to be ready. It needs to have all of its
    // threads set up before proceeding if in kSetOutOfProcess mode.
    char c;
    CheckedReadFileExactly(ReadPipeHandle(), &c, 1);
    EXPECT_EQ(c, '\0');

    mach_port_t local_port = LocalPort();

    // Get an ExceptionPorts object for the task and each of its threads.
    ExceptionPorts task_ports(ExceptionPorts::kTargetTypeTask, ChildTask());
    EXPECT_STREQ("task", task_ports.TargetTypeName());

    // Hopefully the threads returned by task_threads() are in order, with the
    // main thread first and the other thread second. This is currently always
    // the case, although nothing guarantees that it will remain so.
    thread_act_array_t threads;
    mach_msg_type_number_t thread_count = 0;
    kern_return_t kr = task_threads(ChildTask(), &threads, &thread_count);
    ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "task_threads");

    ScopedForbidReturn threads_need_owners;
    ASSERT_EQ(thread_count, 2u);
    base::mac::ScopedMachSendRight main_thread(threads[0]);
    base::mac::ScopedMachSendRight other_thread(threads[1]);
    threads_need_owners.Disarm();

    ExceptionPorts main_thread_ports(ExceptionPorts::kTargetTypeThread,
                                     main_thread.get());
    ExceptionPorts other_thread_ports(ExceptionPorts::kTargetTypeThread,
                                      other_thread.get());
    EXPECT_STREQ("thread", main_thread_ports.TargetTypeName());
    EXPECT_STREQ("thread", other_thread_ports.TargetTypeName());

    if (set_type_ == kSetOutOfProcess) {
      // Test ExceptionPorts::SetExceptionPort() being called from
      // out-of-process.
      //
      // local_port is only a receive right, but a send right is needed for
      // ExceptionPorts::SetExceptionPort(). Make a send right, which can be
      // deallocated once the calls to ExceptionPorts::SetExceptionPort() are
      // done.
      kr = mach_port_insert_right(
          mach_task_self(), local_port, local_port, MACH_MSG_TYPE_MAKE_SEND);
      ASSERT_EQ(kr, KERN_SUCCESS)
          << MachErrorMessage(kr, "mach_port_insert_right");
      base::mac::ScopedMachSendRight send_owner(local_port);

      switch (set_or_swap_) {
        case kSetExceptionPort: {
          ASSERT_TRUE(task_ports.SetExceptionPort(EXC_MASK_CRASH,
                                                  local_port,
                                                  EXCEPTION_DEFAULT,
                                                  THREAD_STATE_NONE));

          if (set_on_ == kSetOnTaskAndThreads) {
            ASSERT_TRUE(
                main_thread_ports.SetExceptionPort(EXC_MASK_CRASH,
                                                   local_port,
                                                   EXCEPTION_STATE,
                                                   MACHINE_THREAD_STATE));

            ASSERT_TRUE(
                other_thread_ports.SetExceptionPort(EXC_MASK_CRASH,
                                                    local_port,
                                                    EXCEPTION_STATE_IDENTITY,
                                                    MACHINE_THREAD_STATE));
          }
          break;
        }

        case kSwapExceptionPorts: {
          ExceptionPorts::ExceptionHandlerVector old_handlers;

          ASSERT_TRUE(task_ports.SwapExceptionPorts(EXC_MASK_CRASH,
                                                    local_port,
                                                    EXCEPTION_DEFAULT,
                                                    THREAD_STATE_NONE,
                                                    &old_handlers));

          if (set_on_ == kSetOnTaskAndThreads) {
            ASSERT_TRUE(
                main_thread_ports.SwapExceptionPorts(EXC_MASK_CRASH,
                                                     local_port,
                                                     EXCEPTION_STATE,
                                                     MACHINE_THREAD_STATE,
                                                     &old_handlers));

            ASSERT_TRUE(
                other_thread_ports.SwapExceptionPorts(EXC_MASK_CRASH,
                                                      local_port,
                                                      EXCEPTION_STATE_IDENTITY,
                                                      MACHINE_THREAD_STATE,
                                                      &old_handlers));
          }
          break;
        }

        default: {
          NOTREACHED();
        }
      }
    }

    // Regardless of where ExceptionPorts::SetExceptionPort() ran,
    // ExceptionPorts::GetExceptionPorts() can always be tested out-of-process.
    {
      SCOPED_TRACE("task");
      TestGetExceptionPorts(task_ports, local_port, EXCEPTION_DEFAULT);
    }

    mach_port_t thread_handler =
        (set_on_ == kSetOnTaskAndThreads) ? local_port : MACH_PORT_NULL;

    {
      SCOPED_TRACE("main_thread");
      TestGetExceptionPorts(main_thread_ports, thread_handler, EXCEPTION_STATE);
    }

    {
      SCOPED_TRACE("other_thread");
      TestGetExceptionPorts(
          other_thread_ports, thread_handler, EXCEPTION_STATE_IDENTITY);
    }

    // Let the child process know that everything in the parent process is set
    // up.
    c = '\0';
    CheckedWriteFile(WritePipeHandle(), &c, 1);

    if (who_crashes_ != kNobodyCrashes) {
      UniversalMachExcServer universal_mach_exc_server(this);

      constexpr mach_msg_timeout_t kTimeoutMs = 50;
      kern_return_t kr =
          MachMessageServer::Run(&universal_mach_exc_server,
                                 local_port,
                                 kMachMessageReceiveAuditTrailer,
                                 MachMessageServer::kOneShot,
                                 MachMessageServer::kReceiveLargeError,
                                 kTimeoutMs);
      EXPECT_EQ(kr, KERN_SUCCESS)
          << MachErrorMessage(kr, "MachMessageServer::Run");

      EXPECT_TRUE(handled_);
    }

    // Wait for the child process to exit or terminate, as indicated by it
    // closing its pipe. This keeps LocalPort() alive in the child as
    // RemotePort(), for the child’s use in its TestGetExceptionPorts().
    CheckedReadFileAtEOF(ReadPipeHandle());
  }

  void MachMultiprocessChild() override {
    Child child(this);
    child.Run();
  }

  SetOrSwap set_or_swap_;
  SetOn set_on_;
  SetType set_type_;
  WhoCrashes who_crashes_;

  // true if an exception message was handled.
  bool handled_;

  DISALLOW_COPY_AND_ASSIGN(TestExceptionPorts);
};

TEST(ExceptionPorts, TaskExceptionPorts_SetInProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(TestExceptionPorts::kSetExceptionPort,
                                          TestExceptionPorts::kSetOnTaskOnly,
                                          TestExceptionPorts::kSetInProcess,
                                          TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SetInProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SetInProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SetInProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SetInProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts,
     TaskAndThreadExceptionPorts_SetInProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SetOutOfProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(TestExceptionPorts::kSetExceptionPort,
                                          TestExceptionPorts::kSetOnTaskOnly,
                                          TestExceptionPorts::kSetOutOfProcess,
                                          TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SetOutOfProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SetOutOfProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SetOutOfProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts,
     TaskAndThreadExceptionPorts_SetOutOfProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts,
     TaskAndThreadExceptionPorts_SetOutOfProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSetExceptionPort,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SwapInProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SwapInProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SwapInProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SwapInProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts,
     TaskAndThreadExceptionPorts_SwapInProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts,
     TaskAndThreadExceptionPorts_SwapInProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetInProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SwapOutOfProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SwapOutOfProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskExceptionPorts_SwapOutOfProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskOnly,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, TaskAndThreadExceptionPorts_SwapOutOfProcess_NoCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kNobodyCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts,
     TaskAndThreadExceptionPorts_SwapOutOfProcess_MainThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kMainThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts,
     TaskAndThreadExceptionPorts_SwapOutOfProcess_OtherThreadCrash) {
  TestExceptionPorts test_exception_ports(
      TestExceptionPorts::kSwapExceptionPorts,
      TestExceptionPorts::kSetOnTaskAndThreads,
      TestExceptionPorts::kSetOutOfProcess,
      TestExceptionPorts::kOtherThreadCrashes);
  test_exception_ports.Run();
}

TEST(ExceptionPorts, HostExceptionPorts) {
  // ExceptionPorts isn’t expected to work as non-root. Just do a quick test to
  // make sure that TargetTypeName() returns the right string, and that the
  // underlying host_get_exception_ports() function appears to be called by
  // looking for a KERN_INVALID_ARGUMENT return value. Or, on the off chance
  // that the test is being run as root, just look for KERN_SUCCESS.
  // host_set_exception_ports() is not tested, because if the test were running
  // as root and the call succeeded, it would have global effects.

  const bool expect_success = geteuid() == 0;

  base::mac::ScopedMachSendRight host(mach_host_self());
  ExceptionPorts explicit_host_ports(ExceptionPorts::kTargetTypeHost,
                                     host.get());
  EXPECT_STREQ("host", explicit_host_ports.TargetTypeName());

  ExceptionPorts::ExceptionHandlerVector explicit_handlers;
  bool rv =
      explicit_host_ports.GetExceptionPorts(ExcMaskValid(), &explicit_handlers);
  EXPECT_EQ(rv, expect_success);

  ExceptionPorts implicit_host_ports(ExceptionPorts::kTargetTypeHost,
                                     HOST_NULL);
  EXPECT_STREQ("host", implicit_host_ports.TargetTypeName());

  ExceptionPorts::ExceptionHandlerVector implicit_handlers;
  rv =
      implicit_host_ports.GetExceptionPorts(ExcMaskValid(), &implicit_handlers);
  EXPECT_EQ(rv, expect_success);

  EXPECT_EQ(implicit_handlers.size(), explicit_handlers.size());
}

}  // namespace
}  // namespace test
}  // namespace crashpad
