support ndk r25 (#844)
This commit is contained in:
parent
c515e1ae2f
commit
a34226ca94
17
.github/workflows/android.yml
vendored
17
.github/workflows/android.yml
vendored
@ -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
|
||||
|
||||
|
||||
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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",
|
||||
})
|
||||
|
||||
[
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 ***
|
||||
|
||||
@ -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++) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user