diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b3cb7d4..3b8a3f2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -27,21 +27,21 @@ project linux:-lpthread all always_show_run_output + hidden ; -local RDYNAMIC = freebsd:"-rdynamic" solaris:"-Bdynamic" aix:"-rdynamic" +local FORCE_SYMBOL_EXPORT = freebsd:"-rdynamic" solaris:"-Bdynamic" aix:"-rdynamic" qnxnto,qcc:"-Bdynamic" qnxnto,gcc:"-rdynamic" android:"-rdynamic" linux:"-rdynamic" darwin,gcc:"-dynamic" - darwin,clang:"-rdynamic" iphone:"-rdynamic" ; + darwin,clang:"-rdynamic" iphone:"-rdynamic" + BOOST_STACKTRACE_TEST_EXPORTS_TABLE_USAGE ; -local HIDE_SYMBS = linux:"-fvisibility=hidden" ; - -local BT_DEPS = $(HIDE_SYMBS) linux:dl backtrace [ check-target-builds ../build//libbacktrace : : no ] ; -local AD2L_DEPS = $(HIDE_SYMBS) linux:dl [ check-target-builds ../build//addr2line : : no ] ; -local WIND_DEPS = $(HIDE_SYMBS) Dbgeng ole32 [ check-target-builds ../build//WinDbg : : no ] ; -local WICA_DEPS = $(HIDE_SYMBS) Dbgeng ole32 [ check-target-builds ../build//WinDbgCached : : no ] ; -local NOOP_DEPS = $(HIDE_SYMBS) ; -local BASIC_DEPS = $(RDYNAMIC) linux:dl [ check-target-builds ../build//WinDbg : no ] ; +local BT_DEPS = linux:dl backtrace [ check-target-builds ../build//libbacktrace : : no ] ; +local AD2L_DEPS = linux:dl [ check-target-builds ../build//addr2line : : no ] ; +local WIND_DEPS = Dbgeng ole32 [ check-target-builds ../build//WinDbg : : no ] ; +local WICA_DEPS = Dbgeng ole32 [ check-target-builds ../build//WinDbgCached : : no ] ; +local NOOP_DEPS = ; +local BASIC_DEPS = $(FORCE_SYMBOL_EXPORT) linux:dl [ check-target-builds ../build//WinDbg : no ] ; local LINKSHARED_BT = shared BOOST_STACKTRACE_DYN_LINK /boost/stacktrace//boost_stacktrace_backtrace $(BT_DEPS) ; local LINKSHARED_AD2L = shared BOOST_STACKTRACE_DYN_LINK /boost/stacktrace//boost_stacktrace_addr2line $(AD2L_DEPS) ; @@ -117,7 +117,7 @@ test-suite stacktrace_tests ##### Tests with disabled debug symbols ##### # Header only tests without debug symbols - [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_BACKTRACE BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(BT_DEPS) : backtrace_ho_no_dbg ] + [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_BACKTRACE $(FORCE_SYMBOL_EXPORT) $(BT_DEPS) : backtrace_ho_no_dbg ] [ run test_noop.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_NOOP $(NOOP_DEPS) : noop_ho_no_dbg ] [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(WIND_DEPS) : windbg_ho_no_dbg ] [ run test.cpp test_impl.cpp : : : off BOOST_STACKTRACE_USE_WINDBG_CACHED BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL $(WICA_DEPS) : windbg_cached_ho_no_dbg ] @@ -127,12 +127,12 @@ test-suite stacktrace_tests : addr2line_ho_no_dbg ] # Test with shared linked implementations without debug symbols - [ run test.cpp : : : off .//test_impl_lib_backtrace_no_dbg $(LINKSHARED_BT) BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL : backtrace_lib_no_dbg ] - [ run test.cpp : : : off .//test_impl_lib_addr2line_no_dbg $(LINKSHARED_AD2L) : addr2line_lib_no_dbg ] - [ run test.cpp : : : off .//test_impl_lib_windbg_no_dbg $(LINKSHARED_WIND) BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL : windbg_lib_no_dbg ] - [ run test.cpp : : : off .//test_impl_lib_windbg_cached_no_dbg $(LINKSHARED_WIND_CACHED) BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL : windbg_cached_lib_no_dbg ] - [ run test_noop.cpp : : : off .//test_impl_lib_noop_no_dbg $(LINKSHARED_NOOP) : noop_lib_no_dbg ] - [ run test.cpp : : : off .//test_impl_lib_basic_no_dbg $(LINKSHARED_BASIC) : basic_lib_no_dbg ] + [ run test.cpp : : : off .//test_impl_lib_backtrace_no_dbg $(LINKSHARED_BT) $(FORCE_SYMBOL_EXPORT) : backtrace_lib_no_dbg ] + [ run test.cpp : : : off .//test_impl_lib_addr2line_no_dbg $(LINKSHARED_AD2L) : addr2line_lib_no_dbg ] + [ run test.cpp : : : off .//test_impl_lib_windbg_no_dbg $(LINKSHARED_WIND) BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL : windbg_lib_no_dbg ] + [ run test.cpp : : : off .//test_impl_lib_windbg_cached_no_dbg $(LINKSHARED_WIND_CACHED) BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL : windbg_cached_lib_no_dbg ] + [ run test_noop.cpp : : : off .//test_impl_lib_noop_no_dbg $(LINKSHARED_NOOP) : noop_lib_no_dbg ] + [ run test.cpp : : : off .//test_impl_lib_basic_no_dbg $(LINKSHARED_BASIC) : basic_lib_no_dbg ] # Thread safety without debug symbols [ run thread_safety_checking.cpp diff --git a/test/test.cpp b/test/test.cpp index b3e54ac..5b81fbb 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -14,49 +14,25 @@ #include +#include "test_impl.hpp" using boost::stacktrace::stacktrace; using boost::stacktrace::frame; -#ifdef BOOST_STACKTRACE_DYN_LINK -# define BOOST_ST_API BOOST_SYMBOL_IMPORT -#else -# define BOOST_ST_API -#endif - #if (defined(BOOST_GCC) && defined(BOOST_WINDOWS) && !defined(BOOST_STACKTRACE_USE_BACKTRACE) && !defined(BOOST_STACKTRACE_USE_ADDR2LINE)) \ || defined(BOOST_STACKTRACE_TEST_NO_DEBUG_AT_ALL) -# define BOOST_STACKTRACE_SYMNAME 0 +# define BOOST_STACKTRACE_TEST_SHOULD_OUTPUT_READABLE_NAMES 0 #else -# define BOOST_STACKTRACE_SYMNAME 1 +# define BOOST_STACKTRACE_TEST_SHOULD_OUTPUT_READABLE_NAMES 1 #endif -typedef std::pair (*foo1_t)(int i); -BOOST_ST_API std::pair foo2(int i, foo1_t foo1); -BOOST_ST_API stacktrace return_from_nested_namespaces(); -BOOST_ST_API boost::stacktrace::stacktrace bar1(); -BOOST_ST_API boost::stacktrace::stacktrace bar2(); -BOOST_SYMBOL_EXPORT BOOST_NOINLINE std::pair foo1(int i) { - if (i) { - return foo2(i - 1, foo1); - } - - std::pair ret; - try { - throw std::logic_error("test"); - } catch (const std::logic_error& /*e*/) { - ret.second = stacktrace(); - return ret; - } -} - void test_deeply_nested_namespaces() { std::stringstream ss; ss << return_from_nested_namespaces(); std::cout << ss.str() << '\n'; -#if BOOST_STACKTRACE_SYMNAME +#if BOOST_STACKTRACE_TEST_SHOULD_OUTPUT_READABLE_NAMES BOOST_TEST(ss.str().find("main") != std::string::npos); BOOST_TEST(ss.str().find("get_backtrace_from_nested_namespaces") != std::string::npos @@ -72,7 +48,7 @@ void test_deeply_nested_namespaces() { // Template parameter Depth is to produce different functions on each Depth. This simplifies debugging when one of the tests catches error template void test_nested() { - std::pair res = foo2(Depth, foo1); + std::pair res = function_from_library(Depth, function_from_main_translation_unit); std::stringstream ss1, ss2; @@ -91,15 +67,15 @@ void test_nested() { BOOST_TEST(ss1.str().find(" in ") != std::string::npos); BOOST_TEST(ss2.str().find(" in ") != std::string::npos); -#if BOOST_STACKTRACE_SYMNAME +#if BOOST_STACKTRACE_TEST_SHOULD_OUTPUT_READABLE_NAMES BOOST_TEST(ss1.str().find("main") != std::string::npos); BOOST_TEST(ss2.str().find("main") != std::string::npos); - BOOST_TEST(ss1.str().find("foo2") != std::string::npos); - BOOST_TEST(ss2.str().find("foo2") != std::string::npos); + BOOST_TEST(ss1.str().find("function_from_library") != std::string::npos); + BOOST_TEST(ss2.str().find("function_from_library") != std::string::npos); - BOOST_TEST(ss1.str().find("foo1") != std::string::npos); - BOOST_TEST(ss2.str().find("foo1") != std::string::npos); + BOOST_TEST(ss1.str().find("function_from_main_translation_unit") != std::string::npos); + BOOST_TEST(ss2.str().find("function_from_main_translation_unit") != std::string::npos); #endif //BOOST_TEST(false); @@ -269,12 +245,12 @@ int main() { test_empty_basic_stacktrace(); test_empty_basic_stacktrace(); - BOOST_TEST(&bar1 != &bar2); - boost::stacktrace::stacktrace b1 = bar1(); + BOOST_TEST(&make_some_stacktrace1 != &make_some_stacktrace2); + boost::stacktrace::stacktrace b1 = make_some_stacktrace1(); BOOST_TEST(b1.size() == 4); - boost::stacktrace::stacktrace b2 = bar2(); + boost::stacktrace::stacktrace b2 = make_some_stacktrace2(); BOOST_TEST(b2.size() == 4); - test_comparisons_base(bar1(), bar2()); + test_comparisons_base(make_some_stacktrace1(), make_some_stacktrace2()); test_nested<300>(); BOOST_TEST(boost::stacktrace::stacktrace(0, 1).size() == 1); diff --git a/test/test_impl.cpp b/test/test_impl.cpp index d831405..ed25ecd 100644 --- a/test/test_impl.cpp +++ b/test/test_impl.cpp @@ -4,29 +4,12 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) - -#include - -#if defined(BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP) || defined(BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP) -#error "LexicalCast headers leaked into the boost/stacktrace/stacktrace.hpp" -#endif - -#if !defined(BOOST_USE_WINDOWS_H) && defined(_WINDOWS_H) -#error "windows.h header leaked into the boost/stacktrace/stacktrace.hpp" -#endif - -#include +#define BOOST_STACKTRACE_TEST_IMPL_LIB 1 +#include "test_impl.hpp" using namespace boost::stacktrace; -#ifdef BOOST_STACKTRACE_DYN_LINK -# define BOOST_ST_API BOOST_SYMBOL_EXPORT -#else -# define BOOST_ST_API -#endif - -typedef std::pair (*foo1_t)(int i); -BOOST_ST_API BOOST_NOINLINE std::pair foo2(int i, foo1_t foo1) { +BOOST_ST_API BOOST_NOINLINE std::pair function_from_library(int i, foo1_t foo1) { if (i) { return foo1(--i); } else { @@ -59,31 +42,31 @@ BOOST_ST_API BOOST_NOINLINE stacktrace return_from_nested_namespaces() { return get_backtrace_from_nested_namespaces(); } -BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace bar1_impl(int d = 0) { +BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace make_some_stacktrace1_impl(int d = 0) { boost::stacktrace::stacktrace result(0, 4); if (result.size() < 4) { if (d > 4) throw std::runtime_error("Stack is not growing in test OR stacktrace fails to work in `bar1` function."); - return bar1_impl(d + 1); + return make_some_stacktrace1_impl(d + 1); } return result; } -BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace bar2_impl(int d = 0) { +BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace make_some_stacktrace2_impl(int d = 0) { boost::stacktrace::stacktrace result(0, 4); if (result.size() < 4) { if (d > 4) throw std::runtime_error("Stack is not growing in test OR stacktrace fails to work in `bar2` function."); - return bar2_impl(d + 1); + return make_some_stacktrace2_impl(d + 1); } return result; } -BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace bar1() { - boost::stacktrace::stacktrace result = bar1_impl(); +BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace make_some_stacktrace1() { + boost::stacktrace::stacktrace result = make_some_stacktrace1_impl(); return result; } -BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace bar2() { - boost::stacktrace::stacktrace result = bar2_impl(); +BOOST_ST_API BOOST_NOINLINE boost::stacktrace::stacktrace make_some_stacktrace2() { + boost::stacktrace::stacktrace result = make_some_stacktrace2_impl(); return result; } diff --git a/test/test_impl.hpp b/test/test_impl.hpp new file mode 100644 index 0000000..2a4ac86 --- /dev/null +++ b/test/test_impl.hpp @@ -0,0 +1,54 @@ +// Copyright Antony Polukhin, 2016-2018. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#include + +#if defined(BOOST_LEXICAL_CAST_TRY_LEXICAL_CONVERT_HPP) || defined(BOOST_LEXICAL_CAST_BAD_LEXICAL_CAST_HPP) +#error "LexicalCast headers leaked into the boost/stacktrace/stacktrace.hpp" +#endif + +#if !defined(BOOST_USE_WINDOWS_H) && defined(_WINDOWS_H) +#error "windows.h header leaked into the boost/stacktrace/stacktrace.hpp" +#endif + +#include + +using namespace boost::stacktrace; + +#if defined(BOOST_STACKTRACE_DYN_LINK) || defined(BOOST_STACKTRACE_TEST_EXPORTS_TABLE_USAGE) +# ifdef BOOST_STACKTRACE_TEST_IMPL_LIB +# define BOOST_ST_API BOOST_SYMBOL_EXPORT +# else +# define BOOST_ST_API BOOST_SYMBOL_IMPORT +# endif +#else +# define BOOST_ST_API +#endif + +typedef std::pair st_pair; +typedef st_pair (*foo1_t)(int i); +BOOST_ST_API st_pair function_from_library(int i, foo1_t foo1); +BOOST_ST_API boost::stacktrace::stacktrace return_from_nested_namespaces(); +BOOST_ST_API boost::stacktrace::stacktrace make_some_stacktrace1(); +BOOST_ST_API boost::stacktrace::stacktrace make_some_stacktrace2(); + +#ifdef BOOST_STACKTRACE_TEST_EXPORTS_TABLE_USAGE + BOOST_SYMBOL_EXPORT +#endif +inline st_pair function_from_main_translation_unit(int i) { + if (i) { + return function_from_library(i - 1, function_from_main_translation_unit); + } + + std::pair ret; + try { + throw std::logic_error("test"); + } catch (const std::logic_error& /*e*/) { + ret.second = stacktrace(); + return ret; + } +} diff --git a/test/test_noop.cpp b/test/test_noop.cpp index f81e78c..5a23c3d 100644 --- a/test/test_noop.cpp +++ b/test/test_noop.cpp @@ -4,41 +4,18 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include "test_impl.hpp" #include #include #include + #include using boost::stacktrace::stacktrace; using boost::stacktrace::frame; -#ifdef BOOST_STACKTRACE_DYN_LINK -# define BOOST_ST_API BOOST_SYMBOL_IMPORT -#else -# define BOOST_ST_API -#endif - -typedef std::pair (*foo1_t)(int i); -BOOST_ST_API std::pair foo2(int i, foo1_t foo1); -BOOST_ST_API stacktrace return_from_nested_namespaces(); - - -BOOST_NOINLINE std::pair foo1(int i) { - if (i) { - return foo2(i - 1, foo1); - } - - std::pair ret; - try { - throw std::logic_error("test"); - } catch (const std::logic_error& /*e*/) { - ret.second = stacktrace(); - return ret; - } -} - void test_deeply_nested_namespaces() { BOOST_TEST(return_from_nested_namespaces().size() == 0); BOOST_TEST(return_from_nested_namespaces().empty()); @@ -46,7 +23,7 @@ void test_deeply_nested_namespaces() { } void test_nested() { - std::pair res = foo2(15, foo1); + std::pair res = function_from_library(15, function_from_main_translation_unit); BOOST_TEST(!res.first); BOOST_TEST(res.first.empty()); diff --git a/test/thread_safety_checking.cpp b/test/thread_safety_checking.cpp index 55763fa..4212adf 100644 --- a/test/thread_safety_checking.cpp +++ b/test/thread_safety_checking.cpp @@ -4,6 +4,7 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include "test_impl.hpp" #include #include @@ -15,31 +16,8 @@ #include -#ifdef BOOST_STACKTRACE_DYN_LINK -# define BOOST_ST_API BOOST_SYMBOL_IMPORT -#else -# define BOOST_ST_API -#endif - using boost::stacktrace::stacktrace; -typedef std::pair (*foo1_t)(int i); -BOOST_ST_API std::pair foo2(int i, foo1_t foo1); -BOOST_ST_API stacktrace return_from_nested_namespaces(); - -BOOST_NOINLINE std::pair foo1(int i) { - if (i) { - return foo2(i - 1, foo1); - } - - std::pair ret; - try { - throw std::logic_error("test"); - } catch (const std::logic_error& /*e*/) { - ret.second = stacktrace(); - return ret; - } -} void main_test_loop() { std::size_t loops = 100; @@ -49,7 +27,7 @@ void main_test_loop() { std::stringstream ss_ethalon; while (--loops) { - std::pair res = foo2(Depth, foo1); + std::pair res = function_from_library(Depth, function_from_main_translation_unit); if (ethalon) { BOOST_TEST(res == *ethalon);