xref: /aosp_15_r20/external/swiftshader/src/Reactor/Debug.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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