Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gtest SEH Exception #709

Closed
SimonEbner opened this issue Aug 24, 2017 · 8 comments
Closed

Gtest SEH Exception #709

SimonEbner opened this issue Aug 24, 2017 · 8 comments

Comments

@SimonEbner
Copy link

SimonEbner commented Aug 24, 2017

Running the following test using GTest causes an SEH Exception for me using VS 2017 / gcc 5.4

TEST(foo, fail1)
{
    auto obj = json{ {"foo", "bar"} };
    ASSERT_THAT(obj, Eq(obj));
}

MATCHER(IsFooObject, "")
{
    return arg == json{ { "foo", "bar" } };
}

TEST(foo, fail2)
{
    auto obj = json{ { "foo", "bar" } };
    ASSERT_THAT(obj, IsFooObject());
}

These 'simpler' tests, however, work fine.

TEST(foo, success1)
{
    auto obj = json{ { "foo", "bar" } };
    ASSERT_EQ(obj, obj);
}

TEST(foo, success2)
{
    auto obj = json{ { "foo", "bar" } };
    ASSERT_TRUE(obj == obj);
}

I could not find any information on how to make json.hpp together with Gtest work. Is there a chance to make custom matchers (MATCHER_P) work?

@nlohmann
Copy link
Owner

Thanks for reporting. I have no experience with Gtest. Can you post the exact exception/error message, and maybe a complete example program so I can try to reproduce/debug?

@SimonEbner
Copy link
Author

SimonEbner commented Aug 24, 2017

Certainly. So I use the latest version (commit c38baf9858311e2887623465c8be433cfa585d2a) of gtest / gmock from https://github.com/google/googletest. The complete mail file is as follows

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "json.hpp"

using namespace testing;
using namespace nlohmann;

TEST(foo, fail1)
{
      auto obj = json{ {"foo", "bar"} };
      ASSERT_THAT(obj, Eq(obj));
}

MATCHER(IsFooObject, "")
{
      return arg == json{ { "foo", "bar" } };
}

TEST(foo, fail2)
{
      auto obj = json{ { "foo", "bar" } };
      ASSERT_THAT(obj, IsFooObject());
}

TEST(foo, success1)
{
      auto obj = json{ { "foo", "bar" } };
      ASSERT_EQ(obj, obj);
}

TEST(foo, success2)
{
      auto obj = json{ { "foo", "bar" } };
      ASSERT_TRUE(obj == obj);
}

int main(int argc, char** argv)
{
      InitGoogleTest(&argc, argv);
      return RUN_ALL_TESTS();
}

which I compile using g++ json_test.cc --std=c++11 -lgtest -lgmock -lpthread -g. I can run the successful tests using ./a.out --gtest_filter="*success*" whereas the other tests fail with ./a.out --gtest_filter=*fail1* (or 2 respectively). When I run the test with gdb I get

Starting program: .../a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from foo
[ RUN      ] foo.fail1

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7946d22 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) where
#0  0x00007ffff7946d22 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x00007ffff7947168 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00000000004100d6 in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:381
#3  0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#4  0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#5  0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869
#6  0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#7  0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#8  0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#9  0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869
#10 0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#11 0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#12 0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#13 0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869
#14 0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#15 0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#16 0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#17 0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869
#18 0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#19 0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#20 0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#21 0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869
#22 0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#23 0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#24 0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#25 0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869
#26 0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#27 0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#28 0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#29 0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869
#30 0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#31 0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlo
---Type <return> to continue, or q <return> to quit---

The list goes on forever, so I'm not sure how much of that information is helpful in this issue. Please let me know if you require further information.

@theodelrieu
Copy link
Contributor

We had this issue at work a long time ago (happened with boost::filesystem::path too), this is linked to this GTest issue.

We added this in a TestHelpers.hpp that we include on each test file to avoid breaking ODR.

namespace nlohmann
{
inline void PrintTo(json const& json, std::ostream* os)
{
  *os << json.dump();
}
}

@gregmarr
Copy link
Contributor

Looks like a stack overflow due to infinite recursion. It's these 4 functions repeating over and over.

#10 0x000000000041017c in testing::internal::DefaultPrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (container=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:395
#11 0x000000000040f89d in testing::internal::PrintTo<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:479
#12 0x000000000040ea11 in testing::internal::UniversalPrinter<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> >::Print (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:720
#13 0x000000000040c890 in testing::internal::UniversalPrint<nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer> > (value=..., os=0x7fffffffd4a0) at /usr/local/include/gtest/gtest-printers.h:869

@gregmarr
Copy link
Contributor

Yes, I agree @theodelrieu , and here's a PR to googletest that purports to fix the issue. google/googletest#1186

@gregmarr
Copy link
Contributor

@SimonEbner If you could try out that PR version and report in that PR that it fixes your issue, then that might help the PR get approved.

@SimonEbner
Copy link
Author

awesome, thank you @theodelrieu for the local fix and @gregmarr for pointint out the PR, both solutions work for me.

@pboettch
Copy link
Contributor

I just stumbled upon the same problem simply doing:

nlohmann::json j;
j = 1;
EXPECT_EQ(j, 0);

GoogleTest has (had?) problems printing j in case of test-failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants