OSDN Git Service

Set up Android-specific debugging
authorGreg Hartman <ghartman@google.com>
Fri, 10 Apr 2015 01:48:53 +0000 (18:48 -0700)
committerGreg Hartman <ghartman@google.com>
Fri, 17 Apr 2015 18:01:20 +0000 (18:01 +0000)
Change-Id: I293568f0d0ee42dd64ee869e3c3ba28810e4883a
Reviewed-on: https://swiftshader-review.googlesource.com/2824
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Greg Hartman <ghartman@google.com>
13 files changed:
src/Common/Debug.cpp
src/Common/Debug.hpp
src/Common/DebugAndroid.cpp [new file with mode: 0644]
src/Common/DebugAndroid.hpp [new file with mode: 0644]
src/OpenGL/common/debug.h
src/OpenGL/compiler/ConstantUnion.h
src/OpenGL/compiler/SymbolTable.h
src/OpenGL/compiler/debug.h
src/OpenGL/libEGL/Android.mk
src/OpenGL/libEGL/Image.hpp
src/OpenGL/libEGL/main.cpp
src/OpenGL/libGLES_CM/Android.mk
src/OpenGL/libGLESv2/Android.mk

index b06e98f..a122c42 100644 (file)
 
 #include "Debug.hpp"
 
-#ifdef __ANDROID__
-#include <utils/String8.h>
-#include <cutils/log.h>
-#endif
-
 #include <stdio.h>
 #include <stdarg.h>
 
