// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>  // for open
#include <sys/mount.h>  // for MS_SLAVE

#include <string>
#include <utility>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/strings/stringprintf.h>
#include <base/message_loop/message_loop.h>
#include <base/optional.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include <libminijail.h>
#include <metrics/metrics_library.h>

#include "crash-reporter/arc_collector.h"
#include "crash-reporter/bert_collector.h"
#include "crash-reporter/chrome_collector.h"
#include "crash-reporter/constants.h"
#include "crash-reporter/crash_reporter_failure_collector.h"
#include "crash-reporter/ec_collector.h"
#include "crash-reporter/ephemeral_crash_collector.h"
#include "crash-reporter/generic_failure_collector.h"
#include "crash-reporter/kernel_collector.h"
#include "crash-reporter/kernel_warning_collector.h"
#include "crash-reporter/missed_crash_collector.h"
#include "crash-reporter/mount_failure_collector.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/selinux_violation_collector.h"
#include "crash-reporter/udev_collector.h"
#include "crash-reporter/unclean_shutdown_collector.h"
#include "crash-reporter/user_collector.h"
#include "crash-reporter/util.h"
#include "crash-reporter/vm_collector.h"
#include "crash-reporter/vm_support.h"

using base::FilePath;
using base::StringPrintf;

namespace {

const char kKernelCrashDetected[] =
    "/run/metrics/external/crash-reporter/kernel-crash-detected";
const char kUncleanShutdownDetected[] =
    "/run/metrics/external/crash-reporter/unclean-shutdown-detected";
const char kBootCollectorDone[] = "/run/crash_reporter/boot-collector-done";

bool always_allow_feedback = false;

MetricsLibrary s_metrics_lib;

bool IsFeedbackAllowed() {
  if (always_allow_feedback || util::HasMockConsent())
    return true;

  VmSupport* vm_support = VmSupport::Get();
  if (vm_support)
    return vm_support->GetMetricsConsent();

  return s_metrics_lib.AreMetricsEnabled();
}

bool TouchFile(const FilePath& file_path) {
  return base::WriteFile(file_path, "", 0) == 0;
}

bool SetUpLockFile() {
  base::FilePath lock_file = paths::Get(paths::kCrashSenderLockFile);
  if (!TouchFile(lock_file)) {
    LOG(ERROR) << "Could not touch lock file: " << lock_file.value();
    return false;
  }

  // Allow crash-access group to read and write crash lock file.
  return util::SetGroupAndPermissions(lock_file, constants::kCrashGroupName,
                                      /*execute=*/false);
}

// Set up necessary crash reporter state.
// This function will change ownership and permissions on many files (to allow
// `crash` to read/write them) so it MUST run as root.
// Return true on success.
bool InitializeSystem(UserCollector* user_collector, bool early) {
  // Try to create the lock file for crash_sender. Creating this early ensures
  // that no one else can make a directory or such with this name. If the lock
  // file isn't a normal file, crash_sender will never work correctly.
  if (!SetUpLockFile()) {
    LOG(ERROR) << "Couldn't set up lock file";
    return false;
  }

  // Set up all the common crash state directories first.  If we can't guarantee
  // these basic paths, just give up & don't turn on anything else.
  if (!CrashCollector::InitializeSystemCrashDirectories(early)) {
    return false;
  }

  // Set up metrics flag directory. Returns with non-zero if we cannot create
  // it.
  if (!CrashCollector::InitializeSystemMetricsDirectories()) {
    return false;
  }

  return user_collector->Enable(early);
}

int BootCollect(KernelCollector* kernel_collector,
                ECCollector* ec_collector,
                BERTCollector* bert_collector,
                UncleanShutdownCollector* unclean_shutdown_collector,
                EphemeralCrashCollector* ephemeral_crash_collector) {
  bool was_kernel_crash = false;
  bool was_unclean_shutdown = false;
  LOG(INFO) << "Running boot collector";

  /* TODO(drinkcat): Distinguish between EC crash and unclean shutdown. */
  ec_collector->Collect();

  // Invoke to collect firmware bert dump.
  bert_collector->Collect();

  kernel_collector->Enable();
  if (kernel_collector->is_enabled()) {
    was_kernel_crash = kernel_collector->Collect();
  }
  was_unclean_shutdown = unclean_shutdown_collector->Collect();

  // Touch a file to notify the metrics daemon that a kernel
  // crash has been detected so that it can log the time since
  // the last kernel crash.
  if (IsFeedbackAllowed()) {
    if (was_kernel_crash) {
      TouchFile(FilePath(kKernelCrashDetected));
    } else if (was_unclean_shutdown) {
      // We only count an unclean shutdown if it did not come with
      // an associated kernel crash.
      TouchFile(FilePath(kUncleanShutdownDetected));
    }
  }

  // Must enable the unclean shutdown collector *after* collecting.
  unclean_shutdown_collector->Enable();

  // Copy lsb-release and os-release into system crash spool.  Done after
  // collecting so that boot-time collected crashes will be associated with the
  // previous boot.
  unclean_shutdown_collector->SaveVersionData();

  // Collect ephemeral crashes.
  ephemeral_crash_collector->Collect();

  // Presence of this files unblocks powerd from performing lid-closed action
  // (crbug.com/988831).
  TouchFile(FilePath(kBootCollectorDone));

  return 0;
}

// Ensure stdout, stdin, and stderr are open file descriptors.  If
// they are not, any code which writes to stderr/stdout may write out
// to files opened during execution.  In particular, when
// crash_reporter is run by the kernel coredump pipe handler (via
// kthread_create/kernel_execve), it will not have file table entries
// 1 and 2 (stdout and stderr) populated.  We populate them here.
void OpenStandardFileDescriptors() {
  int new_fd = -1;
  // We open /dev/null to fill in any of the standard [0, 2] file
  // descriptors.  We leave these open for the duration of the
  // process.  This works because open returns the lowest numbered
  // invalid fd.
  do {
    new_fd = open("/dev/null", 0);
    CHECK_GE(new_fd, 0) << "Unable to open /dev/null";
  } while (new_fd >= 0 && new_fd <= 2);
  close(new_fd);
}

// Reduce privs that we don't need.  But we still need:
// - The top most /proc to pull details out of it.
// - Read access to the crashing process's memory (regardless of user).
// - Write access to the crash spool dir.
void EnterSandbox(bool write_proc, bool log_to_stderr) {
  // If we're not root, we won't be able to jail ourselves (well, we could if
  // we used user namespaces, but maybe later).  Need to double check handling
  // when called by chrome to process its crashes.
  if (getuid() != 0)
    return;

  struct minijail* j = minijail_new();
  minijail_namespace_ipc(j);
  minijail_namespace_uts(j);
  minijail_namespace_net(j);
  minijail_namespace_vfs(j);
  // Remount mounts as MS_SLAVE to prevent crash_reporter from holding on to
  // mounts that might be unmounted in the root mount namespace.
  minijail_remount_mode(j, MS_SLAVE);
  minijail_mount_tmp(j);
  minijail_mount_dev(j);
  if (!log_to_stderr)
    minijail_bind(j, "/dev/log", "/dev/log", 0);
  minijail_no_new_privs(j);
  minijail_new_session_keyring(j);

  // If we're initializing the system, we need to write to /proc/sys/.
  if (!write_proc) {
    minijail_remount_proc_readonly(j);
  }

  minijail_enter(j);
  minijail_destroy(j);
}

}  // namespace

