Mock class:
class MockManagerForClient {
public:
MOCK_CONST_METHOD0(GetEngine, std::shared_ptr<engine::Engine>());
MOCK_METHOD1(RemoveClient, void(std::string const& clientId));
virtual ~MockManagerForClient() = default;
};
Test case:
TEST(ClientTest, Login) {
NiceMock<MockManagerForClient> manager;
EXPECT_CALL(manager, RemoveClient(_)).Times(1);
manager.RemoveClient("1");
}
stack capture in gdb:
Catchpoint 1 (signal SIGSEGV), 0x00005555557266f6 in testing::Cardinality::ConservativeUpperBound() const ()
(gdb) bt
#0 0x00005555557266f6 in testing::Cardinality::ConservativeUpperBound() const ()
#1 0x00005555557216c9 in testing::internal::ExpectationBase::CheckActionCountIfNotDone() const ()
#2 0x00005555556ba810 in testing::internal::TypedExpectation<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::ShouldHandleArguments(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> const&) const (this=0x555555a2c8a0, args=std::tuple containing = {...})
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1111
#3 0x00005555556b9749 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::FindMatchingExpectationLocked(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> const&) const (this=0x7fffffffda00, args=std::tuple containing = {...})
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1739
#4 0x00005555556b8b56 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::UntypedFindMatchingExpectation(void const*, void const**, bool*, std::ostream*, std::ostream*) (this=0x7fffffffda00, untyped_args=0x7fffffffd8f0, untyped_action=0x7fffffffd340, is_excessive=0x7fffffffd337, what=0x7fffffffd3d0, why=0x7fffffffd560)
at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1701
#5 0x000055555572235d in testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void*) ()
#6 0x00005555556b56c0 in testing::internal::FunctionMockerBase<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::InvokeWith(std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>&&) (this=0x7fffffffda00, args=...) at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-spec-builders.h:1602
#7 0x00005555556b4b75 in testing::internal::FunctionMocker<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::Invoke(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (this=0x7fffffffda00, a1="1") at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gmock/gmock-generated-function-mockers.h:101
#8 0x00005555556b46f0 in MockManagerForClient::RemoveClient (this=0x7fffffffd9b0, gmock_a1=...) at /home/phillip/projects/spiral-front/front/engine-test/src/client-impl/./mocks.hpp:33
#9 0x00005555556b3480 in ClientTest_Login_Test::TestBody (this=0x555555a2c1c0) at /home/phillip/projects/spiral-front/front/engine-test/src/client-impl/client-impl-test.cpp:43
#10 0x000055555575f371 in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#11 0x000055555575957b in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#12 0x0000555555739298 in testing::Test::Run() ()
#13 0x0000555555739bf5 in testing::TestInfo::Run() ()
#14 0x000055555573a278 in testing::TestCase::Run() ()
#15 0x0000555555745064 in testing::internal::UnitTestImpl::RunAllTests() ()
#16 0x0000555555760519 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#17 0x000055555575a35f in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#18 0x0000555555743aec in testing::UnitTest::Run() ()
#19 0x00005555556fe830 in RUN_ALL_TESTS () at /home/phillip/.conan/data/googletest/1.8.1/phillip/stable/package/efbe354690ef83824a1e98c7a6076b7ab63bc1b3/include/gtest/gtest.h:2341
#20 0x00005555556fe23c in main (argc=1, argv=0x7fffffffe148) at /home/phillip/projects/spiral-front/front/engine-test/src/main.cpp:7
I have tried several hours and no idea why. I have several others mock class, all works find. The most different of this MockManagerForClient is RemoveClient is return void.
I finally fixed the problem after 2 days. Just like other peoples crash situation, it is due project's compile flags not same as googletest.
My environment is Ubuntu 18.04 with g++ 7.4.0.
To make googletest works with c++11 standard, I use master branch of https://github.com/google/googletest. Build googletest with cmake and check cmake generation file: flags.make
googletest use -std=c++11, will my project use -std=gun++11. So adding following cmake definitions:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
Fixing compile errors due to using c++14 features. Well then the crash issue still there.
Extra compile flags not in my project is: -g -Wall -Wshadow -Werror -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers
After adding them to my project's CMakeLists.txt and fixing compile errors. googletest crash issue finally gone.
Related
I recently updated to fedora 30. When running a test now, my code will coredump on the CPPUNIT_ASSERT in the destrctor of the Message,
gcc version:
gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Cppunit version:
Installed Packages
cppunit.x86_64 1.14.0-7.fc30 #fedora
backtrace:
#0 0x00007ff037a363ff in free () from /lib64/libjemalloc.so.2
#1 0x000000000044ea37 in __gnu_cxx::new_allocator<char>::deallocate (this=0x7ff02fefc000, __p=0x1 <error: Cannot access memory at address 0x1>)
at /usr/include/c++/9/ext/new_allocator.h:128
#2 0x000000000044cc39 in std::allocator_traits<std::allocator<char> >::deallocate (__a=..., __p=0x1 <error: Cannot access memory at address 0x1>
, __n=70999306) at /usr/include/c++/9/bits/alloc_traits.h:470
#3 0x000000000043eb9f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy (this=0x7ff02fefc000, __siz
e=70999305) at /usr/include/c++/9/bits/basic_string.h:237
#4 0x000000000043df95 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose (this=0x7ff02fefc000) at /u
sr/include/c++/9/bits/basic_string.h:232
#5 0x000000000043b9a5 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string (this=0x7ff02fefc000, __
in_chrg=<optimized out>) at /usr/include/c++/9/bits/basic_string.h:658
#6 0x0000000000738397 in std::_Destroy<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (__pointer=0x7ff02fefc0
00) at /usr/include/c++/9/bits/stl_construct.h:98
#7 0x00000000007359f9 in std::_Destroy_aux<false>::__destroy<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (
__first=0x7ff02fefc000, __last=0x7ff02fefb460) at /usr/include/c++/9/bits/stl_construct.h:108
#8 0x00000000007326a2 in std::_Destroy<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__first=0x7ff02fefb5e0
, __last=0x7ff02fefb460) at /usr/include/c++/9/bits/stl_construct.h:137
#9 0x000000000072fb65 in std::_Destroy<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_str
ing<char, std::char_traits<char>, std::allocator<char> > > (__first=0x7ff02fefb5e0, __last=0x7ff02fefb460) at /usr/include/c++/9/bits/stl_constru
ct.h:206
#10 0x000000000075d72d in std::deque<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11
::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_destroy_data_aux (this=0x7fffdd38c658, __first="", __last=non-derefer
enceable iterator for std::deque) at /usr/include/c++/9/bits/deque.tcc:864
#11 0x00007ff0384e52ed in CppUnit::Message::~Message() () from /lib64/libcppunit-1.14.so.0
#12 0x0000000000ed4ac8 in UT_MyTest::basic(this=0x7ff034b294b0, chunks=std::vector of lengt
h 1000, capacity 1024 = {...}, index=...) at /home/felix/git/master/src/core/UT_MyTest.cpp:708
Removing the CPPUNIT_ASSERT on line 708 enables the test to pass without issue - including it coredumps with this dump above. The values of __first and __last are "" - not sure if that will cause it to dump. I'm thinking my versioning is off, but I'm not sure. Has anyone any suggestions?
Edit:
The line it coredumps on for this particular test:
CPPUNIT_ASSERT(correctHashes != 0);
This coredump happens in any test that use CPPUNIT_ASSERT
Upgrading to cppunit 1.15 from the fc32 repo fixed the issue for me.
I'm getting a very weird bug when defining a test suite with boost like this:
BOOST_AUTO_TEST_SUITE(zerocoin_implementation_tests)
The error looks like this:
terminate called after throwing an instance of 'std::length_error'
what(): basic_string::_M_create
Here's the relevant backtrace:
#5 0x00007ffff5ce6fe8 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff5ce2875 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff5d7c949 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x00007ffff70afe15 in boost::unit_test::test_unit::test_unit(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::test_unit_type) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#9 0x00007ffff70b0456 in boost::unit_test::test_suite::test_suite(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#10 0x00007ffff70b0612 in boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::decorator::collector&) ()
from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
From what I can tell, this has to do with Boost trying to create a max length string. I'd like to see exactly what it is doing. What's the best way of expanding boost macros to see the pre-compiled version?
Side Note
Weirdly, if I change the line very slightly to:
BOOST_AUTO_TEST_SUITE(zerocsoin_implementation_tests)
I get the following error:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
And backtrace:
#6 0x00007ffff5ce7594 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff70afe15 in boost::unit_test::test_unit::test_unit(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::test_unit_type) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#8 0x00007ffff70b0456 in boost::unit_test::test_suite::test_suite(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#9 0x00007ffff70b0612 in boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::decorator::collector&) ()
from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
The source code for the file (and the rest of the project) can be found here: https://github.com/phoreproject/Phore/blob/segwit/src/test/zerocoin_implementation_tests.cpp
Diff that probably caused the bug: https://github.com/phoreproject/phore/compare/master...segwit#diff-bb4f094cc636d668944ed6af9b72c0d9
Two approaches:
Exception Breakpoints
Just start the test in the debugger and catch the exception.
In gdb you could do
(gdb) catch throw
Catchpoint 2 (throw)
which act like a general breakpoint. Visual Studio has a Manage Exeptions dialog.¹
Boost Test Breakpoints
For debugging Boost Test I like to set a break at the test_method member of the specific test case class I want to break at. E.g. with a test_runner that has a few nested suites like:
./test_runner --list_content
import*
utility*
xml*
xml_utilities*
child_text_test*
loggable_xml_path_test*
And we run these 3 tests like:
./test_runner -t import/utility/xml
Running 3 test cases...
*** No errors detected
To debug them with gdb I'd do
gdb ./test_runner
start -t import/utility/xml
Which stops at main, then I type:
break import::utility::xml
Auto completion helps, so to get the exact names, you can just pick from the completions:
xml
xml::as_element(xmlpp::Node const&)
xml::attr_value(xmlpp::Element const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
xml::attr_value(xmlpp::Node const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
xml::child_text[abi:cxx11](xmlpp::Element const&, char const*)
xml::child_text_test
xml::child_text_test::test_method()
xml::child_text_test_invoker()
xml::child_text_test_registrar62
xml::end_suite94_registrar94
xml::first_child(xmlpp::Element const&, char const*)
xml::get_content[abi:cxx11](xmlpp::Element const&)
xml::get_content[abi:cxx11](xmlpp::Node const*)
xml::is_attr_value(xmlpp::Node const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
xml::loggable_xml_path[abi:cxx11](xmlpp::Node const&)
xml::loggable_xml_path_test
xml::loggable_xml_path_test::test_method()
xml::loggable_xml_path_test_invoker()
xml::loggable_xml_path_test_registrar77
xml::trace_xml(xmlpp::Element const&, LogSource::LogTx)
xml::trace_xml_formatted(xmlpp::Element const&, LogSource::LogTx)
xml::xml_registrar20
xml::xml_utilities
xml::xml_utilities::test_method()
xml::xml_utilities_invoker()
xml::xml_utilities_registrar22
Pick the ones named test_method(), e.g.
break import::utility::xml::child_text_test::test_method()
Breakpoint 2 at 0x730762: file /path/src/import/utility/xml_tests.cpp, line 62.
Now you can continue execution and the debugger will automatic pause execution at the start of your unit test.
¹ see also
Make Visual Studio break on User (std::exception) Exceptions?
How do I make VC++'s debugger break on exceptions?
I've recently updated my Gentoo Linux PC with GCC 5.4.0.
I also recompiled all packages depending on gcc (it was mentioned in gcc upgrade guide for gentoo).
Most of programs works well, however my tests, using cppunit, throw std::bad_alloc before starting.
At first I thought there might be a problem with updated version of cppunit, so I downgraded it to previous version, but the problem still exists.
Whenever I start any test, the application immediately throws:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
I started the application in gdb and printed debug backtrace:
#0 0x00007ffff545d218 in raise () from /lib64/libc.so.6
#1 0x00007ffff545e69a in abort () from /lib64/libc.so.6
#2 0x00007ffff5d8f18d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6
#3 0x00007ffff5d8d046 in ?? () from /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6
#4 0x00007ffff5d8d091 in std::terminate() () from /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6
#5 0x00007ffff5d8d297 in __cxa_throw () from /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6
#6 0x00007ffff5db5f52 in std::__throw_bad_alloc() () from /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6
#7 0x0000000000b2b3ae in __gnu_cxx::new_allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::allocate
(this=0x7fffffffda58, __n=18446741874689290911) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/ext/new_allocator.h:102
#8 0x0000000000b2b1e2 in std::allocator_traits<std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::allocate (__a=..., __n=18446741874689290911) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/bits/alloc_traits.h:491
#9 0x0000000000b2b09e in std::__cxx1998::_Vector_base<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_allocate (this=0x7fffffffda58,
__n=18446741874689290911) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/bits/stl_vector.h:170
#10 0x0000000000b2af71 in std::__cxx1998::_Vector_base<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_create_storage (this=0x7fffffffda58,
__n=18446741874689290911) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/bits/stl_vector.h:185
#11 0x0000000000b2acf1 in std::__cxx1998::_Vector_base<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_Vector_base (this=0x7fffffffda58,
__n=18446741874689290911, __a=...) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/bits/stl_vector.h:136
#12 0x0000000000b29c9c in std::__cxx1998::vector<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::vector (this=0x7fffffffda58,
__x=std::__cxx1998::vector of length -2199020260704, capacity -2199020259433 = {...}) at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/bits/stl_vector.h:320
#13 0x0000000000b29449 in std::__debug::vector<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::vector (this=0x7fffffffda40)
at /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/debug/vector:193
#14 0x0000000000b294ef in CppUnit::TestSuiteBuilderContextBase::TestSuiteBuilderContextBase (this=0x7fffffffda20) at /usr/include/cppunit/extensions/TestSuiteBuilderContext.h:29
#15 0x0000000000b29515 in CppUnit::TestSuiteBuilderContext<Types_Decimal>::TestSuiteBuilderContext (this=0x7fffffffda20, contextBase=...) at /usr/include/cppunit/extensions/TestSuiteBuilderContext.h:106
#16 0x0000000000b28a16 in Types_Decimal::addTestsToSuite (baseContext=...) at ./Tests/../../pCpp/CppUnitTests/Types_Decimal.hpp:10
#17 0x0000000000b28caa in Types_Decimal::suite () at ./Tests/../../pCpp/CppUnitTests/Types_Decimal.hpp:12
#18 0x0000000000b2871f in main () at Types_Decimal.cpp:8
There is no problem with test file itself, because I made no changes to it, and lots of test were working for long time.
After looking into stack trace, I'm pretty curious what happened on frame #12: __x=std::**__cxx1998**::vector of length **-2199020260704**, capacity **-2199020259433** = {...}
Why there is cxx1998? Both length and capacity looks pretty insane (uninitialized?).
TestSuiteBuilderContext.h:29:
void
TestSuiteBuilderContextBase::addTest( Test *test )
{
m_suite.addTest( test ); //line 29
}
TestSuite.cpp:
/// Adds a test to the suite.
void
TestSuite::addTest( Test *test )
{
m_tests.push_back( test );
}
I came up with partial solution.
It looks like the compile option:
-D_GLIBCXX_DEBUG
Was causing the problem. After removing it - tests run succesfully.
For some reason only in debug mode (with flags -g3) I have a segmentation fault with Boost Locale format function.
// at ../../source/EntryPoint/Application.cpp:110
logInfo("sdfsdf");
which internally without any transformations uses boost::locale::format
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff3a893c3 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/lib/libstdc++.so.6
(gdb) bt
#0 0x00007ffff3a893c3 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/lib/libstdc++.so.6
#1 0x0000000000d8392b in boost::locale::details::formattible<char>::write<std::string> (output=..., ptr=0x7fffffffd340)
at /usr/include/boost/locale/format.hpp:92
#2 0x0000000000d837b6 in boost::locale::details::operator<< (out=..., fmt=...)
at /usr/include/boost/locale/format.hpp:78
#3 0x0000000000d8319e in boost::locale::basic_format<char>::format_output (
this=0x7fffffffd410, out=..., sformat="[{1} | {2}]: ({3}, {4})")
at /usr/include/boost/locale/format.hpp:395
#4 0x0000000000d82b45 in boost::locale::basic_format<char>::write (
this=0x7fffffffd410, out=...) at /usr/include/boost/locale/format.hpp:269
#5 0x0000000000d8277f in boost::locale::basic_format<char>::str (
this=0x7fffffffd410, loc=...) at /usr/include/boost/locale/format.hpp:254
#6 0x0000000000d823eb in Uni::Logging::Private::Formatter::_format<std::string&, std::string&, char const*&, int const&> (
this=0x135afa0 <Uni::Logging::Private::Formatter::get()::_instance>,
message="[{1} | {2}]: ({3}, {4})") at /opt/Uni/source/Logging/format.hpp:30
#7 0x0000000000d8221b in Uni::Logging::Private::Formatter::format<std::string&, std::string&, char const*&, int const&> (message="[{1} | {2}]: ({3}, {4})")
at /opt/Uni/source/Logging/format.hpp:19
---Type <return> to continue, or q <return> to quit---
#8 0x0000000000d8210e in Uni::Logging::format<std::string&, std::string&, char const*&, int const&> (message="[{1} | {2}]: ({3}, {4})")
at /opt/Uni/source/Logging/format.hpp:77
#9 0x0000000000e465a3 in Uni::Logging::SimpleLogger::log<>(int const&, char const*, int const&, std::string const&) (
this=0x135b048 <_ZL30Uni_Logging_globalSimpleLogger>,
severity=#0x7fffffffd76c: 2,
notifiedFilePath=0x103bcd8 "../../source/EntryPoint/Application.cpp",
notifiedLineNumber=#0x7fffffffd768: 110, message="sdfsdf")
at /opt/Uni/source/Logging/SimpleLogger.hpp:49
#10 0x0000000000e8f753 in FsiSimulation::EntryPoint::ApplicationPrivateImplementation::ApplicationPrivateImplementation (this=0x13662d0, in=0x7fffffffd820,
argc_=#0x7fffffffd81c: 1, argv_=0x7fffffffd938)
at ../../source/EntryPoint/Application.cpp:110
#11 0x0000000000e8b72b in FsiSimulation::EntryPoint::Application::Application (
this=0x7fffffffd820, argc=#0x7fffffffd81c: 1, argv=0x7fffffffd938)
at ../../source/EntryPoint/Application.cpp:158
#12 0x0000000000e8b517 in main (argc=1, argv=0x7fffffffd938)
at ../../source/EntryPoint/main.cpp:7
Once again with the same code I don't have any segmentation faults in release mode. Any ideas how to track the problem?
I'm trying to use Clang and I'm having issues with its reference-counting mechanism.
Whenever I try to assign a CompilerInvocation to a CompilerInstance, at runtime I get an error:
clangjit(13823,0x7fff7646f310) malloc: *** error for object 0x103002c00: pointer being freed was not allocated
This is a minimal program that reproduces the issue:
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
using namespace clang;
int main(int argc, const char* const *argv) {
CompilerInstance* CI = new CompilerInstance();
CI->setInvocation(new CompilerInvocation());
}
CompilerInstance internally does reference counting using:
IntrusiveRefCntPtr<CompilerInvocation> Invocation;
and the setter is defined as:
void CompilerInstance::setInvocation(CompilerInvocation *Value) {
Invocation = Value;
}
(I have no control over either of these since they come from Clang).
This is the stack trace at the point of failure:
#0 0x00007fff8d097866 in __pthread_kill ()
#1 0x00007fff8df2635c in pthread_kill ()
#2 0x00007fff8d03ab1a in abort ()
#3 0x00007fff8485807f in free ()
#4 0x0000000100002678 in std::__1::allocator<std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*> >::deallocate(std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*, unsigned long) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1632
#5 0x000000010000266c in std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*> > >::deallocate(std::__1::allocator<std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*> >&, std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*, unsigned long) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:1443
#6 0x0000000100002654 in std::__1::__tree<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::destroy(std::__1::__tree_node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, void*>*) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1446
#7 0x0000000100002551 in ~__tree at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1433
#8 0x00000001000024f5 in ~__tree at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tree:1432
#9 0x00000001000024d5 in ~set at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/set:398
#10 0x0000000100002325 in ~set at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/set:398
#11 0x00000001000022f5 in ~SmallSet at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/SmallSet.h:31
#12 0x00000001000022c5 in ~SmallSet at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/SmallSet.h:31
#13 0x000000010000229e in ~SetVector at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/SetVector.h:37
#14 0x0000000100001de5 in ~SetVector at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/SetVector.h:37
#15 0x0000000100001d55 in ~HeaderSearchOptions at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/clang/Lex/HeaderSearchOptions.h:45
#16 0x0000000100001d25 in ~HeaderSearchOptions at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/clang/Lex/HeaderSearchOptions.h:45
#17 0x0000000100001cf3 in llvm::RefCountedBase<clang::HeaderSearchOptions>::Release() const at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/IntrusiveRefCntPtr.h:54
#18 0x0000000100001c45 in llvm::IntrusiveRefCntPtrInfo<clang::HeaderSearchOptions>::release(clang::HeaderSearchOptions*) at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/IntrusiveRefCntPtr.h:89
#19 0x0000000100001c1d in llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions>::release() at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/IntrusiveRefCntPtr.h:178
#20 0x0000000100001bd1 in ~IntrusiveRefCntPtr at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/IntrusiveRefCntPtr.h:148
#21 0x0000000100001315 in ~IntrusiveRefCntPtr at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/llvm/ADT/IntrusiveRefCntPtr.h:148
#22 0x0000000100001297 in ~CompilerInvocationBase at /Users/juancn/Downloads/clang+llvm-3.4.1-x86_64-apple-darwin10.9/include/clang/Frontend/CompilerInvocation.h:52
#23 0x0000000100254435 in clang::CompilerInstance::setInvocation(clang::CompilerInvocation*) ()
#24 0x0000000100000ea4 in main at /Users/juancn/projects/clangjit/clangjit/clangjit/main.cpp:7
What I don't understand is why setInvocation() is calling the destructor on CompilerInvocationBase which seems to be the reason of the failure (my C++ is a bit rusty, so it's quite likely that I missing something obvious).
UPDATE: I just found that just deleting the object causes the issue:
CompilerInvocation* CI = new CompilerInvocation;
delete CI;
So it looks like a bug in Clang. I still haven't found a way to work around it.
I figured it out (sort of). I was linking to clang binaries for OSX (clang+llvm-3.4.1-x86_64-apple-darwin10.9) but it seems something was off with them.
I rebuilt Clang + LLVM from scratch and used the locally built libraries instead. That solved the issue.