blob: 4131bd0bc44129a264264388153cb55ce72e9654 [file] [log] [blame]
Nicolas Capensc07dc4b2018-08-06 14:20:45 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Ben Claytoneb50d252019-04-15 13:50:01 -040015// debug.h: Debugging utilities.
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040016
Ben Claytoneb50d252019-04-15 13:50:01 -040017#ifndef rr_DEBUG_H_
18#define rr_DEBUG_H_
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040019
20#include <assert.h>
21#include <stdio.h>
Ben Clayton713b8d32019-12-17 20:37:56 +000022#include <stdlib.h>
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040023
Ben Claytonce54c592020-02-07 11:30:51 +000024#include <cctype>
25#include <string>
26
Ben Claytoneb50d252019-04-15 13:50:01 -040027#if !defined(TRACE_OUTPUT_FILE)
Ben Clayton713b8d32019-12-17 20:37:56 +000028# define TRACE_OUTPUT_FILE "debug.txt"
Ben Claytoneb50d252019-04-15 13:50:01 -040029#endif
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040030
Ben Clayton46e28cb2019-04-25 11:18:06 +010031#if defined(__GNUC__) || defined(__clang__)
Ben Clayton713b8d32019-12-17 20:37:56 +000032# define CHECK_PRINTF_ARGS __attribute__((format(printf, 1, 2)))
Ben Clayton46e28cb2019-04-25 11:18:06 +010033#else
Ben Clayton713b8d32019-12-17 20:37:56 +000034# define CHECK_PRINTF_ARGS
Ben Clayton46e28cb2019-04-25 11:18:06 +010035#endif
36
Nicolas Capens157ba262019-12-10 17:49:14 -050037namespace rr {
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040038
Nicolas Capens157ba262019-12-10 17:49:14 -050039// Outputs text to the debugging log
40void trace(const char *format, ...) CHECK_PRINTF_ARGS;
41inline void trace() {}
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040042
Nicolas Capens157ba262019-12-10 17:49:14 -050043// Outputs text to the debugging log and prints to stderr.
44void warn(const char *format, ...) CHECK_PRINTF_ARGS;
45inline void warn() {}
46
47// Outputs the message to the debugging log and stderr, and calls abort().
48void abort(const char *format, ...) CHECK_PRINTF_ARGS;
49
Ben Claytonce54c592020-02-07 11:30:51 +000050// Outputs text to the debugging log, and asserts once if a debugger is attached.
51void trace_assert(const char *format, ...) CHECK_PRINTF_ARGS;
52
Nicolas Capens157ba262019-12-10 17:49:14 -050053} // namespace rr
Nicolas Capensc07dc4b2018-08-06 14:20:45 -040054
Ben Claytoneb50d252019-04-15 13:50:01 -040055// A macro to output a trace of a function call and its arguments to the
56// debugging log. Disabled if RR_DISABLE_TRACE is defined.
57#if defined(RR_DISABLE_TRACE)
Ben Clayton713b8d32019-12-17 20:37:56 +000058# define TRACE(message, ...) (void(0))
Ben Claytonce54c592020-02-07 11:30:51 +000059# define TRACE_ASSERT(message, ...) (void(0))
Ben Claytoneb50d252019-04-15 13:50:01 -040060#else
Ben Clayton713b8d32019-12-17 20:37:56 +000061# define TRACE(message, ...) rr::trace("%s:%d TRACE: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
Ben Claytonce54c592020-02-07 11:30:51 +000062# define TRACE_ASSERT(message, ...) rr::trace_assert("%s:%d %s TRACE_ASSERT: " message "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
Ben Claytoneb50d252019-04-15 13:50:01 -040063#endif
64
65// A macro to print a warning message to the debugging log and stderr to denote
66// an issue that needs fixing.
Nicolas Capens60aa34a2020-04-24 10:41:28 -040067#define FIXME(message, ...) rr::warn("%s:%d FIXME: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
Ben Claytoneb50d252019-04-15 13:50:01 -040068
69// A macro to print a warning message to the debugging log and stderr.
Nicolas Capens60aa34a2020-04-24 10:41:28 -040070#define WARN(message, ...) rr::warn("%s:%d WARNING: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
Ben Claytoneb50d252019-04-15 13:50:01 -040071
Ben Claytoneb50d252019-04-15 13:50:01 -040072// A macro that delegates to:
Nicolas Capens27177022020-04-22 11:09:24 -040073// abort() in debug builds (!NDEBUG || DCHECK_ALWAYS_ON)
Ben Claytoneb50d252019-04-15 13:50:01 -040074// or
Nicolas Capens27177022020-04-22 11:09:24 -040075// warn() in release builds (NDEBUG && !DCHECK_ALWAYS_ON)
Ben Claytoneb50d252019-04-15 13:50:01 -040076#undef DABORT
77#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
Nicolas Capens27177022020-04-22 11:09:24 -040078# define DABORT(message, ...) rr::abort("%s:%d ABORT: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
Ben Claytoneb50d252019-04-15 13:50:01 -040079#else
Nicolas Capens27177022020-04-22 11:09:24 -040080# define DABORT(message, ...) rr::warn("%s:%d WARNING: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__);
Ben Claytoneb50d252019-04-15 13:50:01 -040081#endif
82
83// A macro asserting a condition.
84// If the condition fails, the condition and message is passed to DABORT().
85#undef ASSERT_MSG
Nicolas Capens60aa34a2020-04-24 10:41:28 -040086#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
87# define ASSERT_MSG(expression, format, ...) \
88 do \
89 { \
90 if(!(expression)) \
91 { \
92 DABORT("ASSERT(%s): " format "\n", #expression, ##__VA_ARGS__); \
93 } \
94 } while(0)
95#else
96// Silence unused variable warnings without evaluating the expressions.
97// TODO(b/154914395): Also ignore variadic arguments (similar to RR_WATCH expansion)
98# define ASSERT_MSG(expression, format, ...) \
99 do \
100 { \
101 (void)sizeof((int)(bool)(expression)); \
102 (void)sizeof(format); \
103 } while(0)
104#endif
Ben Claytoneb50d252019-04-15 13:50:01 -0400105
106// A macro asserting a condition.
107// If the condition fails, the condition is passed to DABORT().
108#undef ASSERT
Nicolas Capens60aa34a2020-04-24 10:41:28 -0400109#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
110# define ASSERT(expression) \
111 do \
112 { \
113 if(!(expression)) \
114 { \
115 DABORT("ASSERT(%s)\n", #expression); \
116 } \
117 } while(0)
118#else
119// Silence unused variable warnings without evaluating the expressions.
120# define ASSERT(expression) \
121 do \
122 { \
123 (void)sizeof((int)(bool)(expression)); \
124 } while(0)
125#endif
Ben Claytoneb50d252019-04-15 13:50:01 -0400126
Ben Claytonce54c592020-02-07 11:30:51 +0000127// A macro to indicate functionality currently unimplemented, for a feature advertised
128// as supported. This is similar to UNIMPLEMENTED() but does not check there's a bug
129// number.
130#undef UNIMPLEMENTED_NO_BUG
131#define UNIMPLEMENTED_NO_BUG(format, ...) \
132 DABORT("UNIMPLEMENTED: " format, ##__VA_ARGS__);
Ben Claytoneb50d252019-04-15 13:50:01 -0400133
Ben Claytonce54c592020-02-07 11:30:51 +0000134// A macro to indicate functionality currently unimplemented, for a feature advertised
135// as supported. Since this is a bug, a bug ID must be provided, in b/### format.
136// For unimplemented functionality not advertised as supported, use UNSUPPORTED() instead.
137#undef UNIMPLEMENTED
138#define UNIMPLEMENTED(format, ...) \
139 static_assert(format[0] == 'b' && format[1] == '/' && format[2] >= '0' && format[2] <= '9', "explanation must start with bug reference in b/### format"); \
140 UNIMPLEMENTED_NO_BUG(format, ##__VA_ARGS__)
141
142// A macro to indicate unsupported functionality.
143// This should be called when a feature is attempted to be used, but is not
144// currently implemented by Reactor.
145// Note that in a well-behaved application these should not be reached as the
146// application should be respecting the advertised features / limits.
147#undef UNSUPPORTED
148#define UNSUPPORTED(format, ...) DABORT("UNSUPPORTED: " format, ##__VA_ARGS__)
149
150// A macro for code which should never be reached, even with misbehaving
151// applications.
Ben Claytoneb50d252019-04-15 13:50:01 -0400152#undef UNREACHABLE
153#define UNREACHABLE(format, ...) DABORT("UNREACHABLE: " format, ##__VA_ARGS__)
154
Nicolas Capens60aa34a2020-04-24 10:41:28 -0400155// A macro asserting a condition and returning if false.
156// Note this macro always evaluates the expression and also returns in Release builds.
Ben Claytoneb50d252019-04-15 13:50:01 -0400157#undef ASSERT_OR_RETURN
158#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
Ben Clayton713b8d32019-12-17 20:37:56 +0000159# define ASSERT_OR_RETURN(expression) ASSERT(expression)
Ben Claytoneb50d252019-04-15 13:50:01 -0400160#else
Ben Clayton713b8d32019-12-17 20:37:56 +0000161# define ASSERT_OR_RETURN(expression) \
162 do \
163 { \
164 if(!(expression)) \
165 { \
166 return; \
167 } \
168 } while(0)
Ben Claytoneb50d252019-04-15 13:50:01 -0400169#endif
170
Ben Clayton713b8d32019-12-17 20:37:56 +0000171#endif // rr_DEBUG_H_