// Information to invoke a specific call on a collector.
struct InvocationInfo {
  // True iff this callback should be invoked.
  // Once this is true and we invoke the associated callback, main() returns,
  // so only one handler can run for each execution of crash_reporter.
  bool should_handle;
  // Callback to invoke if |should_handle| is true. (can be null).
  base::RepeatingCallback<bool()> cb;
};

// Information required to initialize and invoke a collector
struct CollectorInfo {
  // An un-owned pointer to the collector
  CrashCollector* collector;
  // Initialization function. If none is specified, invoke the default
  // crash_collector Initialize().
  base::RepeatingClosure init;
  // List of handlers with associated conditions.
  // If a particular condition is true, run init and the associated handler (if
  // any). If there is no associated handler, keep going.
  std::vector<InvocationInfo> handlers;
};

int main(int argc, char* argv[]) {
  DEFINE_bool(init, false, "Initialize crash logging");
  DEFINE_bool(boot_collect, false, "Run per-boot crash collection tasks");
  DEFINE_bool(clean_shutdown, false, "Signal clean shutdown");
  DEFINE_bool(mount_failure, false, "Report mount failure");
  DEFINE_bool(umount_failure, false, "Report umount failure");
  DEFINE_string(mount_device, "",
                "Device that failed to mount. Used with --mount_failure and "
                "--umount_failure");
  DEFINE_bool(ephemeral_collect, false,
              "Move crash reports to more persistent storage if available "
              "(tmpfs -> reboot vault) or (tmpfs/reboot vault -> encstateful)");
  DEFINE_bool(crash_test, false, "Crash test");
  DEFINE_bool(early, false,
              "Modifies crash-reporter to work during early boot");
  DEFINE_bool(preserve_across_clobber, false,
              "Persist early user crash reports across clobbers.");
  DEFINE_string(user, "", "User crash info (pid:signal:exec_name)");
  DEFINE_string(udev, "", "Udev event description (type:device:subsystem)");
  DEFINE_bool(kernel_warning, false, "Report collected kernel warning");
  DEFINE_bool(kernel_wifi_warning, false,
              "Report collected kernel wifi warning");
  DEFINE_bool(kernel_suspend_warning, false,
              "Report collected kernel suspend warning");
  DEFINE_bool(missed_chrome_crash, false,
              "Report that we missed a Chrome crash");
  DEFINE_bool(log_to_stderr, false, "Log to stderr instead of syslog.");
  DEFINE_string(arc_service_failure, "",
                "The specific ARC service name that failed");
  DEFINE_bool(suspend_failure, false, "Report collected suspend failure logs.");
  DEFINE_bool(vm_crash, false, "Report collected from VM crash");
  DEFINE_int32(vm_pid, -1, "PID of the main VM process");
  DEFINE_bool(crash_reporter_crashed, false,
              "Report crash_reporter itself crashing");
  DEFINE_string(service_failure, "", "The specific service name that failed");
  DEFINE_bool(selinux_violation, false, "Report collected SELinux violation");
  // TODO(crbug.com/1000398): Remove --chrome flag after Chrome switches from
  // breakpad to crashpad.
  // Note: --chrome is being replaced by --chrome_memfd;
  //       --chrome_dump_dir is only used for tests and only used when
  // --chrome_memfd is used and not when --chrome is used.
  DEFINE_string(chrome, "", "Chrome crash dump file");
  DEFINE_int32(chrome_memfd, -1, "Chrome crash dump memfd");
  DEFINE_string(chrome_dump_dir, "",
                "Directory to write Chrome minidumps, used for tests only");
  DEFINE_int32(pid, -1, "PID of crashing process");
  DEFINE_int32(uid, -1, "UID of crashing process");
  DEFINE_string(exe, "", "Executable name of crashing process");
  DEFINE_int64(crash_loop_before, -1,
               "UNIX timestamp. If invoked before this time, use the special "
               "login-crash-loop handling system. (Keep crash report in memory "
               "and then pass to debugd for immediate upload.)");
  DEFINE_bool(core2md_failure, false, "Core2md failure test");
  DEFINE_bool(directory_failure, false, "Spool directory failure test");
  DEFINE_bool(
      always_allow_feedback, false,
      "Force if feedback is allowed check to return true, used for tests only");
#if USE_CHEETS
  DEFINE_string(arc_java_crash, "",
                "Read Java crash log of the given type from standard input");
  DEFINE_string(arc_device, "", "Metadata for --arc_java_crash");
  DEFINE_string(arc_board, "", "Metadata for --arc_java_crash");
  DEFINE_string(arc_cpu_abi, "", "Metadata for --arc_java_crash");
  DEFINE_string(arc_fingerprint, "", "Metadata for --arc_java_crash");
#endif

  OpenStandardFileDescriptors();
  FilePath my_path = base::MakeAbsoluteFilePath(FilePath(argv[0]));
  brillo::FlagHelper::Init(argc, argv, "Chromium OS Crash Reporter");

  base::MessageLoopForIO message_loop;
  base::FileDescriptorWatcher watcher(message_loop.task_runner());

  // In certain cases, /dev/log may not be available: log to stderr instead.
  if (FLAGS_log_to_stderr) {
    brillo::InitLog(brillo::kLogToStderr);
  } else {
    brillo::OpenLog(my_path.BaseName().value().c_str(), true);
    brillo::InitLog(brillo::kLogToSyslog);
  }

  if (util::SkipCrashCollection(argc, argv)) {
    return 0;
  }

  if (FLAGS_always_allow_feedback) {
    CHECK(util::IsTestImage()) << "--always_allow_feedback is only for tests";
    always_allow_feedback = true;
  }

  // Make it possible to test what happens when we crash while handling a crash.
  if (FLAGS_crash_test) {
    LOG(ERROR) << "crash_test requested";
    *(volatile char*)0 = 0;
    return 0;
  }

  // Now that we've processed the command line, sandbox ourselves.
  EnterSandbox(FLAGS_init || FLAGS_clean_shutdown, FLAGS_log_to_stderr);

  // Decide if we should use Crash-Loop sending mode. If session_manager sees
  // several Chrome crashes in a brief period, it will log the user out. On the
  // last Chrome startup before it logs the user out, it will set the
  // --crash_loop_before flag. The value of the flag will be a time_t timestamp
  // giving the last second at which a crash would be considered a crash loop
  // and thus log the user out. If we have another crash before that second,
  // we have detected a crash-loop and we want to invoke special handling
  // (specifically, we don't want to save the crash in the user's home directory
  // because that will be inaccessible to crash_sender once the user is logged
  // out).
  CrashCollector::CrashSendingMode crash_sending_mode =
      CrashCollector::kNormalCrashSendMode;
  if (FLAGS_crash_loop_before >= 0) {
    base::Time crash_loop_before =
        base::Time::FromTimeT(static_cast<time_t>(FLAGS_crash_loop_before));
    if (base::Time::Now() <= crash_loop_before) {
      crash_sending_mode = CrashCollector::kCrashLoopSendingMode;
      LOG(INFO) << "Using crash loop sending mode";
    }
  }

  UserCollectorBase::CrashAttributes user_crash_attrs;
  if (!FLAGS_user.empty()) {
    base::Optional<UserCollectorBase::CrashAttributes> attrs =
        UserCollectorBase::ParseCrashAttributes(FLAGS_user);
    if (!attrs.has_value()) {
      LOG(ERROR) << "Invalid parameter: --user=" << FLAGS_user;
      return 1;
    }
    user_crash_attrs = *attrs;
  }

  std::vector<CollectorInfo> collectors;
#if USE_CHEETS
  ArcCollector arc_collector;

  // Always initialize arc_collector so that we can use it to determine if the
  // process is an arc process.
  arc_collector.Initialize(IsFeedbackAllowed, FLAGS_directory_failure,
                           false /* early */);
  bool is_arc_process = !FLAGS_user.empty() && ArcCollector::IsArcRunning() &&
                        arc_collector.IsArcProcess(user_crash_attrs.pid);

  collectors.push_back({
      .collector = &arc_collector,
      .init = base::DoNothing(),
      .handlers =
          {{
               .should_handle = is_arc_process,
               .cb = base::BindRepeating(&ArcCollector::HandleCrash,
                                         base::Unretained(&arc_collector),
                                         user_crash_attrs, nullptr),
           },
           {
               .should_handle = !FLAGS_arc_java_crash.empty(),
               .cb = base::BindRepeating(
                   &ArcCollector::HandleJavaCrash,
                   base::Unretained(&arc_collector), FLAGS_arc_java_crash,
                   ArcCollector::BuildProperty{
                       .device = FLAGS_arc_device,
                       .board = FLAGS_arc_board,
                       .cpu_abi = FLAGS_arc_cpu_abi,
                       .fingerprint = FLAGS_arc_fingerprint,
                   }),
           }},
  });
#else   // USE_CHEETS
  bool is_arc_process = false;
#endif  // USE_CHEETS

  UserCollector user_collector;
  collectors.push_back({
      .collector = &user_collector,
      .init = base::BindRepeating(
          &UserCollector::Initialize, base::Unretained(&user_collector),
          my_path.value(), IsFeedbackAllowed, FLAGS_core2md_failure,
          FLAGS_directory_failure, FLAGS_early),
      .handlers = {{
                       // NOTE: This is not handling a crash; it's instead
                       // initializing the entire crash reporting system.
                       .should_handle = FLAGS_init,
                       .cb = base::BindRepeating(InitializeSystem,
                                                 &user_collector, FLAGS_early),
                   },
                   {
                       .should_handle = FLAGS_clean_shutdown,
                       // Leave cb unset: clean_shutdown requires other
                       // collectors, so it's handled later.
                   },
                   {
                       .should_handle = !FLAGS_user.empty() && !is_arc_process,
                       .cb = base::BindRepeating(
                           &UserCollector::HandleCrash,
                           base::Unretained(&user_collector), user_crash_attrs,
                           nullptr),
                   }},
  });

  EphemeralCrashCollector ephemeral_crash_collector;
  collectors.push_back({
      .collector = &ephemeral_crash_collector,
      .init =
          base::BindRepeating(&EphemeralCrashCollector::Initialize,
                              base::Unretained(&ephemeral_crash_collector),
                              IsFeedbackAllowed, FLAGS_preserve_across_clobber),
      .handlers =
          {{
               .should_handle = FLAGS_ephemeral_collect,
               .cb = base::BindRepeating(
                   &EphemeralCrashCollector::Collect,
                   base::Unretained(&ephemeral_crash_collector)),
           },
           {
               .should_handle = FLAGS_boot_collect,
               // leave cb empty because boot_collect needs multiple collectors.
               // It's handled separately at the end of main.
           }},
  });

  MountFailureCollector mount_failure_collector(
      MountFailureCollector::ValidateStorageDeviceType(FLAGS_mount_device));
  collectors.push_back({
      .collector = &mount_failure_collector,
      .handlers = {{
          .should_handle = FLAGS_mount_failure || FLAGS_umount_failure,
          .cb = base::BindRepeating(&MountFailureCollector::Collect,
                                    base::Unretained(&mount_failure_collector),
                                    FLAGS_mount_failure),
      }},
  });

  MissedCrashCollector missed_crash_collector;
  collectors.push_back({
      .collector = &missed_crash_collector,
      .handlers = {{
          .should_handle = FLAGS_missed_chrome_crash,
          .cb = base::BindRepeating(&MissedCrashCollector::Collect,
                                    base::Unretained(&missed_crash_collector),
                                    FLAGS_pid),
      }},
  });

  UncleanShutdownCollector unclean_shutdown_collector;
  collectors.push_back({
      .collector = &unclean_shutdown_collector,
      .handlers = {{
          .should_handle = FLAGS_boot_collect || FLAGS_clean_shutdown,
          // leave cb empty because both of these need multiple collectors and
          // are handled separately at the end of main.
      }},
  });

  std::vector<InvocationInfo> boot_handlers = {{
      .should_handle = FLAGS_boot_collect,
      // leave cb empty because boot_collect needs multiple collectors and is
      // handled separately at the end of main. should_handle is only true so
      // the collector gets initialized.
  }};

  KernelCollector kernel_collector;
  collectors.push_back({
      .collector = &kernel_collector,
      .handlers = boot_handlers,
  });

  ECCollector ec_collector;
  collectors.push_back({
      .collector = &ec_collector,
      .handlers = boot_handlers,
  });

  BERTCollector bert_collector;
  collectors.push_back({
      .collector = &bert_collector,
      .handlers = boot_handlers,
  });

  UdevCollector udev_collector;
  collectors.push_back({.collector = &udev_collector,
                        .handlers = {{
                            .should_handle = !FLAGS_udev.empty(),
                            .cb = base::BindRepeating(
                                &UdevCollector::HandleCrash,
                                base::Unretained(&udev_collector), FLAGS_udev),
                        }}});

  CHECK(FLAGS_chrome.empty() || FLAGS_chrome_memfd == -1)
      << "--chrome= and --chrome_memfd= cannot be both set";

  ChromeCollector chrome_collector(crash_sending_mode);
  collectors.push_back({
      .collector = &chrome_collector,
      .handlers =
          {{
               .should_handle = !FLAGS_chrome.empty(),
               .cb = base::BindRepeating(&ChromeCollector::HandleCrash,
                                         base::Unretained(&chrome_collector),
                                         FilePath(FLAGS_chrome), FLAGS_pid,
                                         FLAGS_uid, FLAGS_exe),
           },
           {
               .should_handle = FLAGS_chrome_memfd >= 0,
               .cb = base::BindRepeating(
                   &ChromeCollector::HandleCrashThroughMemfd,
                   base::Unretained(&chrome_collector), FLAGS_chrome_memfd,
                   FLAGS_pid, FLAGS_uid, FLAGS_exe, FLAGS_chrome_dump_dir),
           }},
  });

  KernelWarningCollector kernel_warning_collector;
  base::RepeatingCallback<bool(KernelWarningCollector::WarningType)>
      kernel_warn_cb =
          base::BindRepeating(&KernelWarningCollector::Collect,
                              base::Unretained(&kernel_warning_collector));
  collectors.push_back({
      .collector = &kernel_warning_collector,
      .handlers = {{
                       .should_handle = FLAGS_kernel_warning,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kGeneric),
                   },
                   {
                       .should_handle = FLAGS_kernel_wifi_warning,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kWifi),
                   },
                   {
                       .should_handle = FLAGS_kernel_suspend_warning,
                       .cb = base::BindRepeating(
                           kernel_warn_cb,
                           KernelWarningCollector::WarningType::kSuspend),
                   }},
  });

  GenericFailureCollector generic_failure_collector;
  collectors.push_back(
      {.collector = &generic_failure_collector,
       .handlers = {
           {
               .should_handle = FLAGS_suspend_failure,
               .cb = base::BindRepeating(
                   &GenericFailureCollector::Collect,
                   base::Unretained(&generic_failure_collector),
                   GenericFailureCollector::kSuspendFailure),
           },
           {
               .should_handle = !FLAGS_arc_service_failure.empty(),
               .cb = base::BindRepeating(
                   &GenericFailureCollector::CollectFull,
                   base::Unretained(&generic_failure_collector),
                   StringPrintf("%s-%s",
                                GenericFailureCollector::kArcServiceFailure,
                                FLAGS_arc_service_failure.c_str()),
                   GenericFailureCollector::kArcServiceFailure,
                   util::GetServiceFailureWeight()),
           },
           {
               .should_handle = !FLAGS_service_failure.empty(),
               .cb = base::BindRepeating(
                   &GenericFailureCollector::CollectFull,
                   base::Unretained(&generic_failure_collector),
                   StringPrintf("%s-%s",
                                GenericFailureCollector::kServiceFailure,
                                FLAGS_service_failure.c_str()),
                   GenericFailureCollector::kServiceFailure,
                   util::GetServiceFailureWeight()),
           }}});

  SELinuxViolationCollector selinux_violation_collector;
  collectors.push_back({.collector = &selinux_violation_collector,
                        .handlers = {{
                            .should_handle = FLAGS_selinux_violation,
                            .cb = base::BindRepeating(
                                &SELinuxViolationCollector::Collect,
                                base::Unretained(&selinux_violation_collector)),
                        }}});

  CrashReporterFailureCollector crash_reporter_failure_collector;
  collectors.push_back(
      {.collector = &crash_reporter_failure_collector,
       .handlers = {{
           .should_handle = FLAGS_crash_reporter_crashed,
           .cb = base::BindRepeating(
               &CrashReporterFailureCollector::Collect,
               base::Unretained(&crash_reporter_failure_collector)),
       }}});

  VmCollector vm_collector;
  collectors.push_back({.collector = &vm_collector,
                        .handlers = {{
                            .should_handle = FLAGS_vm_crash,
                            .cb = base::BindRepeating(
                                &VmCollector::Collect,
                                base::Unretained(&vm_collector), FLAGS_vm_pid),
                        }}});

  for (const CollectorInfo& collector : collectors) {
    bool ran_init = false;
    for (const InvocationInfo& info : collector.handlers) {
      if (info.should_handle) {
        if (!ran_init) {
          if (collector.init) {
            collector.init.Run();
          } else {
            collector.collector->Initialize(IsFeedbackAllowed, FLAGS_early);
          }
          ran_init = true;
        }
        if (info.cb) {
          // Accumulate logs to a string to help in diagnosing failures during
          // collection.
          brillo::LogToString(true);
          bool handled = info.cb.Run();
          brillo::LogToString(false);
          return handled ? 0 : 1;
        }
      }
    }
  }

  // These special cases (which use multiple collectors) are at the end so that
  // it's clear that all relevant collectors have been initialized.
  if (FLAGS_boot_collect) {
    return BootCollect(&kernel_collector, &ec_collector, &bert_collector,
                       &unclean_shutdown_collector, &ephemeral_crash_collector);
  }

  if (FLAGS_clean_shutdown) {
    int ret = 0;
    if (!unclean_shutdown_collector.Disable())
      ret = 1;
    if (!user_collector.Disable())
      ret = 1;
    return ret;
  }
}
