// 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 "handler/handler_main.h"

#include <errno.h>
#include <getopt.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>

#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/auto_reset.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/scoped_generic.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "client/crash_report_database.h"
#include "client/crashpad_client.h"
#include "client/crashpad_info.h"
#include "client/prune_crash_reports.h"
#include "client/simple_string_dictionary.h"
#include "handler/crash_report_upload_thread.h"
#include "handler/prune_crash_reports_thread.h"
#include "tools/tool_support.h"
#include "util/file/file_io.h"
#include "util/misc/address_types.h"
#include "util/misc/metrics.h"
#include "util/misc/paths.h"
#include "util/numeric/in_range_cast.h"
#include "util/stdlib/map_insert.h"
#include "util/stdlib/string_number_conversion.h"
#include "util/string/split_string.h"
#include "util/synchronization/semaphore.h"

#if defined(OS_CHROMEOS)
#include "handler/linux/cros_crash_report_exception_handler.h"
#endif

#if defined(OS_LINUX) || defined(OS_ANDROID)
#include <unistd.h>

#include "handler/linux/crash_report_exception_handler.h"
#include "handler/linux/exception_handler_server.h"
#include "util/posix/signals.h"
#elif defined(OS_MACOSX)
#include <libgen.h>
#include <signal.h>

#include "base/mac/scoped_mach_port.h"
#include "handler/mac/crash_report_exception_handler.h"
#include "handler/mac/exception_handler_server.h"
#include "handler/mac/file_limit_annotation.h"
#include "util/mach/bootstrap.h"
#include "util/mach/child_port_handshake.h"
#include "util/posix/close_stdio.h"
#include "util/posix/signals.h"
#elif defined(OS_WIN)
#include <windows.h>

#include "handler/win/crash_report_exception_handler.h"
#include "util/win/exception_handler_server.h"
#include "util/win/handle.h"
#include "util/win/initial_client_data.h"
#include "util/win/session_end_watcher.h"
#elif defined(OS_LINUX)
#include "handler/linux/crash_report_exception_handler.h"
#include "handler/linux/exception_handler_server.h"
#endif  // OS_MACOSX

