// Copyright 2015 The Chromium 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 "components/crash/content/app/crashpad.h"

#include <memory>

#include "base/debug/crash_logging.h"
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/crash/content/app/crash_reporter_client.h"
#include "components/crash/content/app/crash_switches.h"
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
#include "third_party/crashpad/crashpad/client/crashpad_info.h"
#include "third_party/crashpad/crashpad/client/simulate_crash_win.h"

namespace crash_reporter {
namespace internal {

namespace {

base::LazyInstance<crashpad::CrashpadClient>::Leaky g_crashpad_client =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

void GetPlatformCrashpadAnnotations(
    std::map<std::string, std::string>* annotations) {
  CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
  wchar_t exe_file[MAX_PATH] = {};
  CHECK(::GetModuleFileName(nullptr, exe_file, arraysize(exe_file)));
  base::string16 product_name, version, special_build, channel_name;
  crash_reporter_client->GetProductNameAndVersion(
      exe_file, &product_name, &version, &special_build, &channel_name);
  (*annotations)["prod"] = base::UTF16ToUTF8(product_name);
  (*annotations)["ver"] = base::UTF16ToUTF8(version);
  (*annotations)["channel"] = base::UTF16ToUTF8(channel_name);
  if (!special_build.empty())
    (*annotations)["special"] = base::UTF16ToUTF8(special_build);
#if defined(ARCH_CPU_X86)
  (*annotations)["plat"] = std::string("Win32");
#elif defined(ARCH_CPU_X86_64)
  (*annotations)["plat"] = std::string("Win64");
#endif
}

base::FilePath PlatformCrashpadInitialization(bool initial_client,
                                              bool browser_process,
                                              bool embedded_handler) {
  base::FilePath database_path;  // Only valid in the browser process.
  base::FilePath metrics_path;  // Only valid in the browser process.

  const char kPipeNameVar[] = "CHROME_CRASHPAD_PIPE_NAME";
  const char kServerUrlVar[] = "CHROME_CRASHPAD_SERVER_URL";
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  if (initial_client) {
    CrashReporterClient* crash_reporter_client = GetCrashReporterClient();

    base::string16 database_path_str;
    if (crash_reporter_client->GetCrashDumpLocation(&database_path_str))
      database_path = base::FilePath(database_path_str);

    base::string16 metrics_path_str;
    if (crash_reporter_client->GetCrashMetricsLocation(&metrics_path_str)) {
      metrics_path = base::FilePath(metrics_path_str);
      CHECK(base::CreateDirectoryAndGetError(metrics_path, nullptr));
    }

    std::map<std::string, std::string> process_annotations;
    GetPlatformCrashpadAnnotations(&process_annotations);

#if defined(GOOGLE_CHROME_BUILD)
    std::string url = "https://clients2.google.com/cr/report";
#else
    std::string url;
#endif

    // Allow the crash server to be overridden for testing. If the variable
    // isn't present in the environment then the default URL will remain.
    env->GetVar(kServerUrlVar, &url);

    wchar_t exe_file_path[MAX_PATH] = {};
    CHECK(
        ::GetModuleFileName(nullptr, exe_file_path, arraysize(exe_file_path)));

    base::FilePath exe_file(exe_file_path);

    bool is_per_user_install =
        crash_reporter_client->GetIsPerUserInstall(exe_file.value());
    if (crash_reporter_client->GetShouldDumpLargerDumps(is_per_user_install)) {
      const uint32_t kIndirectMemoryLimit = 4 * 1024 * 1024;
      crashpad::CrashpadInfo::GetCrashpadInfo()
          ->set_gather_indirectly_referenced_memory(
              crashpad::TriState::kEnabled, kIndirectMemoryLimit);
    }

    // If the handler is embedded in the binary (e.g. chrome, setup), we
    // reinvoke it with --type=crashpad-handler. Otherwise, we use the
    // standalone crashpad_handler.exe (for tests, etc.).
    std::vector<std::string> arguments;
    if (embedded_handler) {
      arguments.push_back(std::string("--type=") + switches::kCrashpadHandler);
      // The prefetch argument added here has to be documented in
      // chrome_switches.cc, below the kPrefetchArgument* constants. A constant
      // can't be used here because crashpad can't depend on Chrome.
      arguments.push_back("/prefetch:7");
    } else {
      base::FilePath exe_dir = exe_file.DirName();
      exe_file = exe_dir.Append(FILE_PATH_LITERAL("crashpad_handler.exe"));
    }

    if (!g_crashpad_client.Get().StartHandler(
            exe_file, database_path, metrics_path, url, process_annotations,
            arguments, false, true)) {
      // This means that CreateThread() failed, so this process is very messed
      // up. This should be effectively unreachable. It is unlikely that there
      // is any utility to ever making this non-fatal, however, if this is done,
      // calls to BlockUntilHandlerStarted() will have to be amended.
      LOG(FATAL) << "synchronous part of handler startup failed";
    }

    // If we're the browser, push the pipe name into the environment so child
    // processes can connect to it. If we inherited another crashpad_handler's
    // pipe name, we'll overwrite it here.
    env->SetVar(kPipeNameVar,
                base::UTF16ToUTF8(g_crashpad_client.Get().GetHandlerIPCPipe()));
  } else {
    std::string pipe_name_utf8;
    if (env->GetVar(kPipeNameVar, &pipe_name_utf8)) {
      g_crashpad_client.Get().SetHandlerIPCPipe(
          base::UTF8ToUTF16(pipe_name_utf8));
    }
  }

  return database_path;
}

// TODO(scottmg): http://crbug.com/546288 These exported functions are for
// compatibility with how Breakpad worked, but it seems like there's no need to
// do the CreateRemoteThread() dance with a minor extension of the Crashpad API
// (to just pass the pid we want a dump for). We should add that and then modify
// hang_crash_dump_win.cc to work in a more direct manner.

// Used for dumping a process state when there is no crash.
extern "C" void __declspec(dllexport) __cdecl DumpProcessWithoutCrash() {
  CRASHPAD_SIMULATE_CRASH();
}

namespace {

// We need to prevent ICF from folding DumpForHangDebuggingThread(),
// DumpProcessForHungInputThread(), DumpProcessForHungInputNoCrashKeysThread()
// and DumpProcessWithoutCrashThread() together, since that makes them
// indistinguishable in crash dumps. We do this by making the function
// bodies unique, and prevent optimization from shuffling things around.
MSVC_DISABLE_OPTIMIZE()
MSVC_PUSH_DISABLE_WARNING(4748)

// Note that this function must be in a namespace for the [Renderer hang]
// annotations to work on the crash server.
DWORD WINAPI DumpProcessWithoutCrashThread(void*) {
  DumpProcessWithoutCrash();
  return 0;
}

// TODO(dtapuska): Remove when enough information is gathered where the crash
// reports without crash keys come from.
DWORD WINAPI DumpProcessForHungInputThread(void* crash_keys_str) {
  base::StringPairs crash_keys;
  if (crash_keys_str && base::SplitStringIntoKeyValuePairs(
                            reinterpret_cast<const char*>(crash_keys_str), ':',
                            ',', &crash_keys)) {
    for (const auto& crash_key : crash_keys) {
      base::debug::SetCrashKeyValue(crash_key.first, crash_key.second);
    }
  }
  DumpProcessWithoutCrash();
  return 0;
}

// TODO(dtapuska): Remove when enough information is gathered where the crash
// reports without crash keys come from.
DWORD WINAPI DumpProcessForHungInputNoCrashKeysThread(void* reason) {
#pragma warning(push)
#pragma warning(disable : 4311 4302)
  base::debug::SetCrashKeyValue(
      "hung-reason", base::IntToString(reinterpret_cast<int>(reason)));
#pragma warning(pop)

  DumpProcessWithoutCrash();
  return 0;
}

// TODO(yzshen): Remove when enough information is collected and the hang rate
// of pepper/renderer processes is reduced.
DWORD WINAPI DumpForHangDebuggingThread(void*) {
  DumpProcessWithoutCrash();
  VLOG(1) << "dumped for hang debugging";
  return 0;
}

MSVC_POP_WARNING()
MSVC_ENABLE_OPTIMIZE()

}  // namespace

}  // namespace internal

void BlockUntilHandlerStarted() {
  // We know that the StartHandler() at least started asynchronous startup if
  // we're here, as if it doesn't, we abort.
  const unsigned int kTimeoutMS = 5000;
  if (!internal::g_crashpad_client.Get().WaitForHandlerStart(kTimeoutMS)) {
    LOG(ERROR) << "Crashpad handler failed to start, crash reporting disabled";
  }
}

}  // namespace crash_reporter

extern "C" {

// Crashes the process after generating a dump for the provided exception. Note
// that the crash reporter should be initialized before calling this function
// for it to do anything.
// NOTE: This function is used by SyzyASAN to invoke a crash. If you change the
// the name or signature of this function you will break SyzyASAN instrumented
// releases of Chrome. Please contact syzygy-team@chromium.org before doing so!
int __declspec(dllexport) CrashForException(
    EXCEPTION_POINTERS* info) {
  crash_reporter::internal::g_crashpad_client.Get().DumpAndCrash(info);
  return EXCEPTION_CONTINUE_SEARCH;
}

// Injects a thread into a remote process to dump state when there is no crash.
HANDLE __declspec(dllexport) __cdecl InjectDumpProcessWithoutCrash(
    HANDLE process) {
  return CreateRemoteThread(
      process, nullptr, 0,
      crash_reporter::internal::DumpProcessWithoutCrashThread, nullptr, 0,
      nullptr);
}

// Injects a thread into a remote process to dump state when there is no crash.
// |serialized_crash_keys| is a nul terminated string that represents serialized
// crash keys sent from the browser. Keys and values are separated by ':', and
// key/value pairs are separated by ','. All keys should be previously
// registered as crash keys. This method is used solely to classify hung input.
HANDLE __declspec(dllexport) __cdecl InjectDumpForHungInput(
    HANDLE process,
    void* serialized_crash_keys) {
  return CreateRemoteThread(
      process, nullptr, 0,
      crash_reporter::internal::DumpProcessForHungInputThread,
      serialized_crash_keys, 0, nullptr);
}

// Injects a thread into a remote process to dump state when there is no crash.
// This method provides |reason| which will interpreted as an integer and logged
// as a crash key.
HANDLE __declspec(dllexport) __cdecl InjectDumpForHungInputNoCrashKeys(
    HANDLE process,
    int reason) {
  return CreateRemoteThread(
      process, nullptr, 0,
      crash_reporter::internal::DumpProcessForHungInputNoCrashKeysThread,
      reinterpret_cast<void*>(reason), 0, nullptr);
}

HANDLE __declspec(dllexport) __cdecl InjectDumpForHangDebugging(
    HANDLE process) {
  return CreateRemoteThread(
      process, nullptr, 0, crash_reporter::internal::DumpForHangDebuggingThread,
      0, 0, nullptr);
}

#if defined(ARCH_CPU_X86_64)

static int CrashForExceptionInNonABICompliantCodeRange(
    PEXCEPTION_RECORD ExceptionRecord,
    ULONG64 EstablisherFrame,
    PCONTEXT ContextRecord,
    PDISPATCHER_CONTEXT DispatcherContext) {
  EXCEPTION_POINTERS info = { ExceptionRecord, ContextRecord };
  return CrashForException(&info);
}

// See https://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
typedef struct _UNWIND_INFO {
  unsigned char Version : 3;
  unsigned char Flags : 5;
  unsigned char SizeOfProlog;
  unsigned char CountOfCodes;
  unsigned char FrameRegister : 4;
  unsigned char FrameOffset : 4;
  ULONG ExceptionHandler;
} UNWIND_INFO, *PUNWIND_INFO;

struct ExceptionHandlerRecord {
  RUNTIME_FUNCTION runtime_function;
  UNWIND_INFO unwind_info;
  unsigned char thunk[12];
};

// These are GetProcAddress()d from V8 binding code.
void __declspec(dllexport) __cdecl RegisterNonABICompliantCodeRange(
    void* start,
    size_t size_in_bytes) {
  ExceptionHandlerRecord* record =
      reinterpret_cast<ExceptionHandlerRecord*>(start);

  // We assume that the first page of the code range is executable and
  // committed and reserved for breakpad. What could possibly go wrong?

  // All addresses are 32bit relative offsets to start.
  record->runtime_function.BeginAddress = 0;
  record->runtime_function.EndAddress =
      base::checked_cast<DWORD>(size_in_bytes);
  record->runtime_function.UnwindData =
      offsetof(ExceptionHandlerRecord, unwind_info);

  // Create unwind info that only specifies an exception handler.
  record->unwind_info.Version = 1;
  record->unwind_info.Flags = UNW_FLAG_EHANDLER;
  record->unwind_info.SizeOfProlog = 0;
  record->unwind_info.CountOfCodes = 0;
  record->unwind_info.FrameRegister = 0;
  record->unwind_info.FrameOffset = 0;
  record->unwind_info.ExceptionHandler =
      offsetof(ExceptionHandlerRecord, thunk);

  // Hardcoded thunk.
  // mov imm64, rax
  record->thunk[0] = 0x48;
  record->thunk[1] = 0xb8;
  void* handler = &CrashForExceptionInNonABICompliantCodeRange;
  memcpy(&record->thunk[2], &handler, 8);

  // jmp rax
  record->thunk[10] = 0xff;
  record->thunk[11] = 0xe0;

  // Protect reserved page against modifications.
  DWORD old_protect;
  CHECK(VirtualProtect(
      start, sizeof(ExceptionHandlerRecord), PAGE_EXECUTE_READ, &old_protect));
  CHECK(RtlAddFunctionTable(
      &record->runtime_function, 1, reinterpret_cast<DWORD64>(start)));
}

void __declspec(dllexport) __cdecl UnregisterNonABICompliantCodeRange(
    void* start) {
  ExceptionHandlerRecord* record =
      reinterpret_cast<ExceptionHandlerRecord*>(start);

  CHECK(RtlDeleteFunctionTable(&record->runtime_function));
}
#endif  // ARCH_CPU_X86_64

}  // extern "C"
