1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
base / allocator / partition_allocator / src / partition_alloc / partition_alloc_base / log_message.h [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PARTITION_ALLOC_PARTITION_ALLOC_BASE_LOG_MESSAGE_H_
#define PARTITION_ALLOC_PARTITION_ALLOC_BASE_LOG_MESSAGE_H_
#include <cstddef>
#include "partition_alloc/build_config.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#include "partition_alloc/partition_alloc_base/scoped_clear_last_error.h"
#include "partition_alloc/partition_alloc_base/strings/cstring_builder.h"
namespace partition_alloc::internal::logging {
// Sets the Log Message Handler that gets passed every log message before
// it's sent to other log destinations (if any).
// Returns true to signal that it handled the message and the message
// should not be sent to other log destinations.
typedef bool (*LogMessageHandlerFunction)(int severity,
const char* file,
int line,
size_t message_start,
const char* str);
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
void SetLogMessageHandler(LogMessageHandlerFunction handler);
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
LogMessageHandlerFunction GetLogMessageHandler();
using LogSeverity = int;
constexpr LogSeverity LOGGING_VERBOSE = -1; // This is level 1 verbosity
// Note: the log severities are used to index into the array of names,
// see log_severity_names.
constexpr LogSeverity LOGGING_INFO = 0;
constexpr LogSeverity LOGGING_WARNING = 1;
constexpr LogSeverity LOGGING_ERROR = 2;
constexpr LogSeverity LOGGING_FATAL = 3;
constexpr LogSeverity LOGGING_NUM_SEVERITIES = 4;
// LOGGING_DFATAL is LOGGING_FATAL in DCHECK-enabled builds, ERROR in normal
// mode.
#if PA_BUILDFLAG(DCHECKS_ARE_ON)
constexpr LogSeverity LOGGING_DFATAL = LOGGING_FATAL;
#else
constexpr LogSeverity LOGGING_DFATAL = LOGGING_ERROR;
#endif
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
extern base::strings::CStringBuilder* g_swallow_stream;
// This class more or less represents a particular log message. You
// create an instance of LogMessage and then stream stuff to it.
// When you finish streaming to it, ~LogMessage is called and the
// full message gets streamed to the appropriate destination.
//
// You shouldn't actually use LogMessage's constructor to log things,
// though. You should use the PA_LOG() macro (and variants thereof)
// above.
class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) LogMessage {
public:
// Used for PA_LOG(severity).
LogMessage(const char* file, int line, LogSeverity severity);
// Used for CHECK(). Implied severity = LOGGING_FATAL.
LogMessage(const char* file, int line, const char* condition);
LogMessage(const LogMessage&) = delete;
LogMessage& operator=(const LogMessage&) = delete;
virtual ~LogMessage();
base::strings::CStringBuilder& stream() { return stream_; }
LogSeverity severity() { return severity_; }
const char* c_str() { return stream_.c_str(); }
private:
void Init(const char* file, int line);
const LogSeverity severity_;
base::strings::CStringBuilder stream_;
size_t message_start_; // Offset of the start of the message (past prefix
// info).
// The file and line information passed in to the constructor.
const char* const file_;
const int line_;
// This is useful since the LogMessage class uses a lot of Win32 calls
// that will lose the value of GLE and the code that called the log function
// will have lost the thread error value when the log call returns.
base::ScopedClearLastError last_error_;
};
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
// is not used" and "statement has no effect".
class LogMessageVoidify {
public:
LogMessageVoidify() = default;
// This has to be an operator with a precedence lower than << but
// higher than ?:
void operator&(base::strings::CStringBuilder&) {}
};
#if PA_BUILDFLAG(IS_WIN)
typedef unsigned long SystemErrorCode;
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
typedef int SystemErrorCode;
#endif
// Alias for ::GetLastError() on Windows and errno on POSIX. Avoids having to
// pull in windows.h just for GetLastError() and DWORD.
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)
SystemErrorCode GetLastSystemErrorCode();
#if PA_BUILDFLAG(IS_WIN)
// Appends a formatted system message of the GetLastError() type.
class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) Win32ErrorLogMessage
: public LogMessage {
public:
Win32ErrorLogMessage(const char* file,
int line,
LogSeverity severity,
SystemErrorCode err);
Win32ErrorLogMessage(const Win32ErrorLogMessage&) = delete;
Win32ErrorLogMessage& operator=(const Win32ErrorLogMessage&) = delete;
// Appends the error message before destructing the encapsulated class.
~Win32ErrorLogMessage() override;
private:
SystemErrorCode err_;
};
#elif PA_BUILDFLAG(IS_POSIX) || PA_BUILDFLAG(IS_FUCHSIA)
// Appends a formatted system message of the errno type
class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ErrnoLogMessage
: public LogMessage {
public:
ErrnoLogMessage(const char* file,
int line,
LogSeverity severity,
SystemErrorCode err);
ErrnoLogMessage(const ErrnoLogMessage&) = delete;
ErrnoLogMessage& operator=(const ErrnoLogMessage&) = delete;
// Appends the error message before destructing the encapsulated class.
~ErrnoLogMessage() override;
private:
SystemErrorCode err_;
};
#endif // PA_BUILDFLAG(IS_WIN)
} // namespace partition_alloc::internal::logging
#endif // PARTITION_ALLOC_PARTITION_ALLOC_BASE_LOG_MESSAGE_H_