Re: [eigen] Re: GTest occasionally segfaults with Quaterniond typedef?

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Update to previous, only two copies of the same unit test appear to be required to reproduce the segfault for me. 

Attached here is a minimal set of files for me to reproduce what I am seeing.

This test at least seems to fail 100% of the time for me so far.

As a solution, I can keep placing the "EIGEN_MAKE_ALIGNED_OPERATOR_NEW" in all of my unit tests.  Obviously this appears to be needed, but is this expected?

--
Respectfully,
 
Mark C. Sauder
Systems and Applications Engineer, M.S. M.E.
801-698-8786

On Wed, May 25, 2016 at 8:35 AM, Mark Sauder <mcsauder@xxxxxxxxx> wrote:
Thanks Gael and Ryan,

To reproduce the issue I have to include the test along with others and comment out "EIGEN_MAKE_ALIGNED_OPERATOR_NEW".  Upon seeing the segfault occurrences, (within the larger unit test framework), it is remedied by uncommenting "EIGEN_MAKE_ALIGNED_OPERATOR_NEW"

Just by building what I attached I have not been able to reproduce the segfault, but pasting that same unit test (unaltered) alongside other unit tests causes that test and only that test to segfault occasionally.

I think I've figured out a way to reproduce what I see with just the attached files.  You should be able to simply copy/paste and run the compile script then ./buid/bin/unitTest.

Perhaps this can shed more light on things.

--
Respectfully,
 
Mark C. Sauder
Systems and Applications Engineer, M.S. M.E.

On Wed, May 25, 2016 at 6:42 AM, Ryan Pavlik <ryan.pavlik@xxxxxxxxx> wrote:

I don't recall exactly how the Google test fixture macros work, but could they be deriving from your fixture class (and not having the aligned operator new for the derived class)?

A check, or at least a workaround, would be to put all alignment sensitive members in essentially a pimpl structure allocated by your fixture class with new or make unique. I end up putting a lot of my eigen types in such structures if I have any doubt about how or where they'll be used and if the alignment requirements will be met. Presumably the "needs other tests" is a semi spurious prerequisite: required just to cause an allocation at an unaligned address.

Ryan


On Wed, May 25, 2016, 4:12 AM Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:

Hi,

just to be sure, to reproduce the issue you need both "EIGEN_MAKE_ALIGNED_OPERATOR_NEW" *and* to include this test with others?

So it theory we should not be able to reproduce, right? (I tried and I cannot)

Could it be that operator new is redefined somewhere? or that you are linking to a library providing a custom malloc()? or maybe the instance of the QuaternionTest object is not created through operator new but through a malloc and placement new?


gael


On Wed, May 25, 2016 at 7:42 AM, Mark Sauder <mcsauder@xxxxxxxxx> wrote:
P.P.S. here is a backtrace of the test executed/segfaulting within my unit test framework:

[----------] 1 test from QuaternionTest
[ RUN      ] QuaternionTest.assignment

Program received signal SIGSEGV, Segmentation fault.
QuaternionTest::SetUp (this=0x72f8f0)
    at /home/mark/code/GPC-UAV/test/QuaternionTest.cpp:21
21            vector1 = Eigen::Vector4d(1., 1., 1., 1.);
(gdb) backtrace
#0  QuaternionTest::SetUp (this=0x72f8f0)
    at /home/mark/code/GPC-UAV/test/QuaternionTest.cpp:21
#1  0x00000000004ce94a in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#2  0x00000000004c957b in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#3  0x00000000004ae2c7 in testing::Test::Run() ()
#4  0x00000000004aebc2 in testing::TestInfo::Run() ()
#5  0x00000000004af2b1 in testing::TestCase::Run() ()
#6  0x00000000004b638e in testing::internal::UnitTestImpl::RunAllTests() ()
#7  0x00000000004cff21 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#8  0x00000000004ca429 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#9  0x00000000004b4e2c in testing::UnitTest::Run() ()
#10 0x00000000004a8117 in RUN_ALL_TESTS() ()
#11 0x00000000004a80b1 in main ()



-
​Mark​

On Tue, May 24, 2016 at 11:13 PM, Mark Sauder <mcsauder@xxxxxxxxx> wrote:
P.S.

O.S.: Ubuntu 16.04, (fresh install, not upgraded from 15.10; re-installed to see if it fixed the issue), all packages updated and upgraded.  Intel® Core™ i7-4700HQ CPU @ 2.40GHz × 8, 64-bit

Thanks for any input on my gremlin! :)

--
Respectfully,
 
Mark C. Sauder
Systems and Applications Engineer, M.S. M.E.

On Tue, May 24, 2016 at 8:06 PM, Mark Sauder <mcsauder@xxxxxxxxx> wrote:
Hi Eigen,

I've recently had some troubles that Gael G. and Christoph H. have patiently helped me with, (thank you both very much for your time), but I still have an issue that I wonder if anyone else might be seeing as well.  Files are attached, the scenario is below, along with code you can copy/paste into files to attempt to reproduce my gremlin in case the attached files are stripped away.

