Debugging: Merge VkDebug into System/Debug
Delete Vulkan/VkDebug.hpp and Vulkan/VkDebug.cpp, use System/Debug.hpp from now on.
Also delete System/DebugAndroid.hpp and System/DebugAndroid.cpp.
These declared yet another version of the debug macros, along with the
AndroidEnterDebugger() function. None of this stuff is actually used
for the Android platform builds, and this change brings in logcat support
to the standard set of macros.
Bug: b/146051794
Change-Id: Ib52ec6af34cdf4ac390c73cb331239d81bed6e06
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/40968
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/System/Debug.cpp b/src/System/Debug.cpp
index 5fafc90..f510200 100644
--- a/src/System/Debug.cpp
+++ b/src/System/Debug.cpp
@@ -1,4 +1,4 @@
-// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
+// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,26 +14,212 @@
#include "Debug.hpp"
-#include <stdarg.h>
-#include <stdio.h>
+#include <atomic>
+#include <cstdarg>
+#include <cstdio>
+#include <string>
+
+#if __ANDROID__
+# include <android/log.h>
+#endif
+
+#if defined(__unix__)
+# define PTRACE
+# include <sys/ptrace.h>
+# include <sys/types.h>
+#elif defined(_WIN32) || defined(_WIN64)
+# include <windows.h>
+#elif defined(__APPLE__) || defined(__MACH__)
+# include <sys/sysctl.h>
+# include <unistd.h>
+#endif
+
+#ifdef ERROR
+# undef ERROR // b/127920555
+#endif
+
+namespace {
+
+bool IsUnderDebugger()
+{
+#if defined(PTRACE) && !defined(__APPLE__) && !defined(__MACH__)
+ static bool checked = false;
+ static bool res = false;
+
+ if(!checked)
+ {
+ // If a debugger is attached then we're already being ptraced and ptrace
+ // will return a non-zero value.
+ checked = true;
+ if(ptrace(PTRACE_TRACEME, 0, 1, 0) != 0)
+ {
+ res = true;
+ }
+ else
+ {
+ ptrace(PTRACE_DETACH, 0, 1, 0);
+ }
+ }
+
+ return res;
+#elif defined(_WIN32) || defined(_WIN64)
+ return IsDebuggerPresent() != 0;
+#elif defined(__APPLE__) || defined(__MACH__)
+ // Code comes from the Apple Technical Q&A QA1361
+
+ // Tell sysctl what info we're requestion. Specifically we're asking for
+ // info about this our PID.
+ int res = 0;
+ int request[4] = {
+ CTL_KERN,
+ KERN_PROC,
+ KERN_PROC_PID,
+ getpid()
+ };
+ struct kinfo_proc info;
+ size_t size = sizeof(info);
+
+ info.kp_proc.p_flag = 0;
+
+ // Get the info we're requesting, if sysctl fails then info.kp_proc.p_flag will remain 0.
+ res = sysctl(request, sizeof(request) / sizeof(*request), &info, &size, NULL, 0);
+ ASSERT_MSG(res == 0, "syscl returned %d", res);
+
+ // We're being debugged if the P_TRACED flag is set
+ return ((info.kp_proc.p_flag & P_TRACED) != 0);
+#else
+ return false;
+#endif
+}
+
+enum class Level
+{
+ DEBUG,
+ INFO,
+ WARN,
+ ERROR,
+ FATAL,
+};
+
+#ifdef __ANDROID__
+void logv_android(Level level, const char *msg)
+{
+ switch(level)
+ {
+ case Level::DEBUG:
+ __android_log_write(ANDROID_LOG_DEBUG, "SwiftShader", msg);
+ break;
+ case Level::INFO:
+ __android_log_write(ANDROID_LOG_INFO, "SwiftShader", msg);
+ break;
+ case Level::WARN:
+ __android_log_write(ANDROID_LOG_WARN, "SwiftShader", msg);
+ break;
+ case Level::ERROR:
+ __android_log_write(ANDROID_LOG_ERROR, "SwiftShader", msg);
+ break;
+ case Level::FATAL:
+ __android_log_write(ANDROID_LOG_FATAL, "SwiftShader", msg);
+ break;
+ }
+}
+#else
+void logv_std(Level level, const char *msg)
+{
+ switch(level)
+ {
+ case Level::DEBUG:
+ case Level::INFO:
+ fprintf(stdout, "%s", msg);
+ break;
+ case Level::WARN:
+ case Level::ERROR:
+ case Level::FATAL:
+ fprintf(stderr, "%s", msg);
+ break;
+ }
+}
+#endif
+
+void logv(Level level, const char *format, va_list args)
+{
+#ifndef SWIFTSHADER_DISABLE_TRACE
+ char buffer[2048];
+ vsnprintf(buffer, sizeof(buffer), format, args);
+
+# if defined(__ANDROID__)
+ logv_android(level, buffer);
+# elif defined(_WIN32)
+ logv_std(level, buffer);
+ ::OutputDebugString(buffer);
+# else
+ logv_std(level, buffer);
+# endif
+
+ const bool traceToFile = false;
+ if(traceToFile)
+ {
+ FILE *file = fopen(TRACE_OUTPUT_FILE, "a");
+
+ if(file)
+ {
+ vfprintf(file, format, args);
+ fclose(file);
+ }
+ }
+#endif // SWIFTSHADER_DISABLE_TRACE
+}
+
+} // anonymous namespace
namespace sw {
void trace(const char *format, ...)
{
- if(false)
+ va_list vararg;
+ va_start(vararg, format);
+ logv(Level::DEBUG, format, vararg);
+ va_end(vararg);
+}
+
+void warn(const char *format, ...)
+{
+ va_list vararg;
+ va_start(vararg, format);
+ logv(Level::WARN, format, vararg);
+ va_end(vararg);
+}
+
+void abort(const char *format, ...)
+{
+ va_list vararg;
+
+ va_start(vararg, format);
+ logv(Level::FATAL, format, vararg);
+ va_end(vararg);
+
+ ::abort();
+}
+
+void trace_assert(const char *format, ...)
+{
+ static std::atomic<bool> asserted = { false };
+ if(IsUnderDebugger() && !asserted.exchange(true))
{
- FILE *file = fopen("debug.txt", "a");
+ // Abort after tracing and printing to stderr
+ va_list vararg;
+ va_start(vararg, format);
+ logv(Level::FATAL, format, vararg);
+ va_end(vararg);
- if(file)
- {
- va_list vararg;
- va_start(vararg, format);
- vfprintf(file, format, vararg);
- va_end(vararg);
-
- fclose(file);
- }
+ ::abort();
+ }
+ else if(!asserted)
+ {
+ va_list vararg;
+ va_start(vararg, format);
+ logv(Level::FATAL, format, vararg);
+ va_end(vararg);
}
}