gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
logging.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014, 2017, 2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#ifndef __BASE_LOGGING_HH__
42#define __BASE_LOGGING_HH__
43
44#include <cassert>
45#include <functional>
46#include <sstream>
47#include <utility>
48#include <string>
49#include <vector>
50
51#include "base/compiler.hh"
52#include "base/cprintf.hh"
53
54namespace gem5
55{
56
57class Logger
58{
59 public:
60
64 static Logger &getPanic();
65 static Logger &getFatal();
66 static Logger &getWarn();
67 static Logger &getInfo();
68 static Logger &getHack();
69
75
76 static void
78 {
79 getPanic().enabled = (ll >= PANIC);
80 getFatal().enabled = (ll >= FATAL);
81 getWarn().enabled = (ll >= WARN);
82 getInfo().enabled = (ll >= INFO);
83 getHack().enabled = (ll >= HACK);
84 }
85
86 struct Loc
87 {
88 Loc(const char *file, int line) : file(file), line(line) {}
89 const char *file;
90 int line;
91 };
92
93 Logger(const char *prefix) : enabled(true), prefix(prefix)
94 {
95 assert(prefix);
96 }
97
98 virtual ~Logger() {};
99
100 template<typename ...Args> void
101 print(const Loc &loc, const char *format, const Args &...args)
102 {
103 std::stringstream ss;
104 ccprintf(ss, format, args...);
105 const std::string str = ss.str();
106
107 std::stringstream ss_formatted;
108 ss_formatted << prefix << str;
109 if (str.length() && str.back() != '\n' && str.back() != '\r')
110 ss_formatted << std::endl;
111 if (!enabled)
112 return;
113 log(loc, ss_formatted.str());
114 }
115
116 template<typename ...Args> void
117 print(const Loc &loc, const std::string &format, const Args &...args)
118 {
119 print(loc, format.c_str(), args...);
120 }
121
127 [[noreturn]] void exit_helper() { exit(); ::abort(); }
128
130 void
131 registerExtraLog(std::function<std::string()> cb)
132 {
133 extraLogs.emplace_back(std::move(cb));
134 }
135
136 protected:
138
144 std::string
146 {
147 std::stringstream ss;
148 for (const auto &cb : extraLogs) {
149 std::string str = cb();
150 ss << str;
151 if (str.length() && str.back() != '\n' && str.back() != '\r')
152 ss << std::endl;
153 }
154 return ss.str();
155 }
156
158 virtual void
159 log(const Loc &loc, std::string s)
160 {
161 std::cerr << loc.file << ":" << loc.line << ": " << s
163 }
164
165 virtual void exit() { /* Fall through to the abort in exit_helper. */ }
166
167 const char *prefix;
168
170 std::vector<std::function<std::string()>> extraLogs;
171};
172
173#define base_message(logger, ...) \
174 [&log = logger](const auto&... args) { \
175 log.print(::gem5::Logger::Loc(__FILE__, __LINE__), args...); \
176 }(__VA_ARGS__)
177
178/*
179 * Only print the message the first time this expression is
180 * encountered. i.e. This doesn't check the string itself and
181 * prevent duplicate strings, this prevents the statement from
182 * happening more than once. So, even if the arguments change and that
183 * would have resulted in a different message thoes messages would be
184 * supressed.
185 */
186#define base_message_once(logger, ...) \
187 [&log = logger](const auto&... args) { \
188 static bool once{false}; \
189 if (GEM5_UNLIKELY(!once)) { \
190 once = true; \
191 base_message(log, args...); \
192 } \
193 }(__VA_ARGS__)
194
195/*
196 * logger.exit_helper() can't be called inside the lambda for now as the
197 * lambda's operator() can't be [[noreturn]]. As a result, exit_message and it'
198 * s derivative cannot be used in functions without also specifying a return
199 * value, which is inconvenient if not impossible.
200 */
201
202#define exit_message(logger, ...) \
203 ( \
204 [&log = logger](const auto&... args) { \
205 base_message(log, args...); \
206 }(__VA_ARGS__), \
207 logger.exit_helper() \
208 )
209
220#define panic(...) exit_message(::gem5::Logger::getPanic(), __VA_ARGS__)
221
232#define fatal(...) exit_message(::gem5::Logger::getFatal(), __VA_ARGS__)
233
246#define panic_if(cond, ...) \
247 ( \
248 GEM5_UNLIKELY(static_cast<bool>(cond)) ? \
249 panic("panic condition " # cond " occurred: %s", \
250 ::gem5::csprintf(__VA_ARGS__)) : \
251 void(0) \
252 )
253
254
268#define fatal_if(cond, ...) \
269 ( \
270 GEM5_UNLIKELY(static_cast<bool>(cond)) ? \
271 fatal("fatal condition " # cond " occurred: %s", \
272 ::gem5::csprintf(__VA_ARGS__)) : \
273 void(0) \
274 )
275
276
288#define warn(...) base_message(::gem5::Logger::getWarn(), __VA_ARGS__)
289#define inform(...) base_message(::gem5::Logger::getInfo(), __VA_ARGS__)
290#define hack(...) base_message(::gem5::Logger::getHack(), __VA_ARGS__)
291
292#define warn_once(...) \
293 base_message_once(::gem5::Logger::getWarn(), __VA_ARGS__)
294#define inform_once(...) \
295 base_message_once(::gem5::Logger::getInfo(), __VA_ARGS__)
296#define hack_once(...) \
297 base_message_once(::gem5::Logger::getHack(), __VA_ARGS__)
298 // end of api_logger
299
315#define warn_if(cond, ...) \
316 ( \
317 static_cast<bool>(cond) ? \
318 warn(__VA_ARGS__) : \
319 void(0) \
320 )
321
322#define warn_if_once(cond, ...) \
323 ( \
324 static_cast<bool>(cond) ? \
325 warn_once(__VA_ARGS__) : \
326 void(0) \
327 )
328 // end of api_logger
330
331#ifdef NDEBUG
332#define NDEBUG_DEFINED 1
333#else
334#define NDEBUG_DEFINED 0
335#endif
336
349#define gem5_assert(cond, ...) \
350 ( \
351 GEM5_UNLIKELY(NDEBUG_DEFINED || static_cast<bool>(cond)) ? \
352 void(0) : \
353 [](const auto&... args) { \
354 auto msg = [&]{ \
355 if constexpr (sizeof...(args) == 0) return ""; \
356 else return std::string(": ") + csprintf(args...); \
357 }; \
358 panic("assert(" #cond ") failed%s", msg()); \
359 }(__VA_ARGS__) \
360 )
361 // end of api_logger
363
364#define chatty_assert(...) \
365 ( \
366 gem5_assert(args...), \
367 GEM5_DEPRECATED_MACRO(chatty_assert, {}, "Please use gem5_assert()") \
368 )
369
370} // namespace gem5
371#endif // __BASE_LOGGING_HH__
virtual void exit()
Definition logging.hh:165
virtual ~Logger()
Definition logging.hh:98
virtual void log(const Loc &loc, std::string s)
Generates the log message.
Definition logging.hh:159
const char * prefix
Definition logging.hh:167
static Logger & getWarn()
void registerExtraLog(std::function< std::string()> cb)
Register callback to generate extra log.
Definition logging.hh:131
std::vector< std::function< std::string()> > extraLogs
Data structure to store extra log callbacks.
Definition logging.hh:170
Logger(const char *prefix)
Definition logging.hh:93
void print(const Loc &loc, const std::string &format, const Args &...args)
Definition logging.hh:117
static Logger & getInfo()
static Logger & getHack()
void print(const Loc &loc, const char *format, const Args &...args)
Definition logging.hh:101
std::string getFormattedExtraLog() const
Generate the formatted extra log string.
Definition logging.hh:145
static Logger & getPanic()
Get a Logger for the specified type of message.
void exit_helper()
This helper is necessary since noreturn isn't inherited by virtual functions, and gcc will get mad if...
Definition logging.hh:127
static Logger & getFatal()
static void setLevel(LogLevel ll)
Definition logging.hh:77
STL vector class.
Definition stl.hh:37
Bitfield< 4 > s
Bitfield< 31, 29 > format
Bitfield< 21 > ss
Definition misc_types.hh:60
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
const char * file
Definition logging.hh:89
Loc(const char *file, int line)
Definition logging.hh:88

Generated on Mon May 26 2025 09:19:06 for gem5 by doxygen 1.13.2