xref: /aosp_15_r20/external/cronet/base/debug/crash_logging.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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