-#ifdef __ANDROID__
-       void trace(const char *format, ...)
-       {
-               va_list vararg;
-               va_start(vararg, format);
-               ALOGI("%s", android::String8::formatV(format, vararg).string());
-               va_end(vararg);
-       }
-#else
-       void trace(const char *format, ...)
+void trace(const char *format, ...)
+{
+       if(false)
        {
-               if(false)
-               {
-                       FILE *file = fopen("debug.txt", "a");
+               FILE *file = fopen("debug.txt", "a");
 
-                       if(file)
-                       {
-                               va_list vararg;
-                               va_start(vararg, format);
-                               vfprintf(file, format, vararg);
-                               va_end(vararg);
+               if(file)
+               {
+                       va_list vararg;
+                       va_start(vararg, format);
+                       vfprintf(file, format, vararg);
+                       va_end(vararg);
 
-                               fclose(file);
-                       }
+                       fclose(file);
                }
        }
-#endif
+}
index 9cb4952..569e9a3 100644 (file)
@@ -13,8 +13,8 @@
 #define Debug_hpp\r
 \r
 #ifdef __ANDROID__\r
-#include <cutils/log.h>\r
-#endif\r
+#include "DebugAndroid.hpp"\r
+#else\r
 \r
 #include <assert.h>\r
 #include <stdio.h>\r
@@ -30,30 +30,10 @@ void trace(const char *format, ...);
        #define TRACE(...) ((void)0)\r
 #endif\r
 \r
-#ifdef __ANDROID__\r
-       // On Android Virtual Devices we heavily depend on logging, even in\r
-       // production builds. We do this because AVDs are components of larger\r
-       // systems, and may be configured in ways that are difficult to\r
-       // reproduce locally. For example some system run tests against\r
-       // third-party code that we cannot access.  Aborting (cf. assert) on\r
-       // unimplemented functionality creates two problems. First, it produces\r
-       // a service failure where none is needed. Second, it puts the\r
-       // customer on the critical path for notifying us of a problem.\r
-       // The alternative, skipping unimplemented functionality silently, is\r
-       // arguably worse: neither the service provider nor the customer will\r
-       // learn that unimplemented functionality may have compromised the test\r
-       // results.\r
-       // Logging invocations of unimplemented functionality is useful to both\r
-       // service provider and the customer. The service provider can learn\r
-       // that the functionality is needed. The customer learns that the test\r
-       // results may be compromised.\r
-       #define UNIMPLEMENTED() {ALOGE("Unimplemented: %s %s:%d", __FUNCTION__, __FILE__, __LINE__); }\r
+#ifndef NDEBUG\r
+       #define UNIMPLEMENTED() {trace("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); ASSERT(false);}\r
 #else\r
-       #ifndef NDEBUG\r
-               #define UNIMPLEMENTED() {trace("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); ASSERT(false);}\r
-       #else\r
-               #define UNIMPLEMENTED() ((void)0)\r
-       #endif\r
+       #define UNIMPLEMENTED() ((void)0)\r
 #endif\r
 \r
 #ifndef NDEBUG\r
@@ -62,4 +42,5 @@ void trace(const char *format, ...);
        #define ASSERT assert\r
 #endif\r
 \r
+#endif   // __ANDROID__\r
 #endif   // Debug_hpp\r
diff --git a/src/Common/DebugAndroid.cpp b/src/Common/DebugAndroid.cpp
new file mode 100644 (file)
index 0000000..67e63cd
--- /dev/null
@@ -0,0 +1,34 @@
+#include "DebugAndroid.hpp"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <cutils/properties.h>
+
+void AndroidEnterDebugger()
+{
+    ALOGE(__FUNCTION__);
+#ifndef NDEBUG
+    static volatile int * const makefault = nullptr;
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.db.uid", value, "-1");
+    int debug_uid = atoi(value);
+    if ((debug_uid >= 0) && (geteuid() < static_cast<uid_t>(debug_uid)))
+    {
+        ALOGE("Waiting for debugger: gdbserver :${PORT} --attach %u", gettid());
+        while (1) {
+            pause();
+        }
+    } else {
+        ALOGE("No debugger");
+    }
+#endif
+}
+
+void trace(const char *format, ...)
+{
+    va_list vararg;
+    va_start(vararg, format);
+    android_vprintLog(ANDROID_LOG_VERBOSE, NULL, LOG_TAG, format, vararg);
+    va_end(vararg);
+}
diff --git a/src/Common/DebugAndroid.hpp b/src/Common/DebugAndroid.hpp
new file mode 100644 (file)
index 0000000..f87ba66
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef DebugAndroid_hpp
+#define DebugAndroid_hpp
+
+#include <cutils/log.h>
+
+// On Android Virtual Devices we heavily depend on logging, even in
+// production builds. We do this because AVDs are components of larger
+// systems, and may be configured in ways that are difficult to
+// reproduce locally. For example some system run tests against
+// third-party code that we cannot access.  Aborting (cf. assert) on
+// unimplemented functionality creates two problems. First, it produces
+// a service failure where none is needed. Second, it puts the
+// customer on the critical path for notifying us of a problem.
+// The alternative, skipping unimplemented functionality silently, is
+// arguably worse: neither the service provider nor the customer will
+// learn that unimplemented functionality may have compromised the test
+// results.
+// Logging invocations of unimplemented functionality is useful to both
+// service provider and the customer. The service provider can learn
+// that the functionality is needed. The customer learns that the test
+// results may be compromised.
+
+/**
+ * Enter the debugger with a memory fault iff debuggerd is set to capture this
+ * process. Otherwise return.
+ */
+void AndroidEnterDebugger();
+
+#define ASSERT(E) do { \
+               if (!(E)) { \
+                       ALOGE("badness: assertion_failed %s in %s at %s:%d", #E,        \
+                                 __FUNCTION__, __FILE__, __LINE__);                                    \
+                       AndroidEnterDebugger();                                                                         \
+               }                                                                                                                               \
+       } while(0)
+
+#define assert(E) ASSERT(E)
+
+#define ERR(format, ...)                                                                                               \
+       do {                                                                                                                            \
+               ALOGE("badness: err %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+                         __LINE__, ##__VA_ARGS__);                                                                     \
+               AndroidEnterDebugger();                                                                                 \
+       } while(0)
+
+#define FIXME(format, ...)                                                                                             \
+       do {                                                                                                                            \
+               ALOGE("badness: fixme %s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+                         __LINE__, ##__VA_ARGS__);                                                                     \
+               AndroidEnterDebugger();                                                                                 \
+       } while(0)
+
+#define UNIMPLEMENTED() do {                                           \
+               ALOGE("badness: unimplemented: %s %s:%d",       \
+                         __FUNCTION__, __FILE__, __LINE__);    \
+               AndroidEnterDebugger();                                         \
+       } while(0)
+
+#define UNREACHABLE() do {                                                             \
+               ALOGE("badness: unreachable reached: %s %s:%d", \
+                         __FUNCTION__, __FILE__, __LINE__);            \
+               AndroidEnterDebugger();                                                 \
+       } while(0)
+
+#ifndef NDEBUG
+       #define TRACE(format, ...)                                                                 \
+               ALOGV("%s %s:%d (" format ")", __FUNCTION__, __FILE__, \
+                         __LINE__, ##__VA_ARGS__)
+#else
+       #define TRACE(...) ((void)0)
+#endif
+
+void trace(const char *format, ...);
+
+#endif   // DebugAndroid_hpp
index f628040..ea7aba2 100644 (file)
@@ -15,9 +15,8 @@
 #define COMMON_DEBUG_H_\r
 \r
 #ifdef __ANDROID__\r
-#include <cutils/log.h>\r
-#endif\r
-\r
+#include "../../Common/DebugAndroid.hpp"\r
+#else\r
 #include <stdio.h>\r
 #include <assert.h>\r
 \r
@@ -64,33 +63,13 @@ namespace es
 #endif\r
 \r
 // A macro to indicate unimplemented functionality\r
-#ifdef __ANDROID__\r
-       // On Android Virtual Devices we heavily depend on logging, even in\r
-       // production builds. We do this because AVDs are components of larger\r
-       // systems, and may be configured in ways that are difficult to\r
-       // reproduce locally. For example some system run tests against\r
-       // third-party code that we cannot access.  Aborting (cf. assert) on\r
-       // unimplemented functionality creates two problems. First, it produces\r
-       // a service failure where none is needed. Second, it puts the\r
-       // customer on the critical path for notifying us of a problem.\r
-       // The alternative, skipping unimplemented functionality silently, is\r
-       // arguably worse: neither the service provider nor the customer will\r
-       // learn that unimplemented functionality may have compromised the test\r
-       // results.\r
-       // Logging invocations of unimplemented functionality is useful to both\r
-       // service provider and the customer. The service provider can learn\r
-       // that the functionality is needed. The customer learns that the test\r
-       // results may be compromised.\r
-       #define UNIMPLEMENTED() {ALOGE("Unimplemented: %s %s:%d", __FUNCTION__, __FILE__, __LINE__); }\r
+#if !defined(NDEBUG)\r
+#define UNIMPLEMENTED() do { \\r
+    FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \\r
+    assert(false); \\r
+    } while(0)\r
 #else\r
-       #if !defined(NDEBUG)\r
-               #define UNIMPLEMENTED() do { \\r
-                       FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \\r
-                       assert(false); \\r
-               } while(0)\r
-       #else\r
-           #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)\r
-       #endif\r
+    #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__)\r
 #endif\r
 \r
 // A macro for code which is not expected to be reached under valid assumptions\r
@@ -104,6 +83,8 @@ namespace es
     #define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__)\r
 #endif\r
 \r
+#endif   // __ANDROID__\r
+\r
 // A macro functioning as a compile-time assert to validate constant conditions\r
 #define META_ASSERT(condition) typedef int COMPILE_TIME_ASSERT_##__LINE__[static_cast<bool>(condition) ? 1 : -1]\r
 \r
index ffc1c4c..d1802c8 100644 (file)
@@ -7,7 +7,11 @@
 #ifndef _CONSTANT_UNION_INCLUDED_
 #define _CONSTANT_UNION_INCLUDED_
 
+#ifndef __ANDROID__
 #include <assert.h>
+#else
+#include "../../Common/DebugAndroid.hpp"
+#endif
 
 class ConstantUnion {
 public:
index 45dc096..64c43fd 100644 (file)
 //   are tracked in the intermediate representation, not the symbol table.
 //
 
+#ifndef __ANDROID__
 #include <assert.h>
+#else
+#include "../../Common/DebugAndroid.hpp"
+#endif
 
 #include "InfoSink.h"
 #include "intermediate.h"
index 7a37151..a3af34f 100644 (file)
@@ -9,6 +9,12 @@
 #ifndef COMPILER_DEBUG_H_
 #define COMPILER_DEBUG_H_
 
+#ifdef __ANDROID__
+#include "../../Common/DebugAndroid.hpp"
+
+#define Trace(...) ((void)0)
+#else
+
 #include <assert.h>
 
 #ifdef _DEBUG
@@ -49,5 +55,6 @@ void Trace(const char* format, ...);
     assert(false); \
 } while(0)
 
+#endif   // __ANDROID__
 #endif   // COMPILER_DEBUG_H_
 
index b50d145..d9fc910 100644 (file)
@@ -8,7 +8,7 @@ LOCAL_MODULE := libEGL_swiftshader
 
 LOCAL_SRC_FILES += \
        ../common/Object.cpp \
-       ../common/debug.cpp \
+       ../../Common/DebugAndroid.cpp \
        Config.cpp \
        Display.cpp \
        Surface.cpp \
@@ -19,7 +19,7 @@ LOCAL_CFLAGS += -DLOG_TAG=\"libEGL_swiftshader\"
 
 # Android's make system also uses NDEBUG, so we need to set/unset it forcefully
 # Uncomment for ON:
-LOCAL_CFLAGS += -UNDEBUG -g
+LOCAL_CFLAGS += -UNDEBUG -g -O0
 # Uncomment for OFF:
 #LOCAL_CFLAGS += -DANGLE_DISABLE_TRACE
 
index 071cf7d..38b479f 100644 (file)
@@ -8,7 +8,11 @@
 #include <system/window.h>\r
 #endif\r
 \r
+#ifdef __ANDROID__\r
+#include "../../Common/DebugAndroid.hpp"\r
+#else\r
 #include <assert.h>\r
+#endif\r
 \r
 namespace egl\r
 {\r
index 72ed6e7..351cc8b 100644 (file)
@@ -70,7 +70,7 @@ CONSTRUCTOR static void eglAttachProcess()
 {\r
     TRACE("()");\r
 \r
-       #if !defined(ANGLE_DISABLE_TRACE)\r
+       #if !defined(ANGLE_DISABLE_TRACE) && defined(TRACE_OUTPUT_FILE)\r
         FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");\r
 \r
         if(debug)\r
index 44d64e9..d60ddf7 100644 (file)
@@ -9,7 +9,7 @@ LOCAL_MODULE := libGLESv1_CM_swiftshader
 LOCAL_SRC_FILES := \
        ../../Common/CPUID.cpp \
        ../../Common/Configurator.cpp \
-       ../../Common/Debug.cpp \
+       ../../Common/DebugAndroid.cpp \
        ../../Common/Half.cpp \
        ../../Common/Math.cpp \
        ../../Common/Memory.cpp \
@@ -68,7 +68,6 @@ LOCAL_SRC_FILES += \
 LOCAL_SRC_FILES += \
        ../common/NameSpace.cpp \
        ../common/Object.cpp \
-       ../common/debug.cpp \
        ../common/MatrixStack.cpp \
 
 LOCAL_SRC_FILES += \
@@ -93,7 +92,7 @@ LOCAL_CFLAGS += -fvisibility=protected
 
 # Android's make system also uses NDEBUG, so we need to set/unset it forcefully
 # Uncomment for ON:
-LOCAL_CFLAGS += -UNDEBUG -g
+LOCAL_CFLAGS += -UNDEBUG -g -O0
 # Uncomment for OFF:
 #LOCAL_CFLAGS += -fomit-frame-pointer -ffunction-sections -fdata-sections -DANGLE_DISABLE_TRACE
 
index 032e893..421de06 100644 (file)
@@ -9,7 +9,7 @@ LOCAL_MODULE := libGLESv2_swiftshader
 LOCAL_SRC_FILES := \
        ../../Common/CPUID.cpp \
        ../../Common/Configurator.cpp \
-       ../../Common/Debug.cpp \
+       ../../Common/DebugAndroid.cpp \
        ../../Common/Half.cpp \
        ../../Common/Math.cpp \
        ../../Common/Memory.cpp \
@@ -68,7 +68,6 @@ LOCAL_SRC_FILES += \
 LOCAL_SRC_FILES += \
        ../common/NameSpace.cpp \
        ../common/Object.cpp \
-       ../common/debug.cpp \
 
 LOCAL_SRC_FILES += \
        ../compiler/preprocessor/Diagnostics.cpp \
@@ -129,7 +128,7 @@ LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv2_swiftshader\"
 
 # Android's make system also uses NDEBUG, so we need to set/unset it forcefully
 # Uncomment for ON:
-LOCAL_CFLAGS += -UNDEBUG -g
+LOCAL_CFLAGS += -UNDEBUG -g -O0
 # Uncomment for OFF:
 #LOCAL_CFLAGS += -fomit-frame-pointer -ffunction-sections -fdata-sections -DANGLE_DISABLE_TRACE