wangyu5 / googlemock

Automatically exported from code.google.com/p/googlemock
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Infinite Loop when calling a mock function that takes boost::filesystem::path as parameter #170

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Minimal example:

---------------------
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <boost/filesystem.hpp>

class MyMock {
public:
  MOCK_METHOD1(func, void(const boost::filesystem::path &path));
};

TEST(MyTest, mockTest) {
  MyMock mock;
  mock.func(boost::filesystem::path("/myfile"));
}
-------------------

When running this test (using gtest 1.7.0 and gmock 1.7.0 on linux 64bit with 
g++ (Ubuntu 4.9.1-16ubuntu6)), it aborts with a SIGSEV.
gdb shows that the SIGSEV is raised in malloc(), while the stack is very large 
and contains a short periodic set of functions calling each other in a circle. 
I assume there is an infinite loop.

The interesting part of the stacktrace is here:

#0  _int_malloc (av=0x7ffff703a760 <main_arena>, bytes=26) at malloc.c:3302
#1  0x00007ffff6cff1e0 in __GI___libc_malloc (bytes=26) at malloc.c:2891
#2  0x00007ffff72b7688 in operator new(unsigned long) () from 
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff731b669 in std::string::_Rep::_S_create(unsigned long, unsigned 
long, std::allocator<char> const&) () from 
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff731b6f4 in std::string::_M_mutate(unsigned long, unsigned long, 
unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff731bd2e in std::string::_M_replace_safe(unsigned long, unsigned 
long, char const*, unsigned long) () from 
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff731d1f9 in std::string::replace(unsigned long, unsigned long, 
char const*, unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff7779821 in boost::filesystem::path::begin() const () from 
/usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.55.0
#8  0x00000000004c3cd4 in 
testing::internal::DefaultPrintTo<boost::filesystem::path> (container=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:275
#9  0x00000000004c3846 in testing::internal::PrintTo<boost::filesystem::path> 
(value=..., os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:376
#10 0x00000000004c2ea6 in 
testing::internal::UniversalPrinter<boost::filesystem::path>::Print (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:600
#11 0x00000000004c237d in 
testing::internal::UniversalPrint<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:756
#12 0x00000000004c3d37 in 
testing::internal::DefaultPrintTo<boost::filesystem::path> (container=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:287
#13 0x00000000004c3846 in testing::internal::PrintTo<boost::filesystem::path> 
(value=..., os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:376
#14 0x00000000004c2ea6 in 
testing::internal::UniversalPrinter<boost::filesystem::path>::Print (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:600
#15 0x00000000004c237d in 
testing::internal::UniversalPrint<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:756
#16 0x00000000004c3d37 in 
testing::internal::DefaultPrintTo<boost::filesystem::path> (container=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:287

[...many more repetitions of these lines..]

#116387 0x00000000004c237d in 
testing::internal::UniversalPrint<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:756
#116388 0x00000000004c3d37 in 
testing::internal::DefaultPrintTo<boost::filesystem::path> (container=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:287
#116389 0x00000000004c3846 in 
testing::internal::PrintTo<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:376
#116390 0x00000000004c2ea6 in 
testing::internal::UniversalPrinter<boost::filesystem::path>::Print (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:600
#116391 0x00000000004c237d in 
testing::internal::UniversalPrint<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:756
#116392 0x00000000004c3d37 in 
testing::internal::DefaultPrintTo<boost::filesystem::path> (container=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:287
#116393 0x00000000004c3846 in 
testing::internal::PrintTo<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:376
#116394 0x00000000004c2ea6 in 
testing::internal::UniversalPrinter<boost::filesystem::path>::Print (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:600
#116395 0x00000000004c237d in 
testing::internal::UniversalPrint<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:756
#116396 0x00000000004c3d37 in 
testing::internal::DefaultPrintTo<boost::filesystem::path> (container=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:287
#116397 0x00000000004c3846 in 
testing::internal::PrintTo<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:376
#116398 0x00000000004c2ea6 in 
testing::internal::UniversalPrinter<boost::filesystem::path>::Print (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:600
#116399 0x00000000004c237d in 
testing::internal::UniversalPrint<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:756
#116400 0x00000000004c3d37 in 
testing::internal::DefaultPrintTo<boost::filesystem::path> (container=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:287
#116401 0x00000000004c3846 in 
testing::internal::PrintTo<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:376
#116402 0x00000000004c2ea6 in 
testing::internal::UniversalPrinter<boost::filesystem::path>::Print (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:600
#116403 0x00000000004c237d in 
testing::internal::UniversalPrint<boost::filesystem::path> (value=..., 
os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:756
#116404 0x00000000004c22d0 in 
testing::internal::UniversalPrinter<boost::filesystem::path const&>::Print 
(value=..., os=0x7fffffffd720) at 
/home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/
gtest-printers.h:668
#116405 0x00000000004c0d81 in 
testing::internal::TuplePrefixPrinter<1ul>::PrintPrefixTo<std::tuple<boost::file
system::path const&> > (t=std::tuple containing = {...}, os=0x7fffffffd720)
    at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/gtest-printers.h:810
#116406 0x00000000004bfe71 in 
testing::internal::PrintTupleTo<std::tuple<boost::filesystem::path const&> > 
(t=std::tuple containing = {...}, os=0x7fffffffd720)
    at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/gtest-printers.h:827
#116407 0x00000000004bd1e5 in 
testing::internal::PrintTo<boost::filesystem::path const&> (t=std::tuple 
containing = {...}, os=0x7fffffffd720)
    at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/gtest-printers.h:503
#116408 0x00000000004b8eaa in 
testing::internal::UniversalPrinter<std::tuple<boost::filesystem::path const&> 
>::Print (value=std::tuple containing = {...}, os=0x7fffffffd720)
    at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/gtest-printers.h:600
#116409 0x00000000004b66a6 in 
testing::internal::UniversalPrint<std::tuple<boost::filesystem::path const&> > 
(value=std::tuple containing = {...}, os=0x7fffffffd720)
    at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gtest/src/gtest/include/gtest/gtest-printers.h:756
#116410 0x00000000004b4e8b in testing::internal::FunctionMockerBase<void 
(boost::filesystem::path const&)>::UntypedDescribeUninterestingCall(void 
const*, std::ostream*) const (this=0x7fffffffd950, untyped_args=0x7fffffffd8f0, 
    os=0x7fffffffd720) at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gmock/src/gmock/include/gmock/gmock-spec-builders.h:1604
#116411 0x000000000050204d in 
testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void const*) ()
#116412 0x00000000004af8af in testing::internal::FunctionMockerBase<void 
(boost::filesystem::path 
const&)>::InvokeWith(std::tuple<boost::filesystem::path const&> const&) 
(this=0x7fffffffd950, args=std::tuple containing = {...})
    at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gmock/src/gmock/include/gmock/gmock-spec-builders.h:1529
#116413 0x00000000004ad301 in testing::internal::FunctionMocker<void 
(boost::filesystem::path const&)>::Invoke(boost::filesystem::path const&) 
(this=0x7fffffffd950, a1=...)
    at /home/heinzi/workspace_cpp/cryfs/build.debug/test/gmock/src/gmock/include/gmock/gmock-generated-function-mockers.h:97
#116414 0x00000000004c8d7f in MyMock::func (this=0x7fffffffd950, gmock_a1=...) 
at /home/heinzi/workspace_cpp/cryfs/src/test/fspp/test.cpp:7
---Type <return> to continue, or q <return> to quit---
#116415 0x00000000004c8b84 in MyTest_mockTest_Test::TestBody (this=0x75bd10) at 
/home/heinzi/workspace_cpp/cryfs/src/test/fspp/test.cpp:12
#116416 0x00000000004f34a2 in void 
testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, 
void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#116417 0x00000000004ee2b7 in void 
testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, 
void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#116418 0x00000000004d429b in testing::Test::Run() ()
#116419 0x00000000004d4b1b in testing::TestInfo::Run() ()
#116420 0x00000000004d51f0 in testing::TestCase::Run() ()
#116421 0x00000000004dbe42 in testing::internal::UnitTestImpl::RunAllTests() ()
#116422 0x00000000004f4a65 in bool 
testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::Uni
tTestImpl, bool>(testing::internal::UnitTestImpl*, bool 
(testing::internal::UnitTestImpl::*)(), char const*) ()
#116423 0x00000000004ef14f in bool 
testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTe
stImpl, bool>(testing::internal::UnitTestImpl*, bool 
(testing::internal::UnitTestImpl::*)(), char const*) ()
#116424 0x00000000004da96e in testing::UnitTest::Run() ()
#116425 0x00000000004fe856 in RUN_ALL_TESTS() ()
#116426 0x00000000004fe7f1 in main ()

Original issue reported on code.google.com by heinzis...@gmail.com on 18 Nov 2014 at 6:27

GoogleCodeExporter commented 9 years ago
btw I'm using libboost-filesystem in version 1.55

Original comment by heinzis...@gmail.com on 18 Nov 2014 at 6:29

GoogleCodeExporter commented 9 years ago
Can you make an even more minimal example that doesn't depend on Boost?
I'd like to know what it is about boost::filesystem::path that makes this 
happen.

Original comment by billydon...@google.com on 18 Nov 2014 at 6:33

GoogleCodeExporter commented 9 years ago
I tried to, but gave up after some hours. It is quite complicated to resolve 
all the inner boost dependencies, boost::filesystem::path is having.

Original comment by heinzis...@gmail.com on 18 Nov 2014 at 8:12

GoogleCodeExporter commented 9 years ago
I have this bug too.
The problem in function DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), 
value, os); [gmock-printers.h]. This function calls infinity times, because it 
desides that boost::filesystem::path is container (has cons_iterator), then 
takes first element: it = container.begin(), and then calls DefaultPrintTo(..., 
*it, ) again (subsequented call) - and we have infifnity calls loop, because 
the value_type of path iterator is - path !!!! (we have infinity nested 
containers)

Original comment by ibez...@gmail.com on 23 Apr 2015 at 3:29

GoogleCodeExporter commented 9 years ago
This bug can also be triggered in Visual Studio 2012 with boost 1.51 gmock 
1.7.0.

You can work around this bug if you define a PrintTo function. Defining a 
PrintTo function is described in 
https://code.google.com/p/googletest/wiki/AdvancedGuide#Teaching_Google_Test_How
_to_Print_Your_Values

I use the following PrintTo function:

namespace boost {
    namespace filesystem {
        void PrintTo(const boost::filesystem::path& path, std::ostream* os) {
            *os << path;
        }
    }
}

Original comment by hb2...@googlemail.com on 20 May 2015 at 1:32