support ndk r25 (#844)

This commit is contained in:
Sergiu Deitsch 2022-08-01 10:46:35 +02:00 committed by GitHub
parent c515e1ae2f
commit a34226ca94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 148 additions and 72 deletions

View File

@ -9,6 +9,8 @@ jobs:
defaults:
run:
shell: bash
env:
NDK_VERSION: 25.0.8775105
strategy:
fail-fast: true
matrix:
@ -29,19 +31,26 @@ jobs:
run: |
echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
- name: Setup NDK
env:
ANDROID_SDK_ROOT: /usr/local/lib/android/sdk
run: |
echo 'y' | ${{env.ANDROID_SDK_ROOT}}/cmdline-tools/latest/bin/sdkmanager --install 'ndk;${{env.NDK_VERSION}}'
- name: Configure
env:
CXXFLAGS: -Wall -Wextra -Wpedantic -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}
run: |
cmake -S . -B build_${{matrix.abi}} \
-DANDROID_ABI=${{matrix.abi}} \
-DANDROID_NATIVE_API_LEVEL=28 \
-DANDROID_STL=c++_shared \
-DCMAKE_ANDROID_API=28 \
-DCMAKE_ANDROID_ARCH_ABI=${{matrix.abi}} \
-DCMAKE_ANDROID_NDK=/usr/local/lib/android/sdk/ndk/${{env.NDK_VERSION}} \
-DCMAKE_ANDROID_STL_TYPE=c++_shared \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-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 \
-DCMAKE_SYSTEM_NAME=Android \
-G Ninja \
-Werror

View File

@ -5,7 +5,7 @@ on: [push, pull_request]
jobs:
build-macos:
name: AppleClang-C++${{matrix.std}}-${{matrix.build_type}}
runs-on: macos-10.15
runs-on: macos-12
strategy:
fail-fast: true
matrix:

View File