namespace crashpad {

namespace {

void Usage(const base::FilePath& me) {
  fprintf(stderr,
"Usage: %" PRFilePath " [OPTION]...\n"
"Crashpad's exception handler server.\n"
"\n"
"      --annotation=KEY=VALUE  set a process annotation in each crash report\n"
#if defined(OS_WIN) || defined(OS_LINUX)
"      --attachment=FILE_PATH  attach specified file to each crash report\n"
"                              at the time of the crash\n"
#endif  // OS_WIN || OS_LINUX
"      --database=PATH         store the crash report database at PATH\n"
#if defined(OS_MACOSX)
"      --handshake-fd=FD       establish communication with the client over FD\n"
#endif  // OS_MACOSX
#if defined(OS_WIN)
"      --initial-client-data=HANDLE_request_crash_dump,\n"
"                            HANDLE_request_non_crash_dump,\n"
"                            HANDLE_non_crash_dump_completed,\n"
"                            HANDLE_pipe,\n"
"                            HANDLE_client_process,\n"
"                            Address_crash_exception_information,\n"
"                            Address_non_crash_exception_information,\n"
"                            Address_debug_critical_section\n"
"                              use precreated data to register initial client\n"
#endif  // OS_WIN
#if defined(OS_ANDROID) || defined(OS_LINUX)
"      --initial-client-fd=FD  a socket connected to a client.\n"
#endif  // OS_ANDROID || OS_LINUX
#if defined(OS_MACOSX)
"      --mach-service=SERVICE  register SERVICE with the bootstrap server\n"
#endif  // OS_MACOSX
"      --metrics-dir=DIR       store metrics files in DIR (only in Chromium)\n"
"      --monitor-self          run a second handler to catch crashes in the first\n"
"      --monitor-self-annotation=KEY=VALUE\n"
"                              set a module annotation in the handler\n"
"      --monitor-self-argument=ARGUMENT\n"
"                              provide additional arguments to the second handler\n"
"      --no-identify-client-via-url\n"
"                              when uploading crash report, don't add\n"
"                              client-identifying arguments to URL\n"
"      --no-periodic-tasks     don't scan for new reports or prune the database\n"
"      --no-rate-limit         don't rate limit crash uploads\n"
"      --no-upload-gzip        don't use gzip compression when uploading\n"
#if defined(OS_ANDROID)
"      --no-write-minidump-to-database\n"
"                              don't write minidump to database\n"
#endif  // OS_ANDROID
#if defined(OS_WIN)
"      --pipe-name=PIPE        communicate with the client over PIPE\n"
#endif  // OS_WIN
#if defined(OS_MACOSX)
"      --reset-own-crash-exception-port-to-system-default\n"
"                              reset the server's exception handler to default\n"
#endif  // OS_MACOSX
#if defined(OS_LINUX) || defined(OS_ANDROID)
"      --sanitization-information=SANITIZATION_INFORMATION_ADDRESS\n"
"                              the address of a SanitizationInformation struct.\n"
"      --shared-client-connection the file descriptor provided by\n"
"                              --initial-client-fd is shared among multiple\n"
"                              clients\n"
"      --trace-parent-with-exception=EXCEPTION_INFORMATION_ADDRESS\n"
"                              request a dump for the handler's parent process\n"
#endif  // OS_LINUX || OS_ANDROID
"      --url=URL               send crash reports to this Breakpad server URL,\n"
"                              only if uploads are enabled for the database\n"
#if defined(OS_CHROMEOS)
"      --use-cros-crash-reporter\n"
"                              pass crash reports to /sbin/crash_reporter\n"
"                              instead of storing them in the database\n"
"      --minidump-dir-for-tests=TEST_MINIDUMP_DIR\n"
"                              causes /sbin/crash_reporter to leave dumps in\n"
"                              this directory instead of the normal location\n"
"      --always-allow-feedback\n"
"                              pass the --always_allow_feedback flag to\n"
"                              crash_reporter, thus skipping metrics consent\n"
"                              checks\n"
#endif  // OS_CHROMEOS
#if defined(OS_ANDROID)
"      --write-minidump-to-log write minidump to log\n"
#endif  // OS_ANDROID
"      --help                  display this help and exit\n"
"      --version               output version information and exit\n",
          me.value().c_str());
  ToolSupport::UsageTail(me);
}

struct Options {
  std::map<std::string, std::string> annotations;
  std::map<std::string, std::string> monitor_self_annotations;
  std::string url;
  base::FilePath database;
  base::FilePath metrics_dir;
  std::vector<std::string> monitor_self_arguments;
#if defined(OS_MACOSX)
  std::string mach_service;
  int handshake_fd;
  bool reset_own_crash_exception_port_to_system_default;
#elif defined(OS_LINUX) || defined(OS_ANDROID)
  VMAddress exception_information_address;
  VMAddress sanitization_information_address;
  int initial_client_fd;
  bool shared_client_connection;
#if defined(OS_ANDROID)
  bool write_minidump_to_log;
  bool write_minidump_to_database;
#endif  // OS_ANDROID
#elif defined(OS_WIN)
  std::string pipe_name;
  InitialClientData initial_client_data;
#endif  // OS_MACOSX
  bool identify_client_via_url;
  bool monitor_self;
  bool periodic_tasks;
  bool rate_limit;
  bool upload_gzip;
#if defined(OS_CHROMEOS)
  bool use_cros_crash_reporter = false;
  base::FilePath minidump_dir_for_tests;
  bool always_allow_feedback = false;
#endif  // OS_CHROMEOS
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
    defined(OS_ANDROID)
  std::vector<base::FilePath> attachments;
#endif // OS_WIN || OS_LINUX
};

// Splits |key_value| on '=' and inserts the resulting key and value into |map|.
// If |key_value| has the wrong format, logs an error and returns false. If the
// key is already in the map, logs a warning, replaces the existing value, and
// returns true. If the key and value were inserted into the map, returns true.
// |argument| is used to give context to logged messages.
bool AddKeyValueToMap(std::map<std::string, std::string>* map,
                      const std::string& key_value,
                      const char* argument) {
  std::string key;
  std::string value;
  if (!SplitStringFirst(key_value, '=', &key, &value)) {
    LOG(ERROR) << argument << " requires KEY=VALUE";
    return false;
  }

  std::string old_value;
  if (!MapInsertOrReplace(map, key, value, &old_value)) {
    LOG(WARNING) << argument << " has duplicate key " << key
                 << ", discarding value " << old_value;
  }
  return true;
}

// Calls Metrics::HandlerLifetimeMilestone, but only on the first call. This is
// to prevent multiple exit events from inadvertently being recorded, which
// might happen if a crash occurs during destruction in what would otherwise be
// a normal exit, or if a CallMetricsRecordNormalExit object is destroyed after
// something else logs an exit event.
void MetricsRecordExit(Metrics::LifetimeMilestone milestone) {
  static bool once = [](Metrics::LifetimeMilestone milestone) {
    Metrics::HandlerLifetimeMilestone(milestone);
    return true;
  }(milestone);
  ALLOW_UNUSED_LOCAL(once);
}

// Calls MetricsRecordExit() to record a failure, and returns EXIT_FAILURE for
// the convenience of callers in main() which can simply write “return
// ExitFailure();”.
int ExitFailure() {
  MetricsRecordExit(Metrics::LifetimeMilestone::kFailed);
  return EXIT_FAILURE;
}

class CallMetricsRecordNormalExit {
 public:
  CallMetricsRecordNormalExit() {}
  ~CallMetricsRecordNormalExit() {
    MetricsRecordExit(Metrics::LifetimeMilestone::kExitedNormally);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CallMetricsRecordNormalExit);
};

#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_ANDROID)

void HandleCrashSignal(int sig, siginfo_t* siginfo, void* context) {
  MetricsRecordExit(Metrics::LifetimeMilestone::kCrashed);

  // Is siginfo->si_code useful? The only interesting values on macOS are 0 (not
  // useful, signals generated asynchronously such as by kill() or raise()) and
  // small positive numbers (useful, signal generated via a hardware fault). The
  // standard specifies these other constants, and while xnu never uses them,
  // they are intended to denote signals generated asynchronously and are
  // included here. Additionally, existing practice on other systems
  // (acknowledged by the standard) is for negative numbers to indicate that a
  // signal was generated asynchronously. Although xnu does not do this, allow
  // for the possibility for completeness.
  bool si_code_valid = !(siginfo->si_code <= 0 ||
                         siginfo->si_code == SI_USER ||
                         siginfo->si_code == SI_QUEUE ||
                         siginfo->si_code == SI_TIMER ||
                         siginfo->si_code == SI_ASYNCIO ||
                         siginfo->si_code == SI_MESGQ);

  // 0x5343 = 'SC', signifying “signal and code”, disambiguates from the schema
  // used by ExceptionCodeForMetrics(). That system primarily uses Mach
  // exception types and codes, which are not available to a POSIX signal
  // handler. It does provide a way to encode only signal numbers, but does so
  // with the understanding that certain “raw” signals would not be encountered
  // without a Mach exception. Furthermore, it does not allow siginfo->si_code
  // to be encoded, because that’s not available to Mach exception handlers. It
  // would be a shame to lose that information available to a POSIX signal
  // handler.
  int metrics_code = 0x53430000 | (InRangeCast<uint8_t>(sig, 0xff) << 8);
  if (si_code_valid) {
    metrics_code |= InRangeCast<uint8_t>(siginfo->si_code, 0xff);
  }
  Metrics::HandlerCrashed(metrics_code);

  Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
}

void HandleTerminateSignal(int sig, siginfo_t* siginfo, void* context) {
  MetricsRecordExit(Metrics::LifetimeMilestone::kTerminated);
  Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
}

void ReinstallCrashHandler() {
  // This is used to re-enable the metrics-recording crash handler after
  // MonitorSelf() sets up a Crashpad exception handler. On macOS, the
  // metrics-recording handler uses signals and the Crashpad handler uses Mach
  // exceptions, so there’s nothing to re-enable.
  // On Linux, the signal handler installed by StartHandler() restores the
  // previously installed signal handler by default.
}

void InstallCrashHandler() {
  Signals::InstallCrashHandlers(HandleCrashSignal, 0, nullptr);

  // Not a crash handler, but close enough.
  Signals::InstallTerminateHandlers(HandleTerminateSignal, 0, nullptr);
}

#if defined(OS_MACOSX)

struct ResetSIGTERMTraits {
  static struct sigaction* InvalidValue() {
    return nullptr;
  }

