1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker
15*03ce13f7SAndroid Build Coastguard Worker #include "Debug.hpp"
16*03ce13f7SAndroid Build Coastguard Worker
17*03ce13f7SAndroid Build Coastguard Worker #include <atomic>
18*03ce13f7SAndroid Build Coastguard Worker #include <cstdarg>
19*03ce13f7SAndroid Build Coastguard Worker #include <cstdio>
20*03ce13f7SAndroid Build Coastguard Worker #include <string>
21*03ce13f7SAndroid Build Coastguard Worker
22*03ce13f7SAndroid Build Coastguard Worker #if __ANDROID__
23*03ce13f7SAndroid Build Coastguard Worker # include <android/log.h>
24*03ce13f7SAndroid Build Coastguard Worker #endif
25*03ce13f7SAndroid Build Coastguard Worker
26*03ce13f7SAndroid Build Coastguard Worker #if defined(__unix__)
27*03ce13f7SAndroid Build Coastguard Worker # define PTRACE
28*03ce13f7SAndroid Build Coastguard Worker # include <sys/ptrace.h>
29*03ce13f7SAndroid Build Coastguard Worker # include <sys/types.h>
30*03ce13f7SAndroid Build Coastguard Worker #elif defined(_WIN32) || defined(_WIN64)
31*03ce13f7SAndroid Build Coastguard Worker # include <windows.h>
32*03ce13f7SAndroid Build Coastguard Worker #elif defined(__APPLE__) || defined(__MACH__)
33*03ce13f7SAndroid Build Coastguard Worker # include <sys/sysctl.h>
34*03ce13f7SAndroid Build Coastguard Worker # include <unistd.h>
35*03ce13f7SAndroid Build Coastguard Worker #endif
36*03ce13f7SAndroid Build Coastguard Worker
37*03ce13f7SAndroid Build Coastguard Worker #ifdef ERROR
38*03ce13f7SAndroid Build Coastguard Worker # undef ERROR // b/127920555
39*03ce13f7SAndroid Build Coastguard Worker #endif
40*03ce13f7SAndroid Build Coastguard Worker
41*03ce13f7SAndroid Build Coastguard Worker #ifndef REACTOR_LOGGING_LEVEL
42*03ce13f7SAndroid Build Coastguard Worker # define REACTOR_LOGGING_LEVEL Info
43*03ce13f7SAndroid Build Coastguard Worker #endif
44*03ce13f7SAndroid Build Coastguard Worker
45*03ce13f7SAndroid Build Coastguard Worker namespace {
46*03ce13f7SAndroid Build Coastguard Worker
IsUnderDebugger()47*03ce13f7SAndroid Build Coastguard Worker bool IsUnderDebugger()
48*03ce13f7SAndroid Build Coastguard Worker {
49*03ce13f7SAndroid Build Coastguard Worker #if defined(PTRACE) && !defined(__APPLE__) && !defined(__MACH__)
50*03ce13f7SAndroid Build Coastguard Worker static bool checked = false;
51*03ce13f7SAndroid Build Coastguard Worker static bool res = false;
52*03ce13f7SAndroid Build Coastguard Worker
53*03ce13f7SAndroid Build Coastguard Worker if(!checked)
54*03ce13f7SAndroid Build Coastguard Worker {
55*03ce13f7SAndroid Build Coastguard Worker // If a debugger is attached then we're already being ptraced and ptrace
56*03ce13f7SAndroid Build Coastguard Worker // will return a non-zero value.
57*03ce13f7SAndroid Build Coastguard Worker checked = true;
58*03ce13f7SAndroid Build Coastguard Worker if(ptrace(PTRACE_TRACEME, 0, 1, 0) != 0)
59*03ce13f7SAndroid Build Coastguard Worker {
60*03ce13f7SAndroid Build Coastguard Worker res = true;
61*03ce13f7SAndroid Build Coastguard Worker }
62*03ce13f7SAndroid Build Coastguard Worker else
63*03ce13f7SAndroid Build Coastguard Worker {
64*03ce13f7SAndroid Build Coastguard Worker ptrace(PTRACE_DETACH, 0, 1, 0);
65*03ce13f7SAndroid Build Coastguard Worker }
66*03ce13f7SAndroid Build Coastguard Worker }
67*03ce13f7SAndroid Build Coastguard Worker
68*03ce13f7SAndroid Build Coastguard Worker return res;
69*03ce13f7SAndroid Build Coastguard Worker #elif defined(_WIN32) || defined(_WIN64)
70*03ce13f7SAndroid Build Coastguard Worker return IsDebuggerPresent() != 0;
71*03ce13f7SAndroid Build Coastguard Worker #elif defined(__APPLE__) || defined(__MACH__)
72*03ce13f7SAndroid Build Coastguard Worker // Code comes from the Apple Technical Q&A QA1361
73*03ce13f7SAndroid Build Coastguard Worker
74*03ce13f7SAndroid Build Coastguard Worker // Tell sysctl what info we're requestion. Specifically we're asking for
75*03ce13f7SAndroid Build Coastguard Worker // info about this our PID.
76*03ce13f7SAndroid Build Coastguard Worker int res = 0;
77*03ce13f7SAndroid Build Coastguard Worker int request[4] = {
78*03ce13f7SAndroid Build Coastguard Worker CTL_KERN,
79*03ce13f7SAndroid Build Coastguard Worker KERN_PROC,
80*03ce13f7SAndroid Build Coastguard Worker KERN_PROC_PID,
81*03ce13f7SAndroid Build Coastguard Worker getpid()
82*03ce13f7SAndroid Build Coastguard Worker };
83*03ce13f7SAndroid Build Coastguard Worker struct kinfo_proc info;
84*03ce13f7SAndroid Build Coastguard Worker size_t size = sizeof(info);
85*03ce13f7SAndroid Build Coastguard Worker
86*03ce13f7SAndroid Build Coastguard Worker info.kp_proc.p_flag = 0;
87*03ce13f7SAndroid Build Coastguard Worker
88*03ce13f7SAndroid Build Coastguard Worker // Get the info we're requesting, if sysctl fails then info.kp_proc.p_flag will remain 0.
89*03ce13f7SAndroid Build Coastguard Worker res = sysctl(request, sizeof(request) / sizeof(*request), &info, &size, NULL, 0);
90*03ce13f7SAndroid Build Coastguard Worker ASSERT_MSG(res == 0, "syscl returned %d", res);
91*03ce13f7SAndroid Build Coastguard Worker
92*03ce13f7SAndroid Build Coastguard Worker // We're being debugged if the P_TRACED flag is set
93*03ce13f7SAndroid Build Coastguard Worker return ((info.kp_proc.p_flag & P_TRACED) != 0);
94*03ce13f7SAndroid Build Coastguard Worker #else
95*03ce13f7SAndroid Build Coastguard Worker return false;
96*03ce13f7SAndroid Build Coastguard Worker #endif
97*03ce13f7SAndroid Build Coastguard Worker }
98*03ce13f7SAndroid Build Coastguard Worker
99*03ce13f7SAndroid Build Coastguard Worker enum class Level
100*03ce13f7SAndroid Build Coastguard Worker {
101*03ce13f7SAndroid Build Coastguard Worker Debug,
102*03ce13f7SAndroid Build Coastguard Worker Info,
103*03ce13f7SAndroid Build Coastguard Worker Warn,
104*03ce13f7SAndroid Build Coastguard Worker Error,
105*03ce13f7SAndroid Build Coastguard Worker Fatal,
106*03ce13f7SAndroid Build Coastguard Worker };
107*03ce13f7SAndroid Build Coastguard Worker
108*03ce13f7SAndroid Build Coastguard Worker #ifdef __ANDROID__
logv_android(Level level,const char * msg)109*03ce13f7SAndroid Build Coastguard Worker [[maybe_unused]] void logv_android(Level level, const char *msg)
110*03ce13f7SAndroid Build Coastguard Worker {
111*03ce13f7SAndroid Build Coastguard Worker switch(level)
112*03ce13f7SAndroid Build Coastguard Worker {
113*03ce13f7SAndroid Build Coastguard Worker case Level::Debug:
114*03ce13f7SAndroid Build Coastguard Worker __android_log_write(ANDROID_LOG_DEBUG, "SwiftShader", msg);
115*03ce13f7SAndroid Build Coastguard Worker break;
116*03ce13f7SAndroid Build Coastguard Worker case Level::Info:
117*03ce13f7SAndroid Build Coastguard Worker __android_log_write(ANDROID_LOG_INFO, "SwiftShader", msg);
118*03ce13f7SAndroid Build Coastguard Worker break;
119*03ce13f7SAndroid Build Coastguard Worker case Level::Warn:
120*03ce13f7SAndroid Build Coastguard Worker __android_log_write(ANDROID_LOG_WARN, "SwiftShader", msg);
121*03ce13f7SAndroid Build Coastguard Worker break;
122*03ce13f7SAndroid Build Coastguard Worker case Level::Error:
123*03ce13f7SAndroid Build Coastguard Worker __android_log_write(ANDROID_LOG_ERROR, "SwiftShader", msg);
124*03ce13f7SAndroid Build Coastguard Worker break;
125*03ce13f7SAndroid Build Coastguard Worker case Level::Fatal:
126*03ce13f7SAndroid Build Coastguard Worker __android_log_write(ANDROID_LOG_FATAL, "SwiftShader", msg);
127*03ce13f7SAndroid Build Coastguard Worker break;
128*03ce13f7SAndroid Build Coastguard Worker }
129*03ce13f7SAndroid Build Coastguard Worker }
130*03ce13f7SAndroid Build Coastguard Worker #else
logv_std(Level level,const char * msg)131*03ce13f7SAndroid Build Coastguard Worker [[maybe_unused]] void logv_std(Level level, const char *msg)
132*03ce13f7SAndroid Build Coastguard Worker {
133*03ce13f7SAndroid Build Coastguard Worker switch(level)
134*03ce13f7SAndroid Build Coastguard Worker {
135*03ce13f7SAndroid Build Coastguard Worker case Level::Debug:
136*03ce13f7SAndroid Build Coastguard Worker case Level::Info:
137*03ce13f7SAndroid Build Coastguard Worker fprintf(stdout, "%s", msg);
138*03ce13f7SAndroid Build Coastguard Worker break;
139*03ce13f7SAndroid Build Coastguard Worker case Level::Warn:
140*03ce13f7SAndroid Build Coastguard Worker case Level::Error:
141*03ce13f7SAndroid Build Coastguard Worker case Level::Fatal:
142*03ce13f7SAndroid Build Coastguard Worker fprintf(stderr, "%s", msg);
143*03ce13f7SAndroid Build Coastguard Worker break;
144*03ce13f7SAndroid Build Coastguard Worker }
145*03ce13f7SAndroid Build Coastguard Worker }
146*03ce13f7SAndroid Build Coastguard Worker #endif
147*03ce13f7SAndroid Build Coastguard Worker
logv(Level level,const char * format,va_list args)148*03ce13f7SAndroid Build Coastguard Worker void logv(Level level, const char *format, va_list args)
149*03ce13f7SAndroid Build Coastguard Worker {
150*03ce13f7SAndroid Build Coastguard Worker if(static_cast<int>(level) < static_cast<int>(Level::REACTOR_LOGGING_LEVEL))
151*03ce13f7SAndroid Build Coastguard Worker {
152*03ce13f7SAndroid Build Coastguard Worker return;
153*03ce13f7SAndroid Build Coastguard Worker }
154*03ce13f7SAndroid Build Coastguard Worker
155*03ce13f7SAndroid Build Coastguard Worker #ifndef SWIFTSHADER_DISABLE_TRACE
156*03ce13f7SAndroid Build Coastguard Worker char buffer[2048];
157*03ce13f7SAndroid Build Coastguard Worker vsnprintf(buffer, sizeof(buffer), format, args);
158*03ce13f7SAndroid Build Coastguard Worker
159*03ce13f7SAndroid Build Coastguard Worker # if defined(__ANDROID__)
160*03ce13f7SAndroid Build Coastguard Worker logv_android(level, buffer);
161*03ce13f7SAndroid Build Coastguard Worker # elif defined(_WIN32)
162*03ce13f7SAndroid Build Coastguard Worker logv_std(level, buffer);
163*03ce13f7SAndroid Build Coastguard Worker ::OutputDebugString(buffer);
164*03ce13f7SAndroid Build Coastguard Worker # else
165*03ce13f7SAndroid Build Coastguard Worker logv_std(level, buffer);
166*03ce13f7SAndroid Build Coastguard Worker # endif
167*03ce13f7SAndroid Build Coastguard Worker
168*03ce13f7SAndroid Build Coastguard Worker const bool traceToFile = false;
169*03ce13f7SAndroid Build Coastguard Worker if(traceToFile)
170*03ce13f7SAndroid Build Coastguard Worker {
171*03ce13f7SAndroid Build Coastguard Worker FILE *file = fopen(TRACE_OUTPUT_FILE, "a");
172*03ce13f7SAndroid Build Coastguard Worker
173*03ce13f7SAndroid Build Coastguard Worker if(file)
174*03ce13f7SAndroid Build Coastguard Worker {
175*03ce13f7SAndroid Build Coastguard Worker vfprintf(file, format, args);
176*03ce13f7SAndroid Build Coastguard Worker fclose(file);
177*03ce13f7SAndroid Build Coastguard Worker }
178*03ce13f7SAndroid Build Coastguard Worker }
179*03ce13f7SAndroid Build Coastguard Worker #endif // SWIFTSHADER_DISABLE_TRACE
180*03ce13f7SAndroid Build Coastguard Worker }
181*03ce13f7SAndroid Build Coastguard Worker
182*03ce13f7SAndroid Build Coastguard Worker } // anonymous namespace
183*03ce13f7SAndroid Build Coastguard Worker
184*03ce13f7SAndroid Build Coastguard Worker namespace rr {
185*03ce13f7SAndroid Build Coastguard Worker
trace(const char * format,...)186*03ce13f7SAndroid Build Coastguard Worker void trace(const char *format, ...)
187*03ce13f7SAndroid Build Coastguard Worker {
188*03ce13f7SAndroid Build Coastguard Worker va_list vararg;
189*03ce13f7SAndroid Build Coastguard Worker va_start(vararg, format);
190*03ce13f7SAndroid Build Coastguard Worker logv(Level::Debug, format, vararg);
191*03ce13f7SAndroid Build Coastguard Worker va_end(vararg);
192*03ce13f7SAndroid Build Coastguard Worker }
193*03ce13f7SAndroid Build Coastguard Worker
warn(const char * format,...)194*03ce13f7SAndroid Build Coastguard Worker void warn(const char *format, ...)
195*03ce13f7SAndroid Build Coastguard Worker {
196*03ce13f7SAndroid Build Coastguard Worker va_list vararg;
197*03ce13f7SAndroid Build Coastguard Worker va_start(vararg, format);
198*03ce13f7SAndroid Build Coastguard Worker logv(Level::Warn, format, vararg);
199*03ce13f7SAndroid Build Coastguard Worker va_end(vararg);
200*03ce13f7SAndroid Build Coastguard Worker }
201*03ce13f7SAndroid Build Coastguard Worker
abort(const char * format,...)202*03ce13f7SAndroid Build Coastguard Worker void abort(const char *format, ...)
203*03ce13f7SAndroid Build Coastguard Worker {
204*03ce13f7SAndroid Build Coastguard Worker va_list vararg;
205*03ce13f7SAndroid Build Coastguard Worker
206*03ce13f7SAndroid Build Coastguard Worker va_start(vararg, format);
207*03ce13f7SAndroid Build Coastguard Worker logv(Level::Fatal, format, vararg);
208*03ce13f7SAndroid Build Coastguard Worker va_end(vararg);
209*03ce13f7SAndroid Build Coastguard Worker
210*03ce13f7SAndroid Build Coastguard Worker ::abort();
211*03ce13f7SAndroid Build Coastguard Worker }
212*03ce13f7SAndroid Build Coastguard Worker
trace_assert(const char * format,...)213*03ce13f7SAndroid Build Coastguard Worker void trace_assert(const char *format, ...)
214*03ce13f7SAndroid Build Coastguard Worker {
215*03ce13f7SAndroid Build Coastguard Worker static std::atomic<bool> asserted = { false };
216*03ce13f7SAndroid Build Coastguard Worker if(IsUnderDebugger() && !asserted.exchange(true))
217*03ce13f7SAndroid Build Coastguard Worker {
218*03ce13f7SAndroid Build Coastguard Worker // Abort after tracing and printing to stderr
219*03ce13f7SAndroid Build Coastguard Worker va_list vararg;
220*03ce13f7SAndroid Build Coastguard Worker va_start(vararg, format);
221*03ce13f7SAndroid Build Coastguard Worker logv(Level::Fatal, format, vararg);
222*03ce13f7SAndroid Build Coastguard Worker va_end(vararg);
223*03ce13f7SAndroid Build Coastguard Worker
224*03ce13f7SAndroid Build Coastguard Worker ::abort();
225*03ce13f7SAndroid Build Coastguard Worker }
226*03ce13f7SAndroid Build Coastguard Worker else if(!asserted)
227*03ce13f7SAndroid Build Coastguard Worker {
228*03ce13f7SAndroid Build Coastguard Worker va_list vararg;
229*03ce13f7SAndroid Build Coastguard Worker va_start(vararg, format);
230*03ce13f7SAndroid Build Coastguard Worker logv(Level::Fatal, format, vararg);
231*03ce13f7SAndroid Build Coastguard Worker va_end(vararg);
232*03ce13f7SAndroid Build Coastguard Worker }
233*03ce13f7SAndroid Build Coastguard Worker }
234*03ce13f7SAndroid Build Coastguard Worker
235*03ce13f7SAndroid Build Coastguard Worker } // namespace rr
236