1// Copyright (c) 2012 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.
4
5#include "chrome/common/child_process_logging.h"
6
7#include <windows.h>
8
9#include "base/debug/crash_logging.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/strings/utf_string_conversions.h"
12#include "chrome/common/chrome_constants.h"
13#include "chrome/common/crash_keys.h"
14#include "chrome/installer/util/google_update_settings.h"
15#include "components/metrics/client_info.h"
16
17namespace child_process_logging {
18
19namespace {
20
21// exported in breakpad_win.cc:
22//    void __declspec(dllexport) __cdecl SetCrashKeyValueImpl.
23typedef void (__cdecl *SetCrashKeyValue)(const wchar_t*, const wchar_t*);
24
25// exported in breakpad_win.cc:
26//    void __declspec(dllexport) __cdecl ClearCrashKeyValueImpl.
27typedef void (__cdecl *ClearCrashKeyValue)(const wchar_t*);
28
29void SetCrashKeyValueTrampoline(const base::StringPiece& key,
30                                const base::StringPiece& value) {
31  static SetCrashKeyValue set_crash_key = NULL;
32  if (!set_crash_key) {
33    HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
34    if (!exe_module)
35      return;
36    set_crash_key = reinterpret_cast<SetCrashKeyValue>(
37        GetProcAddress(exe_module, "SetCrashKeyValueImpl"));
38  }
39
40  if (set_crash_key) {
41    (set_crash_key)(base::UTF8ToWide(key).data(),
42                    base::UTF8ToWide(value).data());
43  }
44}
45
46void ClearCrashKeyValueTrampoline(const base::StringPiece& key) {
47  static ClearCrashKeyValue clear_crash_key = NULL;
48  if (!clear_crash_key) {
49    HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName);
50    if (!exe_module)
51      return;
52    clear_crash_key = reinterpret_cast<ClearCrashKeyValue>(
53        GetProcAddress(exe_module, "ClearCrashKeyValueImpl"));
54  }
55
56  if (clear_crash_key)
57    (clear_crash_key)(base::UTF8ToWide(key).data());
58}
59
60}  // namespace
61
62void Init() {
63  // Note: on other platforms, this is set up during Breakpad initialization,
64  // in ChromeBreakpadClient. But on Windows, that is before the DLL module is
65  // loaded, which is a prerequisite of the crash key system.
66  crash_keys::RegisterChromeCrashKeys();
67  base::debug::SetCrashKeyReportingFunctions(
68      &SetCrashKeyValueTrampoline, &ClearCrashKeyValueTrampoline);
69
70  // This would be handled by BreakpadClient::SetCrashClientIdFromGUID(), but
71  // because of the aforementioned issue, crash keys aren't ready yet at the
72  // time of Breakpad initialization, load the client id backed up in Google
73  // Update settings instead.
74  scoped_ptr<metrics::ClientInfo> client_info =
75      GoogleUpdateSettings::LoadMetricsClientInfo();
76  if (client_info)
77    crash_keys::SetCrashClientIdFromGUID(client_info->client_id);
78}
79
80}  // namespace child_process_logging
81