  static void Free(struct sigaction* sa) {
    int rv = sigaction(SIGTERM, sa, nullptr);
    PLOG_IF(ERROR, rv != 0) << "sigaction";
  }
};
using ScopedResetSIGTERM =
    base::ScopedGeneric<struct sigaction*, ResetSIGTERMTraits>;

ExceptionHandlerServer* g_exception_handler_server;

// This signal handler is only operative when being run from launchd.
void HandleSIGTERM(int sig, siginfo_t* siginfo, void* context) {
  // Don’t call MetricsRecordExit(). This is part of the normal exit path when
  // running from launchd.

  DCHECK(g_exception_handler_server);
  g_exception_handler_server->Stop();
}

#endif  // OS_MACOSX

#elif defined(OS_WIN)

LONG(WINAPI* g_original_exception_filter)(EXCEPTION_POINTERS*) = nullptr;

LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
  MetricsRecordExit(Metrics::LifetimeMilestone::kCrashed);
  Metrics::HandlerCrashed(exception_pointers->ExceptionRecord->ExceptionCode);

  if (g_original_exception_filter)
    return g_original_exception_filter(exception_pointers);
  else
    return EXCEPTION_CONTINUE_SEARCH;
}

// Handles events like Control-C and Control-Break on a console.
BOOL WINAPI ConsoleHandler(DWORD console_event) {
  MetricsRecordExit(Metrics::LifetimeMilestone::kTerminated);
  return false;
}

// Handles a WM_ENDSESSION message sent when the user session is ending.
class TerminateHandler final : public SessionEndWatcher {
 public:
  TerminateHandler() : SessionEndWatcher() {}
  ~TerminateHandler() override {}

 private:
  // SessionEndWatcher:
  void SessionEnding() override {
    MetricsRecordExit(Metrics::LifetimeMilestone::kTerminated);
  }

