1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
6*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
7*635a8641SAndroid Build Coastguard Worker #include "base/callback.h"
8*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
9*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
12*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
13*635a8641SAndroid Build Coastguard Worker
14*635a8641SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
15*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
18*635a8641SAndroid Build Coastguard Worker #include <signal.h>
19*635a8641SAndroid Build Coastguard Worker #include <unistd.h>
20*635a8641SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
21*635a8641SAndroid Build Coastguard Worker #endif // OS_POSIX
22*635a8641SAndroid Build Coastguard Worker
23*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX) || defined(OS_ANDROID)
24*635a8641SAndroid Build Coastguard Worker #include <ucontext.h>
25*635a8641SAndroid Build Coastguard Worker #endif
26*635a8641SAndroid Build Coastguard Worker
27*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
28*635a8641SAndroid Build Coastguard Worker #include <excpt.h>
29*635a8641SAndroid Build Coastguard Worker #include <windows.h>
30*635a8641SAndroid Build Coastguard Worker #endif // OS_WIN
31*635a8641SAndroid Build Coastguard Worker
32*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
33*635a8641SAndroid Build Coastguard Worker #include <lib/zx/event.h>
34*635a8641SAndroid Build Coastguard Worker #include <lib/zx/port.h>
35*635a8641SAndroid Build Coastguard Worker #include <lib/zx/process.h>
36*635a8641SAndroid Build Coastguard Worker #include <lib/zx/thread.h>
37*635a8641SAndroid Build Coastguard Worker #include <lib/zx/time.h>
38*635a8641SAndroid Build Coastguard Worker #include <zircon/process.h>
39*635a8641SAndroid Build Coastguard Worker #include <zircon/syscalls/debug.h>
40*635a8641SAndroid Build Coastguard Worker #include <zircon/syscalls/port.h>
41*635a8641SAndroid Build Coastguard Worker #include <zircon/types.h>
42*635a8641SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_logging.h"
43*635a8641SAndroid Build Coastguard Worker #endif
44*635a8641SAndroid Build Coastguard Worker
45*635a8641SAndroid Build Coastguard Worker namespace logging {
46*635a8641SAndroid Build Coastguard Worker
47*635a8641SAndroid Build Coastguard Worker namespace {
48*635a8641SAndroid Build Coastguard Worker
49*635a8641SAndroid Build Coastguard Worker using ::testing::Return;
50*635a8641SAndroid Build Coastguard Worker using ::testing::_;
51*635a8641SAndroid Build Coastguard Worker
52*635a8641SAndroid Build Coastguard Worker // Needs to be global since log assert handlers can't maintain state.
53*635a8641SAndroid Build Coastguard Worker int g_log_sink_call_count = 0;
54*635a8641SAndroid Build Coastguard Worker
55*635a8641SAndroid Build Coastguard Worker #if !defined(OFFICIAL_BUILD) || defined(DCHECK_ALWAYS_ON) || !defined(NDEBUG)
LogSink(const char * file,int line,const base::StringPiece message,const base::StringPiece stack_trace)56*635a8641SAndroid Build Coastguard Worker void LogSink(const char* file,
57*635a8641SAndroid Build Coastguard Worker int line,
58*635a8641SAndroid Build Coastguard Worker const base::StringPiece message,
59*635a8641SAndroid Build Coastguard Worker const base::StringPiece stack_trace) {
60*635a8641SAndroid Build Coastguard Worker ++g_log_sink_call_count;
61*635a8641SAndroid Build Coastguard Worker }
62*635a8641SAndroid Build Coastguard Worker #endif
63*635a8641SAndroid Build Coastguard Worker
64*635a8641SAndroid Build Coastguard Worker // Class to make sure any manipulations we do to the min log level are
65*635a8641SAndroid Build Coastguard Worker // contained (i.e., do not affect other unit tests).
66*635a8641SAndroid Build Coastguard Worker class LogStateSaver {
67*635a8641SAndroid Build Coastguard Worker public:
LogStateSaver()68*635a8641SAndroid Build Coastguard Worker LogStateSaver() : old_min_log_level_(GetMinLogLevel()) {}
69*635a8641SAndroid Build Coastguard Worker
~LogStateSaver()70*635a8641SAndroid Build Coastguard Worker ~LogStateSaver() {
71*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(old_min_log_level_);
72*635a8641SAndroid Build Coastguard Worker g_log_sink_call_count = 0;
73*635a8641SAndroid Build Coastguard Worker }
74*635a8641SAndroid Build Coastguard Worker
75*635a8641SAndroid Build Coastguard Worker private:
76*635a8641SAndroid Build Coastguard Worker int old_min_log_level_;
77*635a8641SAndroid Build Coastguard Worker
78*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(LogStateSaver);
79*635a8641SAndroid Build Coastguard Worker };
80*635a8641SAndroid Build Coastguard Worker
81*635a8641SAndroid Build Coastguard Worker class LoggingTest : public testing::Test {
82*635a8641SAndroid Build Coastguard Worker private:
83*635a8641SAndroid Build Coastguard Worker LogStateSaver log_state_saver_;
84*635a8641SAndroid Build Coastguard Worker };
85*635a8641SAndroid Build Coastguard Worker
86*635a8641SAndroid Build Coastguard Worker class MockLogSource {
87*635a8641SAndroid Build Coastguard Worker public:
88*635a8641SAndroid Build Coastguard Worker MOCK_METHOD0(Log, const char*());
89*635a8641SAndroid Build Coastguard Worker };
90*635a8641SAndroid Build Coastguard Worker
91*635a8641SAndroid Build Coastguard Worker class MockLogAssertHandler {
92*635a8641SAndroid Build Coastguard Worker public:
93*635a8641SAndroid Build Coastguard Worker MOCK_METHOD4(
94*635a8641SAndroid Build Coastguard Worker HandleLogAssert,
95*635a8641SAndroid Build Coastguard Worker void(const char*, int, const base::StringPiece, const base::StringPiece));
96*635a8641SAndroid Build Coastguard Worker };
97*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,BasicLogging)98*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, BasicLogging) {
99*635a8641SAndroid Build Coastguard Worker MockLogSource mock_log_source;
100*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(mock_log_source, Log())
101*635a8641SAndroid Build Coastguard Worker .Times(DCHECK_IS_ON() ? 16 : 8)
102*635a8641SAndroid Build Coastguard Worker .WillRepeatedly(Return("log message"));
103*635a8641SAndroid Build Coastguard Worker
104*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(LOG_INFO);
105*635a8641SAndroid Build Coastguard Worker
106*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(INFO));
107*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE((DCHECK_IS_ON() != 0) == DLOG_IS_ON(INFO));
108*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(VLOG_IS_ON(0));
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker LOG(INFO) << mock_log_source.Log();
111*635a8641SAndroid Build Coastguard Worker LOG_IF(INFO, true) << mock_log_source.Log();
112*635a8641SAndroid Build Coastguard Worker PLOG(INFO) << mock_log_source.Log();
113*635a8641SAndroid Build Coastguard Worker PLOG_IF(INFO, true) << mock_log_source.Log();
114*635a8641SAndroid Build Coastguard Worker VLOG(0) << mock_log_source.Log();
115*635a8641SAndroid Build Coastguard Worker VLOG_IF(0, true) << mock_log_source.Log();
116*635a8641SAndroid Build Coastguard Worker VPLOG(0) << mock_log_source.Log();
117*635a8641SAndroid Build Coastguard Worker VPLOG_IF(0, true) << mock_log_source.Log();
118*635a8641SAndroid Build Coastguard Worker
119*635a8641SAndroid Build Coastguard Worker DLOG(INFO) << mock_log_source.Log();
120*635a8641SAndroid Build Coastguard Worker DLOG_IF(INFO, true) << mock_log_source.Log();
121*635a8641SAndroid Build Coastguard Worker DPLOG(INFO) << mock_log_source.Log();
122*635a8641SAndroid Build Coastguard Worker DPLOG_IF(INFO, true) << mock_log_source.Log();
123*635a8641SAndroid Build Coastguard Worker DVLOG(0) << mock_log_source.Log();
124*635a8641SAndroid Build Coastguard Worker DVLOG_IF(0, true) << mock_log_source.Log();
125*635a8641SAndroid Build Coastguard Worker DVPLOG(0) << mock_log_source.Log();
126*635a8641SAndroid Build Coastguard Worker DVPLOG_IF(0, true) << mock_log_source.Log();
127*635a8641SAndroid Build Coastguard Worker }
128*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,LogIsOn)129*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, LogIsOn) {
130*635a8641SAndroid Build Coastguard Worker #if defined(NDEBUG)
131*635a8641SAndroid Build Coastguard Worker const bool kDfatalIsFatal = false;
132*635a8641SAndroid Build Coastguard Worker #else // defined(NDEBUG)
133*635a8641SAndroid Build Coastguard Worker const bool kDfatalIsFatal = true;
134*635a8641SAndroid Build Coastguard Worker #endif // defined(NDEBUG)
135*635a8641SAndroid Build Coastguard Worker
136*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(LOG_INFO);
137*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(INFO));
138*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(WARNING));
139*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(ERROR));
140*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(FATAL));
141*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(DFATAL));
142*635a8641SAndroid Build Coastguard Worker
143*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(LOG_WARNING);
144*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(LOG_IS_ON(INFO));
145*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(WARNING));
146*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(ERROR));
147*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(FATAL));
148*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(DFATAL));
149*635a8641SAndroid Build Coastguard Worker
150*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(LOG_ERROR);
151*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(LOG_IS_ON(INFO));
152*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(LOG_IS_ON(WARNING));
153*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(ERROR));
154*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(FATAL));
155*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(DFATAL));
156*635a8641SAndroid Build Coastguard Worker
157*635a8641SAndroid Build Coastguard Worker // LOG_IS_ON(FATAL) should always be true.
158*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(LOG_FATAL + 1);
159*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(LOG_IS_ON(INFO));
160*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(LOG_IS_ON(WARNING));
161*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(LOG_IS_ON(ERROR));
162*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(FATAL));
163*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kDfatalIsFatal, LOG_IS_ON(DFATAL));
164*635a8641SAndroid Build Coastguard Worker }
165*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,LoggingIsLazyBySeverity)166*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, LoggingIsLazyBySeverity) {
167*635a8641SAndroid Build Coastguard Worker MockLogSource mock_log_source;
168*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(mock_log_source, Log()).Times(0);
169*635a8641SAndroid Build Coastguard Worker
170*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(LOG_WARNING);
171*635a8641SAndroid Build Coastguard Worker
172*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(LOG_IS_ON(INFO));
173*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(DLOG_IS_ON(INFO));
174*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(VLOG_IS_ON(1));
175*635a8641SAndroid Build Coastguard Worker
176*635a8641SAndroid Build Coastguard Worker LOG(INFO) << mock_log_source.Log();
177*635a8641SAndroid Build Coastguard Worker LOG_IF(INFO, false) << mock_log_source.Log();
178*635a8641SAndroid Build Coastguard Worker PLOG(INFO) << mock_log_source.Log();
179*635a8641SAndroid Build Coastguard Worker PLOG_IF(INFO, false) << mock_log_source.Log();
180*635a8641SAndroid Build Coastguard Worker VLOG(1) << mock_log_source.Log();
181*635a8641SAndroid Build Coastguard Worker VLOG_IF(1, true) << mock_log_source.Log();
182*635a8641SAndroid Build Coastguard Worker VPLOG(1) << mock_log_source.Log();
183*635a8641SAndroid Build Coastguard Worker VPLOG_IF(1, true) << mock_log_source.Log();
184*635a8641SAndroid Build Coastguard Worker
185*635a8641SAndroid Build Coastguard Worker DLOG(INFO) << mock_log_source.Log();
186*635a8641SAndroid Build Coastguard Worker DLOG_IF(INFO, true) << mock_log_source.Log();
187*635a8641SAndroid Build Coastguard Worker DPLOG(INFO) << mock_log_source.Log();
188*635a8641SAndroid Build Coastguard Worker DPLOG_IF(INFO, true) << mock_log_source.Log();
189*635a8641SAndroid Build Coastguard Worker DVLOG(1) << mock_log_source.Log();
190*635a8641SAndroid Build Coastguard Worker DVLOG_IF(1, true) << mock_log_source.Log();
191*635a8641SAndroid Build Coastguard Worker DVPLOG(1) << mock_log_source.Log();
192*635a8641SAndroid Build Coastguard Worker DVPLOG_IF(1, true) << mock_log_source.Log();
193*635a8641SAndroid Build Coastguard Worker }
194*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,LoggingIsLazyByDestination)195*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, LoggingIsLazyByDestination) {
196*635a8641SAndroid Build Coastguard Worker MockLogSource mock_log_source;
197*635a8641SAndroid Build Coastguard Worker MockLogSource mock_log_source_error;
198*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(mock_log_source, Log()).Times(0);
199*635a8641SAndroid Build Coastguard Worker
200*635a8641SAndroid Build Coastguard Worker // Severity >= ERROR is always printed to stderr.
201*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(mock_log_source_error, Log()).Times(1).
202*635a8641SAndroid Build Coastguard Worker WillRepeatedly(Return("log message"));
203*635a8641SAndroid Build Coastguard Worker
204*635a8641SAndroid Build Coastguard Worker LoggingSettings settings;
205*635a8641SAndroid Build Coastguard Worker settings.logging_dest = LOG_NONE;
206*635a8641SAndroid Build Coastguard Worker InitLogging(settings);
207*635a8641SAndroid Build Coastguard Worker
208*635a8641SAndroid Build Coastguard Worker LOG(INFO) << mock_log_source.Log();
209*635a8641SAndroid Build Coastguard Worker LOG(WARNING) << mock_log_source.Log();
210*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << mock_log_source_error.Log();
211*635a8641SAndroid Build Coastguard Worker }
212*635a8641SAndroid Build Coastguard Worker
213*635a8641SAndroid Build Coastguard Worker // Official builds have CHECKs directly call BreakDebugger.
214*635a8641SAndroid Build Coastguard Worker #if !defined(OFFICIAL_BUILD)
215*635a8641SAndroid Build Coastguard Worker
216*635a8641SAndroid Build Coastguard Worker // https://crbug.com/709067 tracks test flakiness on iOS.
217*635a8641SAndroid Build Coastguard Worker #if defined(OS_IOS)
218*635a8641SAndroid Build Coastguard Worker #define MAYBE_CheckStreamsAreLazy DISABLED_CheckStreamsAreLazy
219*635a8641SAndroid Build Coastguard Worker #else
220*635a8641SAndroid Build Coastguard Worker #define MAYBE_CheckStreamsAreLazy CheckStreamsAreLazy
221*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(LoggingTest,MAYBE_CheckStreamsAreLazy)222*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, MAYBE_CheckStreamsAreLazy) {
223*635a8641SAndroid Build Coastguard Worker MockLogSource mock_log_source, uncalled_mock_log_source;
224*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(mock_log_source, Log()).Times(8).
225*635a8641SAndroid Build Coastguard Worker WillRepeatedly(Return("check message"));
226*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(uncalled_mock_log_source, Log()).Times(0);
227*635a8641SAndroid Build Coastguard Worker
228*635a8641SAndroid Build Coastguard Worker ScopedLogAssertHandler scoped_assert_handler(base::Bind(LogSink));
229*635a8641SAndroid Build Coastguard Worker
230*635a8641SAndroid Build Coastguard Worker CHECK(mock_log_source.Log()) << uncalled_mock_log_source.Log();
231*635a8641SAndroid Build Coastguard Worker PCHECK(!mock_log_source.Log()) << mock_log_source.Log();
232*635a8641SAndroid Build Coastguard Worker CHECK_EQ(mock_log_source.Log(), mock_log_source.Log())
233*635a8641SAndroid Build Coastguard Worker << uncalled_mock_log_source.Log();
234*635a8641SAndroid Build Coastguard Worker CHECK_NE(mock_log_source.Log(), mock_log_source.Log())
235*635a8641SAndroid Build Coastguard Worker << mock_log_source.Log();
236*635a8641SAndroid Build Coastguard Worker }
237*635a8641SAndroid Build Coastguard Worker
238*635a8641SAndroid Build Coastguard Worker #endif
239*635a8641SAndroid Build Coastguard Worker
240*635a8641SAndroid Build Coastguard Worker #if defined(OFFICIAL_BUILD) && defined(OS_WIN)
CheckContainingFunc(int death_location)241*635a8641SAndroid Build Coastguard Worker NOINLINE void CheckContainingFunc(int death_location) {
242*635a8641SAndroid Build Coastguard Worker CHECK(death_location != 1);
243*635a8641SAndroid Build Coastguard Worker CHECK(death_location != 2);
244*635a8641SAndroid Build Coastguard Worker CHECK(death_location != 3);
245*635a8641SAndroid Build Coastguard Worker }
246*635a8641SAndroid Build Coastguard Worker
GetCheckExceptionData(EXCEPTION_POINTERS * p,DWORD * code,void ** addr)247*635a8641SAndroid Build Coastguard Worker int GetCheckExceptionData(EXCEPTION_POINTERS* p, DWORD* code, void** addr) {
248*635a8641SAndroid Build Coastguard Worker *code = p->ExceptionRecord->ExceptionCode;
249*635a8641SAndroid Build Coastguard Worker *addr = p->ExceptionRecord->ExceptionAddress;
250*635a8641SAndroid Build Coastguard Worker return EXCEPTION_EXECUTE_HANDLER;
251*635a8641SAndroid Build Coastguard Worker }
252*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,CheckCausesDistinctBreakpoints)253*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, CheckCausesDistinctBreakpoints) {
254*635a8641SAndroid Build Coastguard Worker DWORD code1 = 0;
255*635a8641SAndroid Build Coastguard Worker DWORD code2 = 0;
256*635a8641SAndroid Build Coastguard Worker DWORD code3 = 0;
257*635a8641SAndroid Build Coastguard Worker void* addr1 = nullptr;
258*635a8641SAndroid Build Coastguard Worker void* addr2 = nullptr;
259*635a8641SAndroid Build Coastguard Worker void* addr3 = nullptr;
260*635a8641SAndroid Build Coastguard Worker
261*635a8641SAndroid Build Coastguard Worker // Record the exception code and addresses.
262*635a8641SAndroid Build Coastguard Worker __try {
263*635a8641SAndroid Build Coastguard Worker CheckContainingFunc(1);
264*635a8641SAndroid Build Coastguard Worker } __except (
265*635a8641SAndroid Build Coastguard Worker GetCheckExceptionData(GetExceptionInformation(), &code1, &addr1)) {
266*635a8641SAndroid Build Coastguard Worker }
267*635a8641SAndroid Build Coastguard Worker
268*635a8641SAndroid Build Coastguard Worker __try {
269*635a8641SAndroid Build Coastguard Worker CheckContainingFunc(2);
270*635a8641SAndroid Build Coastguard Worker } __except (
271*635a8641SAndroid Build Coastguard Worker GetCheckExceptionData(GetExceptionInformation(), &code2, &addr2)) {
272*635a8641SAndroid Build Coastguard Worker }
273*635a8641SAndroid Build Coastguard Worker
274*635a8641SAndroid Build Coastguard Worker __try {
275*635a8641SAndroid Build Coastguard Worker CheckContainingFunc(3);
276*635a8641SAndroid Build Coastguard Worker } __except (
277*635a8641SAndroid Build Coastguard Worker GetCheckExceptionData(GetExceptionInformation(), &code3, &addr3)) {
278*635a8641SAndroid Build Coastguard Worker }
279*635a8641SAndroid Build Coastguard Worker
280*635a8641SAndroid Build Coastguard Worker // Ensure that the exception codes are correct (in particular, breakpoints,
281*635a8641SAndroid Build Coastguard Worker // not access violations).
282*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(STATUS_BREAKPOINT, code1);
283*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(STATUS_BREAKPOINT, code2);
284*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(STATUS_BREAKPOINT, code3);
285*635a8641SAndroid Build Coastguard Worker
286*635a8641SAndroid Build Coastguard Worker // Ensure that none of the CHECKs are colocated.
287*635a8641SAndroid Build Coastguard Worker EXPECT_NE(addr1, addr2);
288*635a8641SAndroid Build Coastguard Worker EXPECT_NE(addr1, addr3);
289*635a8641SAndroid Build Coastguard Worker EXPECT_NE(addr2, addr3);
290*635a8641SAndroid Build Coastguard Worker }
291*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA)
292*635a8641SAndroid Build Coastguard Worker
293*635a8641SAndroid Build Coastguard Worker // CHECK causes a direct crash (without jumping to another function) only in
294*635a8641SAndroid Build Coastguard Worker // official builds. Unfortunately, continuous test coverage on official builds
295*635a8641SAndroid Build Coastguard Worker // is lower. Furthermore, since the Fuchsia implementation uses threads, it is
296*635a8641SAndroid Build Coastguard Worker // not possible to rely on an implementation of CHECK that calls abort(), which
297*635a8641SAndroid Build Coastguard Worker // takes down the whole process, preventing the thread exception handler from
298*635a8641SAndroid Build Coastguard Worker // handling the exception. DO_CHECK here falls back on IMMEDIATE_CRASH() in
299*635a8641SAndroid Build Coastguard Worker // non-official builds, to catch regressions earlier in the CQ.
300*635a8641SAndroid Build Coastguard Worker #if defined(OFFICIAL_BUILD)
301*635a8641SAndroid Build Coastguard Worker #define DO_CHECK CHECK
302*635a8641SAndroid Build Coastguard Worker #else
303*635a8641SAndroid Build Coastguard Worker #define DO_CHECK(cond) \
304*635a8641SAndroid Build Coastguard Worker if (!(cond)) { \
305*635a8641SAndroid Build Coastguard Worker IMMEDIATE_CRASH(); \
306*635a8641SAndroid Build Coastguard Worker }
307*635a8641SAndroid Build Coastguard Worker #endif
308*635a8641SAndroid Build Coastguard Worker
309*635a8641SAndroid Build Coastguard Worker static const unsigned int kExceptionPortKey = 1u;
310*635a8641SAndroid Build Coastguard Worker static const unsigned int kThreadEndedPortKey = 2u;
311*635a8641SAndroid Build Coastguard Worker
312*635a8641SAndroid Build Coastguard Worker struct thread_data_t {
313*635a8641SAndroid Build Coastguard Worker // For signaling the thread ended properly.
314*635a8641SAndroid Build Coastguard Worker zx::unowned_event event;
315*635a8641SAndroid Build Coastguard Worker // For registering thread termination.
316*635a8641SAndroid Build Coastguard Worker zx::unowned_port port;
317*635a8641SAndroid Build Coastguard Worker // Location where the thread is expected to crash.
318*635a8641SAndroid Build Coastguard Worker int death_location;
319*635a8641SAndroid Build Coastguard Worker };
320*635a8641SAndroid Build Coastguard Worker
CrashThread(void * arg)321*635a8641SAndroid Build Coastguard Worker void* CrashThread(void* arg) {
322*635a8641SAndroid Build Coastguard Worker zx_status_t status;
323*635a8641SAndroid Build Coastguard Worker
324*635a8641SAndroid Build Coastguard Worker thread_data_t* data = (thread_data_t*)arg;
325*635a8641SAndroid Build Coastguard Worker int death_location = data->death_location;
326*635a8641SAndroid Build Coastguard Worker
327*635a8641SAndroid Build Coastguard Worker // Register the exception handler on the port.
328*635a8641SAndroid Build Coastguard Worker status = zx::thread::self()->bind_exception_port(*data->port,
329*635a8641SAndroid Build Coastguard Worker kExceptionPortKey, 0);
330*635a8641SAndroid Build Coastguard Worker if (status != ZX_OK) {
331*635a8641SAndroid Build Coastguard Worker data->event->signal(0, ZX_USER_SIGNAL_0);
332*635a8641SAndroid Build Coastguard Worker return nullptr;
333*635a8641SAndroid Build Coastguard Worker }
334*635a8641SAndroid Build Coastguard Worker
335*635a8641SAndroid Build Coastguard Worker DO_CHECK(death_location != 1);
336*635a8641SAndroid Build Coastguard Worker DO_CHECK(death_location != 2);
337*635a8641SAndroid Build Coastguard Worker DO_CHECK(death_location != 3);
338*635a8641SAndroid Build Coastguard Worker
339*635a8641SAndroid Build Coastguard Worker // We should never reach this point, signal the thread incorrectly ended
340*635a8641SAndroid Build Coastguard Worker // properly.
341*635a8641SAndroid Build Coastguard Worker data->event->signal(0, ZX_USER_SIGNAL_0);
342*635a8641SAndroid Build Coastguard Worker return nullptr;
343*635a8641SAndroid Build Coastguard Worker }
344*635a8641SAndroid Build Coastguard Worker
345*635a8641SAndroid Build Coastguard Worker // Runs the CrashThread function in a separate thread.
SpawnCrashThread(int death_location,uintptr_t * child_crash_addr)346*635a8641SAndroid Build Coastguard Worker void SpawnCrashThread(int death_location, uintptr_t* child_crash_addr) {
347*635a8641SAndroid Build Coastguard Worker zx::port port;
348*635a8641SAndroid Build Coastguard Worker zx::event event;
349*635a8641SAndroid Build Coastguard Worker zx_status_t status;
350*635a8641SAndroid Build Coastguard Worker
351*635a8641SAndroid Build Coastguard Worker status = zx::port::create(0, &port);
352*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(status, ZX_OK);
353*635a8641SAndroid Build Coastguard Worker status = zx::event::create(0, &event);
354*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(status, ZX_OK);
355*635a8641SAndroid Build Coastguard Worker
356*635a8641SAndroid Build Coastguard Worker // Register the thread ended event on the port.
357*635a8641SAndroid Build Coastguard Worker status = event.wait_async(port, kThreadEndedPortKey, ZX_USER_SIGNAL_0,
358*635a8641SAndroid Build Coastguard Worker ZX_WAIT_ASYNC_ONCE);
359*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(status, ZX_OK);
360*635a8641SAndroid Build Coastguard Worker
361*635a8641SAndroid Build Coastguard Worker // Run the thread.
362*635a8641SAndroid Build Coastguard Worker thread_data_t thread_data = {zx::unowned_event(event), zx::unowned_port(port),
363*635a8641SAndroid Build Coastguard Worker death_location};
364*635a8641SAndroid Build Coastguard Worker pthread_t thread;
365*635a8641SAndroid Build Coastguard Worker int ret = pthread_create(&thread, nullptr, CrashThread, &thread_data);
366*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(ret, 0);
367*635a8641SAndroid Build Coastguard Worker
368*635a8641SAndroid Build Coastguard Worker // Wait on the port.
369*635a8641SAndroid Build Coastguard Worker zx_port_packet_t packet;
370*635a8641SAndroid Build Coastguard Worker status = port.wait(zx::time::infinite(), &packet);
371*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(status, ZX_OK);
372*635a8641SAndroid Build Coastguard Worker // Check the thread did crash and not terminate.
373*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(packet.key, kExceptionPortKey);
374*635a8641SAndroid Build Coastguard Worker
375*635a8641SAndroid Build Coastguard Worker // Get the crash address.
376*635a8641SAndroid Build Coastguard Worker zx::thread zircon_thread;
377*635a8641SAndroid Build Coastguard Worker status = zx::process::self()->get_child(packet.exception.tid,
378*635a8641SAndroid Build Coastguard Worker ZX_RIGHT_SAME_RIGHTS, &zircon_thread);
379*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(status, ZX_OK);
380*635a8641SAndroid Build Coastguard Worker zx_thread_state_general_regs_t buffer;
381*635a8641SAndroid Build Coastguard Worker status = zircon_thread.read_state(ZX_THREAD_STATE_GENERAL_REGS, &buffer,
382*635a8641SAndroid Build Coastguard Worker sizeof(buffer));
383*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(status, ZX_OK);
384*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_64)
385*635a8641SAndroid Build Coastguard Worker *child_crash_addr = static_cast<uintptr_t>(buffer.rip);
386*635a8641SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_ARM64)
387*635a8641SAndroid Build Coastguard Worker *child_crash_addr = static_cast<uintptr_t>(buffer.pc);
388*635a8641SAndroid Build Coastguard Worker #else
389*635a8641SAndroid Build Coastguard Worker #error Unsupported architecture
390*635a8641SAndroid Build Coastguard Worker #endif
391*635a8641SAndroid Build Coastguard Worker
392*635a8641SAndroid Build Coastguard Worker status = zircon_thread.kill();
393*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(status, ZX_OK);
394*635a8641SAndroid Build Coastguard Worker }
395*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,CheckCausesDistinctBreakpoints)396*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, CheckCausesDistinctBreakpoints) {
397*635a8641SAndroid Build Coastguard Worker uintptr_t child_crash_addr_1 = 0;
398*635a8641SAndroid Build Coastguard Worker uintptr_t child_crash_addr_2 = 0;
399*635a8641SAndroid Build Coastguard Worker uintptr_t child_crash_addr_3 = 0;
400*635a8641SAndroid Build Coastguard Worker
401*635a8641SAndroid Build Coastguard Worker SpawnCrashThread(1, &child_crash_addr_1);
402*635a8641SAndroid Build Coastguard Worker SpawnCrashThread(2, &child_crash_addr_2);
403*635a8641SAndroid Build Coastguard Worker SpawnCrashThread(3, &child_crash_addr_3);
404*635a8641SAndroid Build Coastguard Worker
405*635a8641SAndroid Build Coastguard Worker ASSERT_NE(0u, child_crash_addr_1);
406*635a8641SAndroid Build Coastguard Worker ASSERT_NE(0u, child_crash_addr_2);
407*635a8641SAndroid Build Coastguard Worker ASSERT_NE(0u, child_crash_addr_3);
408*635a8641SAndroid Build Coastguard Worker ASSERT_NE(child_crash_addr_1, child_crash_addr_2);
409*635a8641SAndroid Build Coastguard Worker ASSERT_NE(child_crash_addr_1, child_crash_addr_3);
410*635a8641SAndroid Build Coastguard Worker ASSERT_NE(child_crash_addr_2, child_crash_addr_3);
411*635a8641SAndroid Build Coastguard Worker }
412*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_IOS) && \
413*635a8641SAndroid Build Coastguard Worker (defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY))
414*635a8641SAndroid Build Coastguard Worker
415*635a8641SAndroid Build Coastguard Worker int g_child_crash_pipe;
416*635a8641SAndroid Build Coastguard Worker
CheckCrashTestSighandler(int,siginfo_t * info,void * context_ptr)417*635a8641SAndroid Build Coastguard Worker void CheckCrashTestSighandler(int, siginfo_t* info, void* context_ptr) {
418*635a8641SAndroid Build Coastguard Worker // Conversely to what clearly stated in "man 2 sigaction", some Linux kernels
419*635a8641SAndroid Build Coastguard Worker // do NOT populate the |info->si_addr| in the case of a SIGTRAP. Hence we
420*635a8641SAndroid Build Coastguard Worker // need the arch-specific boilerplate below, which is inspired by breakpad.
421*635a8641SAndroid Build Coastguard Worker // At the same time, on OSX, ucontext.h is deprecated but si_addr works fine.
422*635a8641SAndroid Build Coastguard Worker uintptr_t crash_addr = 0;
423*635a8641SAndroid Build Coastguard Worker #if defined(OS_MACOSX)
424*635a8641SAndroid Build Coastguard Worker crash_addr = reinterpret_cast<uintptr_t>(info->si_addr);
425*635a8641SAndroid Build Coastguard Worker #else // OS_POSIX && !OS_MACOSX
426*635a8641SAndroid Build Coastguard Worker ucontext_t* context = reinterpret_cast<ucontext_t*>(context_ptr);
427*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86)
428*635a8641SAndroid Build Coastguard Worker crash_addr = static_cast<uintptr_t>(context->uc_mcontext.gregs[REG_EIP]);
429*635a8641SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_X86_64)
430*635a8641SAndroid Build Coastguard Worker crash_addr = static_cast<uintptr_t>(context->uc_mcontext.gregs[REG_RIP]);
431*635a8641SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_ARMEL)
432*635a8641SAndroid Build Coastguard Worker crash_addr = static_cast<uintptr_t>(context->uc_mcontext.arm_pc);
433*635a8641SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_ARM64)
434*635a8641SAndroid Build Coastguard Worker crash_addr = static_cast<uintptr_t>(context->uc_mcontext.pc);
435*635a8641SAndroid Build Coastguard Worker #endif // ARCH_*
436*635a8641SAndroid Build Coastguard Worker #endif // OS_POSIX && !OS_MACOSX
437*635a8641SAndroid Build Coastguard Worker HANDLE_EINTR(write(g_child_crash_pipe, &crash_addr, sizeof(uintptr_t)));
438*635a8641SAndroid Build Coastguard Worker _exit(0);
439*635a8641SAndroid Build Coastguard Worker }
440*635a8641SAndroid Build Coastguard Worker
441*635a8641SAndroid Build Coastguard Worker // CHECK causes a direct crash (without jumping to another function) only in
442*635a8641SAndroid Build Coastguard Worker // official builds. Unfortunately, continuous test coverage on official builds
443*635a8641SAndroid Build Coastguard Worker // is lower. DO_CHECK here falls back on a home-brewed implementation in
444*635a8641SAndroid Build Coastguard Worker // non-official builds, to catch regressions earlier in the CQ.
445*635a8641SAndroid Build Coastguard Worker #if defined(OFFICIAL_BUILD)
446*635a8641SAndroid Build Coastguard Worker #define DO_CHECK CHECK
447*635a8641SAndroid Build Coastguard Worker #else
448*635a8641SAndroid Build Coastguard Worker #define DO_CHECK(cond) \
449*635a8641SAndroid Build Coastguard Worker if (!(cond)) \
450*635a8641SAndroid Build Coastguard Worker IMMEDIATE_CRASH()
451*635a8641SAndroid Build Coastguard Worker #endif
452*635a8641SAndroid Build Coastguard Worker
CrashChildMain(int death_location)453*635a8641SAndroid Build Coastguard Worker void CrashChildMain(int death_location) {
454*635a8641SAndroid Build Coastguard Worker struct sigaction act = {};
455*635a8641SAndroid Build Coastguard Worker act.sa_sigaction = CheckCrashTestSighandler;
456*635a8641SAndroid Build Coastguard Worker act.sa_flags = SA_SIGINFO;
457*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0, sigaction(SIGTRAP, &act, nullptr));
458*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0, sigaction(SIGBUS, &act, nullptr));
459*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0, sigaction(SIGILL, &act, nullptr));
460*635a8641SAndroid Build Coastguard Worker DO_CHECK(death_location != 1);
461*635a8641SAndroid Build Coastguard Worker DO_CHECK(death_location != 2);
462*635a8641SAndroid Build Coastguard Worker printf("\n");
463*635a8641SAndroid Build Coastguard Worker DO_CHECK(death_location != 3);
464*635a8641SAndroid Build Coastguard Worker
465*635a8641SAndroid Build Coastguard Worker // Should never reach this point.
466*635a8641SAndroid Build Coastguard Worker const uintptr_t failed = 0;
467*635a8641SAndroid Build Coastguard Worker HANDLE_EINTR(write(g_child_crash_pipe, &failed, sizeof(uintptr_t)));
468*635a8641SAndroid Build Coastguard Worker };
469*635a8641SAndroid Build Coastguard Worker
SpawnChildAndCrash(int death_location,uintptr_t * child_crash_addr)470*635a8641SAndroid Build Coastguard Worker void SpawnChildAndCrash(int death_location, uintptr_t* child_crash_addr) {
471*635a8641SAndroid Build Coastguard Worker int pipefd[2];
472*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(0, pipe(pipefd));
473*635a8641SAndroid Build Coastguard Worker
474*635a8641SAndroid Build Coastguard Worker int pid = fork();
475*635a8641SAndroid Build Coastguard Worker ASSERT_GE(pid, 0);
476*635a8641SAndroid Build Coastguard Worker
477*635a8641SAndroid Build Coastguard Worker if (pid == 0) { // child process.
478*635a8641SAndroid Build Coastguard Worker close(pipefd[0]); // Close reader (parent) end.
479*635a8641SAndroid Build Coastguard Worker g_child_crash_pipe = pipefd[1];
480*635a8641SAndroid Build Coastguard Worker CrashChildMain(death_location);
481*635a8641SAndroid Build Coastguard Worker FAIL() << "The child process was supposed to crash. It didn't.";
482*635a8641SAndroid Build Coastguard Worker }
483*635a8641SAndroid Build Coastguard Worker
484*635a8641SAndroid Build Coastguard Worker close(pipefd[1]); // Close writer (child) end.
485*635a8641SAndroid Build Coastguard Worker DCHECK(child_crash_addr);
486*635a8641SAndroid Build Coastguard Worker int res = HANDLE_EINTR(read(pipefd[0], child_crash_addr, sizeof(uintptr_t)));
487*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(static_cast<int>(sizeof(uintptr_t)), res);
488*635a8641SAndroid Build Coastguard Worker }
489*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,CheckCausesDistinctBreakpoints)490*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, CheckCausesDistinctBreakpoints) {
491*635a8641SAndroid Build Coastguard Worker uintptr_t child_crash_addr_1 = 0;
492*635a8641SAndroid Build Coastguard Worker uintptr_t child_crash_addr_2 = 0;
493*635a8641SAndroid Build Coastguard Worker uintptr_t child_crash_addr_3 = 0;
494*635a8641SAndroid Build Coastguard Worker
495*635a8641SAndroid Build Coastguard Worker SpawnChildAndCrash(1, &child_crash_addr_1);
496*635a8641SAndroid Build Coastguard Worker SpawnChildAndCrash(2, &child_crash_addr_2);
497*635a8641SAndroid Build Coastguard Worker SpawnChildAndCrash(3, &child_crash_addr_3);
498*635a8641SAndroid Build Coastguard Worker
499*635a8641SAndroid Build Coastguard Worker ASSERT_NE(0u, child_crash_addr_1);
500*635a8641SAndroid Build Coastguard Worker ASSERT_NE(0u, child_crash_addr_2);
501*635a8641SAndroid Build Coastguard Worker ASSERT_NE(0u, child_crash_addr_3);
502*635a8641SAndroid Build Coastguard Worker ASSERT_NE(child_crash_addr_1, child_crash_addr_2);
503*635a8641SAndroid Build Coastguard Worker ASSERT_NE(child_crash_addr_1, child_crash_addr_3);
504*635a8641SAndroid Build Coastguard Worker ASSERT_NE(child_crash_addr_2, child_crash_addr_3);
505*635a8641SAndroid Build Coastguard Worker }
506*635a8641SAndroid Build Coastguard Worker #endif // OS_POSIX
507*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,DebugLoggingReleaseBehavior)508*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, DebugLoggingReleaseBehavior) {
509*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
510*635a8641SAndroid Build Coastguard Worker int debug_only_variable = 1;
511*635a8641SAndroid Build Coastguard Worker #endif
512*635a8641SAndroid Build Coastguard Worker // These should avoid emitting references to |debug_only_variable|
513*635a8641SAndroid Build Coastguard Worker // in release mode.
514*635a8641SAndroid Build Coastguard Worker DLOG_IF(INFO, debug_only_variable) << "test";
515*635a8641SAndroid Build Coastguard Worker DLOG_ASSERT(debug_only_variable) << "test";
516*635a8641SAndroid Build Coastguard Worker DPLOG_IF(INFO, debug_only_variable) << "test";
517*635a8641SAndroid Build Coastguard Worker DVLOG_IF(1, debug_only_variable) << "test";
518*635a8641SAndroid Build Coastguard Worker }
519*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,DcheckStreamsAreLazy)520*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, DcheckStreamsAreLazy) {
521*635a8641SAndroid Build Coastguard Worker MockLogSource mock_log_source;
522*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(mock_log_source, Log()).Times(0);
523*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
524*635a8641SAndroid Build Coastguard Worker DCHECK(true) << mock_log_source.Log();
525*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(0, 0) << mock_log_source.Log();
526*635a8641SAndroid Build Coastguard Worker #else
527*635a8641SAndroid Build Coastguard Worker DCHECK(mock_log_source.Log()) << mock_log_source.Log();
528*635a8641SAndroid Build Coastguard Worker DPCHECK(mock_log_source.Log()) << mock_log_source.Log();
529*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(0, 0) << mock_log_source.Log();
530*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(mock_log_source.Log(), static_cast<const char*>(nullptr))
531*635a8641SAndroid Build Coastguard Worker << mock_log_source.Log();
532*635a8641SAndroid Build Coastguard Worker #endif
533*635a8641SAndroid Build Coastguard Worker }
534*635a8641SAndroid Build Coastguard Worker
DcheckEmptyFunction1()535*635a8641SAndroid Build Coastguard Worker void DcheckEmptyFunction1() {
536*635a8641SAndroid Build Coastguard Worker // Provide a body so that Release builds do not cause the compiler to
537*635a8641SAndroid Build Coastguard Worker // optimize DcheckEmptyFunction1 and DcheckEmptyFunction2 as a single
538*635a8641SAndroid Build Coastguard Worker // function, which breaks the Dcheck tests below.
539*635a8641SAndroid Build Coastguard Worker LOG(INFO) << "DcheckEmptyFunction1";
540*635a8641SAndroid Build Coastguard Worker }
DcheckEmptyFunction2()541*635a8641SAndroid Build Coastguard Worker void DcheckEmptyFunction2() {}
542*635a8641SAndroid Build Coastguard Worker
543*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_CONFIGURABLE
544*635a8641SAndroid Build Coastguard Worker class ScopedDcheckSeverity {
545*635a8641SAndroid Build Coastguard Worker public:
ScopedDcheckSeverity(LogSeverity new_severity)546*635a8641SAndroid Build Coastguard Worker ScopedDcheckSeverity(LogSeverity new_severity) : old_severity_(LOG_DCHECK) {
547*635a8641SAndroid Build Coastguard Worker LOG_DCHECK = new_severity;
548*635a8641SAndroid Build Coastguard Worker }
549*635a8641SAndroid Build Coastguard Worker
~ScopedDcheckSeverity()550*635a8641SAndroid Build Coastguard Worker ~ScopedDcheckSeverity() { LOG_DCHECK = old_severity_; }
551*635a8641SAndroid Build Coastguard Worker
552*635a8641SAndroid Build Coastguard Worker private:
553*635a8641SAndroid Build Coastguard Worker LogSeverity old_severity_;
554*635a8641SAndroid Build Coastguard Worker };
555*635a8641SAndroid Build Coastguard Worker #endif // DCHECK_IS_CONFIGURABLE
556*635a8641SAndroid Build Coastguard Worker
557*635a8641SAndroid Build Coastguard Worker // https://crbug.com/709067 tracks test flakiness on iOS.
558*635a8641SAndroid Build Coastguard Worker #if defined(OS_IOS)
559*635a8641SAndroid Build Coastguard Worker #define MAYBE_Dcheck DISABLED_Dcheck
560*635a8641SAndroid Build Coastguard Worker #else
561*635a8641SAndroid Build Coastguard Worker #define MAYBE_Dcheck Dcheck
562*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(LoggingTest,MAYBE_Dcheck)563*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, MAYBE_Dcheck) {
564*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_CONFIGURABLE
565*635a8641SAndroid Build Coastguard Worker // DCHECKs are enabled, and LOG_DCHECK is mutable, but defaults to non-fatal.
566*635a8641SAndroid Build Coastguard Worker // Set it to LOG_FATAL to get the expected behavior from the rest of this
567*635a8641SAndroid Build Coastguard Worker // test.
568*635a8641SAndroid Build Coastguard Worker ScopedDcheckSeverity dcheck_severity(LOG_FATAL);
569*635a8641SAndroid Build Coastguard Worker #endif // DCHECK_IS_CONFIGURABLE
570*635a8641SAndroid Build Coastguard Worker
571*635a8641SAndroid Build Coastguard Worker #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
572*635a8641SAndroid Build Coastguard Worker // Release build.
573*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(DCHECK_IS_ON());
574*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(DLOG_IS_ON(DCHECK));
575*635a8641SAndroid Build Coastguard Worker #elif defined(NDEBUG) && defined(DCHECK_ALWAYS_ON)
576*635a8641SAndroid Build Coastguard Worker // Release build with real DCHECKS.
577*635a8641SAndroid Build Coastguard Worker ScopedLogAssertHandler scoped_assert_handler(base::Bind(LogSink));
578*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(DCHECK_IS_ON());
579*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(DLOG_IS_ON(DCHECK));
580*635a8641SAndroid Build Coastguard Worker #else
581*635a8641SAndroid Build Coastguard Worker // Debug build.
582*635a8641SAndroid Build Coastguard Worker ScopedLogAssertHandler scoped_assert_handler(base::Bind(LogSink));
583*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(DCHECK_IS_ON());
584*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(DLOG_IS_ON(DCHECK));
585*635a8641SAndroid Build Coastguard Worker #endif
586*635a8641SAndroid Build Coastguard Worker
587*635a8641SAndroid Build Coastguard Worker // DCHECKs are fatal iff they're compiled in DCHECK_IS_ON() and the DCHECK
588*635a8641SAndroid Build Coastguard Worker // log level is set to fatal.
589*635a8641SAndroid Build Coastguard Worker const bool dchecks_are_fatal = DCHECK_IS_ON() && LOG_DCHECK == LOG_FATAL;
590*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, g_log_sink_call_count);
591*635a8641SAndroid Build Coastguard Worker DCHECK(false);
592*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(dchecks_are_fatal ? 1 : 0, g_log_sink_call_count);
593*635a8641SAndroid Build Coastguard Worker DPCHECK(false);
594*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(dchecks_are_fatal ? 2 : 0, g_log_sink_call_count);
595*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(0, 1);
596*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(dchecks_are_fatal ? 3 : 0, g_log_sink_call_count);
597*635a8641SAndroid Build Coastguard Worker
598*635a8641SAndroid Build Coastguard Worker // Test DCHECK on std::nullptr_t
599*635a8641SAndroid Build Coastguard Worker g_log_sink_call_count = 0;
600*635a8641SAndroid Build Coastguard Worker const void* p_null = nullptr;
601*635a8641SAndroid Build Coastguard Worker const void* p_not_null = &p_null;
602*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(p_null, nullptr);
603*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(nullptr, p_null);
604*635a8641SAndroid Build Coastguard Worker DCHECK_NE(p_not_null, nullptr);
605*635a8641SAndroid Build Coastguard Worker DCHECK_NE(nullptr, p_not_null);
606*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, g_log_sink_call_count);
607*635a8641SAndroid Build Coastguard Worker
608*635a8641SAndroid Build Coastguard Worker // Test DCHECK on a scoped enum.
609*635a8641SAndroid Build Coastguard Worker enum class Animal { DOG, CAT };
610*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(Animal::DOG, Animal::DOG);
611*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, g_log_sink_call_count);
612*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(Animal::DOG, Animal::CAT);
613*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(dchecks_are_fatal ? 1 : 0, g_log_sink_call_count);
614*635a8641SAndroid Build Coastguard Worker
615*635a8641SAndroid Build Coastguard Worker // Test DCHECK on functions and function pointers.
616*635a8641SAndroid Build Coastguard Worker g_log_sink_call_count = 0;
617*635a8641SAndroid Build Coastguard Worker struct MemberFunctions {
618*635a8641SAndroid Build Coastguard Worker void MemberFunction1() {
619*635a8641SAndroid Build Coastguard Worker // See the comment in DcheckEmptyFunction1().
620*635a8641SAndroid Build Coastguard Worker LOG(INFO) << "Do not merge with MemberFunction2.";
621*635a8641SAndroid Build Coastguard Worker }
622*635a8641SAndroid Build Coastguard Worker void MemberFunction2() {}
623*635a8641SAndroid Build Coastguard Worker };
624*635a8641SAndroid Build Coastguard Worker void (MemberFunctions::*mp1)() = &MemberFunctions::MemberFunction1;
625*635a8641SAndroid Build Coastguard Worker void (MemberFunctions::*mp2)() = &MemberFunctions::MemberFunction2;
626*635a8641SAndroid Build Coastguard Worker void (*fp1)() = DcheckEmptyFunction1;
627*635a8641SAndroid Build Coastguard Worker void (*fp2)() = DcheckEmptyFunction2;
628*635a8641SAndroid Build Coastguard Worker void (*fp3)() = DcheckEmptyFunction1;
629*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(fp1, fp3);
630*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, g_log_sink_call_count);
631*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(mp1, &MemberFunctions::MemberFunction1);
632*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, g_log_sink_call_count);
633*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(mp2, &MemberFunctions::MemberFunction2);
634*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, g_log_sink_call_count);
635*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(fp1, fp2);
636*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(dchecks_are_fatal ? 1 : 0, g_log_sink_call_count);
637*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(mp2, &MemberFunctions::MemberFunction1);
638*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(dchecks_are_fatal ? 2 : 0, g_log_sink_call_count);
639*635a8641SAndroid Build Coastguard Worker }
640*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,DcheckReleaseBehavior)641*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, DcheckReleaseBehavior) {
642*635a8641SAndroid Build Coastguard Worker int some_variable = 1;
643*635a8641SAndroid Build Coastguard Worker // These should still reference |some_variable| so we don't get
644*635a8641SAndroid Build Coastguard Worker // unused variable warnings.
645*635a8641SAndroid Build Coastguard Worker DCHECK(some_variable) << "test";
646*635a8641SAndroid Build Coastguard Worker DPCHECK(some_variable) << "test";
647*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(some_variable, 1) << "test";
648*635a8641SAndroid Build Coastguard Worker }
649*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,DCheckEqStatements)650*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, DCheckEqStatements) {
651*635a8641SAndroid Build Coastguard Worker bool reached = false;
652*635a8641SAndroid Build Coastguard Worker if (false)
653*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(false, true); // Unreached.
654*635a8641SAndroid Build Coastguard Worker else
655*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(true, reached = true); // Reached, passed.
656*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(DCHECK_IS_ON() ? true : false, reached);
657*635a8641SAndroid Build Coastguard Worker
658*635a8641SAndroid Build Coastguard Worker if (false)
659*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(false, true); // Unreached.
660*635a8641SAndroid Build Coastguard Worker }
661*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,CheckEqStatements)662*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, CheckEqStatements) {
663*635a8641SAndroid Build Coastguard Worker bool reached = false;
664*635a8641SAndroid Build Coastguard Worker if (false)
665*635a8641SAndroid Build Coastguard Worker CHECK_EQ(false, true); // Unreached.
666*635a8641SAndroid Build Coastguard Worker else
667*635a8641SAndroid Build Coastguard Worker CHECK_EQ(true, reached = true); // Reached, passed.
668*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(reached);
669*635a8641SAndroid Build Coastguard Worker
670*635a8641SAndroid Build Coastguard Worker if (false)
671*635a8641SAndroid Build Coastguard Worker CHECK_EQ(false, true); // Unreached.
672*635a8641SAndroid Build Coastguard Worker }
673*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,NestedLogAssertHandlers)674*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, NestedLogAssertHandlers) {
675*635a8641SAndroid Build Coastguard Worker ::testing::InSequence dummy;
676*635a8641SAndroid Build Coastguard Worker ::testing::StrictMock<MockLogAssertHandler> handler_a, handler_b;
677*635a8641SAndroid Build Coastguard Worker
678*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(
679*635a8641SAndroid Build Coastguard Worker handler_a,
680*635a8641SAndroid Build Coastguard Worker HandleLogAssert(
681*635a8641SAndroid Build Coastguard Worker _, _, base::StringPiece("First assert must be caught by handler_a"),
682*635a8641SAndroid Build Coastguard Worker _));
683*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(
684*635a8641SAndroid Build Coastguard Worker handler_b,
685*635a8641SAndroid Build Coastguard Worker HandleLogAssert(
686*635a8641SAndroid Build Coastguard Worker _, _, base::StringPiece("Second assert must be caught by handler_b"),
687*635a8641SAndroid Build Coastguard Worker _));
688*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(
689*635a8641SAndroid Build Coastguard Worker handler_a,
690*635a8641SAndroid Build Coastguard Worker HandleLogAssert(
691*635a8641SAndroid Build Coastguard Worker _, _,
692*635a8641SAndroid Build Coastguard Worker base::StringPiece("Last assert must be caught by handler_a again"),
693*635a8641SAndroid Build Coastguard Worker _));
694*635a8641SAndroid Build Coastguard Worker
695*635a8641SAndroid Build Coastguard Worker logging::ScopedLogAssertHandler scoped_handler_a(base::Bind(
696*635a8641SAndroid Build Coastguard Worker &MockLogAssertHandler::HandleLogAssert, base::Unretained(&handler_a)));
697*635a8641SAndroid Build Coastguard Worker
698*635a8641SAndroid Build Coastguard Worker // Using LOG(FATAL) rather than CHECK(false) here since log messages aren't
699*635a8641SAndroid Build Coastguard Worker // preserved for CHECKs in official builds.
700*635a8641SAndroid Build Coastguard Worker LOG(FATAL) << "First assert must be caught by handler_a";
701*635a8641SAndroid Build Coastguard Worker
702*635a8641SAndroid Build Coastguard Worker {
703*635a8641SAndroid Build Coastguard Worker logging::ScopedLogAssertHandler scoped_handler_b(base::Bind(
704*635a8641SAndroid Build Coastguard Worker &MockLogAssertHandler::HandleLogAssert, base::Unretained(&handler_b)));
705*635a8641SAndroid Build Coastguard Worker LOG(FATAL) << "Second assert must be caught by handler_b";
706*635a8641SAndroid Build Coastguard Worker }
707*635a8641SAndroid Build Coastguard Worker
708*635a8641SAndroid Build Coastguard Worker LOG(FATAL) << "Last assert must be caught by handler_a again";
709*635a8641SAndroid Build Coastguard Worker }
710*635a8641SAndroid Build Coastguard Worker
711*635a8641SAndroid Build Coastguard Worker // Test that defining an operator<< for a type in a namespace doesn't prevent
712*635a8641SAndroid Build Coastguard Worker // other code in that namespace from calling the operator<<(ostream, wstring)
713*635a8641SAndroid Build Coastguard Worker // defined by logging.h. This can fail if operator<<(ostream, wstring) can't be
714*635a8641SAndroid Build Coastguard Worker // found by ADL, since defining another operator<< prevents name lookup from
715*635a8641SAndroid Build Coastguard Worker // looking in the global namespace.
716*635a8641SAndroid Build Coastguard Worker namespace nested_test {
717*635a8641SAndroid Build Coastguard Worker class Streamable {};
operator <<(std::ostream & out,const Streamable &)718*635a8641SAndroid Build Coastguard Worker ALLOW_UNUSED_TYPE std::ostream& operator<<(std::ostream& out,
719*635a8641SAndroid Build Coastguard Worker const Streamable&) {
720*635a8641SAndroid Build Coastguard Worker return out << "Streamable";
721*635a8641SAndroid Build Coastguard Worker }
TEST_F(LoggingTest,StreamingWstringFindsCorrectOperator)722*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, StreamingWstringFindsCorrectOperator) {
723*635a8641SAndroid Build Coastguard Worker std::wstring wstr = L"Hello World";
724*635a8641SAndroid Build Coastguard Worker std::ostringstream ostr;
725*635a8641SAndroid Build Coastguard Worker ostr << wstr;
726*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("Hello World", ostr.str());
727*635a8641SAndroid Build Coastguard Worker }
728*635a8641SAndroid Build Coastguard Worker } // namespace nested_test
729*635a8641SAndroid Build Coastguard Worker
730*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_CONFIGURABLE
TEST_F(LoggingTest,ConfigurableDCheck)731*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, ConfigurableDCheck) {
732*635a8641SAndroid Build Coastguard Worker // Verify that DCHECKs default to non-fatal in configurable-DCHECK builds.
733*635a8641SAndroid Build Coastguard Worker // Note that we require only that DCHECK is non-fatal by default, rather
734*635a8641SAndroid Build Coastguard Worker // than requiring that it be exactly INFO, ERROR, etc level.
735*635a8641SAndroid Build Coastguard Worker EXPECT_LT(LOG_DCHECK, LOG_FATAL);
736*635a8641SAndroid Build Coastguard Worker DCHECK(false);
737*635a8641SAndroid Build Coastguard Worker
738*635a8641SAndroid Build Coastguard Worker // Verify that DCHECK* aren't hard-wired to crash on failure.
739*635a8641SAndroid Build Coastguard Worker LOG_DCHECK = LOG_INFO;
740*635a8641SAndroid Build Coastguard Worker DCHECK(false);
741*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(1, 2);
742*635a8641SAndroid Build Coastguard Worker
743*635a8641SAndroid Build Coastguard Worker // Verify that DCHECK does crash if LOG_DCHECK is set to LOG_FATAL.
744*635a8641SAndroid Build Coastguard Worker LOG_DCHECK = LOG_FATAL;
745*635a8641SAndroid Build Coastguard Worker
746*635a8641SAndroid Build Coastguard Worker ::testing::StrictMock<MockLogAssertHandler> handler;
747*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(handler, HandleLogAssert(_, _, _, _)).Times(2);
748*635a8641SAndroid Build Coastguard Worker {
749*635a8641SAndroid Build Coastguard Worker logging::ScopedLogAssertHandler scoped_handler_b(base::Bind(
750*635a8641SAndroid Build Coastguard Worker &MockLogAssertHandler::HandleLogAssert, base::Unretained(&handler)));
751*635a8641SAndroid Build Coastguard Worker DCHECK(false);
752*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(1, 2);
753*635a8641SAndroid Build Coastguard Worker }
754*635a8641SAndroid Build Coastguard Worker }
755*635a8641SAndroid Build Coastguard Worker
TEST_F(LoggingTest,ConfigurableDCheckFeature)756*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, ConfigurableDCheckFeature) {
757*635a8641SAndroid Build Coastguard Worker // Initialize FeatureList with and without DcheckIsFatal, and verify the
758*635a8641SAndroid Build Coastguard Worker // value of LOG_DCHECK. Note that we don't require that DCHECK take a
759*635a8641SAndroid Build Coastguard Worker // specific value when the feature is off, only that it is non-fatal.
760*635a8641SAndroid Build Coastguard Worker
761*635a8641SAndroid Build Coastguard Worker {
762*635a8641SAndroid Build Coastguard Worker base::test::ScopedFeatureList feature_list;
763*635a8641SAndroid Build Coastguard Worker feature_list.InitFromCommandLine("DcheckIsFatal", "");
764*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(LOG_DCHECK, LOG_FATAL);
765*635a8641SAndroid Build Coastguard Worker }
766*635a8641SAndroid Build Coastguard Worker
767*635a8641SAndroid Build Coastguard Worker {
768*635a8641SAndroid Build Coastguard Worker base::test::ScopedFeatureList feature_list;
769*635a8641SAndroid Build Coastguard Worker feature_list.InitFromCommandLine("", "DcheckIsFatal");
770*635a8641SAndroid Build Coastguard Worker EXPECT_LT(LOG_DCHECK, LOG_FATAL);
771*635a8641SAndroid Build Coastguard Worker }
772*635a8641SAndroid Build Coastguard Worker
773*635a8641SAndroid Build Coastguard Worker // The default case is last, so we leave LOG_DCHECK in the default state.
774*635a8641SAndroid Build Coastguard Worker {
775*635a8641SAndroid Build Coastguard Worker base::test::ScopedFeatureList feature_list;
776*635a8641SAndroid Build Coastguard Worker feature_list.InitFromCommandLine("", "");
777*635a8641SAndroid Build Coastguard Worker EXPECT_LT(LOG_DCHECK, LOG_FATAL);
778*635a8641SAndroid Build Coastguard Worker }
779*635a8641SAndroid Build Coastguard Worker }
780*635a8641SAndroid Build Coastguard Worker #endif // DCHECK_IS_CONFIGURABLE
781*635a8641SAndroid Build Coastguard Worker
782*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA)
TEST_F(LoggingTest,FuchsiaLogging)783*635a8641SAndroid Build Coastguard Worker TEST_F(LoggingTest, FuchsiaLogging) {
784*635a8641SAndroid Build Coastguard Worker MockLogSource mock_log_source;
785*635a8641SAndroid Build Coastguard Worker EXPECT_CALL(mock_log_source, Log())
786*635a8641SAndroid Build Coastguard Worker .Times(DCHECK_IS_ON() ? 2 : 1)
787*635a8641SAndroid Build Coastguard Worker .WillRepeatedly(Return("log message"));
788*635a8641SAndroid Build Coastguard Worker
789*635a8641SAndroid Build Coastguard Worker SetMinLogLevel(LOG_INFO);
790*635a8641SAndroid Build Coastguard Worker
791*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(LOG_IS_ON(INFO));
792*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE((DCHECK_IS_ON() != 0) == DLOG_IS_ON(INFO));
793*635a8641SAndroid Build Coastguard Worker
794*635a8641SAndroid Build Coastguard Worker ZX_LOG(INFO, ZX_ERR_INTERNAL) << mock_log_source.Log();
795*635a8641SAndroid Build Coastguard Worker ZX_DLOG(INFO, ZX_ERR_INTERNAL) << mock_log_source.Log();
796*635a8641SAndroid Build Coastguard Worker
797*635a8641SAndroid Build Coastguard Worker ZX_CHECK(true, ZX_ERR_INTERNAL);
798*635a8641SAndroid Build Coastguard Worker ZX_DCHECK(true, ZX_ERR_INTERNAL);
799*635a8641SAndroid Build Coastguard Worker }
800*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_FUCHSIA)
801*635a8641SAndroid Build Coastguard Worker
802*635a8641SAndroid Build Coastguard Worker } // namespace
803*635a8641SAndroid Build Coastguard Worker
804*635a8641SAndroid Build Coastguard Worker } // namespace logging
805