// Copyright 2014 The Crashpad Authors
//
// 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 <fcntl.h>
#include <getopt.h>
#include <libgen.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <string>
#include <vector>

#include "base/apple/mach_logging.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "tools/tool_support.h"
#include "util/mach/bootstrap.h"
#include "util/mach/exc_server_variants.h"
#include "util/mach/exception_behaviors.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/mach/symbolic_constants_mach.h"
#include "util/posix/symbolic_constants_posix.h"
#include "util/stdlib/string_number_conversion.h"

namespace crashpad {
namespace {

struct Options {
  std::string file_path;
  std::string mach_service;
  FILE* file;
  int timeout_secs;
  bool has_timeout;
  MachMessageServer::Persistent persistent;
};

class ExceptionServer final : public UniversalMachExcServer::Interface {
 public:
  ExceptionServer(const Options& options,
                  const std::string& me,
                  int* exceptions_handled)
      : UniversalMachExcServer::Interface(),
        options_(options),
        me_(me),
        exceptions_handled_(exceptions_handled) {}

  // 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;
    ++*exceptions_handled_;

    fprintf(options_.file,
            "%s: behavior %s",
            me_.c_str(),
            ExceptionBehaviorToString(
                behavior, kUseFullName | kUnknownIsNumeric | kUseOr).c_str());

    kern_return_t kr;
    if (ExceptionBehaviorHasIdentity(behavior)) {
      // It’s not possible to call pid_for_task() once EXC_CORPSE_NOTIFY has
      // been generated. It is possible to obtain the process ID by mapping the
      // corpse kcdata area from the task’s address space at code[0] (size
      // code[1]) and locating TASK_CRASHINFO_PID within that area. This area
      // also includes TASK_CRASHINFO_CRASHED_THREADID which could be used
      // instead of thread_info() below, and TASK_CRASHINFO_EXCEPTION_CODES
      // which could be used to recover the exception codes passed to the
      // EXC_CRASH handler. None of this is currently done because corpses are a
      // new 10.11-only feature. See 10.11 <corpses/task_corpse.h> and
      // <kern/kern_cdata.h>.
      if (exception != EXC_CORPSE_NOTIFY) {
        pid_t pid;
        kr = pid_for_task(task, &pid);
        if (kr != KERN_SUCCESS) {
          fprintf(options_.file, "\n");
          fflush(options_.file);
          MACH_LOG(ERROR, kr) << "pid_for_task";
          return KERN_FAILURE;
        }
        fprintf(options_.file, ", pid %d", pid);
      }

      thread_identifier_info identifier_info;
      mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
      kr = thread_info(thread,
                       THREAD_IDENTIFIER_INFO,
                       reinterpret_cast<thread_info_t>(&identifier_info),
                       &count);
      if (kr != KERN_SUCCESS) {
        fprintf(options_.file, "\n");
        fflush(options_.file);
        MACH_LOG(ERROR, kr) << "thread_info";
        return KERN_FAILURE;
      }
      fprintf(options_.file, ", thread %lld", identifier_info.thread_id);
    }

    fprintf(
        options_.file,
        ", exception %s, codes[%d]",
        ExceptionToString(exception, kUseFullName | kUnknownIsNumeric).c_str(),
        code_count);

    for (size_t index = 0; index < code_count; ++index) {
      fprintf(options_.file,
              "%s %#llx",
              index != 0 ? "," : "",
              code[index]);
    }

    if (exception == EXC_CRASH) {
      mach_exception_code_t original_code_0;
      int signal;
      exception_type_t original_exception =
          ExcCrashRecoverOriginalException(code[0], &original_code_0, &signal);
      fprintf(options_.file,
              ", original exception %s, original code[0] %lld, signal %s",
              ExceptionToString(original_exception,
                                kUseFullName | kUnknownIsNumeric).c_str(),
              original_code_0,
              SignalToString(signal, kUseFullName | kUnknownIsNumeric).c_str());
    }

    if (ExceptionBehaviorHasState(behavior)) {
      std::string flavor_string =
          ThreadStateFlavorToString(*flavor, kUseFullName | kUnknownIsNumeric);
      fprintf(options_.file,
              ", flavor %s, old_state_count %d",
              flavor_string.c_str(),
              old_state_count);
    }

    fprintf(options_.file, "\n");
    fflush(options_.file);

    if (exception != EXC_CRASH && exception != kMachExceptionSimulated) {
      // Find another handler.
      return KERN_FAILURE;
    }

    ExcServerCopyState(
        behavior, old_state, old_state_count, new_state, new_state_count);

    return ExcServerSuccessfulReturnValue(exception, behavior, false);
  }

