diff --git a/.github/workflows/android-builds.yml b/.github/workflows/android-builds.yml new file mode 100644 index 000000000..0e0571ea9 --- /dev/null +++ b/.github/workflows/android-builds.yml @@ -0,0 +1,40 @@ +name: Android + +on: [push, pull_request] + +jobs: + build: + name: NDK-C++${{matrix.std}}-${{matrix.abi}}-${{matrix.build_type}} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + std: [98, 11, 14, 17, 20] + abi: [arm64-v8a, armeabi-v7a, x86_64, x86] + build_type: [Debug] + + steps: + - uses: actions/checkout@v2 + + - name: Setup Ninja + uses: ashutoshvarma/setup-ninja@master + with: + version: 1.10.0 + + - name: Configure + shell: bash + run: | + cmake -S . -B ${{runner.workspace}}/build_CXX${{matrix.std}}-${{matrix.abi}} \ + -G "Ninja Multi-Config" \ + -DCMAKE_CXX_EXTENSIONS=OFF \ + -DCMAKE_CXX_STANDARD=${{matrix.std}} \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON \ + -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ + -DANDROID_STL=c++_shared \ + -DANDROID_NATIVE_API_LEVEL=28 \ + -DANDROID_ABI=${{matrix.abi}} \ + - name: Build + run: | + cmake --build ${{runner.workspace}}/build_CXX${{matrix.std}}-${{matrix.abi}} \ + --config ${{matrix.build_type}} + diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fb042f41..1622b6b1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,8 @@ find_package (Unwind) if (Unwind_FOUND) set (HAVE_LIB_UNWIND 1) - set (HAVE_UNWIND_H 1) +else (Unwind_FOUND) + check_include_file_cxx (unwind.h HAVE_UNWIND_H) endif (Unwind_FOUND) check_include_file_cxx (dlfcn.h HAVE_DLFCN_H) diff --git a/bazel/glog.bzl b/bazel/glog.bzl index 1617e37a3..5e5fa1277 100644 --- a/bazel/glog.bzl +++ b/bazel/glog.bzl @@ -53,7 +53,6 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs): "-DHAVE_CXX11_NULLPTR_T", "-DHAVE_STDINT_H", "-DHAVE_STRING_H", - "-DHAVE_UNWIND_H", "-DGLOG_CUSTOM_PREFIX_SUPPORT", "-I%s/glog_internal" % gendir, ] + (["-DHAVE_LIB_GFLAGS"] if with_gflags else []) @@ -70,6 +69,7 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs): "-DHAVE_SYS_UTSNAME_H", # For src/utilities.cc. "-DHAVE_SYS_TIME_H", + "-DHAVE_UNWIND_H", # Enable dumping stacktrace upon sigaction. "-DHAVE_SIGACTION", # For logging.cc. diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in index d2e304d75..4d379a366 100644 --- a/src/config.h.cmake.in +++ b/src/config.h.cmake.in @@ -31,9 +31,6 @@ /* Define to 1 if you have the `pthread' library (-lpthread). */ #cmakedefine HAVE_LIBPTHREAD -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBUNWIND_H - /* define if you have google gflags library */ #cmakedefine HAVE_LIB_GFLAGS @@ -115,8 +112,8 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNWIND_H ${HAVE_UNWIND_H} +/* Define if you have the header file. */ +#cmakedefine HAVE_UNWIND_H /* define if the compiler supports using expression for operator */ #cmakedefine HAVE_USING_OPERATOR diff --git a/src/logging.cc b/src/logging.cc index e652cfdad..235029805 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -770,10 +770,11 @@ static void WriteToStderr(const char* message, size_t len) { } inline void LogDestination::MaybeLogToStderr(LogSeverity severity, - const char* message, size_t message_len, size_t /*prefix_len*/) { + const char* message, size_t message_len, size_t prefix_len) { if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { ColoredWriteToStderr(severity, message, message_len); #ifdef GLOG_OS_WINDOWS + (void) prefix_len; // On Windows, also output to the debugger ::OutputDebugStringA(message); #elif defined(__ANDROID__) @@ -787,6 +788,8 @@ inline void LogDestination::MaybeLogToStderr(LogSeverity severity, __android_log_write(android_log_levels[severity], glog_internal_namespace_::ProgramInvocationShortName(), message + prefix_len); +#else + (void) prefix_len; #endif } } @@ -1672,23 +1675,6 @@ ostream& LogMessage::stream() { return data_->stream_; } -namespace { -#if defined(__ANDROID__) -int AndroidLogLevel(const int severity) { - switch (severity) { - case 3: - return ANDROID_LOG_FATAL; - case 2: - return ANDROID_LOG_ERROR; - case 1: - return ANDROID_LOG_WARN; - default: - return ANDROID_LOG_INFO; - } -} -#endif // defined(__ANDROID__) -} // namespace - // Flush buffered message, called by the destructor, or any other function // that needs to synchronize the log. void LogMessage::Flush() { @@ -1724,12 +1710,6 @@ void LogMessage::Flush() { } LogDestination::WaitForSinks(data_); -#if defined(__ANDROID__) - const int level = AndroidLogLevel((int)data_->severity_); - const std::string text = std::string(data_->message_text_); - __android_log_write(level, "native", text.substr(0,data_->num_chars_to_log_).c_str()); -#endif // defined(__ANDROID__) - if (append_newline) { // Fix the ostrstream back how it was before we screwed with it. // It's 99.44% certain that we don't need to worry about doing this. @@ -1859,6 +1839,12 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { if (write(STDERR_FILENO, message, strlen(message)) < 0) { // Ignore errors. } +#if defined(__ANDROID__) + // ANDROID_LOG_FATAL as this message is of FATAL severity. + __android_log_write(ANDROID_LOG_FATAL, + glog_internal_namespace_::ProgramInvocationShortName(), + message); +#endif Fail(); } } diff --git a/src/stacktrace_x86_64-inl.h b/src/stacktrace_x86_64-inl.h index 2adfdfa42..62f82be25 100644 --- a/src/stacktrace_x86_64-inl.h +++ b/src/stacktrace_x86_64-inl.h @@ -47,7 +47,7 @@ typedef struct { // Workaround for the malloc() in _Unwind_Backtrace() issue. -static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) { +static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context */*uc*/, void */*opq*/) { return _URC_NO_REASON; } diff --git a/src/utilities.cc b/src/utilities.cc index b3771d952..83ea4c83a 100644 --- a/src/utilities.cc +++ b/src/utilities.cc @@ -54,6 +54,9 @@ #ifdef HAVE_PWD_H # include #endif +#ifdef __ANDROID__ +#include +#endif #include "base/googleinit.h" @@ -92,6 +95,12 @@ static void DebugWriteToStderr(const char* data, void *) { if (write(STDERR_FILENO, data, strlen(data)) < 0) { // Ignore errors. } +#if defined(__ANDROID__) + // ANDROID_LOG_FATAL as fatal error occurred and now is dumping call stack. + __android_log_write(ANDROID_LOG_FATAL, + glog_internal_namespace_::ProgramInvocationShortName(), + data); +#endif } static void DebugWriteToString(const char* data, void *arg) { diff --git a/src/utilities.h b/src/utilities.h index b8e1aec3d..3bac3323d 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -88,11 +88,11 @@ #if defined(HAVE_LIB_UNWIND) # define STACKTRACE_H "stacktrace_libunwind-inl.h" +#elif defined(HAVE_UNWIND_H) +# define STACKTRACE_H "stacktrace_x86_64-inl.h" #elif !defined(NO_FRAME_POINTER) # if defined(__i386__) && __GNUC__ >= 2 # define STACKTRACE_H "stacktrace_x86-inl.h" -# elif defined(__x86_64__) && __GNUC__ >= 2 && HAVE_UNWIND_H -# define STACKTRACE_H "stacktrace_x86_64-inl.h" # elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2 # define STACKTRACE_H "stacktrace_powerpc-inl.h" # elif defined(GLOG_OS_WINDOWS)