// Copyright 2016 The Chromium Embedded Framework Authors. Portions copyright // 2016 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 #include "libcef/common/crash_reporting_win.h" #include "libcef/common/crash_reporting.h" #include "base/debug/crash_logging.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/chrome_constants.h" #include "components/crash/core/common/crash_keys.h" namespace crash_reporting_win { namespace { // exported in crash_reporter_client.cc: // size_t __declspec(dllexport) __cdecl GetCrashKeyCountImpl. typedef size_t(__cdecl* GetCrashKeyCount)(); // exported in crash_reporter_client.cc: // bool __declspec(dllexport) __cdecl GetCrashKeyImpl. typedef bool(__cdecl* GetCrashKey)(size_t, const char**, size_t*); size_t GetCrashKeyCountTrampoline() { static GetCrashKeyCount get_crash_key_count = []() { HMODULE elf_module = GetModuleHandle(chrome::kChromeElfDllName); return reinterpret_cast( elf_module ? GetProcAddress(elf_module, "GetCrashKeyCountImpl") : nullptr); }(); if (get_crash_key_count) { return (get_crash_key_count)(); } return 0; } bool GetCrashKeyTrampoline(size_t index, const char** key_name, size_t* max_length) { static GetCrashKey get_crash_key = []() { HMODULE elf_module = GetModuleHandle(chrome::kChromeElfDllName); return reinterpret_cast( elf_module ? GetProcAddress(elf_module, "GetCrashKeyImpl") : nullptr); }(); if (get_crash_key) { return (get_crash_key)(index, key_name, max_length); } return false; } // From chrome/common/child_process_logging_win.cc: // exported in breakpad_win.cc/crashpad_win.cc: // void __declspec(dllexport) __cdecl SetCrashKeyValueImpl. typedef void(__cdecl* SetCrashKeyValue)(const wchar_t*, const wchar_t*); // exported in breakpad_win.cc/crashpad_win.cc: // void __declspec(dllexport) __cdecl ClearCrashKeyValueImpl. typedef void(__cdecl* ClearCrashKeyValue)(const wchar_t*); void SetCrashKeyValueTrampoline(const base::StringPiece& key, const base::StringPiece& value) { static SetCrashKeyValue set_crash_key = []() { HMODULE elf_module = GetModuleHandle(chrome::kChromeElfDllName); return reinterpret_cast( elf_module ? GetProcAddress(elf_module, "SetCrashKeyValueImpl") : nullptr); }(); if (set_crash_key) { (set_crash_key)(base::UTF8ToWide(key).data(), base::UTF8ToWide(value).data()); } } void ClearCrashKeyValueTrampoline(const base::StringPiece& key) { static ClearCrashKeyValue clear_crash_key = []() { HMODULE elf_module = GetModuleHandle(chrome::kChromeElfDllName); return reinterpret_cast( elf_module ? GetProcAddress(elf_module, "ClearCrashKeyValueImpl") : nullptr); }(); if (clear_crash_key) (clear_crash_key)(base::UTF8ToWide(key).data()); } } // namespace bool InitializeCrashReportingForModule() { base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValueTrampoline, &ClearCrashKeyValueTrampoline); std::vector keys; size_t key_ct = GetCrashKeyCountTrampoline(); if (key_ct > 0U) { keys.reserve(key_ct); const char* key_name; size_t max_length; for (size_t i = 0; i < key_ct; ++i) { if (GetCrashKeyTrampoline(i, &key_name, &max_length)) keys.push_back({key_name, max_length}); } } if (!keys.empty()) { base::debug::InitCrashKeys(&keys[0], keys.size(), crash_keys::kChunkMaxLength); return true; } return false; } void BlockUntilHandlerStarted() { if (!crash_reporting::Enabled()) return; HMODULE chrome_elf = GetModuleHandle(chrome::kChromeElfDllName); if (chrome_elf) { auto block_until_handler_started = reinterpret_cast( GetProcAddress(chrome_elf, "BlockUntilHandlerStartedImpl")); if (block_until_handler_started) block_until_handler_started(); } } } // namespace crash_reporting_win