1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "chrome/app/kasko_client.h"
13 #include "base/debug/crash_logging.h"
14 #include "base/guid.h"
15 #include "base/logging.h"
16 #include "base/process/process_handle.h"
17 #include "base/win/wrapped_window_proc.h"
18 #include "breakpad/src/client/windows/common/ipc_protocol.h"
19 #include "chrome/app/chrome_watcher_client_win.h"
20 #include "chrome/chrome_watcher/chrome_watcher_main_api.h"
21 #include "chrome/common/chrome_constants.h"
22 #include "chrome/common/crash_keys.h"
23 #include "components/crash/app/crash_keys_win.h"
24 #include "syzygy/kasko/api/client.h"
27 ChromeWatcherClient
* g_chrome_watcher_client
= nullptr;
30 KaskoClient::KaskoClient(ChromeWatcherClient
* chrome_watcher_client
) {
31 DCHECK(!g_chrome_watcher_client
);
32 g_chrome_watcher_client
= chrome_watcher_client
;
34 kasko::api::InitializeClient(
35 GetKaskoEndpoint(base::GetCurrentProcId()).c_str());
38 KaskoClient::~KaskoClient() {
39 DCHECK(g_chrome_watcher_client
);
40 g_chrome_watcher_client
= nullptr;
41 kasko::api::ShutdownClient();
44 extern "C" void __declspec(dllexport
) ReportCrashWithProtobuf(
45 EXCEPTION_POINTERS
* info
, const char* protobuf
, size_t protobuf_length
) {
47 sizeof(kasko::api::CrashKey
) == sizeof(google_breakpad::CustomInfoEntry
),
48 "CrashKey and CustomInfoEntry structs are not compatible.");
49 static_assert(offsetof(kasko::api::CrashKey
, name
) ==
50 offsetof(google_breakpad::CustomInfoEntry
, name
),
51 "CrashKey and CustomInfoEntry structs are not compatible.");
52 static_assert(offsetof(kasko::api::CrashKey
, value
) ==
53 offsetof(google_breakpad::CustomInfoEntry
, value
),
54 "CrashKey and CustomInfoEntry structs are not compatible.");
56 sizeof(reinterpret_cast<kasko::api::CrashKey
*>(0)->name
) ==
57 sizeof(reinterpret_cast<google_breakpad::CustomInfoEntry
*>(0)->name
),
58 "CrashKey and CustomInfoEntry structs are not compatible.");
60 sizeof(reinterpret_cast<kasko::api::CrashKey
*>(0)->value
) ==
61 sizeof(reinterpret_cast<google_breakpad::CustomInfoEntry
*>(0)->value
),
62 "CrashKey and CustomInfoEntry structs are not compatible.");
64 // Assign a GUID that can be used to correlate the Kasko report to the
65 // Breakpad report, to verify data consistency.
66 std::string guid
= base::GenerateGUID();
68 base::debug::ScopedCrashKey
kasko_guid(crash_keys::kKaskoGuid
, guid
);
69 size_t crash_key_count
=
70 breakpad::CrashKeysWin::keeper()->custom_info_entries().size();
71 const kasko::api::CrashKey
* crash_keys
=
72 reinterpret_cast<const kasko::api::CrashKey
*>(
73 breakpad::CrashKeysWin::keeper()->custom_info_entries().data());
75 if (g_chrome_watcher_client
&&
76 g_chrome_watcher_client
->EnsureInitialized()) {
77 kasko::api::SendReport(info
, protobuf
, protobuf_length
, crash_keys
,
83 base::debug::ScopedCrashKey
kasko_equivalent_guid(
84 crash_keys::kKaskoEquivalentGuid
, guid
);
85 // While Kasko remains experimental, also report via Breakpad.
86 base::win::WinProcExceptionFilter crash_for_exception
=
87 reinterpret_cast<base::win::WinProcExceptionFilter
>(::GetProcAddress(
88 ::GetModuleHandle(chrome::kBrowserProcessExecutableName
),
89 "CrashForException"));
90 crash_for_exception(info
);
94 #endif // defined(SYZYASAN)