From 2e9d59ad10741d77bb8261b6d024c4b7637e0098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 21 Nov 2017 18:05:25 +0100 Subject: [PATCH] Android: Use __android_log_assert facility to get pretty message-asserts into crash dumps. --- Common/Log.h | 46 +++++++++++++++++++++++++++++++++++++-- Common/LogManager.cpp | 15 +++++++++++++ Common/MsgHandler.h | 2 +- ext/native/base/logging.h | 2 +- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/Common/Log.h b/Common/Log.h index 5e45d89c34..2272b8fb38 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -20,7 +20,11 @@ #include #include -#include "MsgHandler.h" +#include "Common/MsgHandler.h" + +#if defined(__ANDROID__) +#include +#endif #define NOTICE_LEVEL 1 // VERY important information that is NOT errors. Like startup and debugprintfs from the game itself. #define ERROR_LEVEL 2 // Important errors. @@ -106,6 +110,14 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); #define DEBUG_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LDEBUG, __VA_ARGS__) } while (false) #define VERBOSE_LOG(t,...) do { GENERIC_LOG(LogTypes::t, LogTypes::LVERBOSE, __VA_ARGS__) } while (false) +#if defined(__ANDROID__) + +// Tricky macro to get the basename, that also works if *built* on Win32. +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : (__builtin_strrchr(__FILE__, '\\') ? __builtin_strrchr(__FILE__, '\\') + 1 : __FILE__)) +void AndroidAssertLog(const char *func, const char *file, int line, const char *condition, const char *fmt, ...); + +#endif + #if MAX_LOGLEVEL >= DEBUG_LEVEL #define _dbg_assert_(_t_, _a_) \ if (!(_a_)) {\ @@ -113,12 +125,27 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); __LINE__, __FILE__); \ if (!PanicYesNo("*** Assertion ***\n")) { assert(false); } \ } + +#if defined(__ANDROID__) + +#define _dbg_assert_msg_(_t_, _a_, ...)\ + if (!(_a_)) {\ + printf(__VA_ARGS__); \ + ERROR_LOG(_t_, __VA_ARGS__); \ + if (!PanicYesNo(__VA_ARGS__)) AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ + } + +#else // __ANDROID__ + #define _dbg_assert_msg_(_t_, _a_, ...)\ if (!(_a_)) {\ printf(__VA_ARGS__); \ ERROR_LOG(_t_, __VA_ARGS__); \ if (!PanicYesNo(__VA_ARGS__)) { assert(false);} \ } + +#endif // __ANDROID__ + #define _dbg_update_() ; //Host_UpdateLogDisplay(); #else // not debug @@ -131,9 +158,24 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type); #endif // MAX_LOGLEVEL DEBUG #define _assert_(_a_) \ - _dbg_assert_(SYSTEM, _a_) + if (!(_a_)) {\ + ERROR_LOG(SYSTEM, "Error...\n\n Line: %d\n File: %s\n\nIgnore and continue?", \ + __LINE__, __FILE__); \ + if (!PanicYesNo("*** Assertion ***\n")) { assert(false); } \ + } + +#if defined(__ANDROID__) + +#define _assert_msg_(_t_, _a_, ...) \ + if (!(_a_) && !PanicYesNo(__VA_ARGS__)) { \ + AndroidAssertLog(__FUNCTION__, __FILENAME__, __LINE__, #_a_, __VA_ARGS__); \ + } + +#else // __ANDROID__ #define _assert_msg_(_t_, _a_, ...) \ if (!(_a_) && !PanicYesNo(__VA_ARGS__)) { \ assert(false); \ } + +#endif // __ANDROID__ \ No newline at end of file diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index d5a74ef5e1..57dde3beff 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -57,6 +57,21 @@ bool GenericLogEnabled(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type) { return false; } +#if defined(__ANDROID__) + +#define LOG_BUF_SIZE 1024 + +void AndroidAssertLog(const char *func, const char *file, int line, const char *condition, const char *fmt, ...) { + char buf[LOG_BUF_SIZE]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + __android_log_assert(condition, "PPSSPP", "%s:%d (%s): [%s] %s", file, line, func, condition, buf); + va_end(args); +} + +#endif + LogManager *LogManager::logManager_ = NULL; struct LogNameTableEntry { diff --git a/Common/MsgHandler.h b/Common/MsgHandler.h index 6dd2d6a4ff..ee28d8ea33 100644 --- a/Common/MsgHandler.h +++ b/Common/MsgHandler.h @@ -25,7 +25,7 @@ enum MSG_TYPE { CRITICAL }; -extern bool MsgAlert(bool yes_no, int Style, const char* format, ...) +bool MsgAlert(bool yes_no, int Style, const char* format, ...) #ifdef __GNUC__ __attribute__((format(printf, 3, 4))) #endif diff --git a/ext/native/base/logging.h b/ext/native/base/logging.h index 4cecf3f8f5..41e6ab519a 100644 --- a/ext/native/base/logging.h +++ b/ext/native/base/logging.h @@ -65,7 +65,7 @@ void OutputDebugStringUTF8(const char *p); #define ILOG(...) __android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__); #define WLOG(...) __android_log_print(ANDROID_LOG_WARN, APP_NAME, __VA_ARGS__); #define ELOG(...) __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); -#define FLOG(...) { __android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__); Crash(); } +#define FLOG(...) __android_log_print(ANDROID_LOG_FATAL, APP_NAME, __VA_ARGS__); #define MessageBox(a, b, c, d) __android_log_print(ANDROID_LOG_INFO, APP_NAME, "%s %s", (b), (c));