1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif
#include "components/crash/core/common/crash_keys.h"
#include <deque>
#include <string_view>
#include <vector>
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/crash/core/common/crash_buildflags.h"
#include "components/crash/core/common/crash_key.h"
namespace crash_keys {
namespace {
#if !BUILDFLAG(USE_CRASHPAD_ANNOTATION)
// When using Crashpad, the crash reporting client ID is the responsibility of
// Crashpad. It is not set directly by Chrome. When using Breakpad instead of
// Crashpad, the crash reporting client ID is the same as the metrics client ID.
const char kMetricsClientId[] = "guid";
crash_reporter::CrashKeyString<40> client_id_key(kMetricsClientId);
#endif
} // namespace
void SetMetricsClientIdFromGUID(const std::string& metrics_client_guid) {
#if !BUILDFLAG(USE_CRASHPAD_ANNOTATION)
std::string stripped_guid(metrics_client_guid);
// Remove all instance of '-' char from the GUID. So BCD-WXY becomes BCDWXY.
base::ReplaceSubstringsAfterOffset(&stripped_guid, 0, "-",
std::string_view());
if (stripped_guid.empty())
return;
client_id_key.Set(stripped_guid);
#endif
}
void ClearMetricsClientId() {
// Breakpad cannot be enabled or disabled without an application restart, and
// it needs to use the metrics client ID as its stable crash client ID, so
// leave its client ID intact even when metrics reporting is disabled while
// the application is running.
}
using SwitchesCrashKeys = std::deque<crash_reporter::CrashKeyString<64>>;
SwitchesCrashKeys& GetSwitchesCrashKeys() {
static base::NoDestructor<SwitchesCrashKeys> switches_keys;
return *switches_keys;
}
static crash_reporter::CrashKeyString<4> num_switches_key("num-switches");
void SetSwitchesFromCommandLine(const base::CommandLine& command_line,
SwitchFilterFunction skip_filter) {
const base::CommandLine::StringVector& argv = command_line.argv();
// Set the number of switches in case of uninteresting switches in
// command_line.
num_switches_key.Set(base::NumberToString(argv.size() - 1));
size_t key_i = 0;
// Go through the argv, skipping the exec path. Stop if there are too many
// switches to hold in crash keys.
for (size_t i = 1; i < argv.size(); ++i) {
#if BUILDFLAG(IS_WIN)
std::string switch_str = base::WideToUTF8(argv[i]);
#else
std::string switch_str = argv[i];
#endif
// Skip uninteresting switches.
if (skip_filter && (*skip_filter)(switch_str))
continue;
if (key_i >= GetSwitchesCrashKeys().size()) {
static base::NoDestructor<std::deque<std::string>> crash_keys_names;
crash_keys_names->emplace_back(
base::StringPrintf("switch-%" PRIuS, key_i + 1));
GetSwitchesCrashKeys().emplace_back(crash_keys_names->back().c_str());
}
GetSwitchesCrashKeys()[key_i++].Set(switch_str);
}
// Clear any remaining switches.
for (; key_i < GetSwitchesCrashKeys().size(); ++key_i)
GetSwitchesCrashKeys()[key_i].Clear();
}
void ResetCommandLineForTesting() {
num_switches_key.Clear();
for (auto& key : GetSwitchesCrashKeys()) {
key.Clear();
}
}
using PrinterInfoKey = crash_reporter::CrashKeyString<64>;
static PrinterInfoKey printer_info_keys[] = {
{"prn-info-1", PrinterInfoKey::Tag::kArray},
{"prn-info-2", PrinterInfoKey::Tag::kArray},
{"prn-info-3", PrinterInfoKey::Tag::kArray},
{"prn-info-4", PrinterInfoKey::Tag::kArray},
};
ScopedPrinterInfo::ScopedPrinterInfo(const std::string& printer_name,
std::vector<std::string> data) {
CHECK_LE(data.size(), std::size(printer_info_keys));
for (size_t i = 0; i < std::size(printer_info_keys); ++i) {
if (i < data.size()) {
printer_info_keys[i].Set(data[i]);
} else {
printer_info_keys[i].Clear();
}
}
if (data.empty()) {
// No keys were provided. Just store the printer_name.
printer_info_keys[0].Set(printer_name);
}
}
ScopedPrinterInfo::~ScopedPrinterInfo() {
for (auto& crash_key : printer_info_keys) {
crash_key.Clear();
}
}
} // namespace crash_keys
|