I use GoogleTest for unit testing, and it works great, but a few weeks ago I started having trouble with segfault issues caused by misalignment in other parts of my project and I now see it in GTest unit tests as well... but the worst part is that the GTest segfault only happens about 50% of the time, to which I have no explanation.

If I employ the following test in addition to the other unit tests in the framework of my project, this test will segfault part of the time, not every time, just sometimes, which is what I am hoping to understand.  However, if I simply test only the code below, using the CMakeLists.txt following and nothing else, I can't get it to fail even once.

If I uncomment the "EIGEN_MAKE_ALIGNED_OPERATOR_NEW" line, when this test is one of many other unit tests, it never segfaults within my unit test framework.  It is clearly an alignment issue, however, I would love to know why it fails sometimes and not every time.

So my question is... Does anyone else see anomalous segfaults using Eigen and GoogleTest like this?  If you add this unit test to your unit test suites, does it occasionally segfault but not always?

(Files are attached, but I don't know if they'll get stripped in the mailing list.)

Thanks for any advice Eigen!

-Mark  Sauder


CODE:


Here is the unit test I can get to segfault about 50% of the time, it is simple enough and accomplished nothing outside of creating a Vector4d and a Quaterniond and initializing them.  Following that is my
CMakeLists.txt file content, (just "mkdir build", "cd build", "cmake ..", "cd ..", "make" and the resulting unit test will always pass... but as one of your other unit tests as with my project, I would like to hear back if it segfaults occasionally.  Thanks again.

______________________________________________________

#include "gtest/gtest.h"

#include <Eigen/Dense>
#include <Eigen/Geometry>
#include <iostream>

class QuaternionTest
    : public ::testing::Test
{
public:
    //EIGEN_MAKE_ALIGNED_OPERATOR_NEW
protected:

    virtual void SetUp()
    {
        vector1 = Eigen::Vector4d(1.., 1., 1., 1.);
        quaternion1 = Eigen::Quaterniond::Identity();
    }

    Eigen::Vector4d vector1;
    Eigen::Quaterniond quaternion1;
};

TEST_F(QuaternionTest, assignment)
{  
}



________________________________________________________



CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)

PROJECT(unitTesting)

INCLUDE(ExternalProject)

SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

FIND_PACKAGE(Eigen3)
FIND_PACKAGE(Threads)

ADD_DEFINITIONS(
  -O3
  -DAPL=0
  -DIBM=0
  -DLIN=1
  -DNDEBUG
  -DXPLM200
  -DXPLM210
  -Wall
  -Wextra
  -fvisibility=hidden
  -fPIC
  -g
  -march=native
  -pedantic
  -pthread
  )

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -fms-extensions")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fms-extensions")

SET(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
EXTERNALPROJECT_ADD(GTestExternal
  PREFIX             "${GTEST_PREFIX}"
  URL https://googletest.googlecode.com/files/gtest-1.7.0.zip
  URL_HASH SHA1=f85f6d2481e2c6c4a18539e391aa4ea8ab0394af
  INSTALL_COMMAND ""
)

SET(LIBPREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
SET(LIBSUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
SET(GTEST_LOCATION "${GTEST_PREFIX}/src/GTestExternal-build")
SET(GTEST_LIBRARY  "${GTEST_LOCATION}/${LIBPREFIX}gtest${LIBSUFFIX}")
SET(GTEST_MAINLIB  "${GTEST_LOCATION}/${LIBPREFIX}gtest_main${LIBSUFFIX}")

ADD_LIBRARY(GTest IMPORTED STATIC GLOBAL)
SET_TARGET_PROPERTIES(GTest PROPERTIES
    IMPORTED_LOCATION
    "${GTEST_LIBRARY}"
    IMPORTED_LINK_INTERFACE_LIBRARIES
    "${CMAKE_THREAD_LIBS_INIT}"
    )

ADD_LIBRARY(GTestMain IMPORTED STATIC GLOBAL)
SET_TARGET_PROPERTIES(GTestMain PROPERTIES
    IMPORTED_LOCATION
    "${GTEST_MAINLIB}"
    IMPORTED_LINK_INTERFACE_LIBRARIES
    "${GTEST_LIBRARY};${CMAKE_THREAD_LIBS_INIT}"
    )

ADD_DEPENDENCIES(GTest GTestExternal)
ADD_DEPENDENCIES(GTestMain GTestExternal)

EXTERNALPROJECT_GET_PROPERTY(GTestExternal source_dir)

INCLUDE_DIRECTORIES(
  eigen
  ${EIGEN3_INCLUDE_DIR}
  ${source_dir}/include
)

SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LD_VERSION_SCRIPT_FLAG}")

ADD_EXECUTABLE(unitTests
  QuaternionTest.cpp
  )

TARGET_LINK_LIBRARIES(unitTests
  GTestMain
)

_________________________________________________________________________








CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)

PROJECT(unitTesting)

INCLUDE(ExternalProject)

SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

FIND_PACKAGE(Eigen3)
FIND_PACKAGE(Threads)

ADD_DEFINITIONS(
  -O3
  -DAPL=0
  -DIBM=0
  -DLIN=1
  -DNDEBUG
  -DXPLM200
  -DXPLM210
  -Wall
  -Wextra
  -fvisibility=hidden
  -fPIC
  -g
  -march=native
  -pedantic
  -pthread
  )

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11 -fms-extensions")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fms-extensions")