  DISALLOW_COPY_AND_ASSIGN(TerminateHandler);
};

void ReinstallCrashHandler() {
  // This is used to re-enable the metrics-recording crash handler after
  // MonitorSelf() sets up a Crashpad exception handler. The Crashpad handler
  // takes over the UnhandledExceptionFilter, so reinstall the metrics-recording
  // one.
  g_original_exception_filter =
      SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
}

void InstallCrashHandler() {
  ReinstallCrashHandler();

  // These are termination handlers, not crash handlers, but that’s close
  // enough. Note that destroying the TerminateHandler would wait for its thread
  // to exit, which isn’t necessary or desirable.
  SetConsoleCtrlHandler(ConsoleHandler, true);
  static TerminateHandler* terminate_handler = new TerminateHandler();
  ALLOW_UNUSED_LOCAL(terminate_handler);
}

#endif  // OS_MACOSX

void MonitorSelf(const Options& options) {
  base::FilePath executable_path;
  if (!Paths::Executable(&executable_path)) {
    return;
  }

  if (std::find(options.monitor_self_arguments.begin(),
                options.monitor_self_arguments.end(),
                "--monitor-self") != options.monitor_self_arguments.end()) {
    LOG(WARNING) << "--monitor-self-argument=--monitor-self is not supported";
    return;
  }
  std::vector<std::string> extra_arguments(options.monitor_self_arguments);
  if (!options.identify_client_via_url) {
    extra_arguments.push_back("--no-identify-client-via-url");
  }
  extra_arguments.push_back("--no-periodic-tasks");
  if (!options.rate_limit) {
    extra_arguments.push_back("--no-rate-limit");
  }
  if (!options.upload_gzip) {
    extra_arguments.push_back("--no-upload-gzip");
  }
  for (const auto& iterator : options.monitor_self_annotations) {
    extra_arguments.push_back(
        base::StringPrintf("--monitor-self-annotation=%s=%s",
                           iterator.first.c_str(),
                           iterator.second.c_str()));
  }

  // Don’t use options.metrics_dir. The current implementation only allows one
  // instance of crashpad_handler to be writing metrics at a time, and it should
  // be the primary instance.
  CrashpadClient crashpad_client;
#if defined(OS_ANDROID)
  if (!crashpad_client.StartHandlerAtCrash(executable_path,
                                           options.database,
                                           base::FilePath(),
                                           options.url,
                                           options.annotations,
                                           extra_arguments)) {
    return;
  }
#else
  if (!crashpad_client.StartHandler(executable_path,
                                    options.database,
                                    base::FilePath(),
                                    options.url,
                                    options.annotations,
                                    extra_arguments,
                                    true,
                                    false)) {
    return;
  }
#endif

  // Make sure that appropriate metrics will be recorded on crash before this
  // process is terminated.
  ReinstallCrashHandler();
}

class ScopedStoppable {
 public:
  ScopedStoppable() = default;

  ~ScopedStoppable() {
    if (stoppable_) {
      stoppable_->Stop();
    }
  }

  void Reset(Stoppable* stoppable) { stoppable_.reset(stoppable); }

  Stoppable* Get() { return stoppable_.get(); }

 private:
  std::unique_ptr<Stoppable> stoppable_;

  DISALLOW_COPY_AND_ASSIGN(ScopedStoppable);
};

}  // namespace