 private:
  const Options& options_;
  const std::string& me_;
  int* exceptions_handled_;
};

void Usage(const std::string& me) {
  // clang-format off
  fprintf(stderr,
"Usage: %s -m SERVICE [OPTION]...\n"
"Catch Mach exceptions and display information about them.\n"
"\n"
"  -f, --file=FILE             append information to FILE instead of stdout\n"
"  -m, --mach-service=SERVICE  register SERVICE with the bootstrap server\n"
"  -p, --persistent            continue processing exceptions after the first\n"
"  -t, --timeout=TIMEOUT       run for a maximum of TIMEOUT seconds\n"
"      --help                  display this help and exit\n"
"      --version               output version information and exit\n",
          me.c_str());
  // clang-format on
  ToolSupport::UsageTail(me);
}

int CatchExceptionToolMain(int argc, char* argv[]) {
  const std::string me(basename(argv[0]));

  enum OptionFlags {
    // “Short” (single-character) options.
    kOptionFile = 'f',
    kOptionMachService = 'm',
    kOptionPersistent = 'p',
    kOptionTimeout = 't',

    // Long options without short equivalents.
    kOptionLastChar = 255,

    // Standard options.
    kOptionHelp = -2,
    kOptionVersion = -3,
  };

  Options options = {};

  static constexpr option long_options[] = {
      {"file", required_argument, nullptr, kOptionFile},
      {"mach-service", required_argument, nullptr, kOptionMachService},
      {"persistent", no_argument, nullptr, kOptionPersistent},
      {"timeout", required_argument, nullptr, kOptionTimeout},
      {"help", no_argument, nullptr, kOptionHelp},
      {"version", no_argument, nullptr, kOptionVersion},
      {nullptr, 0, nullptr, 0},
  };

  int opt;
  while ((opt = getopt_long(argc, argv, "f:m:pt:", long_options, nullptr)) !=
         -1) {
    switch (opt) {
      case kOptionFile:
        options.file_path = optarg;
        break;
      case kOptionMachService:
        options.mach_service = optarg;
        break;
      case kOptionPersistent:
        options.persistent = MachMessageServer::kPersistent;
        break;
      case kOptionTimeout:
        if (!StringToNumber(optarg, &options.timeout_secs) ||
            options.timeout_secs < 0) {
          ToolSupport::UsageHint(me, "-t requires a zero or positive TIMEOUT");
          return EXIT_FAILURE;
        }
        options.has_timeout = true;
        break;
      case kOptionHelp:
        Usage(me);
        return EXIT_SUCCESS;
      case kOptionVersion:
        ToolSupport::Version(me);
        return EXIT_SUCCESS;
      default:
        ToolSupport::UsageHint(me, nullptr);
        return EXIT_FAILURE;
    }
  }
  argc -= optind;
  argv += optind;

  if (options.mach_service.empty()) {
    ToolSupport::UsageHint(me, "-m is required");
    return EXIT_FAILURE;
  }

  base::apple::ScopedMachReceiveRight service_port(
      BootstrapCheckIn(options.mach_service));
  if (service_port == kMachPortNull) {
    return EXIT_FAILURE;
  }

  base::ScopedFILE file_owner;
  if (options.file_path.empty()) {
    options.file = stdout;
  } else {
    file_owner.reset(fopen(options.file_path.c_str(), "a"));
    if (!file_owner.get()) {
      PLOG(ERROR) << "fopen " << options.file_path;
      return EXIT_FAILURE;
    }
    options.file = file_owner.get();
    if (fcntl(fileno(options.file), F_SETFD, FD_CLOEXEC) == -1) {
      PLOG(ERROR) << "fcntl " << options.file_path;
      return EXIT_FAILURE;
    }
  }

  int exceptions_handled = 0;
  ExceptionServer exception_server(options, me, &exceptions_handled);
  UniversalMachExcServer universal_mach_exc_server(&exception_server);

  // Assume that if persistent mode has been requested, it’s desirable to ignore
  // large messages and keep running.
  MachMessageServer::ReceiveLarge receive_large =
      (options.persistent == MachMessageServer::kPersistent)
          ? MachMessageServer::kReceiveLargeIgnore
          : MachMessageServer::kReceiveLargeError;

  mach_msg_timeout_t timeout_ms;
  if (!options.has_timeout) {
    timeout_ms = kMachMessageTimeoutWaitIndefinitely;
  } else if (options.timeout_secs == 0) {
    timeout_ms = kMachMessageTimeoutNonblocking;
  } else {
    timeout_ms = options.timeout_secs * 1000;
  }

  mach_msg_return_t mr = MachMessageServer::Run(&universal_mach_exc_server,
                                                service_port.get(),
                                                MACH_MSG_OPTION_NONE,
                                                options.persistent,
                                                receive_large,
                                                timeout_ms);
  if (mr == MACH_RCV_TIMED_OUT && options.has_timeout && options.persistent &&
      exceptions_handled) {
    // This is not an error: when exiting on timeout during persistent
    // processing and at least one exception was handled, it’s considered a
    // success.
  } else if (mr != MACH_MSG_SUCCESS) {
    MACH_LOG(ERROR, mr) << "MachMessageServer::Run";
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

}  // namespace
}  // namespace crashpad

int main(int argc, char* argv[]) {
  return crashpad::CatchExceptionToolMain(argc, argv);
}