SET(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
EXTERNALPROJECT_ADD(GTestExternal
  PREFIX             "${GTEST_PREFIX}"
  URL https://googletest.googlecode.com/files/gtest-1.7.0.zip
  URL_HASH SHA1=f85f6d2481e2c6c4a18539e391aa4ea8ab0394af
  INSTALL_COMMAND ""
)

SET(LIBPREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
SET(LIBSUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
SET(GTEST_LOCATION "${GTEST_PREFIX}/src/GTestExternal-build")
SET(GTEST_LIBRARY  "${GTEST_LOCATION}/${LIBPREFIX}gtest${LIBSUFFIX}")
SET(GTEST_MAINLIB  "${GTEST_LOCATION}/${LIBPREFIX}gtest_main${LIBSUFFIX}")

ADD_LIBRARY(GTest IMPORTED STATIC GLOBAL)
SET_TARGET_PROPERTIES(GTest PROPERTIES
    IMPORTED_LOCATION
    "${GTEST_LIBRARY}"
    IMPORTED_LINK_INTERFACE_LIBRARIES
    "${CMAKE_THREAD_LIBS_INIT}"
    )

ADD_LIBRARY(GTestMain IMPORTED STATIC GLOBAL)
SET_TARGET_PROPERTIES(GTestMain PROPERTIES
    IMPORTED_LOCATION
    "${GTEST_MAINLIB}"
    IMPORTED_LINK_INTERFACE_LIBRARIES
    "${GTEST_LIBRARY};${CMAKE_THREAD_LIBS_INIT}"
    )

ADD_DEPENDENCIES(GTest GTestExternal)
ADD_DEPENDENCIES(GTestMain GTestExternal)

EXTERNALPROJECT_GET_PROPERTY(GTestExternal source_dir)

INCLUDE_DIRECTORIES(
  eigen
  ${EIGEN3_INCLUDE_DIR}
  ${source_dir}/include
)

SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LD_VERSION_SCRIPT_FLAG}")

ADD_EXECUTABLE(unitTests
  QuaternionTest.cpp
  QuaternionTest1.cpp
  )

TARGET_LINK_LIBRARIES(unitTests
  GTestMain
)

Attachment: compile.sh
Description: Bourne shell script

/**
 * @file QuaternionTest.cpp
 * @copyright Grey Point Corporation
 */

#include "gtest/gtest.h"

#include <Eigen/Dense>
#include <Eigen/Geometry>
#include <iostream>

class QuaternionTest
    : public ::testing::Test
{
public:
    // EIGEN_MAKE_ALIGNED_OPERATOR_NEW
protected:

    virtual void SetUp()
    {
        vector1 = Eigen::Vector4d(1., 1., 1., 1.);
        quaternion1 = Eigen::Quaterniond::Identity();
    }

    Eigen::Vector4d vector1;
    Eigen::Quaterniond quaternion1;
};

TEST_F(QuaternionTest, assignment)
{   
    // ASSERT_EQ(vector1, Eigen::Vector4d(1., 1., 1., 1.));

    // ASSERT_EQ(quaternion1.w(), 1.0);
    // ASSERT_EQ(quaternion1.y(), 0.0);
    // ASSERT_EQ(quaternion1.x(), 0.0);
    // ASSERT_EQ(quaternion1.z(), 0.0);
}
/**
 * @file QuaternionTest.cpp
 * @copyright Grey Point Corporation
 */

#include "gtest/gtest.h"

#include <Eigen/Dense>
#include <Eigen/Geometry>
#include <iostream>

class QuaternionTest
    : public ::testing::Test
{
public:
    // EIGEN_MAKE_ALIGNED_OPERATOR_NEW
protected:

    virtual void SetUp()
    {
        vector1 = Eigen::Vector4d(1., 1., 1., 1.);
        quaternion1 = Eigen::Quaterniond::Identity();
    }

    Eigen::Vector4d vector1;
    Eigen::Quaterniond quaternion1;
};

TEST_F(QuaternionTest, assignment1)
{   
    // ASSERT_EQ(vector1, Eigen::Vector4d(1., 1., 1., 1.));

    // ASSERT_EQ(quaternion1.w(), 1.0);
    // ASSERT_EQ(quaternion1.y(), 0.0);
    // ASSERT_EQ(quaternion1.x(), 0.0);
    // ASSERT_EQ(quaternion1.z(), 0.0);
}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/