xref: /aosp_15_r20/external/cronet/base/debug/alias.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_DEBUG_ALIAS_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_DEBUG_ALIAS_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker namespace base {
13*6777b538SAndroid Build Coastguard Worker namespace debug {
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker // Make the optimizer think that |var| is aliased. This can be used to inhibit
16*6777b538SAndroid Build Coastguard Worker // three different kinds of optimizations:
17*6777b538SAndroid Build Coastguard Worker //
18*6777b538SAndroid Build Coastguard Worker // Case #1: Prevent a local variable from being optimized out if it would not
19*6777b538SAndroid Build Coastguard Worker // otherwise be live at the point of a potential crash. This can only be done
20*6777b538SAndroid Build Coastguard Worker // with local variables, not globals, object members, or function return values
21*6777b538SAndroid Build Coastguard Worker // - these must be copied to locals if you want to ensure they are recorded in
22*6777b538SAndroid Build Coastguard Worker // crash dumps. Function arguments are fine to use since the
23*6777b538SAndroid Build Coastguard Worker // base::debug::Alias() call on them will make sure they are copied to the stack
24*6777b538SAndroid Build Coastguard Worker // even if they were passed in a register. Note that if the local variable is a
25*6777b538SAndroid Build Coastguard Worker // pointer then its value will be retained but the memory that it points to will
26*6777b538SAndroid Build Coastguard Worker // probably not be saved in the crash dump - by default only stack memory is
27*6777b538SAndroid Build Coastguard Worker // saved. Therefore the aliasing technique is usually only worthwhile with
28*6777b538SAndroid Build Coastguard Worker // non-pointer variables. If you have a pointer to an object and you want to
29*6777b538SAndroid Build Coastguard Worker // retain the object's state you need to copy the object or its fields to local
30*6777b538SAndroid Build Coastguard Worker // variables.
31*6777b538SAndroid Build Coastguard Worker //
32*6777b538SAndroid Build Coastguard Worker // Example usage:
33*6777b538SAndroid Build Coastguard Worker //   int last_error = err_;
34*6777b538SAndroid Build Coastguard Worker //   base::debug::Alias(&last_error);
35*6777b538SAndroid Build Coastguard Worker //   DEBUG_ALIAS_FOR_CSTR(name_copy, p->name, 16);
36*6777b538SAndroid Build Coastguard Worker //   CHECK(false);
37*6777b538SAndroid Build Coastguard Worker //
38*6777b538SAndroid Build Coastguard Worker // Case #2: Prevent a tail call into a function. This is useful to make sure the
39*6777b538SAndroid Build Coastguard Worker // function containing the call to base::debug::Alias() will be present in the
40*6777b538SAndroid Build Coastguard Worker // call stack. In this case there is no memory that needs to be on
41*6777b538SAndroid Build Coastguard Worker // the stack so we can use nullptr. The call to base::debug::Alias() needs to
42*6777b538SAndroid Build Coastguard Worker // happen after the call that is suspected to be tail called. Note: This
43*6777b538SAndroid Build Coastguard Worker // technique will prevent tail calls at the specific call site only. To prevent
44*6777b538SAndroid Build Coastguard Worker // them for all invocations of a function look at NOT_TAIL_CALLED.
45*6777b538SAndroid Build Coastguard Worker //
46*6777b538SAndroid Build Coastguard Worker // Example usage:
47*6777b538SAndroid Build Coastguard Worker //   NOINLINE void Foo(){
48*6777b538SAndroid Build Coastguard Worker //     ... code ...
49*6777b538SAndroid Build Coastguard Worker //
50*6777b538SAndroid Build Coastguard Worker //     Bar();
51*6777b538SAndroid Build Coastguard Worker //     base::debug::Alias(nullptr);
52*6777b538SAndroid Build Coastguard Worker //   }
53*6777b538SAndroid Build Coastguard Worker //
54*6777b538SAndroid Build Coastguard Worker // Case #3: Prevent code folding of a non-unique function. Code folding can
55*6777b538SAndroid Build Coastguard Worker // cause the same address to be assigned to different functions if they are
56*6777b538SAndroid Build Coastguard Worker // identical. If finding the precise signature of a function in the call-stack
57*6777b538SAndroid Build Coastguard Worker // is important and it's suspected the function is identical to other functions
58*6777b538SAndroid Build Coastguard Worker // it can be made unique using NO_CODE_FOLDING which is a wrapper around
59*6777b538SAndroid Build Coastguard Worker // base::debug::Alias();
60*6777b538SAndroid Build Coastguard Worker //
61*6777b538SAndroid Build Coastguard Worker // Example usage:
62*6777b538SAndroid Build Coastguard Worker //   NOINLINE void Foo(){
63*6777b538SAndroid Build Coastguard Worker //     NO_CODE_FOLDING();
64*6777b538SAndroid Build Coastguard Worker //     Bar();
65*6777b538SAndroid Build Coastguard Worker //   }
66*6777b538SAndroid Build Coastguard Worker //
67*6777b538SAndroid Build Coastguard Worker // Finally please note that these effects compound. This means that saving a
68*6777b538SAndroid Build Coastguard Worker // stack variable (case #1) using base::debug::Alias() will also inhibit
69*6777b538SAndroid Build Coastguard Worker // tail calls for calls in earlier lines and prevent code folding.
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker void BASE_EXPORT Alias(const void* var);
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker }  // namespace debug
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker // The canonical definitions/declarations for `strlcpy()`, `u16cstrlcpy()`,
76*6777b538SAndroid Build Coastguard Worker // and `wcslcpy()` are in //base/strings/string_util.{cc,h}. These prototypes
77*6777b538SAndroid Build Coastguard Worker // are forward declared here to avoid having to include string_utils.h and its
78*6777b538SAndroid Build Coastguard Worker // transitive tree of headers in an otherwise small header (which is itself
79*6777b538SAndroid Build Coastguard Worker // included in some very popular headers).
80*6777b538SAndroid Build Coastguard Worker BASE_EXPORT size_t strlcpy(char* dst, const char* src, size_t dst_size);
81*6777b538SAndroid Build Coastguard Worker BASE_EXPORT size_t u16cstrlcpy(char16_t* dst,
82*6777b538SAndroid Build Coastguard Worker                                const char16_t* src,
83*6777b538SAndroid Build Coastguard Worker                                size_t dst_size);
84*6777b538SAndroid Build Coastguard Worker BASE_EXPORT size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker }  // namespace base
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker // Convenience macro that copies the null-terminated string from `c_str` into a
89*6777b538SAndroid Build Coastguard Worker // stack-allocated char array named `var_name` that holds up to `array_size - 1`
90*6777b538SAndroid Build Coastguard Worker // characters and should be preserved in memory dumps.
91*6777b538SAndroid Build Coastguard Worker #define DEBUG_ALIAS_FOR_CSTR(var_name, c_str, array_size)  \
92*6777b538SAndroid Build Coastguard Worker   char var_name[array_size] = {};                          \
93*6777b538SAndroid Build Coastguard Worker   ::base::strlcpy(var_name, (c_str), std::size(var_name)); \
94*6777b538SAndroid Build Coastguard Worker   ::base::debug::Alias(var_name)
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker #define DEBUG_ALIAS_FOR_U16CSTR(var_name, c_str, array_size)   \
97*6777b538SAndroid Build Coastguard Worker   char16_t var_name[array_size] = {};                          \
98*6777b538SAndroid Build Coastguard Worker   ::base::u16cstrlcpy(var_name, (c_str), std::size(var_name)); \
99*6777b538SAndroid Build Coastguard Worker   ::base::debug::Alias(var_name)
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker #define DEBUG_ALIAS_FOR_WCHARCSTR(var_name, c_str, array_size) \
102*6777b538SAndroid Build Coastguard Worker   wchar_t var_name[array_size] = {};                           \
103*6777b538SAndroid Build Coastguard Worker   ::base::wcslcpy(var_name, (c_str), std::size(var_name));     \
104*6777b538SAndroid Build Coastguard Worker   ::base::debug::Alias(var_name)
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker // Code folding is a linker optimization whereby the linker identifies functions
107*6777b538SAndroid Build Coastguard Worker // that are bit-identical and overlays them. This saves space but it leads to
108*6777b538SAndroid Build Coastguard Worker // confusing call stacks because multiple symbols are at the same address and
109*6777b538SAndroid Build Coastguard Worker // it is unpredictable which one will be displayed. Disabling of code folding is
110*6777b538SAndroid Build Coastguard Worker // particularly useful when function names are used as signatures in crashes.
111*6777b538SAndroid Build Coastguard Worker // This macro doesn't guarantee that code folding will be prevented but it
112*6777b538SAndroid Build Coastguard Worker // greatly reduces the odds and always prevents it within one source file.
113*6777b538SAndroid Build Coastguard Worker // If using in a function that terminates the process it is safest to put the
114*6777b538SAndroid Build Coastguard Worker // NO_CODE_FOLDING macro at the top of the function.
115*6777b538SAndroid Build Coastguard Worker // Use like:
116*6777b538SAndroid Build Coastguard Worker //   void FooBarFailure(size_t size) { NO_CODE_FOLDING(); OOM_CRASH(size); }
117*6777b538SAndroid Build Coastguard Worker #define NO_CODE_FOLDING()           \
118*6777b538SAndroid Build Coastguard Worker   const int line_number = __LINE__; \
119*6777b538SAndroid Build Coastguard Worker   base::debug::Alias(&line_number)
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker #endif  // BASE_DEBUG_ALIAS_H_
122