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 #ifndef BASE_DEBUG_CRASH_LOGGING_H_
6 #define BASE_DEBUG_CRASH_LOGGING_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 
12 #include "base/base_export.h"
13 #include "base/macros.h"
14 #include "base/strings/string_piece.h"
15 
16 namespace base {
17 namespace debug {
18 
19 // A crash key is an annotation that is carried along with a crash report, to
20 // provide additional debugging information beyond a stack trace. Crash keys
21 // have a name and a string value.
22 //
23 // The preferred API is //components/crash/core/common:crash_key, however not
24 // all clients can hold a direct dependency on that target. The API provided
25 // in this file indirects the dependency.
26 //
27 // Example usage:
28 //   static CrashKeyString* crash_key =
29 //       AllocateCrashKeyString("name", CrashKeySize::Size32);
30 //   SetCrashKeyString(crash_key, "value");
31 //   ClearCrashKeyString(crash_key);
32 
33 // The maximum length for a crash key's value must be one of the following
34 // pre-determined values.
35 enum class CrashKeySize {
36   Size32 = 32,
37   Size64 = 64,
38   Size256 = 256,
39 };
40 
41 struct CrashKeyString;
42 
43 // Allocates a new crash key with the specified |name| with storage for a
44 // value up to length |size|. This will return null if the crash key system is
45 // not initialized.
46 BASE_EXPORT CrashKeyString* AllocateCrashKeyString(const char name[],
47                                                    CrashKeySize size);
48 
49 // Stores |value| into the specified |crash_key|. The |crash_key| may be null
50 // if AllocateCrashKeyString() returned null. If |value| is longer than the
51 // size with which the key was allocated, it will be truncated.
52 BASE_EXPORT void SetCrashKeyString(CrashKeyString* crash_key,
53                                    base::StringPiece value);
54 
55 // Clears any value that was stored in |crash_key|. The |crash_key| may be
56 // null.
57 BASE_EXPORT void ClearCrashKeyString(CrashKeyString* crash_key);
58 
59 // A scoper that sets the specified key to value for the lifetime of the
60 // object, and clears it on destruction.
61 class BASE_EXPORT ScopedCrashKeyString {
62  public:
63   ScopedCrashKeyString(CrashKeyString* crash_key, base::StringPiece value);
64   ~ScopedCrashKeyString();
65 
66  private:
67   CrashKeyString* const crash_key_;
68 
69   DISALLOW_COPY_AND_ASSIGN(ScopedCrashKeyString);
70 };
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 // The following declarations are used to initialize the crash key system
74 // in //base by providing implementations for the above functions.
75 
76 // The virtual interface that provides the implementation for the crash key
77 // API. This is implemented by a higher-layer component, and the instance is
78 // set using the function below.
79 class CrashKeyImplementation {
80  public:
81   virtual ~CrashKeyImplementation() = default;
82 
83   virtual CrashKeyString* Allocate(const char name[], CrashKeySize size) = 0;
84   virtual void Set(CrashKeyString* crash_key, base::StringPiece value) = 0;
85   virtual void Clear(CrashKeyString* crash_key) = 0;
86 };
87 
88 // Initializes the crash key system in base by replacing the existing
89 // implementation, if it exists, with |impl|. The |impl| is copied into base.
90 BASE_EXPORT void SetCrashKeyImplementation(
91     std::unique_ptr<CrashKeyImplementation> impl);
92 
93 // The base structure for a crash key, storing the allocation metadata.
94 struct CrashKeyString {
CrashKeyStringCrashKeyString95   constexpr CrashKeyString(const char name[], CrashKeySize size)
96       : name(name), size(size) {}
97   const char* const name;
98   const CrashKeySize size;
99 };
100 
101 }  // namespace debug
102 }  // namespace base
103 
104 #endif  // BASE_DEBUG_CRASH_LOGGING_H_
105