// 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& 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);

  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_