@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.16)
project (glog
VERSION 0.6.0
VERSION 0.7.0
DESCRIPTION "C++ implementation of the Google logging module"
HOMEPAGE_URL https://github.com/google/glog
LANGUAGES CXX
@ -101,7 +101,6 @@ else (Unwind_FOUND)
endif (Unwind_FOUND)
check_include_file_cxx (dlfcn.h HAVE_DLFCN_H)
check_include_file_cxx (execinfo.h HAVE_EXECINFO_H)
check_include_file_cxx (glob.h HAVE_GLOB_H)
check_include_file_cxx (inttypes.h HAVE_INTTYPES_H)
check_include_file_cxx (memory.h HAVE_MEMORY_H)
@ -128,6 +127,8 @@ check_include_file_cxx ("unordered_map" HAVE_UNORDERED_MAP)
check_include_file_cxx ("unordered_set" HAVE_UNORDERED_SET)
check_type_size ("unsigned __int16" HAVE___UINT16 LANGUAGE CXX)
check_type_size (mode_t HAVE_MODE_T LANGUAGE CXX)
check_type_size (ssize_t HAVE_SSIZE_T LANGUAGE CXX)
check_type_size (u_int16_t HAVE_U_INT16_T LANGUAGE CXX)
check_type_size (uint16_t HAVE_UINT16_T LANGUAGE CXX)
@ -138,6 +139,10 @@ check_function_exists (pwrite HAVE_PWRITE)
check_function_exists (sigaction HAVE_SIGACTION)
check_function_exists (sigaltstack HAVE_SIGALTSTACK)
check_cxx_symbol_exists (backtrace execinfo.h HAVE_EXECINFO_BACKTRACE)
check_cxx_symbol_exists (backtrace_symbols execinfo.h
HAVE_EXECINFO_BACKTRACE_SYMBOLS)
# NOTE gcc does not fail if you pass a non-existent -Wno-* option as an
# argument. However, it will happily fail if you pass the corresponding -W*
# option. So, we check whether options that disable warnings exist by testing
@ -389,6 +394,18 @@ else (HAVE_UINT16_T)
set (ac_cv_have_uint16_t 0)
endif (HAVE_UINT16_T)
if (HAVE_SSIZE_T)
set (ac_cv_have_ssize_t 1)
else (HAVE_SSIZE_T)
set (ac_cv_have_ssize_t 0)
endif (HAVE_SSIZE_T)
if (HAVE_MODE_T)
set (ac_cv_have_mode_t 1)
else (HAVE_MODE_T)
set (ac_cv_have_mode_t 0)
endif (HAVE_MODE_T)
if (HAVE_UNISTD_H)
set (ac_cv_have_unistd_h 1)
else (HAVE_UNISTD_H)
@ -438,9 +455,9 @@ else (HAVE_CXX11_NULLPTR_T)
set (ac_cv_cxx11_nullptr_t 0)
endif (HAVE_CXX11_NULLPTR_T)
if (HAVE_EXECINFO_H)
if (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
set (HAVE_STACKTRACE 1)
endif (HAVE_EXECINFO_H)
endif (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
if (HAVE_CXX11_ATOMIC)
set (ac_cv_cxx11_atomic 1)
@ -844,6 +861,9 @@ if (BUILD_TESTING)
add_test (NAME logging COMMAND logging_unittest)
set_tests_properties (logging PROPERTIES TIMEOUT 30)
# MacOS diff is not deterministic: use the output to determine whether the
# test passed.
set_tests_properties (logging PROPERTIES PASS_REGULAR_EXPRESSION ".*\nPASS\n.*")
# FIXME: Skip flaky test
set_tests_properties (logging PROPERTIES SKIP_REGULAR_EXPRESSION

View File

@ -232,29 +232,33 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
}
posix_config = dict_union(common_config, {
"@ac_cv_have_unistd_h@": "1",
"@ac_cv_have_stdint_h@": "1",
"@ac_cv_have_systypes_h@": "1",
"@ac_cv_have_uint16_t@": "1",
"@ac_cv_have___uint16@": "0",
"@ac_cv_have___builtin_expect@": "1",
"@ac_cv_have_libgflags@": "1" if with_gflags else "0",
"@ac_cv___attribute___noinline@": "__attribute__((noinline))",
"@ac_cv___attribute___noreturn@": "__attribute__((noreturn))",
"@ac_cv___attribute___printf_4_5@": "__attribute__((__format__(__printf__, 4, 5)))",
"@ac_cv_have___builtin_expect@": "1",
"@ac_cv_have___uint16@": "0",
"@ac_cv_have_libgflags@": "1" if with_gflags else "0",
"@ac_cv_have_mode_t@": "1",
"@ac_cv_have_ssize_t@": "1",
"@ac_cv_have_stdint_h@": "1",
"@ac_cv_have_systypes_h@": "1",
"@ac_cv_have_uint16_t@": "1",
"@ac_cv_have_unistd_h@": "1",
})
windows_config = dict_union(common_config, {
"@ac_cv_have_unistd_h@": "0",
"@ac_cv_have_stdint_h@": "0",
"@ac_cv_have_systypes_h@": "0",
"@ac_cv_have_uint16_t@": "0",
"@ac_cv_have___uint16@": "1",
"@ac_cv_have___builtin_expect@": "0",
"@ac_cv_have_libgflags@": "0",
"@ac_cv___attribute___noinline@": "",
"@ac_cv___attribute___noreturn@": "__declspec(noreturn)",
"@ac_cv___attribute___printf_4_5@": "",
"@ac_cv_have___builtin_expect@": "0",
"@ac_cv_have___uint16@": "1",
"@ac_cv_have_libgflags@": "0",
"@ac_cv_have_mode_t@": "0",
"@ac_cv_have_ssize_t@": "0",
"@ac_cv_have_stdint_h@": "0",
"@ac_cv_have_systypes_h@": "0",
"@ac_cv_have_uint16_t@": "0",
"@ac_cv_have_unistd_h@": "0",
})
[

View File

@ -16,8 +16,11 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#cmakedefine HAVE_DLFCN_H
/* Define to 1 if you have the <execinfo.h> header file. */
#cmakedefine HAVE_EXECINFO_H
/* Define if you have the `backtrace' function in <execinfo.h> */
#cmakedefine HAVE_EXECINFO_BACKTRACE
/* Define if you have the `backtrace_symbols' function in <execinfo.h> */
#cmakedefine HAVE_EXECINFO_BACKTRACE_SYMBOLS
/* Define if you have the `fcntl' function */
#cmakedefine HAVE_FCNTL

View File

@ -154,7 +154,7 @@ typedef struct {
const char *out_begin; // Beginning of output string.
const char *out_end; // End of output string.
const char *prev_name; // For constructors/destructors.
int prev_name_length; // For constructors/destructors.
ssize_t prev_name_length; // For constructors/destructors.
short nest_level; // For nested names.
bool append; // Append flag.
bool overflowed; // True if output gets overflowed.
@ -172,8 +172,8 @@ static size_t StrLen(const char *str) {
}
// Returns true if "str" has at least "n" characters remaining.
static bool AtLeastNumCharsRemaining(const char *str, int n) {
for (int i = 0; i < n; ++i) {
static bool AtLeastNumCharsRemaining(const char *str, ssize_t n) {
for (ssize_t i = 0; i < n; ++i) {
if (str[i] == '\0') {
return false;
}
@ -269,9 +269,8 @@ static bool ZeroOrMore(ParseFunc parse_func, State *state) {
// Append "str" at "out_cur". If there is an overflow, "overflowed"
// is set to true for later use. The output string is ensured to
// always terminate with '\0' as long as there is no overflow.
static void Append(State *state, const char * const str, const int length) {
int i;
for (i = 0; i < length; ++i) {
static void Append(State *state, const char * const str, ssize_t length) {
for (ssize_t i = 0; i < length; ++i) {
if (state->out_cur + 1 < state->out_end) { // +1 for '\0'
*state->out_cur = str[i];
++state->out_cur;
@ -327,7 +326,7 @@ static bool IsFunctionCloneSuffix(const char *str) {
// Append "str" with some tweaks, iff "append" state is true.
// Returns true so that it can be placed in "if" conditions.
static void MaybeAppendWithLength(State *state, const char * const str,
const int length) {
ssize_t length) {
if (state->append && length > 0) {
// Append a space if the output buffer ends with '<' and "str"
// starts with '<' to avoid <<<.
@ -347,8 +346,8 @@ static void MaybeAppendWithLength(State *state, const char * const str,
// A convenient wrapper arount MaybeAppendWithLength().
static bool MaybeAppend(State *state, const char * const str) {
if (state->append) {
int length = StrLen(str);
MaybeAppendWithLength(state, str, length);
size_t length = StrLen(str);
MaybeAppendWithLength(state, str, static_cast<ssize_t>(length));
}
return true;
}
@ -402,10 +401,10 @@ static void MaybeCancelLastSeparator(State *state) {
// Returns true if the identifier of the given length pointed to by
// "mangled_cur" is anonymous namespace.
static bool IdentifierIsAnonymousNamespace(State *state, int length) {
static bool IdentifierIsAnonymousNamespace(State *state, ssize_t length) {
static const char anon_prefix[] = "_GLOBAL__N_";
return (length >
static_cast<int>(sizeof(anon_prefix)) - 1 && // Should be longer.
return (length > static_cast<ssize_t>(sizeof(anon_prefix)) -
1 && // Should be longer.
StrPrefix(state->mangled_cur, anon_prefix));
}
@ -423,7 +422,7 @@ static bool ParseLocalSourceName(State *state);
static bool ParseNumber(State *state, int *number_out);
static bool ParseFloatNumber(State *state);
static bool ParseSeqId(State *state);
static bool ParseIdentifier(State *state, int length);
static bool ParseIdentifier(State *state, ssize_t length);
static bool ParseAbiTags(State *state);
static bool ParseAbiTag(State *state);
static bool ParseOperatorName(State *state);
@ -692,7 +691,7 @@ static bool ParseSeqId(State *state) {
}
// <identifier> ::= <unqualified source code identifier> (of given length)
static bool ParseIdentifier(State *state, int length) {
static bool ParseIdentifier(State *state, ssize_t length) {
if (length == -1 ||
!AtLeastNumCharsRemaining(state->mangled_cur, length)) {
return false;
@ -892,7 +891,7 @@ static bool ParseCtorDtorName(State *state) {
if (ParseOneCharToken(state, 'C') &&
ParseCharClass(state, "123")) {
const char * const prev_name = state->prev_name;
const int prev_name_length = state->prev_name_length;
const ssize_t prev_name_length = state->prev_name_length;
MaybeAppendWithLength(state, prev_name, prev_name_length);
return true;
}
@ -901,7 +900,7 @@ static bool ParseCtorDtorName(State *state) {
if (ParseOneCharToken(state, 'D') &&
ParseCharClass(state, "012")) {
const char * const prev_name = state->prev_name;
const int prev_name_length = state->prev_name_length;
const ssize_t prev_name_length = state->prev_name_length;
MaybeAppend(state, "~");
MaybeAppendWithLength(state, prev_name, prev_name_length);
return true;

View File

@ -116,6 +116,14 @@ typedef unsigned __int64 uint64;
#error Do not know how to define a 32-bit integer quantity on your system
#endif
#if !(@ac_cv_have_ssize_t@)
typedef ptrdiff_t ssize_t;
#endif
#if !(@ac_cv_have_mode_t@)
typedef int mode_t;
#endif
typedef double WallTime;
struct GLOG_EXPORT LogMessageTime {

View File

@ -1050,7 +1050,7 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) {
//demand that the file is unique for our timestamp (fail if it exists).
flags = flags | O_EXCL;
}
int fd = open(filename, flags, FLAGS_logfile_mode);
int fd = open(filename, flags, static_cast<mode_t>(FLAGS_logfile_mode));
if (fd == -1) return false;
#ifdef HAVE_FCNTL
// Mark the file close-on-exec. We don't really care if this fails
@ -1319,7 +1319,8 @@ void LogFileObject::Write(bool force_flush,
// 'posix_fadvise' introduced in API 21:
// * https://android.googlesource.com/platform/bionic/+/6880f936173081297be0dc12f687d341b86a4cfa/libc/libc.map.txt#732
# else
posix_fadvise(fileno(file_), dropped_mem_length_, this_drop_length,
posix_fadvise(fileno(file_), static_cast<off_t>(dropped_mem_length_),
static_cast<off_t>(this_drop_length),
POSIX_FADV_DONTNEED);
# endif
dropped_mem_length_ = total_drop_length;

View File

@ -174,7 +174,7 @@ void DumpTimeInfo() {
}
// TODO(hamaji): Use signal instead of sigaction?
#ifdef HAVE_SIGACTION
#if defined(HAVE_STACKTRACE) && defined(HAVE_SIGACTION)
// Dumps information about the signal to STDERR.
void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
@ -332,11 +332,15 @@ void FailureSignalHandler(int signal_number,
const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1);
# ifdef HAVE_SIGACTION
DumpSignalInfo(signal_number, signal_info);
#elif !defined(GLOG_OS_WINDOWS)
(void)signal_info;
# endif
// Dump the stack traces.
for (int i = 0; i < depth; ++i) {
DumpStackFrameInfo(" ", stack[i]);
}
#elif !defined(GLOG_OS_WINDOWS)
(void)signal_info;
#endif
// *** TRANSITION ***

View File

@ -36,7 +36,7 @@
#include <glog/logging.h>
#include "stacktrace.h"
#ifdef HAVE_EXECINFO_H
#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
# include <execinfo.h>
#endif
@ -131,7 +131,7 @@ static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
CHECK_LE(size, STACK_LEN);
if (1) {
#ifdef HAVE_EXECINFO_H
#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
char **strings = backtrace_symbols(stack, size);
printf("Obtained %d stack frames.\n", size);
for (int i = 0; i < size; i++) {

View File

@ -58,16 +58,21 @@ static void **NextStackFrame(void **old_sp) {
// at a greater address that the current one.
if (new_sp <= old_sp) return NULL;
// Assume stack frames larger than 100,000 bytes are bogus.
if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
if (reinterpret_cast<uintptr_t>(new_sp) -
reinterpret_cast<uintptr_t>(old_sp) >
100000)
return NULL;
} else {
// In the non-strict mode, allow discontiguous stack frames.
// (alternate-signal-stacks for example).
if (new_sp == old_sp) return NULL;
// And allow frames upto about 1MB.
if ((new_sp > old_sp)
&& ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
if ((new_sp > old_sp) && (reinterpret_cast<uintptr_t>(new_sp) -
reinterpret_cast<uintptr_t>(old_sp) >
1000000))
return NULL;
}
if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
if (reinterpret_cast<uintptr_t>(new_sp) & (sizeof(void *) - 1)) return NULL;
#ifdef __i386__
// On 64-bit machines, the stack pointer can be very close to
// 0xffffffff, so we explicitly check for a pointer into the
@ -82,8 +87,10 @@ static void **NextStackFrame(void **old_sp) {
// Note: NextStackFrame<false>() is only called while the program
// is already on its last leg, so it's ok to be slow here.
static int page_size = getpagesize();
void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1));
if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1) {
void *new_sp_aligned =
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(new_sp) &
static_cast<uintptr_t>(~(page_size - 1)));
if (msync(new_sp_aligned, static_cast<size_t>(page_size), MS_ASYNC) == -1) {
return NULL;
}
}
@ -128,7 +135,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
int n = 0;
while (sp && n < max_depth) {
if (*(sp+1) == (void *)0) {
if (*(sp + 1) == NULL) {
// In 64-bit code, we often see a frame that
// points to itself and has a return address of 0.
break;

View File

@ -94,12 +94,12 @@ void InstallSymbolizeOpenObjectFileCallback(
// where the input symbol is demangled in-place.
// To keep stack consumption low, we would like this function to not
// get inlined.
static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) {
static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, size_t out_size) {
char demangled[256]; // Big enough for sane demangled symbols.
if (Demangle(out, demangled, sizeof(demangled))) {
// Demangling succeeded. Copy to out if the space allows.
size_t len = strlen(demangled);
if (len + 1 <= static_cast<size_t>(out_size)) { // +1 for '\0'.
if (len + 1 <= out_size) { // +1 for '\0'.
SAFE_ASSERT(len < sizeof(demangled));
memmove(out, demangled, len + 1);
}
@ -896,7 +896,7 @@ private:
};
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
int out_size) {
size_t out_size) {
const static SymInitializer symInitializer;
if (!symInitializer.ready) {
return false;
@ -911,7 +911,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
// This could break if a symbol has Unicode in it.
BOOL ret = SymFromAddr(symInitializer.process,
reinterpret_cast<DWORD64>(pc), 0, symbol);
if (ret == 1 && static_cast<int>(symbol->NameLen) < out_size) {
if (ret == 1 && static_cast<ssize_t>(symbol->NameLen) < out_size) {
// `NameLen` does not include the null terminating character.
strncpy(out, symbol->Name, static_cast<size_t>(symbol->NameLen) + 1);
out[static_cast<size_t>(symbol->NameLen)] = '\0';

View File

@ -31,13 +31,15 @@
//
// Unit tests for functions in symbolize.cc.
#include "symbolize.h"
#include <glog/logging.h>
#include <csignal>
#include <iostream>
#include "config.h"
#include <glog/logging.h>
#include "googletest.h"
#include "symbolize.h"
#include "utilities.h"
#ifdef HAVE_LIB_GFLAGS
@ -48,6 +50,13 @@ using namespace GFLAGS_NAMESPACE;
using namespace std;
using namespace GOOGLE_NAMESPACE;
// Avoid compile error due to "cast between pointer-to-function and
// pointer-to-object is an extension" warnings.
#if defined(__GNUG__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#if defined(HAVE_STACKTRACE)
#define always_inline
@ -88,12 +97,16 @@ extern "C" {
void nonstatic_func();
void nonstatic_func() {
volatile int a = 0;
++a;
// NOTE: In C++20, increment of object of volatile-qualified type is
// deprecated.
a = a + 1;
}
static void static_func() {
volatile int a = 0;
++a;
// NOTE: In C++20, increment of object of volatile-qualified type is
// deprecated.
a = a + 1;
}
}
@ -124,7 +137,9 @@ struct Foo {
void ATTRIBUTE_NOINLINE Foo::func(int x) {
volatile int a = x;
++a;
// NOTE: In C++20, increment of object of volatile-qualified type is
// deprecated.
a = a + 1;
}
// With a modern GCC, Symbolize() should return demangled symbol
@ -389,7 +404,9 @@ struct Foo {
__declspec(noinline) void Foo::func(int x) {
volatile int a = x;
++a;
// NOTE: In C++20, increment of object of volatile-qualified type is
// deprecated.
a = a + 1;
}
TEST(Symbolize, SymbolizeWithDemangling) {
@ -445,3 +462,7 @@ int main(int argc, char **argv) {
return 0;
#endif // HAVE_SYMBOLIZE
}
#if defined(__GNUG__)
#pragma GCC diagnostic pop
#endif

View File

@ -100,7 +100,7 @@
# endif
#endif
#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H)
#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_BACKTRACE)
# define STACKTRACE_H "stacktrace_generic-inl.h"
#endif