xref: /aosp_15_r20/external/abseil-cpp/absl/base/internal/raw_logging.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/raw_logging.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include <cstdarg>
18*9356374aSAndroid Build Coastguard Worker #include <cstddef>
19*9356374aSAndroid Build Coastguard Worker #include <cstdio>
20*9356374aSAndroid Build Coastguard Worker #include <cstdlib>
21*9356374aSAndroid Build Coastguard Worker #include <cstring>
22*9356374aSAndroid Build Coastguard Worker #include <string>
23*9356374aSAndroid Build Coastguard Worker 
24*9356374aSAndroid Build Coastguard Worker #ifdef __EMSCRIPTEN__
25*9356374aSAndroid Build Coastguard Worker #include <emscripten/console.h>
26*9356374aSAndroid Build Coastguard Worker #endif
27*9356374aSAndroid Build Coastguard Worker 
28*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h"
29*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
30*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/atomic_hook.h"
31*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/errno_saver.h"
32*9356374aSAndroid Build Coastguard Worker #include "absl/base/log_severity.h"
33*9356374aSAndroid Build Coastguard Worker 
34*9356374aSAndroid Build Coastguard Worker // We know how to perform low-level writes to stderr in POSIX and Windows.  For
35*9356374aSAndroid Build Coastguard Worker // these platforms, we define the token ABSL_LOW_LEVEL_WRITE_SUPPORTED.
36*9356374aSAndroid Build Coastguard Worker // Much of raw_logging.cc becomes a no-op when we can't output messages,
37*9356374aSAndroid Build Coastguard Worker // although a FATAL ABSL_RAW_LOG message will still abort the process.
38*9356374aSAndroid Build Coastguard Worker 
39*9356374aSAndroid Build Coastguard Worker // ABSL_HAVE_POSIX_WRITE is defined when the platform provides posix write()
40*9356374aSAndroid Build Coastguard Worker // (as from unistd.h)
41*9356374aSAndroid Build Coastguard Worker //
42*9356374aSAndroid Build Coastguard Worker // This preprocessor token is also defined in raw_io.cc.  If you need to copy
43*9356374aSAndroid Build Coastguard Worker // this, consider moving both to config.h instead.
44*9356374aSAndroid Build Coastguard Worker #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
45*9356374aSAndroid Build Coastguard Worker     defined(__hexagon__) || defined(__Fuchsia__) ||                     \
46*9356374aSAndroid Build Coastguard Worker     defined(__native_client__) || defined(__OpenBSD__) ||               \
47*9356374aSAndroid Build Coastguard Worker     defined(__EMSCRIPTEN__) || defined(__ASYLO__)
48*9356374aSAndroid Build Coastguard Worker 
49*9356374aSAndroid Build Coastguard Worker #include <unistd.h>
50*9356374aSAndroid Build Coastguard Worker 
51*9356374aSAndroid Build Coastguard Worker #define ABSL_HAVE_POSIX_WRITE 1
52*9356374aSAndroid Build Coastguard Worker #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
53*9356374aSAndroid Build Coastguard Worker #else
54*9356374aSAndroid Build Coastguard Worker #undef ABSL_HAVE_POSIX_WRITE
55*9356374aSAndroid Build Coastguard Worker #endif
56*9356374aSAndroid Build Coastguard Worker 
57*9356374aSAndroid Build Coastguard Worker // ABSL_HAVE_SYSCALL_WRITE is defined when the platform provides the syscall
58*9356374aSAndroid Build Coastguard Worker //   syscall(SYS_write, /*int*/ fd, /*char* */ buf, /*size_t*/ len);
59*9356374aSAndroid Build Coastguard Worker // for low level operations that want to avoid libc.
60*9356374aSAndroid Build Coastguard Worker #if (defined(__linux__) || defined(__FreeBSD__)) && !defined(__ANDROID__)
61*9356374aSAndroid Build Coastguard Worker #include <sys/syscall.h>
62*9356374aSAndroid Build Coastguard Worker #define ABSL_HAVE_SYSCALL_WRITE 1
63*9356374aSAndroid Build Coastguard Worker #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
64*9356374aSAndroid Build Coastguard Worker #else
65*9356374aSAndroid Build Coastguard Worker #undef ABSL_HAVE_SYSCALL_WRITE
66*9356374aSAndroid Build Coastguard Worker #endif
67*9356374aSAndroid Build Coastguard Worker 
68*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
69*9356374aSAndroid Build Coastguard Worker #include <io.h>
70*9356374aSAndroid Build Coastguard Worker 
71*9356374aSAndroid Build Coastguard Worker #define ABSL_HAVE_RAW_IO 1
72*9356374aSAndroid Build Coastguard Worker #define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1
73*9356374aSAndroid Build Coastguard Worker #else
74*9356374aSAndroid Build Coastguard Worker #undef ABSL_HAVE_RAW_IO
75*9356374aSAndroid Build Coastguard Worker #endif
76*9356374aSAndroid Build Coastguard Worker 
77*9356374aSAndroid Build Coastguard Worker namespace absl {
78*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
79*9356374aSAndroid Build Coastguard Worker namespace raw_log_internal {
80*9356374aSAndroid Build Coastguard Worker namespace {
81*9356374aSAndroid Build Coastguard Worker 
82*9356374aSAndroid Build Coastguard Worker // TODO(gfalcon): We want raw-logging to work on as many platforms as possible.
83*9356374aSAndroid Build Coastguard Worker // Explicitly `#error` out when not `ABSL_LOW_LEVEL_WRITE_SUPPORTED`, except for
84*9356374aSAndroid Build Coastguard Worker // a selected set of platforms for which we expect not to be able to raw log.
85*9356374aSAndroid Build Coastguard Worker 
86*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
87*9356374aSAndroid Build Coastguard Worker constexpr char kTruncated[] = " ... (message truncated)\n";
88*9356374aSAndroid Build Coastguard Worker 
89*9356374aSAndroid Build Coastguard Worker // sprintf the format to the buffer, adjusting *buf and *size to reflect the
90*9356374aSAndroid Build Coastguard Worker // consumed bytes, and return whether the message fit without truncation.  If
91*9356374aSAndroid Build Coastguard Worker // truncation occurred, if possible leave room in the buffer for the message
92*9356374aSAndroid Build Coastguard Worker // kTruncated[].
93*9356374aSAndroid Build Coastguard Worker bool VADoRawLog(char** buf, int* size, const char* format, va_list ap)
94*9356374aSAndroid Build Coastguard Worker     ABSL_PRINTF_ATTRIBUTE(3, 0);
VADoRawLog(char ** buf,int * size,const char * format,va_list ap)95*9356374aSAndroid Build Coastguard Worker bool VADoRawLog(char** buf, int* size, const char* format, va_list ap) {
96*9356374aSAndroid Build Coastguard Worker   if (*size < 0) return false;
97*9356374aSAndroid Build Coastguard Worker   int n = vsnprintf(*buf, static_cast<size_t>(*size), format, ap);
98*9356374aSAndroid Build Coastguard Worker   bool result = true;
99*9356374aSAndroid Build Coastguard Worker   if (n < 0 || n > *size) {
100*9356374aSAndroid Build Coastguard Worker     result = false;
101*9356374aSAndroid Build Coastguard Worker     if (static_cast<size_t>(*size) > sizeof(kTruncated)) {
102*9356374aSAndroid Build Coastguard Worker       n = *size - static_cast<int>(sizeof(kTruncated));
103*9356374aSAndroid Build Coastguard Worker     } else {
104*9356374aSAndroid Build Coastguard Worker       n = 0;  // no room for truncation message
105*9356374aSAndroid Build Coastguard Worker     }
106*9356374aSAndroid Build Coastguard Worker   }
107*9356374aSAndroid Build Coastguard Worker   *size -= n;
108*9356374aSAndroid Build Coastguard Worker   *buf += n;
109*9356374aSAndroid Build Coastguard Worker   return result;
110*9356374aSAndroid Build Coastguard Worker }
111*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_LOW_LEVEL_WRITE_SUPPORTED
112*9356374aSAndroid Build Coastguard Worker 
113*9356374aSAndroid Build Coastguard Worker constexpr int kLogBufSize = 3000;
114*9356374aSAndroid Build Coastguard Worker 
115*9356374aSAndroid Build Coastguard Worker // CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
116*9356374aSAndroid Build Coastguard Worker // that invoke malloc() and getenv() that might acquire some locks.
117*9356374aSAndroid Build Coastguard Worker 
118*9356374aSAndroid Build Coastguard Worker // Helper for RawLog below.
119*9356374aSAndroid Build Coastguard Worker // *DoRawLog writes to *buf of *size and move them past the written portion.
120*9356374aSAndroid Build Coastguard Worker // It returns true iff there was no overflow or error.
121*9356374aSAndroid Build Coastguard Worker bool DoRawLog(char** buf, int* size, const char* format, ...)
122*9356374aSAndroid Build Coastguard Worker     ABSL_PRINTF_ATTRIBUTE(3, 4);
DoRawLog(char ** buf,int * size,const char * format,...)123*9356374aSAndroid Build Coastguard Worker bool DoRawLog(char** buf, int* size, const char* format, ...) {
124*9356374aSAndroid Build Coastguard Worker   if (*size < 0) return false;
125*9356374aSAndroid Build Coastguard Worker   va_list ap;
126*9356374aSAndroid Build Coastguard Worker   va_start(ap, format);
127*9356374aSAndroid Build Coastguard Worker   int n = vsnprintf(*buf, static_cast<size_t>(*size), format, ap);
128*9356374aSAndroid Build Coastguard Worker   va_end(ap);
129*9356374aSAndroid Build Coastguard Worker   if (n < 0 || n > *size) return false;
130*9356374aSAndroid Build Coastguard Worker   *size -= n;
131*9356374aSAndroid Build Coastguard Worker   *buf += n;
132*9356374aSAndroid Build Coastguard Worker   return true;
133*9356374aSAndroid Build Coastguard Worker }
134*9356374aSAndroid Build Coastguard Worker 
DefaultLogFilterAndPrefix(absl::LogSeverity,const char * file,int line,char ** buf,int * buf_size)135*9356374aSAndroid Build Coastguard Worker bool DefaultLogFilterAndPrefix(absl::LogSeverity, const char* file, int line,
136*9356374aSAndroid Build Coastguard Worker                                char** buf, int* buf_size) {
137*9356374aSAndroid Build Coastguard Worker   DoRawLog(buf, buf_size, "[%s : %d] RAW: ", file, line);
138*9356374aSAndroid Build Coastguard Worker   return true;
139*9356374aSAndroid Build Coastguard Worker }
140*9356374aSAndroid Build Coastguard Worker 
141*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
142*9356374aSAndroid Build Coastguard Worker absl::base_internal::AtomicHook<LogFilterAndPrefixHook>
143*9356374aSAndroid Build Coastguard Worker     log_filter_and_prefix_hook(DefaultLogFilterAndPrefix);
144*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
145*9356374aSAndroid Build Coastguard Worker absl::base_internal::AtomicHook<AbortHook> abort_hook;
146*9356374aSAndroid Build Coastguard Worker 
147*9356374aSAndroid Build Coastguard Worker void RawLogVA(absl::LogSeverity severity, const char* file, int line,
148*9356374aSAndroid Build Coastguard Worker               const char* format, va_list ap) ABSL_PRINTF_ATTRIBUTE(4, 0);
RawLogVA(absl::LogSeverity severity,const char * file,int line,const char * format,va_list ap)149*9356374aSAndroid Build Coastguard Worker void RawLogVA(absl::LogSeverity severity, const char* file, int line,
150*9356374aSAndroid Build Coastguard Worker               const char* format, va_list ap) {
151*9356374aSAndroid Build Coastguard Worker   char buffer[kLogBufSize];
152*9356374aSAndroid Build Coastguard Worker   char* buf = buffer;
153*9356374aSAndroid Build Coastguard Worker   int size = sizeof(buffer);
154*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
155*9356374aSAndroid Build Coastguard Worker   bool enabled = true;
156*9356374aSAndroid Build Coastguard Worker #else
157*9356374aSAndroid Build Coastguard Worker   bool enabled = false;
158*9356374aSAndroid Build Coastguard Worker #endif
159*9356374aSAndroid Build Coastguard Worker 
160*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_MIN_LOG_LEVEL
161*9356374aSAndroid Build Coastguard Worker   if (severity < static_cast<absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) &&
162*9356374aSAndroid Build Coastguard Worker       severity < absl::LogSeverity::kFatal) {
163*9356374aSAndroid Build Coastguard Worker     enabled = false;
164*9356374aSAndroid Build Coastguard Worker   }
165*9356374aSAndroid Build Coastguard Worker #endif
166*9356374aSAndroid Build Coastguard Worker 
167*9356374aSAndroid Build Coastguard Worker   enabled = log_filter_and_prefix_hook(severity, file, line, &buf, &size);
168*9356374aSAndroid Build Coastguard Worker   const char* const prefix_end = buf;
169*9356374aSAndroid Build Coastguard Worker 
170*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
171*9356374aSAndroid Build Coastguard Worker   if (enabled) {
172*9356374aSAndroid Build Coastguard Worker     bool no_chop = VADoRawLog(&buf, &size, format, ap);
173*9356374aSAndroid Build Coastguard Worker     if (no_chop) {
174*9356374aSAndroid Build Coastguard Worker       DoRawLog(&buf, &size, "\n");
175*9356374aSAndroid Build Coastguard Worker     } else {
176*9356374aSAndroid Build Coastguard Worker       DoRawLog(&buf, &size, "%s", kTruncated);
177*9356374aSAndroid Build Coastguard Worker     }
178*9356374aSAndroid Build Coastguard Worker     AsyncSignalSafeWriteError(buffer, strlen(buffer));
179*9356374aSAndroid Build Coastguard Worker   }
180*9356374aSAndroid Build Coastguard Worker #else
181*9356374aSAndroid Build Coastguard Worker   static_cast<void>(format);
182*9356374aSAndroid Build Coastguard Worker   static_cast<void>(ap);
183*9356374aSAndroid Build Coastguard Worker   static_cast<void>(enabled);
184*9356374aSAndroid Build Coastguard Worker #endif
185*9356374aSAndroid Build Coastguard Worker 
186*9356374aSAndroid Build Coastguard Worker   // Abort the process after logging a FATAL message, even if the output itself
187*9356374aSAndroid Build Coastguard Worker   // was suppressed.
188*9356374aSAndroid Build Coastguard Worker   if (severity == absl::LogSeverity::kFatal) {
189*9356374aSAndroid Build Coastguard Worker     abort_hook(file, line, buffer, prefix_end, buffer + kLogBufSize);
190*9356374aSAndroid Build Coastguard Worker     abort();
191*9356374aSAndroid Build Coastguard Worker   }
192*9356374aSAndroid Build Coastguard Worker }
193*9356374aSAndroid Build Coastguard Worker 
194*9356374aSAndroid Build Coastguard Worker // Non-formatting version of RawLog().
195*9356374aSAndroid Build Coastguard Worker //
196*9356374aSAndroid Build Coastguard Worker // TODO(gfalcon): When string_view no longer depends on base, change this
197*9356374aSAndroid Build Coastguard Worker // interface to take its message as a string_view instead.
DefaultInternalLog(absl::LogSeverity severity,const char * file,int line,const std::string & message)198*9356374aSAndroid Build Coastguard Worker void DefaultInternalLog(absl::LogSeverity severity, const char* file, int line,
199*9356374aSAndroid Build Coastguard Worker                         const std::string& message) {
200*9356374aSAndroid Build Coastguard Worker   RawLog(severity, file, line, "%.*s", static_cast<int>(message.size()),
201*9356374aSAndroid Build Coastguard Worker          message.data());
202*9356374aSAndroid Build Coastguard Worker }
203*9356374aSAndroid Build Coastguard Worker 
204*9356374aSAndroid Build Coastguard Worker }  // namespace
205*9356374aSAndroid Build Coastguard Worker 
AsyncSignalSafeWriteError(const char * s,size_t len)206*9356374aSAndroid Build Coastguard Worker void AsyncSignalSafeWriteError(const char* s, size_t len) {
207*9356374aSAndroid Build Coastguard Worker   if (!len) return;
208*9356374aSAndroid Build Coastguard Worker   absl::base_internal::ErrnoSaver errno_saver;
209*9356374aSAndroid Build Coastguard Worker #if defined(__EMSCRIPTEN__)
210*9356374aSAndroid Build Coastguard Worker   // In WebAssembly, bypass filesystem emulation via fwrite.
211*9356374aSAndroid Build Coastguard Worker   if (s[len - 1] == '\n') {
212*9356374aSAndroid Build Coastguard Worker     // Skip a trailing newline character as emscripten_errn adds one itself.
213*9356374aSAndroid Build Coastguard Worker     len--;
214*9356374aSAndroid Build Coastguard Worker   }
215*9356374aSAndroid Build Coastguard Worker   // emscripten_errn was introduced in 3.1.41 but broken in standalone mode
216*9356374aSAndroid Build Coastguard Worker   // until 3.1.43.
217*9356374aSAndroid Build Coastguard Worker #if ABSL_INTERNAL_EMSCRIPTEN_VERSION >= 3001043
218*9356374aSAndroid Build Coastguard Worker   emscripten_errn(s, len);
219*9356374aSAndroid Build Coastguard Worker #else
220*9356374aSAndroid Build Coastguard Worker   char buf[kLogBufSize];
221*9356374aSAndroid Build Coastguard Worker   if (len >= kLogBufSize) {
222*9356374aSAndroid Build Coastguard Worker     len = kLogBufSize - 1;
223*9356374aSAndroid Build Coastguard Worker     constexpr size_t trunc_len = sizeof(kTruncated) - 2;
224*9356374aSAndroid Build Coastguard Worker     memcpy(buf + len - trunc_len, kTruncated, trunc_len);
225*9356374aSAndroid Build Coastguard Worker     buf[len] = '\0';
226*9356374aSAndroid Build Coastguard Worker     len -= trunc_len;
227*9356374aSAndroid Build Coastguard Worker   } else {
228*9356374aSAndroid Build Coastguard Worker     buf[len] = '\0';
229*9356374aSAndroid Build Coastguard Worker   }
230*9356374aSAndroid Build Coastguard Worker   memcpy(buf, s, len);
231*9356374aSAndroid Build Coastguard Worker   _emscripten_err(buf);
232*9356374aSAndroid Build Coastguard Worker #endif
233*9356374aSAndroid Build Coastguard Worker #elif defined(ABSL_HAVE_SYSCALL_WRITE)
234*9356374aSAndroid Build Coastguard Worker   // We prefer calling write via `syscall` to minimize the risk of libc doing
235*9356374aSAndroid Build Coastguard Worker   // something "helpful".
236*9356374aSAndroid Build Coastguard Worker   syscall(SYS_write, STDERR_FILENO, s, len);
237*9356374aSAndroid Build Coastguard Worker #elif defined(ABSL_HAVE_POSIX_WRITE)
238*9356374aSAndroid Build Coastguard Worker   write(STDERR_FILENO, s, len);
239*9356374aSAndroid Build Coastguard Worker #elif defined(ABSL_HAVE_RAW_IO)
240*9356374aSAndroid Build Coastguard Worker   _write(/* stderr */ 2, s, static_cast<unsigned>(len));
241*9356374aSAndroid Build Coastguard Worker #else
242*9356374aSAndroid Build Coastguard Worker   // stderr logging unsupported on this platform
243*9356374aSAndroid Build Coastguard Worker   (void)s;
244*9356374aSAndroid Build Coastguard Worker   (void)len;
245*9356374aSAndroid Build Coastguard Worker #endif
246*9356374aSAndroid Build Coastguard Worker }
247*9356374aSAndroid Build Coastguard Worker 
RawLog(absl::LogSeverity severity,const char * file,int line,const char * format,...)248*9356374aSAndroid Build Coastguard Worker void RawLog(absl::LogSeverity severity, const char* file, int line,
249*9356374aSAndroid Build Coastguard Worker             const char* format, ...) {
250*9356374aSAndroid Build Coastguard Worker   va_list ap;
251*9356374aSAndroid Build Coastguard Worker   va_start(ap, format);
252*9356374aSAndroid Build Coastguard Worker   RawLogVA(severity, file, line, format, ap);
253*9356374aSAndroid Build Coastguard Worker   va_end(ap);
254*9356374aSAndroid Build Coastguard Worker }
255*9356374aSAndroid Build Coastguard Worker 
RawLoggingFullySupported()256*9356374aSAndroid Build Coastguard Worker bool RawLoggingFullySupported() {
257*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
258*9356374aSAndroid Build Coastguard Worker   return true;
259*9356374aSAndroid Build Coastguard Worker #else   // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
260*9356374aSAndroid Build Coastguard Worker   return false;
261*9356374aSAndroid Build Coastguard Worker #endif  // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
262*9356374aSAndroid Build Coastguard Worker }
263*9356374aSAndroid Build Coastguard Worker 
264*9356374aSAndroid Build Coastguard Worker ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL
265*9356374aSAndroid Build Coastguard Worker     absl::base_internal::AtomicHook<InternalLogFunction>
266*9356374aSAndroid Build Coastguard Worker         internal_log_function(DefaultInternalLog);
267*9356374aSAndroid Build Coastguard Worker 
RegisterLogFilterAndPrefixHook(LogFilterAndPrefixHook func)268*9356374aSAndroid Build Coastguard Worker void RegisterLogFilterAndPrefixHook(LogFilterAndPrefixHook func) {
269*9356374aSAndroid Build Coastguard Worker   log_filter_and_prefix_hook.Store(func);
270*9356374aSAndroid Build Coastguard Worker }
271*9356374aSAndroid Build Coastguard Worker 
RegisterAbortHook(AbortHook func)272*9356374aSAndroid Build Coastguard Worker void RegisterAbortHook(AbortHook func) { abort_hook.Store(func); }
273*9356374aSAndroid Build Coastguard Worker 
RegisterInternalLogFunction(InternalLogFunction func)274*9356374aSAndroid Build Coastguard Worker void RegisterInternalLogFunction(InternalLogFunction func) {
275*9356374aSAndroid Build Coastguard Worker   internal_log_function.Store(func);
276*9356374aSAndroid Build Coastguard Worker }
277*9356374aSAndroid Build Coastguard Worker 
278*9356374aSAndroid Build Coastguard Worker }  // namespace raw_log_internal
279*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
280*9356374aSAndroid Build Coastguard Worker }  // namespace absl
281