// Copyright (c) 2013 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.

// The chrome collector collects crashes from the chrome binary.
// It's a bit special - instead of the kernel running it through
// /proc/sys/kernel/core_pattern, chrome invokes it directly and passes in a
// crash dump generated by Crashpad or the JavaScript error reporting system.

#ifndef CRASH_REPORTER_CHROME_COLLECTOR_H_
#define CRASH_REPORTER_CHROME_COLLECTOR_H_

#include <map>
#include <memory>
#include <string>

#include <base/files/file_path.h>
#include <base/macros.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "crash-reporter/crash_collector.h"

// Chrome crash collector.
class ChromeCollector : public CrashCollector {
 public:
  explicit ChromeCollector(CrashSendingMode crash_sending_mode);
  ChromeCollector(const ChromeCollector&) = delete;
  ChromeCollector& operator=(const ChromeCollector&) = delete;

  ~ChromeCollector() override;

  // Magic string to let Chrome know the crash report succeeded.
  static const char kSuccessMagic[];

  // Handle a specific chrome crash.  Returns true on success.
  bool HandleCrash(const base::FilePath& dump_file_path,
                   pid_t pid,
                   uid_t uid,
                   const std::string& exe_name);

  // Handle a specific chrome crash through a memfd instead of a file.
  // Returns true on success.
  bool HandleCrashThroughMemfd(int memfd,
                               pid_t pid,
                               uid_t uid,
                               const std::string& executable_name,
                               const std::string& non_exe_error_key,
                               const std::string& dump_dir);

  static CollectorInfo GetHandlerInfo(CrashSendingMode mode,
                                      const std::string& dump_file_path,
                                      int memfd,
                                      pid_t pid,
                                      uid_t uid,
                                      const std::string& executable_name,
                                      const std::string& non_exe_error_key,
                                      const std::string& chrome_dump_dir);

  void set_max_upload_bytes_for_test(int max_upload_bytes) {
    max_upload_bytes_ = max_upload_bytes;
  }

 private:
  friend class ChromeCollectorTest;
  FRIEND_TEST(ChromeCollectorTest, GoodValues);
  FRIEND_TEST(ChromeCollectorTest, GoodLacros);
  FRIEND_TEST(ChromeCollectorTest, ParseCrashLogNoDump);
  FRIEND_TEST(ChromeCollectorTest, ParseCrashLogJSStack);
  FRIEND_TEST(ChromeCollectorTest, BadValues);
  FRIEND_TEST(ChromeCollectorTest, Newlines);
  FRIEND_TEST(ChromeCollectorTest, File);
  FRIEND_TEST(ChromeCollectorTest, HandleCrash);
  FRIEND_TEST(ChromeCollectorTest, HandleCrashWithEmbeddedNuls);
  FRIEND_TEST(ChromeCollectorTest, HandleCrashWithWeirdFilename);

  enum CrashType {
    // An executable received a signal like SIGSEGV or SIGILL; the sort of thing
    // that would lead to a core file on Linux. (Also covers Chrome's
    // DumpWithoutCrashing function.)
    kExecutableCrash,

    // A JavaScript error is being reported.
    kJavaScriptError
  };

  // Handle a specific chrome crash with dump data.
  // Returns true on success.
  bool HandleCrashWithDumpData(const std::string& data,
                               pid_t pid,
                               uid_t uid,
                               const std::string& executable_name,
                               const std::string& non_exe_error_key,
                               const std::string& dump_dir);

  // Crashes are expected to be in a TLV-style format of:
  // <name>:<length>:<value>
  // Length is encoded as a decimal number. It can be zero, but must consist of
  // at least one character
  // For file values, name actually contains both a description and a filename,
  // in a fixed format of: <description>"; filename="<filename>".
  // The path to the payload (minidump or JS Exception) will be written to
  // |payload|.
  bool ParseCrashLog(const std::string& data,
                     const base::FilePath& dir,
                     const std::string& basename,
                     CrashType crash_type,
                     base::FilePath* payload,
                     bool* is_lacros_crash);

  // Some classes of JavaScript errors do not have stacks. Since crash_sender
  // cannot send error reports without a payload, create a simple payload that
  // just states there was no stack.
  bool CreateNoStackJSPayload(const base::FilePath& dir,
                              const std::string& dump_basename,
                              base::FilePath* payload_path);

  // Gets the GPU's error state from debugd and writes it to |error_state_path|.
  // Returns true on success.
  bool GetDriErrorState(const base::FilePath& error_state_path);

  // Writes additional logs for the crash to files based on |basename| within
  // |dir|. |key_for_logs| is the key into crash_reporter_logs.conf file. Crash
  // report metadata key names and the corresponding file paths are returned.
  std::map<std::string, base::FilePath> GetAdditionalLogs(
      const base::FilePath& dir,
      const std::string& basename,
      const std::string& key_for_logs,
      CrashType crash_type);

  // Add the (|log_map_key|, |complete_file_name|) pair to |logs| if we are not
  // over kDefaultMaxUploadBytes. If we are over kDefaultMaxUploadBytes,
  // delete the file |complete_file_name| instead and don't change |logs|.
  // |complete_file_name| must be a file created by
  // CrashCollector::WriteNewFile() or CrashCollector::WriteNewCompressedFile()
  // so that CrashCollector::RemoveNewFile() works on it.
  void AddLogIfNotTooBig(const char* log_map_key,
                         const base::FilePath& complete_file_name,
                         std::map<std::string, base::FilePath>* logs);

  // The file where we write our special "done" marker (to indicate to Chrome
  // that we are finished dumping). Always stdout in production.
  FILE* output_file_ptr_;

  // We skip uploading the supplemental files (logs, i915_error_state) if it
  // would make the report larger than max_upload_bytes_. In production, this
  // is always kDefaultMaxUploadBytes.
  int max_upload_bytes_;
};

#endif  // CRASH_REPORTER_CHROME_COLLECTOR_H_
