From 0bb7ae2135382ab903a6ab4b33b4f33475b36fc8 Mon Sep 17 00:00:00 2001 From: Andrey Pikas Date: Sun, 30 Apr 2017 19:37:32 +0300 Subject: [PATCH 1/3] Hide all symbols except explicitly exported with CASS_EXPORT. It fixes crash (or abort failure in Debug configuration) when some .so uses other version (1.1) of rapidjson from /usr/include and override some (not all) rapidjson methods compiled in libcassandra.so. This reproduced when connecting to scylladb. In Debug configuration it looks like rapidjson::Document::StartObject (from /usr/include/rapidjson/...) called with wrong this pointer from Parser (from third_party/rapidjson/...), but preprocessor output shows only sources from third_party/rapidjson. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ba060bbc..e9fbfc71f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,10 +181,12 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) # Create an object library for the driver (single build) if(NOT CMAKE_VERSION VERSION_LESS "2.8.8") + cmake_policy(SET CMP0063 NEW) add_library(cpp-driver OBJECT ${CASS_ALL_SOURCE_FILES}) if(NOT WIN32) set_property(TARGET cpp-driver PROPERTY COMPILE_FLAGS "${CASS_DRIVER_CXX_FLAGS} -fPIC") endif() + set_target_properties(cpp-driver PROPERTIES CXX_VISIBILITY_PRESET hidden) # Build both shared and static libraries set(CASS_BUILD_SHARED ON) @@ -198,6 +200,7 @@ include_directories(${CASS_INCLUDES}) if(CASS_BUILD_SHARED) if(CMAKE_VERSION VERSION_LESS "2.8.8") add_library(${PROJECT_LIB_NAME} SHARED ${CASS_ALL_SOURCE_FILES}) + set_target_properties(${PROJECT_LIB_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden) else() add_library(${PROJECT_LIB_NAME} SHARED $) endif() From edd90cf1ded087a4e9ca27b7111f92eb18d6c2f9 Mon Sep 17 00:00:00 2001 From: Andrey Pikas Date: Sun, 30 Apr 2017 21:50:44 +0300 Subject: [PATCH 2/3] Export methods for tests. --- src/address.hpp | 3 ++- src/get_time.hpp | 4 +++- src/macros.hpp | 16 ++++++++++++++++ src/timestamp_generator.hpp | 2 +- src/utils.cpp | 3 ++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/address.hpp b/src/address.hpp index cb608d81f..aa5e6b7dd 100644 --- a/src/address.hpp +++ b/src/address.hpp @@ -18,6 +18,7 @@ #define __CASS_ADDRESS_HPP_INCLUDED__ #include "hash.hpp" +#include "macros.hpp" #include @@ -29,7 +30,7 @@ namespace cass { -class Address { +class CASS_IMPL_EXPORT Address { public: static const Address EMPTY_KEY; static const Address DELETED_KEY; diff --git a/src/get_time.hpp b/src/get_time.hpp index 34cc1d75d..2221fe028 100644 --- a/src/get_time.hpp +++ b/src/get_time.hpp @@ -19,6 +19,8 @@ #include +#include "macros.hpp" + #define NANOSECONDS_PER_MICROSECOND 1000LL #define NANOSECONDS_PER_MILLISECOND 1000000LL #define NANOSECONDS_PER_SECOND 1000000000LL @@ -27,7 +29,7 @@ namespace cass { -uint64_t get_time_since_epoch_us(); +CASS_IMPL_EXPORT uint64_t get_time_since_epoch_us(); inline uint64_t get_time_since_epoch_ms() { return get_time_since_epoch_us() / MICROSECONDS_PER_MILLISECOND; diff --git a/src/macros.hpp b/src/macros.hpp index 81f11bb1a..7fe738429 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -77,4 +77,20 @@ struct StaticNextPow2 { enum { value = StaticNextPow2Helper<8 * sizeof(size_t) - 1, N>::value }; }; +#if !defined(CASS_STATIC) +# if (defined(WIN32) || defined(_WIN32)) +# if defined(CASS_BUILDING) +# define CASS_IMPL_EXPORT __declspec(dllexport) +# else +# define CASS_IMPL_EXPORT __declspec(dllexport) +# endif +# elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC)) && !defined(CASS_STATIC) +# define CASS_IMPL_EXPORT __global +# elif (defined(__GNUC__) && __GNUC__ >= 4) || defined(__INTEL_COMPILER) +# define CASS_IMPL_EXPORT __attribute__ ((visibility("default"))) +# endif +#else +#define CASS_IMPL_EXPORT +#endif + #endif diff --git a/src/timestamp_generator.hpp b/src/timestamp_generator.hpp index af7000fb5..ee4240577 100644 --- a/src/timestamp_generator.hpp +++ b/src/timestamp_generator.hpp @@ -59,7 +59,7 @@ class ServerSideTimestampGenerator : public TimestampGenerator { virtual int64_t next() { return CASS_INT64_MIN; } }; -class MonotonicTimestampGenerator : public TimestampGenerator { +class CASS_IMPL_EXPORT MonotonicTimestampGenerator : public TimestampGenerator { public: MonotonicTimestampGenerator(int64_t warning_threshold_us = 1000000, int64_t warning_interval_ms = 1000) diff --git a/src/utils.cpp b/src/utils.cpp index 16ec52e37..18f4a7606 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -17,6 +17,7 @@ #include "utils.hpp" #include "constants.hpp" +#include "macros.hpp" #include #include @@ -72,7 +73,7 @@ std::string opcode_to_string(int opcode) { return ""; } -void explode(const std::string& str, std::vector& vec, const char delimiter /* = ',' */) { +CASS_IMPL_EXPORT void explode(const std::string& str, std::vector& vec, const char delimiter /* = ',' */) { std::istringstream stream(str); while (!stream.eof()) { std::string token; From 6df800cdae34d03bb75188c6fb1c4c6c15e5751e Mon Sep 17 00:00:00 2001 From: Andrey Pikas Date: Sun, 30 Apr 2017 22:04:17 +0300 Subject: [PATCH 3/3] Fix Visual Studio compilation error. --- src/utils.cpp | 3 +-- src/utils.hpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index 18f4a7606..16ec52e37 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -17,7 +17,6 @@ #include "utils.hpp" #include "constants.hpp" -#include "macros.hpp" #include #include @@ -73,7 +72,7 @@ std::string opcode_to_string(int opcode) { return ""; } -CASS_IMPL_EXPORT void explode(const std::string& str, std::vector& vec, const char delimiter /* = ',' */) { +void explode(const std::string& str, std::vector& vec, const char delimiter /* = ',' */) { std::istringstream stream(str); while (!stream.eof()) { std::string token; diff --git a/src/utils.hpp b/src/utils.hpp index 2cf677014..cf97b5402 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -82,7 +82,7 @@ inline size_t next_pow_2(size_t num) { std::string opcode_to_string(int opcode); -void explode(const std::string& str, std::vector& vec, const char delimiter = ','); +CASS_IMPL_EXPORT void explode(const std::string& str, std::vector& vec, const char delimiter = ','); std::string& trim(std::string& str);