Skip to content

Gtest SEH Exception #709

Closed
Closed

Description

@SimonEbner

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?

Activity

  1. nlohmann commented on Aug 24, 2017

    @nlohmann
    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?

  2. SimonEbner commented on Aug 24, 2017

    @SimonEbner
    Author

    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.

  3. theodelrieu commented on Aug 24, 2017

    @theodelrieu
    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();
    }
    }
  4. gregmarr commented on Aug 24, 2017

    @gregmarr
    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

  5. gregmarr commented on Aug 24, 2017

    @gregmarr
    Contributor

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

  6. gregmarr commented on Aug 24, 2017

    @gregmarr
    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.

  7. SimonEbner commented on Aug 24, 2017

    @SimonEbner
    Author

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

  8. pboettch commented on Aug 25, 2017

    @pboettch
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions