1 // Copyright 2012 The Chromium Authors
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 "base/debug/crash_logging.h"
6
7 #include <ostream>
8 #include <string_view>
9
10 #include "build/build_config.h"
11
12 namespace base::debug {
13
14 namespace {
15
16 CrashKeyImplementation* g_crash_key_impl = nullptr;
17
18 } // namespace
19
AllocateCrashKeyString(const char name[],CrashKeySize value_length)20 CrashKeyString* AllocateCrashKeyString(const char name[],
21 CrashKeySize value_length) {
22 if (!g_crash_key_impl)
23 return nullptr;
24
25 // TODO(https://crbug.com/1341077): It would be great if the DCHECKs below
26 // could also be enabled on Android, but debugging tryjob failures was a bit
27 // difficult... :-/
28 #if DCHECK_IS_ON() && !BUILDFLAG(IS_ANDROID)
29 std::string_view name_piece = name;
30
31 // Some `CrashKeyImplementation`s reserve certain characters and disallow
32 // using them in crash key names. See also https://crbug.com/1341077.
33 DCHECK_EQ(base::StringPiece::npos, name_piece.find(':'))
34 << "; name_piece = " << name_piece;
35
36 // Some `CrashKeyImplementation`s support only short crash key names (e.g. see
37 // the DCHECK in crash_reporter::internal::CrashKeyStringImpl::Set).
38 // Enforcing this restrictions here ensures that crash keys will work for all
39 // `CrashKeyStringImpl`s.
40 DCHECK_LT(name_piece.size(), 40u);
41 #endif
42
43 return g_crash_key_impl->Allocate(name, value_length);
44 }
45
SetCrashKeyString(CrashKeyString * crash_key,std::string_view value)46 void SetCrashKeyString(CrashKeyString* crash_key, std::string_view value) {
47 if (!g_crash_key_impl || !crash_key)
48 return;
49
50 g_crash_key_impl->Set(crash_key, value);
51 }
52
ClearCrashKeyString(CrashKeyString * crash_key)53 void ClearCrashKeyString(CrashKeyString* crash_key) {
54 if (!g_crash_key_impl || !crash_key)
55 return;
56
57 g_crash_key_impl->Clear(crash_key);
58 }
59
OutputCrashKeysToStream(std::ostream & out)60 void OutputCrashKeysToStream(std::ostream& out) {
61 if (!g_crash_key_impl)
62 return;
63
64 g_crash_key_impl->OutputCrashKeysToStream(out);
65 }
66
ScopedCrashKeyString(CrashKeyString * crash_key,std::string_view value)67 ScopedCrashKeyString::ScopedCrashKeyString(CrashKeyString* crash_key,
68 std::string_view value)
69 : crash_key_(crash_key) {
70 SetCrashKeyString(crash_key_, value);
71 }
72
ScopedCrashKeyString(ScopedCrashKeyString && other)73 ScopedCrashKeyString::ScopedCrashKeyString(ScopedCrashKeyString&& other)
74 : crash_key_(std::exchange(other.crash_key_, nullptr)) {}
75
~ScopedCrashKeyString()76 ScopedCrashKeyString::~ScopedCrashKeyString() {
77 ClearCrashKeyString(crash_key_);
78 }
79
SetCrashKeyImplementation(std::unique_ptr<CrashKeyImplementation> impl)80 void SetCrashKeyImplementation(std::unique_ptr<CrashKeyImplementation> impl) {
81 delete g_crash_key_impl;
82 g_crash_key_impl = impl.release();
83 }
84
85 } // namespace base::debug
86