1 // 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
15 // debug.h: Debugging utilities.
16
17 #ifndef Debug_hpp
18 #define Debug_hpp
19
20 #include <assert.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include <cctype>
25 #include <string>
26
27 #if !defined(TRACE_OUTPUT_FILE)
28 # define TRACE_OUTPUT_FILE "debug.txt"
29 #endif
30
31 #if defined(__GNUC__) || defined(__clang__)
32 # define CHECK_PRINTF_ARGS __attribute__((format(printf, 1, 2)))
33 #else
34 # define CHECK_PRINTF_ARGS
35 #endif
36
37 namespace sw {
38
39 // Outputs text to the debugging log
40 void trace(const char *format, ...) CHECK_PRINTF_ARGS;
trace()41 inline void trace() {}
42
43 // Outputs text to the debugging log and prints to stderr.
44 void warn(const char *format, ...) CHECK_PRINTF_ARGS;
warn()45 inline void warn() {}
46
47 // Outputs the message to the debugging log and stderr, and calls abort().
48 void abort(const char *format, ...) CHECK_PRINTF_ARGS;
49
50 // Outputs text to the debugging log, and traps once if a debugger is attached.
51 void log_trap(const char *format, ...) CHECK_PRINTF_ARGS;
52
53 } // namespace sw
54
55 // A macro to output a trace of a function call and its arguments to the
56 // debugging log. Disabled if SWIFTSHADER_DISABLE_TRACE is defined.
57 #if defined(SWIFTSHADER_DISABLE_TRACE)
58 # define TRACE(message, ...) (void(0))
59 #else
60 # define TRACE(message, ...) sw::trace("%s:%d TRACE: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
61 #endif
62
63 #if defined(SWIFTSHADER_DISABLE_TRACE) || defined(NDEBUG)
64 # define LOG_TRAP(message, ...) (void(0))
65 #else
66 # define LOG_TRAP(message, ...) sw::log_trap("%s:%d %s LOG TRAP: " message "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
67 #endif
68
69 // A macro to print a warning message to the debugging log and stderr to denote
70 // an issue that needs fixing.
71 #define FIXME(message, ...) sw::warn("%s:%d FIXME: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
72
73 // A macro to print a warning message to the debugging log and stderr.
74 #define WARN(message, ...) sw::warn("%s:%d WARNING: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
75
76 // A macro that delegates to:
77 // abort() in debug builds (!NDEBUG || DCHECK_ALWAYS_ON)
78 // or
79 // warn() in release builds (NDEBUG && !DCHECK_ALWAYS_ON)
80 #undef DABORT
81 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
82 # define DABORT(message, ...) sw::abort("%s:%d ABORT: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__)
83 #else
84 # define DABORT(message, ...) sw::warn("%s:%d WARNING: " message "\n", __FILE__, __LINE__, ##__VA_ARGS__);
85 #endif
86
87 // A macro asserting a condition.
88 // If the condition fails, the condition and message is passed to DABORT().
89 #undef ASSERT_MSG
90 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
91 # define ASSERT_MSG(expression, format, ...) \
92 do \
93 { \
94 if(!(expression)) \
95 { \
96 DABORT("ASSERT(%s): " format "\n", #expression, ##__VA_ARGS__); \
97 } \
98 } while(0)
99 #else
100 // Silence unused variable warnings without evaluating the expressions.
101 // TODO(b/154914395): Also ignore variadic arguments (similar to RR_WATCH expansion)
102 # define ASSERT_MSG(expression, format, ...) \
103 do \
104 { \
105 (void)sizeof((int)(bool)(expression)); \
106 (void)sizeof(format); \
107 } while(0)
108 #endif
109
110 // A macro asserting a condition.
111 // If the condition fails, the condition is passed to DABORT().
112 #undef ASSERT
113 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
114 # define ASSERT(expression) \
115 do \
116 { \
117 if(!(expression)) \
118 { \
119 DABORT("ASSERT(%s)\n", #expression); \
120 } \
121 } while(0)
122 #else
123 // Silence unused variable warnings without evaluating the expressions.
124 # define ASSERT(expression) \
125 do \
126 { \
127 (void)sizeof((int)(bool)(expression)); \
128 } while(0)
129 #endif
130
131 // A macro to indicate functionality currently unimplemented, for a feature advertised
132 // as supported. Since this is a bug, a bug ID must be provided, in b/### format.
133 // For unimplemented functionality not advertised as supported, use UNSUPPORTED() instead.
134 #undef UNIMPLEMENTED
135 #define UNIMPLEMENTED(format, ...) \
136 DABORT("UNIMPLEMENTED: " format, ##__VA_ARGS__); \
137 static_assert(format[0] == 'b' && format[1] == '/' && format[2] >= '0' && format[2] <= '9', "explanation must start with bug reference in b/### format")
138
139 // A macro to indicate unsupported functionality.
140 // This should be called when a Vulkan / SPIR-V feature is attempted to be used,
141 // but is not currently implemented by SwiftShader.
142 // Note that in a well-behaved application these should not be reached as the
143 // application should be respecting the advertised features / limits.
144 #undef UNSUPPORTED
145 #define UNSUPPORTED(format, ...) DABORT("UNSUPPORTED: " format, ##__VA_ARGS__)
146
147 // A macro for code which should never be reached, even with misbehaving
148 // applications.
149 #undef UNREACHABLE
150 #define UNREACHABLE(format, ...) DABORT("UNREACHABLE: " format, ##__VA_ARGS__)
151
152 // A macro asserting a condition and returning if false.
153 // Note this macro always evaluates the expression and also returns in Release builds.
154 #undef ASSERT_OR_RETURN
155 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
156 # define ASSERT_OR_RETURN(expression) ASSERT(expression)
157 #else
158 # define ASSERT_OR_RETURN(expression) \
159 do \
160 { \
161 if(!(expression)) \
162 { \
163 return; \
164 } \
165 } while(0)
166 #endif
167
168 #endif // Debug_hpp
169