int HandlerMain(int argc,
                char* argv[],
                const UserStreamDataSources* user_stream_sources) {
#if defined(OS_CHROMEOS)
  if (freopen("/var/log/chrome/chrome", "a", stderr) == nullptr) {
    PLOG(ERROR) << "Failed to redirect stderr to /var/log/chrome/chrome";
  }
#endif

  InstallCrashHandler();
  CallMetricsRecordNormalExit metrics_record_normal_exit;

  const base::FilePath argv0(
      ToolSupport::CommandLineArgumentToFilePathStringType(argv[0]));
  const base::FilePath me(argv0.BaseName());

  enum OptionFlags {
    // Long options without short equivalents.
    kOptionLastChar = 255,
    kOptionAnnotation,
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
    defined(OS_ANDROID)
    kOptionAttachment,
#endif  // OS_WIN || OS_LINUX
    kOptionDatabase,
#if defined(OS_MACOSX)
    kOptionHandshakeFD,
#endif  // OS_MACOSX
#if defined(OS_WIN)
    kOptionInitialClientData,
#endif  // OS_WIN
#if defined(OS_ANDROID) || defined(OS_LINUX)
    kOptionInitialClientFD,
#endif  // OS_ANDROID || OS_LINUX
#if defined(OS_MACOSX)
    kOptionMachService,
#endif  // OS_MACOSX
    kOptionMetrics,
    kOptionMonitorSelf,
    kOptionMonitorSelfAnnotation,
    kOptionMonitorSelfArgument,
    kOptionNoIdentifyClientViaUrl,
    kOptionNoPeriodicTasks,
    kOptionNoRateLimit,
    kOptionNoUploadGzip,
#if defined(OS_ANDROID)
    kOptionNoWriteMinidumpToDatabase,
#endif  // OS_ANDROID
#if defined(OS_WIN)
    kOptionPipeName,
#endif  // OS_WIN
#if defined(OS_MACOSX)
    kOptionResetOwnCrashExceptionPortToSystemDefault,
#endif  // OS_MACOSX
#if defined(OS_LINUX) || defined(OS_ANDROID)
    kOptionSanitizationInformation,
    kOptionSharedClientConnection,
    kOptionTraceParentWithException,
#endif
    kOptionURL,
#if defined(OS_CHROMEOS)
    kOptionUseCrosCrashReporter,
    kOptionMinidumpDirForTests,
    kOptionAlwaysAllowFeedback,
#endif  // OS_CHROMEOS
#if defined(OS_ANDROID)
    kOptionWriteMinidumpToLog,
#endif  // OS_ANDROID

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

  static constexpr option long_options[] = {
    {"annotation", required_argument, nullptr, kOptionAnnotation},
#if defined(OS_WIN) || defined(OS_LINUX)
    {"attachment", required_argument, nullptr, kOptionAttachment},
#endif  // OS_WIN || OS_LINUX
    {"database", required_argument, nullptr, kOptionDatabase},
#if defined(OS_MACOSX)
    {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD},
#endif  // OS_MACOSX
#if defined(OS_WIN)
    {"initial-client-data",
     required_argument,
     nullptr,
     kOptionInitialClientData},
#endif  // OS_MACOSX
#if defined(OS_ANDROID) || defined(OS_LINUX)
    {"initial-client-fd", required_argument, nullptr, kOptionInitialClientFD},
#endif  // OS_ANDROID || OS_LINUX
#if defined(OS_MACOSX)
    {"mach-service", required_argument, nullptr, kOptionMachService},
#endif  // OS_MACOSX
    {"metrics-dir", required_argument, nullptr, kOptionMetrics},
    {"monitor-self", no_argument, nullptr, kOptionMonitorSelf},
    {"monitor-self-annotation",
     required_argument,
     nullptr,
     kOptionMonitorSelfAnnotation},
    {"monitor-self-argument",
     required_argument,
     nullptr,
     kOptionMonitorSelfArgument},
    {"no-identify-client-via-url",
     no_argument,
     nullptr,
     kOptionNoIdentifyClientViaUrl},
    {"no-periodic-tasks", no_argument, nullptr, kOptionNoPeriodicTasks},
    {"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit},
    {"no-upload-gzip", no_argument, nullptr, kOptionNoUploadGzip},
#if defined(OS_ANDROID)
    {"no-write-minidump-to-database",
     no_argument,
     nullptr,
     kOptionNoWriteMinidumpToDatabase},
#endif  // OS_ANDROID
#if defined(OS_WIN)
    {"pipe-name", required_argument, nullptr, kOptionPipeName},
#endif  // OS_WIN
#if defined(OS_MACOSX)
    {"reset-own-crash-exception-port-to-system-default",
     no_argument,
     nullptr,
     kOptionResetOwnCrashExceptionPortToSystemDefault},
#endif  // OS_MACOSX
#if defined(OS_LINUX) || defined(OS_ANDROID)
    {"sanitization-information",
     required_argument,
     nullptr,
     kOptionSanitizationInformation},
    {"shared-client-connection",
     no_argument,
     nullptr,
     kOptionSharedClientConnection},
    {"trace-parent-with-exception",
     required_argument,
     nullptr,
     kOptionTraceParentWithException},
#endif  // OS_LINUX || OS_ANDROID
    {"url", required_argument, nullptr, kOptionURL},
#if defined(OS_CHROMEOS)
    {"use-cros-crash-reporter",
      no_argument,
      nullptr,
      kOptionUseCrosCrashReporter},
    {"minidump-dir-for-tests",
      required_argument,
      nullptr,
      kOptionMinidumpDirForTests},
    {"always-allow-feedback",
      no_argument,
      nullptr,
      kOptionAlwaysAllowFeedback},
#endif  // OS_CHROMEOS
#if defined(OS_ANDROID)
    {"write-minidump-to-log", no_argument, nullptr, kOptionWriteMinidumpToLog},
#endif  // OS_ANDROID
    {"help", no_argument, nullptr, kOptionHelp},
    {"version", no_argument, nullptr, kOptionVersion},
    {nullptr, 0, nullptr, 0},
  };

  Options options = {};
#if defined(OS_MACOSX)
  options.handshake_fd = -1;
#endif
  options.identify_client_via_url = true;
#if defined(OS_LINUX) || defined(OS_ANDROID)
  options.initial_client_fd = kInvalidFileHandle;
#endif
  options.periodic_tasks = true;
  options.rate_limit = true;
  options.upload_gzip = true;
#if defined(OS_ANDROID)
  options.write_minidump_to_database = true;
#endif

  int opt;
  while ((opt = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
    switch (opt) {
      case kOptionAnnotation: {
        if (!AddKeyValueToMap(&options.annotations, optarg, "--annotation")) {
          return ExitFailure();
        }
        break;
      }
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
    defined(OS_ANDROID)
      case kOptionAttachment: {
        options.attachments.push_back(base::FilePath(
            ToolSupport::CommandLineArgumentToFilePathStringType(optarg)));
        break;
      }
#endif  // OS_WIN || OS_LINUX
      case kOptionDatabase: {
        options.database = base::FilePath(
            ToolSupport::CommandLineArgumentToFilePathStringType(optarg));
        break;
      }
#if defined(OS_MACOSX)
      case kOptionHandshakeFD: {
        if (!StringToNumber(optarg, &options.handshake_fd) ||
            options.handshake_fd < 0) {
          ToolSupport::UsageHint(me,
                                 "--handshake-fd requires a file descriptor");
          return ExitFailure();
        }
        break;
      }
      case kOptionMachService: {
        options.mach_service = optarg;
        break;
      }
#endif  // OS_MACOSX
#if defined(OS_WIN)
      case kOptionInitialClientData: {
        if (!options.initial_client_data.InitializeFromString(optarg)) {
          ToolSupport::UsageHint(
              me, "failed to parse --initial-client-data");
          return ExitFailure();
        }
        break;
      }
#endif  // OS_WIN
#if defined(OS_ANDROID) || defined(OS_LINUX)
      case kOptionInitialClientFD: {
        if (!base::StringToInt(optarg, &options.initial_client_fd)) {
          ToolSupport::UsageHint(me, "failed to parse --initial-client-fd");
          return ExitFailure();
        }
        break;
      }
#endif  // OS_ANDROID || OS_LINUX
      case kOptionMetrics: {
        options.metrics_dir = base::FilePath(
            ToolSupport::CommandLineArgumentToFilePathStringType(optarg));
        break;
      }
      case kOptionMonitorSelf: {
        options.monitor_self = true;
        break;
      }
      case kOptionMonitorSelfAnnotation: {
        if (!AddKeyValueToMap(&options.monitor_self_annotations,
                              optarg,
                              "--monitor-self-annotation")) {
          return ExitFailure();
        }
        break;
      }
      case kOptionMonitorSelfArgument: {
        options.monitor_self_arguments.push_back(optarg);
        break;
      }
      case kOptionNoIdentifyClientViaUrl: {
        options.identify_client_via_url = false;
        break;
      }
      case kOptionNoPeriodicTasks: {
        options.periodic_tasks = false;
        break;
      }
      case kOptionNoRateLimit: {
        options.rate_limit = false;
        break;
      }
      case kOptionNoUploadGzip: {
        options.upload_gzip = false;
        break;
      }
#if defined(OS_ANDROID)
      case kOptionNoWriteMinidumpToDatabase: {
        options.write_minidump_to_database = false;
        break;
      }
#endif  // OS_ANDROID
#if defined(OS_WIN)
      case kOptionPipeName: {
        options.pipe_name = optarg;
        break;
      }
#endif  // OS_WIN
#if defined(OS_MACOSX)
      case kOptionResetOwnCrashExceptionPortToSystemDefault: {
        options.reset_own_crash_exception_port_to_system_default = true;
        break;
      }
#endif  // OS_MACOSX
#if defined(OS_LINUX) || defined(OS_ANDROID)
      case kOptionSanitizationInformation: {
        if (!StringToNumber(optarg,
                            &options.sanitization_information_address)) {
          ToolSupport::UsageHint(me,
                                 "failed to parse --sanitization-information");
          return ExitFailure();
        }
        break;
      }
      case kOptionSharedClientConnection: {
        options.shared_client_connection = true;
        break;
      }
      case kOptionTraceParentWithException: {
        if (!StringToNumber(optarg, &options.exception_information_address)) {
          ToolSupport::UsageHint(
              me, "failed to parse --trace-parent-with-exception");
          return ExitFailure();
        }
        break;
      }
#endif  // OS_LINUX || OS_ANDROID
      case kOptionURL: {
        options.url = optarg;
        break;
      }
#if defined(OS_CHROMEOS)
      case kOptionUseCrosCrashReporter: {
        options.use_cros_crash_reporter = true;
        break;
      }
      case kOptionMinidumpDirForTests: {
        options.minidump_dir_for_tests = base::FilePath(
            ToolSupport::CommandLineArgumentToFilePathStringType(optarg));
        break;
      }
      case kOptionAlwaysAllowFeedback: {
        options.always_allow_feedback = true;
        break;
      }
#endif  // OS_CHROMEOS
#if defined(OS_ANDROID)
      case kOptionWriteMinidumpToLog: {
        options.write_minidump_to_log = true;
        break;
      }
#endif  // OS_ANDROID
      case kOptionHelp: {
        Usage(me);
        MetricsRecordExit(Metrics::LifetimeMilestone::kExitedEarly);
        return EXIT_SUCCESS;
      }
      case kOptionVersion: {
        ToolSupport::Version(me);
        MetricsRecordExit(Metrics::LifetimeMilestone::kExitedEarly);
        return EXIT_SUCCESS;
      }
      default: {
        ToolSupport::UsageHint(me, nullptr);
        return ExitFailure();
      }
    }
  }
  argc -= optind;
  argv += optind;

#if defined(OS_MACOSX)
  if (options.handshake_fd < 0 && options.mach_service.empty()) {
    ToolSupport::UsageHint(me, "--handshake-fd or --mach-service is required");
    return ExitFailure();
  }
  if (options.handshake_fd >= 0 && !options.mach_service.empty()) {
    ToolSupport::UsageHint(
        me, "--handshake-fd and --mach-service are incompatible");
    return ExitFailure();
  }
#elif defined(OS_WIN)
  if (!options.initial_client_data.IsValid() && options.pipe_name.empty()) {
    ToolSupport::UsageHint(me,
                           "--initial-client-data or --pipe-name is required");
    return ExitFailure();
  }
  if (options.initial_client_data.IsValid() && !options.pipe_name.empty()) {
    ToolSupport::UsageHint(
        me, "--initial-client-data and --pipe-name are incompatible");
    return ExitFailure();
  }
#elif defined(OS_LINUX) || defined(OS_ANDROID)
  if (!options.exception_information_address &&
      options.initial_client_fd == kInvalidFileHandle) {
    ToolSupport::UsageHint(
        me, "--trace-parent-with-exception or --initial-client-fd is required");
    return ExitFailure();
  }
  if (options.sanitization_information_address &&
      !options.exception_information_address) {
    ToolSupport::UsageHint(
        me,
        "--sanitization_information requires --trace-parent-with-exception");
    return ExitFailure();
  }
  if (options.shared_client_connection &&
      options.initial_client_fd == kInvalidFileHandle) {
    ToolSupport::UsageHint(
        me, "--shared-client-connection requires --initial-client-fd");
    return ExitFailure();
  }
#if defined(OS_ANDROID)
  if (!options.write_minidump_to_log && !options.write_minidump_to_database) {
    ToolSupport::UsageHint(me,
                           "--no_write_minidump_to_database is required to use "
                           "with --write_minidump_to_log.");
    ExitFailure();
  }
#endif  // OS_ANDROID
#endif  // OS_MACOSX

  if (options.database.empty()) {
    ToolSupport::UsageHint(me, "--database is required");
    return ExitFailure();
  }

  if (argc) {
    ToolSupport::UsageHint(me, nullptr);
    return ExitFailure();
  }

#if defined(OS_MACOSX)
  if (options.reset_own_crash_exception_port_to_system_default) {
    CrashpadClient::UseSystemDefaultHandler();
  }
#endif  // OS_MACOSX

  if (options.monitor_self) {
    MonitorSelf(options);
  }

  if (!options.monitor_self_annotations.empty()) {
    // Establish these annotations even if --monitor-self is not present, in
    // case something such as generate_dump wants to try to access them later.
    //
    // If the handler is part of a multi-purpose executable, simple annotations
    // may already be present for this module. If they are, use them.
    CrashpadInfo* crashpad_info = CrashpadInfo::GetCrashpadInfo();
    SimpleStringDictionary* module_annotations =
        crashpad_info->simple_annotations();
    if (!module_annotations) {
      module_annotations = new SimpleStringDictionary();
      crashpad_info->set_simple_annotations(module_annotations);
    }

    for (const auto& iterator : options.monitor_self_annotations) {
      module_annotations->SetKeyValue(iterator.first.c_str(),
                                      iterator.second.c_str());
    }
  }

  std::unique_ptr<CrashReportDatabase> database(
      CrashReportDatabase::Initialize(options.database));
  if (!database) {
    return ExitFailure();
  }

  ScopedStoppable upload_thread;
  if (!options.url.empty()) {
    // TODO(scottmg): options.rate_limit should be removed when we have a
    // configurable database setting to control upload limiting.
    // See https://crashpad.chromium.org/bug/23.
    CrashReportUploadThread::Options upload_thread_options;
    upload_thread_options.identify_client_via_url =
        options.identify_client_via_url;
    upload_thread_options.rate_limit = options.rate_limit;
    upload_thread_options.upload_gzip = options.upload_gzip;
    upload_thread_options.watch_pending_reports = options.periodic_tasks;

    upload_thread.Reset(new CrashReportUploadThread(
        database.get(), options.url, upload_thread_options));
    upload_thread.Get()->Start();
  }

#if defined(OS_LINUX) || defined(OS_ANDROID)
  std::unique_ptr<ExceptionHandlerServer::Delegate> exception_handler;
#else
  std::unique_ptr<CrashReportExceptionHandler> exception_handler;
#endif

#if defined(OS_CHROMEOS)
  if (options.use_cros_crash_reporter) {
    auto cros_handler = std::make_unique<CrosCrashReportExceptionHandler>(
        database.get(),
        &options.annotations,
        user_stream_sources);

    if (!options.minidump_dir_for_tests.empty()) {
      cros_handler->SetDumpDir(options.minidump_dir_for_tests);
    }

    if (options.always_allow_feedback) {
      cros_handler->SetAlwaysAllowFeedback();
    }

    exception_handler = std::move(cros_handler);
  } else {
    exception_handler = std::make_unique<CrashReportExceptionHandler>(
        database.get(),
        static_cast<CrashReportUploadThread*>(upload_thread.Get()),
        &options.annotations,
        &options.attachments,
        true,
        false,
        user_stream_sources);
  }
#else
  exception_handler = std::make_unique<CrashReportExceptionHandler>(
      database.get(),
      static_cast<CrashReportUploadThread*>(upload_thread.Get()),
      &options.annotations,
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_ANDROID)
      &options.attachments,
#endif // OS_WIN || OS_LINUX
#if defined(OS_ANDROID)
      options.write_minidump_to_database,
      options.write_minidump_to_log,
#endif  // OS_ANDROID
#if defined(OS_LINUX)
      true,
      false,
#endif  // OS_LINUX
      user_stream_sources);
#endif  // OS_CHROMEOS

#if defined(OS_LINUX) || defined(OS_ANDROID)
  if (options.exception_information_address) {
    ExceptionHandlerProtocol::ClientInformation info;
    info.exception_information_address = options.exception_information_address;
    info.sanitization_information_address =
        options.sanitization_information_address;
    return exception_handler->HandleException(getppid(), geteuid(), info)
               ? EXIT_SUCCESS
               : ExitFailure();
  }
#endif  // OS_LINUX || OS_ANDROID

  ScopedStoppable prune_thread;
  if (options.periodic_tasks) {
    prune_thread.Reset(new PruneCrashReportThread(
        database.get(), PruneCondition::GetDefault()));
    prune_thread.Get()->Start();
  }

#if defined(OS_MACOSX)
  if (options.mach_service.empty()) {
    // Don’t do this when being run by launchd. See launchd.plist(5).
    CloseStdinAndStdout();
  }

  base::mac::ScopedMachReceiveRight receive_right;

  if (options.handshake_fd >= 0) {
    receive_right.reset(
        ChildPortHandshake::RunServerForFD(
            base::ScopedFD(options.handshake_fd),
            ChildPortHandshake::PortRightType::kReceiveRight));
  } else if (!options.mach_service.empty()) {
    receive_right = BootstrapCheckIn(options.mach_service);
  }

  if (!receive_right.is_valid()) {
    return ExitFailure();
  }

  ExceptionHandlerServer exception_handler_server(
      std::move(receive_right), !options.mach_service.empty());
  base::AutoReset<ExceptionHandlerServer*> reset_g_exception_handler_server(
      &g_exception_handler_server, &exception_handler_server);

  struct sigaction old_sigterm_action;
  ScopedResetSIGTERM reset_sigterm;
  if (!options.mach_service.empty()) {
    // When running from launchd, no no-senders notification could ever be
    // triggered, because launchd maintains a send right to the service. When
    // launchd wants the job to exit, it will send a SIGTERM. See
    // launchd.plist(5).
    //
    // Set up a SIGTERM handler that will call exception_handler_server.Stop().
    // This replaces the HandleTerminateSignal handler for SIGTERM.
    if (Signals::InstallHandler(
            SIGTERM, HandleSIGTERM, 0, &old_sigterm_action)) {
      reset_sigterm.reset(&old_sigterm_action);
    }
  }

  RecordFileLimitAnnotation();
#elif defined(OS_WIN)
  // Shut down as late as possible relative to programs we're watching.
  if (!SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY))
    PLOG(ERROR) << "SetProcessShutdownParameters";

  ExceptionHandlerServer exception_handler_server(!options.pipe_name.empty());

  if (!options.pipe_name.empty()) {
    exception_handler_server.SetPipeName(base::UTF8ToUTF16(options.pipe_name));
  }
#elif defined(OS_LINUX) || defined(OS_ANDROID)
  ExceptionHandlerServer exception_handler_server;
#endif  // OS_MACOSX

  base::GlobalHistogramAllocator* histogram_allocator = nullptr;
  if (!options.metrics_dir.empty()) {
    static constexpr char kMetricsName[] = "CrashpadMetrics";
    constexpr size_t kMetricsFileSize = 1 << 20;
    if (base::GlobalHistogramAllocator::CreateWithActiveFileInDir(
            options.metrics_dir, kMetricsFileSize, 0, kMetricsName)) {
      histogram_allocator = base::GlobalHistogramAllocator::Get();
      histogram_allocator->CreateTrackingHistograms(kMetricsName);
    }
  }

  Metrics::HandlerLifetimeMilestone(Metrics::LifetimeMilestone::kStarted);

#if defined(OS_WIN)
  if (options.initial_client_data.IsValid()) {
    exception_handler_server.InitializeWithInheritedDataForInitialClient(
        options.initial_client_data, exception_handler.get());
  }
#elif defined(OS_LINUX) || defined(OS_ANDROID)
  if (options.initial_client_fd == kInvalidFileHandle ||
      !exception_handler_server.InitializeWithClient(
          ScopedFileHandle(options.initial_client_fd),
          options.shared_client_connection)) {
    return ExitFailure();
  }
#endif  // OS_WIN

  exception_handler_server.Run(exception_handler.get());

  return EXIT_SUCCESS;
}

}  // namespace crashpad
