support stack unwind on Android
This commit is contained in:
parent
acda903486
commit
3965584721
40
.github/workflows/android-builds.yml
vendored
Normal file
40
.github/workflows/android-builds.yml
vendored
Normal file
@ -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}}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -31,9 +31,6 @@
|
||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||
#cmakedefine HAVE_LIBPTHREAD
|
||||
|
||||
/* Define to 1 if you have the <libunwind.h> 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 <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H}
|
||||
|
||||
/* Define to 1 if you have the <unwind.h> header file. */
|
||||
#cmakedefine HAVE_UNWIND_H ${HAVE_UNWIND_H}
|
||||
/* Define if you have the <unwind.h> header file. */
|
||||
#cmakedefine HAVE_UNWIND_H
|
||||
|
||||
/* define if the compiler supports using expression for operator */
|
||||
#cmakedefine HAVE_USING_OPERATOR
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -54,6 +54,9 @@
|
||||
#ifdef HAVE_PWD_H
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#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) {
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user