From: Sergiu Deitsch Date: Tue, 27 Feb 2018 20:03:20 +0000 (+0100) Subject: Symbolizer support for mingw and cygwin (#208) X-Git-Tag: accepted/tizen/5.0/unified/20181102.024921~3 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fupstream%2Fglog.git;a=commitdiff_plain Symbolizer support for mingw and cygwin (#208) * added dbghelp symbolizer support for mingw and cygwin * fixed compiler errors in case is not available * cmake: check whether SymFromAddr actually works --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b491db..f27f00d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include (CheckCSourceCompiles) include (CheckCXXCompilerFlag) include (CheckCXXSourceCompiles) +include (CheckCXXSourceRuns) include (CheckFunctionExists) include (CheckIncludeFile) include (CheckIncludeFileCXX) @@ -34,6 +35,7 @@ include (CheckStructHasMember) include (CheckSymbolExists) include (CheckTypeSize) include (CMakePackageConfigHelpers) +include (CMakePushCheckState) include (CPack) include (CTest) include (DetermineGflagsNamespace) @@ -112,6 +114,7 @@ check_cxx_compiler_flag (-Wunnamed-type-template-args check_symbol_exists (snprintf stdio.h HAVE_SNPRINTF) check_library_exists (unwind get_static_proc_name "" HAVE_LIB_UNWIND) +check_library_exists (DbgHelp UnDecorateSymbolName "" HAVE_DBGHELP) find_library (UNWIND_LIBRARY NAMES unwind DOC "unwind library") mark_as_advanced (UNWIND_LIBRARY) @@ -339,6 +342,49 @@ else (HAVE_USING_OPERATOR) set (ac_cv_cxx_using_operator 0) endif (HAVE_USING_OPERATOR) +if (HAVE_EXECINFO_H) + set (HAVE_STACKTRACE 1) +endif (HAVE_EXECINFO_H) + +if (WIN32 OR CYGWIN) + cmake_push_check_state (RESET) + set (CMAKE_REQUIRED_LIBRARIES DbgHelp) + + check_cxx_source_runs ([=[ + #include + #include + #include + + void foobar() { } + + int main() + { + HANDLE process = GetCurrentProcess(); + + if (!SymInitialize(process, NULL, TRUE)) + return EXIT_FAILURE; + + char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; + SYMBOL_INFO *symbol = reinterpret_cast(buf); + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_SYM_NAME; + + void* const pc = reinterpret_cast(&foobar); + BOOL ret = SymFromAddr(process, reinterpret_cast(pc), 0, symbol); + + return ret ? EXIT_SUCCESS : EXIT_FAILURE; + } + ]=] HAVE_SYMBOLIZE) + + cmake_pop_check_state () + + if (HAVE_SYMBOLIZE) + set (HAVE_STACKTRACE 1) + endif (HAVE_SYMBOLIZE) +elseif (UNIX OR (APPLE AND HAVE_DLADDR)) + set (HAVE_SYMBOLIZE 1) +endif (WIN32 OR CYGWIN) + set (SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) if (WITH_THREADS AND Threads_FOUND) @@ -408,6 +454,10 @@ if (UNWIND_LIBRARY) target_link_libraries (glog PUBLIC ${UNWIND_LIBRARY}) endif (UNWIND_LIBRARY) +if (HAVE_DBGHELP) + target_link_libraries (glog PUBLIC DbgHelp) +endif (HAVE_DBGHELP) + if (HAVE_PTHREAD) target_link_libraries (glog PUBLIC ${CMAKE_THREAD_LIBS_INIT}) endif (HAVE_PTHREAD) @@ -476,19 +526,6 @@ else (NOT BUILD_SHARED_LIBS) "GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS=${_IMPORT}") endif (NOT BUILD_SHARED_LIBS) -if (HAVE_EXECINFO_H) - set (HAVE_STACKTRACE 1) -endif (HAVE_EXECINFO_H) - -if (WIN32) - set (HAVE_STACKTRACE 1) - set (HAVE_SYMBOLIZE 1) -endif (WIN32) - -if (UNIX OR (APPLE AND HAVE_DLADDR)) - set (HAVE_SYMBOLIZE 1) -endif (UNIX OR (APPLE AND HAVE_DLADDR)) - # Unit testing if (BUILD_TESTING) diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in index 9d87d37..e15c737 100644 --- a/src/config.h.cmake.in +++ b/src/config.h.cmake.in @@ -130,6 +130,9 @@ /* define if your compiler has __sync_val_compare_and_swap */ #cmakedefine HAVE___SYNC_VAL_COMPARE_AND_SWAP +/* define if symbolize support is available */ +#cmakedefine HAVE_SYMBOLIZE + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #cmakedefine LT_OBJDIR diff --git a/src/symbolize.cc b/src/symbolize.cc index 98a754f..61fe2ff 100644 --- a/src/symbolize.cc +++ b/src/symbolize.cc @@ -844,18 +844,22 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, _END_GOOGLE_NAMESPACE_ -#elif defined(OS_WINDOWS) +#elif defined(OS_WINDOWS) || defined(OS_CYGWIN) +#include #include + +#ifdef _MSC_VER #pragma comment(lib, "DbgHelp") +#endif _START_GOOGLE_NAMESPACE_ class SymInitializer { public: - HANDLE process = NULL; - bool ready = false; - SymInitializer() { + HANDLE process; + bool ready; + SymInitializer() : process(NULL), ready(false) { // Initialize the symbol handler. // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx process = GetCurrentProcess(); diff --git a/src/symbolize.h b/src/symbolize.h index 86f0c79..9ff16c1 100644 --- a/src/symbolize.h +++ b/src/symbolize.h @@ -130,9 +130,9 @@ void InstallSymbolizeCallback(SymbolizeCallback callback); // file is opened successfully, returns the file descriptor. Otherwise, // returns -1. |out_file_name_size| is the size of the file name buffer // (including the null-terminator). -typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc, - uint64_t &start_address, - uint64_t &base_address, +typedef int (*SymbolizeOpenObjectFileCallback)(uint64 pc, + uint64 &start_address, + uint64 &base_address, char *out_file_name, int out_file_name_size); void InstallSymbolizeOpenObjectFileCallback( diff --git a/src/symbolize_unittest.cc b/src/symbolize_unittest.cc index a0a9737..413161b 100644 --- a/src/symbolize_unittest.cc +++ b/src/symbolize_unittest.cc @@ -357,10 +357,12 @@ void ATTRIBUTE_NOINLINE TestWithReturnAddress() { #endif } -# elif defined(OS_WINDOWS) +# elif defined(OS_WINDOWS) || defined(OS_CYGWIN) +#ifdef _MSC_VER #include #pragma intrinsic(_ReturnAddress) +#endif struct Foo { static void func(int x); @@ -378,7 +380,13 @@ TEST(Symbolize, SymbolizeWithDemangling) { } __declspec(noinline) void TestWithReturnAddress() { - void *return_address = _ReturnAddress(); + void *return_address = +#ifdef __GNUC__ // Cygwin and MinGW support + __builtin_return_address(0) +#else + _ReturnAddress() +#endif + ; const char *symbol = TrySymbolize(return_address); CHECK(symbol != NULL); CHECK_STREQ(symbol, "main"); @@ -401,7 +409,7 @@ int main(int argc, char **argv) { TestWithPCInsideNonInlineFunction(); TestWithReturnAddress(); return RUN_ALL_TESTS(); -# elif defined(OS_WINDOWS) +# elif defined(OS_WINDOWS) || defined(OS_CYGWIN) TestWithReturnAddress(); return RUN_ALL_TESTS(); # else // OS_WINDOWS diff --git a/src/utilities.h b/src/utilities.h index be2cff4..ca21cfb 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -127,6 +127,7 @@ # define HAVE_STACKTRACE #endif +#ifndef HAVE_SYMBOLIZE // defined by gcc #if defined(__ELF__) && defined(OS_LINUX) # define HAVE_SYMBOLIZE @@ -137,6 +138,7 @@ // Use DbgHelp to symbolize # define HAVE_SYMBOLIZE #endif +#endif // !defined(HAVE_SYMBOLIZE) #ifndef ARRAYSIZE // There is a better way, but this is good enough for our purpose.