sofa-framework / sofa

Real-time multi-physics simulation with an emphasis on medical simulation.
https://www.sofa-framework.org
GNU Lesser General Public License v2.1
871 stars 297 forks source link

Memory leak in Simulation.unload() caused by collision pipeline #3318

Closed ScheiklP closed 1 year ago

ScheiklP commented 1 year ago

Problem

Hi, I discovered a memory leak that seems to be connected to the collision detection pipeline / models.

The scene contains 2 nodes with MechanicalObject and PointCollisionModel. I repeatedly load and unload the scene, first with no collision models, then one collision model, and then two collision models. -> each graph has 3 segments.

import Sofa
import Sofa.Core
import Sofa.Simulation
from enum import Enum

class TestCase(Enum):
    ONE_MODEL = 0
    TWO_MODELS = 1
    NONE = 2

class SimulationHandler:
    def __init__(self):

        self.root_node = Sofa.Core.Node("root")
        self.nodes = createScene(self.root_node, TestCase.NONE)
        Sofa.Simulation.init(self.root_node)

    def step(self):
        Sofa.Simulation.animate(self.root_node, self.root_node.getDt())

    def reload(self, case: TestCase = TestCase.NONE):

        Sofa.Simulation.unload(self.root_node)
        self.root_node = Sofa.Core.Node("root")
        self.nodes = createScene(self.root_node, case)
        Sofa.Simulation.init(self.root_node)

def createScene(root, case: TestCase):
    plugins = [
        "Sofa.Component.Collision.Detection.Algorithm",
        "Sofa.Component.Collision.Detection.Intersection",
    ]
    for plugin in plugins:
        root.addObject("RequiredPlugin", pluginName=plugin, name=plugin)

    root.addObject("DefaultAnimationLoop")
    root.addObject("DefaultPipeline")
    root.addObject("BruteForceBroadPhase")
    root.addObject("BVHNarrowPhase")
    root.addObject("DefaultContactManager")
    root.addObject(
        "LocalMinDistance",
        alarmDistance=5.0,
        contactDistance=0.5,
    )

    node_1 = root.addChild("child_1")
    node_1.addObject("MechanicalObject", position=[0, 0, 0] * 5)

    node_2 = root.addChild("child_2")
    node_2.addObject("MechanicalObject", position=[1, 1, 1] * 5)

    if case == TestCase.ONE_MODEL:
        node_1.addObject("PointCollisionModel")
    elif case == TestCase.TWO_MODELS:
        node_1.addObject("PointCollisionModel")
        node_2.addObject("PointCollisionModel")
    elif case == TestCase.NONE:
        pass

    return node_1, node_2

if __name__ == "__main__":
    simulation = SimulationHandler()

    for i in range(5000):
        simulation.step()
        simulation.reload(case=TestCase.NONE)

    for i in range(5000):
        simulation.step()
        simulation.reload(case=TestCase.ONE_MODEL)

    for i in range(5000):
        simulation.step()
        simulation.reload(case=TestCase.TWO_MODELS)

No components of the collision pipeline: image -> No memory increase, even with two collision models

NewProximity image -> Some memory increase with one and no collision models, STRONG increase with two collision models

LocalMinDistance image -> Some memory increase with one and no collision models, STRONG increase with two collision models

As you can see, there is a memory increase with no collision models and one collision model, but with two collision models, the increase is much stronger. This is why I suspect the leak is somewhere in the pipeline, not the collision models themselves.


Environment

Context

mprof run --python python load_unload_env.py mprof plot ...

I guess @damienmarchal and @hugtalbot would be the right people to annoy with another leak. :D

Cheers, Paul

ScheiklP commented 1 year ago

Could this be caused by DefaultPipeline, BruteForceBroadPhase, BVHNarrowPhase, and DefaultContactManager not having a proper reset() function?

damienmarchal commented 1 year ago

Thanks again @ScheiklP for these investigations !

Normally the reset function is not supposed to have any cleanup results as it is only there to set again (re-set) the component in a previous state.

It is the "cleanup" that is called before removal/deletion of the component from the graph.

ScheiklP commented 1 year ago

Thanks again @ScheiklP for these investigations !

Normally the reset function is not supposed to have any cleanup results as it is only there to set again (re-set) the component in a previous state.

It is the "cleanup" that is called before removal/deletion of the component from the graph.

Most of these components also do not have a cleanup function :D

I adapted the sofaProjectExample to match the python scene above to make memory profiling and debugging a bit easier. Same memory leak occurs.

The code:

#include <sofa/defaulttype/VecTypes.h>

#include <sofa/component/collision/detection/algorithm/BruteForceBroadPhase.h>
#include <sofa/component/collision/detection/algorithm/BVHNarrowPhase.h>
#include <sofa/component/collision/detection/algorithm/DefaultPipeline.h>

#include <sofa/component/collision/detection/intersection/NewProximityIntersection.h>

#include <sofa/component/collision/response/contact/DefaultContactManager.h>

#include <sofa/component/collision/geometry/PointModel.h>

#include <sofa/simulation/graph/DAGNode.h>
#include <sofa/simulation/graph/DAGSimulation.h>
#include <sofa/simulation/graph/init.h>

#include <sofa/simulation/DefaultAnimationLoop.h>

#include <sofa/component/statecontainer/MechanicalObject.h>

#include <sofa/core/objectmodel/Context.h>
#include <sofa/simulation/Node.h>
#include <sofa/simulation/Simulation.h>
#include <SofaComponentAll/initSofaComponentAll.h>

#include <sofa/helper/system/FileRepository.h>
#include <sofa/helper/logging/LoggingMessageHandler.h>
#include <sofa/core/logging/PerComponentLoggingMessageHandler.h>
#include <sofa/helper/BackTrace.h>

using namespace sofa::defaulttype;

using sofa::simulation::Node;
using sofa::simulation::graph::DAGNode;
using sofa::helper::system::DataRepository;

// collision pipeline
using sofa::component::collision::detection::algorithm::DefaultPipeline;
using sofa::component::collision::detection::algorithm::BruteForceBroadPhase;
using sofa::component::collision::detection::algorithm::BVHNarrowPhase;
using sofa::component::collision::detection::intersection::NewProximityIntersection;
using sofa::component::collision::response::contact::DefaultContactManager;
using sofa::component::collision::geometry::PointCollisionModel;

// mechanical object
using sofa::component::statecontainer::MechanicalObject;
using sofa::defaulttype::StdVectorTypes;
using sofa::type::Vec;

using sofa::core::behavior::MechanicalState;
using sofa::core::State;
using sofa::core::objectmodel::New;
using sofa::core::objectmodel::Data;

using sofa::simulation::DefaultAnimationLoop;

int main(int argc, char** argv)
{
    sofa::helper::logging::MessageDispatcher::addHandler(&sofa::helper::logging::MainLoggingMessageHandler::getInstance());
    sofa::helper::logging::MessageDispatcher::addHandler(&sofa::helper::logging::MainPerComponentLoggingMessageHandler::getInstance());
    sofa::helper::logging::MainLoggingMessageHandler::getInstance().activate();

    sofa::helper::BackTrace::autodump();

    sofa::simulation::graph::init();

    sofa::simulation::setSimulation(new sofa::simulation::graph::DAGSimulation());

    for (int i = 0; i < 1000; i++) {

        Node::SPtr groot = sofa::simulation::getSimulation()->createNewGraph("root");
        groot->setGravity({ 0,0,0 });
        groot->setDt(0.02);

        DefaultAnimationLoop::SPtr animationLoop = New<DefaultAnimationLoop>();
        groot->addObject(animationLoop);

        // collision pipeline
        DefaultPipeline::SPtr collisionPipeline = New<DefaultPipeline>();
        collisionPipeline->setName("Collision Pipeline");
        groot->addObject(collisionPipeline);

        // collision detection system
        BruteForceBroadPhase::SPtr broadPhaseDetection = New<BruteForceBroadPhase>();
        broadPhaseDetection->setName("Broad Phase Collision Detection");
        groot->addObject(broadPhaseDetection);

        BVHNarrowPhase::SPtr narrowPhaseDetection = New<BVHNarrowPhase>();
        narrowPhaseDetection->setName("Narrow Phase Collision Detection");
        groot->addObject(narrowPhaseDetection);

        // component to detection intersection
        NewProximityIntersection::SPtr detectionProximity = New<NewProximityIntersection>();
        detectionProximity->setName("Detection Proximity");
        detectionProximity->setAlarmDistance(10.0);
        detectionProximity->setContactDistance(0.5);
        groot->addObject(detectionProximity);

        // contact manager
        DefaultContactManager::SPtr contactManager = New<DefaultContactManager>();
        contactManager->setName("Contact Manager");
        contactManager->setDefaultResponseType("PenalityContactForceField");
        groot->addObject(contactManager);

        // Node 1
        Node::SPtr firstNode = New<DAGNode>();
        firstNode->setName("node 1");

        // Node 2
        Node::SPtr secondNode = New<DAGNode>();
        secondNode->setName("node 2");

        // mechanical objects
        typedef MechanicalObject< Vec3dTypes > MechanicalObject3d;
        MechanicalObject3d::SPtr firstMechanicalObject = New<MechanicalObject3d>();
        firstMechanicalObject->setTranslation(0,0,0);
        firstMechanicalObject->setRotation(0,0,0);
        firstMechanicalObject->setScale(1,1,1);

        MechanicalObject3d::SPtr secondMechanicalObject = New<MechanicalObject3d>();
        secondMechanicalObject->setTranslation(1,1,1);
        secondMechanicalObject->setRotation(0,0,0);
        secondMechanicalObject->setScale(1,1,1);

        PointCollisionModel<sofa::defaulttype::Vec3Types>::SPtr firstPointCollisionModel = New<PointCollisionModel<sofa::defaulttype::Vec3Types>>();
        PointCollisionModel<sofa::defaulttype::Vec3Types>::SPtr secondPointCollisionModel = New<PointCollisionModel<sofa::defaulttype::Vec3Types>>();

        firstNode->addObject(firstMechanicalObject);
        firstNode->addObject(firstPointCollisionModel);
        groot->addChild(firstNode);

        secondNode->addObject(secondMechanicalObject);
        secondNode->addObject(secondPointCollisionModel);
        groot->addChild(secondNode);

        // Init the scene
        sofa::simulation::getSimulation()->init(groot.get());

        firstMechanicalObject->resize(50);
        Data<MechanicalObject3d::VecCoord>& firstdpositions = *firstMechanicalObject->write(sofa::core::VecId::position());
        MechanicalObject3d::VecCoord& firstpositions = *firstdpositions.beginEdit();
        for (int i = 0; i < 50; i++) {
            for (int j = 0; j < 3; j++){
                firstpositions[i][j] = 0.0;
            }
        }
        firstdpositions.endEdit();

        secondMechanicalObject->resize(50);
        Data<MechanicalObject3d::VecCoord>& seconddpositions = *secondMechanicalObject->write(sofa::core::VecId::position());
        MechanicalObject3d::VecCoord& secondpositions = *seconddpositions.beginEdit();
        for (int i = 0; i < 50; i++) {
            for (int j = 0; j < 3; j++){
                secondpositions[i][j] = 1.0;
            }
        }
        seconddpositions.endEdit();

        for (int j = 0; j < 50; j++) {
            sofa::simulation::getSimulation()->animate(groot.get(), groot->getDt());
        }

        sofa::simulation::getSimulation()->unload(groot.get());
    }

    sofa::simulation::graph::cleanup();
    return 0;
}

}

mprof run ./bin/sofaProjectExample_d

image

hugtalbot commented 1 year ago

I echo @damienmarchal , thanks a lot @ScheiklP for these interesting investigations!

your last comment means that it could come from the collisionmodel binding, right?

alxbilger commented 1 year ago

I don't know this part of the code, but it is highly suspicious:

https://github.com/alxbilger/sofa/blob/918cd66008f586575c92c1e068f5c267a952b936/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h#L95

    virtual void addIntersectors(TIntersectionClass* object)
    {
        new TIntersectorClass(object);
    }

addIntersectors (in which there is a new call), is called in the constructors of the proximity intersections (BaseProximityIntersection). I cannot find if this allocation is freed somewhere.

ScheiklP commented 1 year ago

I don't know this part of the code, but it is highly suspicious:

https://github.com/alxbilger/sofa/blob/918cd66008f586575c92c1e068f5c267a952b936/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h#L95

    virtual void addIntersectors(TIntersectionClass* object)
    {
        new TIntersectorClass(object);
    }

addIntersectors (in which there is a new call), is called in the constructors of the proximity intersections (BaseProximityIntersection). I cannot find if this allocation is freed somewhere.

Thanks @alxbilger ! :)

I have a commit here, that puts the created pointers into a map, so that they get cleaned up, if they are created multiple times. https://github.com/sofa-framework/sofa/compare/master...ScheiklP:sofa:fix_unload_memory_leak But it does not fix the leak.

What do you think? Should this still be a PR?

ScheiklP commented 1 year ago

I echo @damienmarchal , thanks a lot @ScheiklP for these interesting investigations!

your last comment means that it could come from the collisionmodel binding, right?

Hi @hugtalbot , The collision models have no explicit binding in SofaPython3 as far as I can see. :(

EDIT: I was just not creating the MechanicalObject correctly. :D -> C++ scene also has the leak.

alxbilger commented 1 year ago

I have a commit here, that puts the created pointers into a map, so that they get cleaned up, if they are created multiple times. master...ScheiklP:sofa:fix_unload_memory_leak But it does not fix the leak.

What do you think? Should this still be a PR?

I don't know enough this part of the code to answer you. For sure it sounds better, but I advise more investigations. Anyway, it's not the leak we are looking for.

damienmarchal commented 1 year ago

Thanks again for the investigation.

I see you are using the raw c++ code to make your scene. Instead of doing that the "hard way" you can use "simplapi" which mimick in c++ de python one. It is in sofa/simulation/graph/simpleapi.h and there are exemple in the code base.

hugtalbot commented 1 year ago

Does this not look suspicious to you guys? https://github.com/sofa-framework/sofa/blob/471a3df6a377f92155f34ab4a75e931ec9559f7f/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/BaseContactMapper.h#L99

@damienmarchal @alxbilger @ScheiklP

ScheiklP commented 1 year ago

Does this not look suspicious to you guys?

https://github.com/sofa-framework/sofa/blob/471a3df6a377f92155f34ab4a75e931ec9559f7f/Sofa/Component/Collision/Response/Mapper/src/sofa/component/collision/response/mapper/BaseContactMapper.h#L99

@damienmarchal @alxbilger @ScheiklP

Indeed it does. :D I did some quick checks by printing a string, when the deconstructor of that class is called, and it seems to get deleted somewhere correctly. :)

hugtalbot commented 1 year ago

alright ;) I quickly search for new in the collision repo!

alxbilger commented 1 year ago

@ScheiklP Here is a branch with a simple object tracker: https://github.com/alxbilger/sofa/tree/objecttracker

It counts the number of creation and destruction for each class managed with the SOFA_CLASS macro. Note that if Y derives from X, it counts both X and Y. Finally, it prints a summary when the program finishes (properly). But I cannot guarantee that more destructions does not happen after the summary (static destruction order depends on construction order and https://en.cppreference.com/w/cpp/language/siof). Is this useful to you? Can you spot which component is not destroyed?

The diff is here: https://github.com/sofa-framework/sofa/compare/master...alxbilger:sofa:objecttracker?expand=1

For example, there are a couple of components in caduceus where I see a difference between nb of allocations and destructions.

ScheiklP commented 1 year ago

@alxbilger Thanks!

Before unload
Total Base: 31970 31936 Diff: 34
After unload
Total Base: 31970 31939 Diff: 31
Before unload
Total Base: 32002 31968 Diff: 34
After unload
Total Base: 32002 31971 Diff: 31
Before cleanup
Total Base: 32002 32000 Diff: 2
Total Base: 32002 32000 Diff: 2
After cleanup
Total Base: 32002 32001 Diff: 1

So that looks ok, right? At least the difference is more or less constant. :D But the tracker only tracks actual objects, right? So Creators, Factories, and others that do not inherit from base are not tracked.

Could it be a vector/map that constantly receives new values but is not cleanup up with reset/cleanup? Similar to what was happening in https://github.com/sofa-framework/SofaPython3/pull/304

alxbilger commented 1 year ago

I don't think so because components are destroyed in the unload

On Fri, Sep 23, 2022, 16:43 Paul Scheikl @.***> wrote:

@alxbilger https://github.com/alxbilger Thanks!

Before unload Total Base: 31970 31936 Diff: 34 After unload Total Base: 31970 31939 Diff: 31 Before unload Total Base: 32002 31968 Diff: 34 After unload Total Base: 32002 31971 Diff: 31 Before cleanup Total Base: 32002 32000 Diff: 2 Total Base: 32002 32000 Diff: 2 After cleanup Total Base: 32002 32001 Diff: 1

So that looks ok, right? At least the difference is more or less constant. :D But the tracker only tracks actual objects, right? So Creators, Factories, and others that do not inherit from base are not tracked.

Could it be a vector/map that constantly receives new values but is not cleanup up with reset/cleanup? Similar to what was happening in sofa-framework/SofaPython3#304 https://github.com/sofa-framework/SofaPython3/pull/304

— Reply to this email directly, view it on GitHub https://github.com/sofa-framework/sofa/issues/3318#issuecomment-1256307109, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACQVHUANK4QVMDDWVFQIBHTV7W6ZRANCNFSM6AAAAAAQR3UB3M . You are receiving this because you were mentioned.Message ID: @.***>

ScheiklP commented 1 year ago

@alxbilger not everything. Creators, factories etc are not destroyed during unload

Total Base: 32002 31968 Diff: 34
After unload
Total Base: 32002 31971 Diff: 31
Before cleanup
Total Base: 32002 32000 Diff: 2
Total Base: 32002 32000 Diff: 2
After cleanup
BaseTracker destroyed
Total Base: 32002 32001 Diff: 1
Creator destroyed
Creator destroyed
Creator destroyed
Creator destroyed
Creator destroyed
Factory destroyed
Creator destroyed
Factory destroyed
Creator destroyed
Factory destroyed
alxbilger commented 1 year ago

I see what you mean. That's why I had confidence in https://github.com/alxbilger/sofa/blob/918cd66008f586575c92c1e068f5c267a952b936/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h#L95.

At least now we know that there are no leak in the components themselves. The track continues

ScheiklP commented 1 year ago

memory

damienmarchal commented 1 year ago

With such serious contribution and bug tracking... sound like the return of valgrind in our workflow :)

My contribution:

==91659== 5,152 (32 direct, 5,120 indirect) bytes in 1 blocks are definitely lost in loss record 12,668 of 12,789
==91659==    at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==91659==    by 0x3EA66C2D: createOutputVector<sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3, double>, sofa::type::Vec<3, double>, double> >, sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3, double>, sofa::type::Vec<3, double>, double> > > (Intersection.h:48)
==91659==    by 0x3EA66C2D: beginIntersect (Intersection.inl:60)
==91659==    by 0x3EA66C2D: sofa::core::collision::MemberElementIntersector<sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::detection::intersection::LocalMinDistance>::beginIntersect(sofa::core::CollisionModel*, sofa::core::CollisionModel*, sofa::core::collision::DetectionOutputVector*&) (Intersection.inl:54)
==91659==    by 0x3E97FA7E: sofa::component::collision::detection::algorithm::BVHNarrowPhase::addCollisionPair(std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*> const&) (BVHNarrowPhase.cpp:73)
==91659==    by 0x53714C0: sofa::core::collision::NarrowPhaseDetection::addCollisionPairs(sofa::type::vector<std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*>, sofa::type::CPUMemoryManager<std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*> > > const&) (NarrowPhaseDetection.cpp:41)
==91659==    by 0x3E99415F: sofa::component::collision::detection::algorithm::DefaultPipeline::doCollisionDetection(sofa::type::vector<sofa::core::CollisionModel*, sofa::type::CPUMemoryManager<sofa::core::CollisionModel*> > const&) (DefaultPipeline.cpp:238)
==91659==    by 0x4BBD0D6: sofa::simulation::PipelineImpl::computeCollisionDetection() (PipelineImpl.cpp:117)
==91659==    by 0x4B68E62: sofa::simulation::CollisionVisitor::processCollisionPipeline(sofa::simulation::Node*, sofa::core::collision::Pipeline*) (CollisionVisitor.cpp:78)
==91659==    by 0x4B690BC: runVisitorTask<sofa::simulation::CollisionVisitor, sofa::simulation::Node, sofa::core::co

Sounds like createOutputModel is a good first spot to look at as it allocate an output vector with new... and that this one is returned to finally be stored in a map (eg: line 50 in NarrowPhaseDection).... which is not deleted when destructing object.

ScheiklP commented 1 year ago
==215344== LEAK SUMMARY:
==215344==    definitely lost: 32,000 bytes in 1,000 blocks
==215344==    indirectly lost: 5,104,640 bytes in 997 blocks
==215344==      possibly lost: 15,360 bytes in 3 blocks
==215344==    still reachable: 7,550 bytes in 123 blocks
==215344==         suppressed: 0 bytes in 0 blocks

The 5mb indirectly lost also match the plot quite nicely

image

I'll have a look at that next week. :)

somefoo commented 1 year ago

I suggest using the memory sensitization tools provided by GCC or Clang - it is less hassle than valgrind. It also provides more detail regarding memory leaks.

To do this, build Sofa with the additional flag: cmake .. -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -fsanitize=address"

Here is the output when running the example (CPP) scene provided by @ScheiklP.

The 15 object(s) that are detected are come from the number of unloads performed (I decreased it to 15 from the original 1000 used in the scene by @ScheiklP)

=================================================================
==445057==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 480 byte(s) in 15 object(s) allocated from:
    #0 0x7fc3004af587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x7fc3000d4160 in sofa::core::collision::TDetectionOutputVector<sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> > >* sofa::core::collision::BaseIntersector::createOutputVector<sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> > >(sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >*, sofa::component::collision::geometry::PointCollisionModel<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/Intersection.h:48
    #2 0x7fc3000eb263 in sofa::core::collision::MemberElementIntersector<sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::detection::intersection::MeshNewProximityIntersection>::beginIntersect(sofa::core::CollisionModel*, sofa::core::CollisionModel*, sofa::core::collision::DetectionOutputVector*&) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/Intersection.inl:60
    #3 0x7fc3002426aa in sofa::component::collision::detection::algorithm::BVHNarrowPhase::addCollisionPair(std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*> const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BVHNarrowPhase.cpp:73
    #4 0x7fc2fea01259 in sofa::core::collision::NarrowPhaseDetection::addCollisionPairs(sofa::type::vector<std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*>, sofa::type::CPUMemoryManager<std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*> > > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/NarrowPhaseDetection.cpp:41
    #5 0x7fc300261107 in sofa::component::collision::detection::algorithm::DefaultPipeline::doCollisionDetection(sofa::type::vector<sofa::core::CollisionModel*, sofa::type::CPUMemoryManager<sofa::core::CollisionModel*> > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DefaultPipeline.cpp:238
    #6 0x7fc2ff1ec0e0 in sofa::simulation::PipelineImpl::computeCollisionDetection() /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp:117
    #7 0x7fc2ff12923f in sofa::simulation::CollisionVisitor::processCollisionPipeline(sofa::simulation::Node*, sofa::core::collision::Pipeline*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionVisitor.cpp:78
    #8 0x7fc2ff129ac6 in void sofa::simulation::Visitor::runVisitorTask<sofa::simulation::CollisionVisitor, sofa::simulation::Node, sofa::core::collision::Pipeline>(sofa::simulation::CollisionVisitor*, sofa::simulation::Node*, void (sofa::simulation::CollisionVisitor::*)(sofa::simulation::Node*, sofa::core::collision::Pipeline*), sofa::core::collision::Pipeline*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h:246
    #9 0x7fc2ff129829 in void sofa::simulation::Visitor::for_each<sofa::simulation::CollisionVisitor, sofa::simulation::Node, sofa::simulation::NodeSingle<sofa::core::collision::Pipeline, true>, sofa::core::collision::Pipeline>(sofa::simulation::CollisionVisitor*, sofa::simulation::Node*, sofa::simulation::NodeSingle<sofa::core::collision::Pipeline, true> const&, void (sofa::simulation::CollisionVisitor::*)(sofa::simulation::Node*, sofa::core::collision::Pipeline*), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h:286
    #10 0x7fc2ff12911b in sofa::simulation::CollisionVisitor::processNodeTopDown(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionVisitor.cpp:38
    #11 0x7fc300356978 in sofa::simulation::graph::DAGNode::executeVisitorTopDown(sofa::simulation::Visitor*, std::__cxx11::list<sofa::simulation::graph::DAGNode*, std::allocator<sofa::simulation::graph::DAGNode*> >&, std::map<sofa::simulation::graph::DAGNode*, sofa::simulation::graph::DAGNode::StatusStruct, std::less<sofa::simulation::graph::DAGNode*>, std::allocator<std::pair<sofa::simulation::graph::DAGNode* const, sofa::simulation::graph::DAGNode::StatusStruct> > >&, sofa::simulation::graph::DAGNode*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:685
    #12 0x7fc300356054 in sofa::simulation::graph::DAGNode::doExecuteVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:607
    #13 0x7fc2ff15304b in sofa::simulation::Node::executeVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp:901
    #14 0x7fc2ff10c119 in sofa::simulation::Node::execute(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h:197
    #15 0x7fc2ff109df1 in sofa::simulation::AnimateVisitor::processCollisionPipeline(sofa::simulation::Node*, sofa::core::collision::Pipeline*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/AnimateVisitor.cpp:94
    #16 0x7fc2ff10a179 in sofa::simulation::AnimateVisitor::processNodeTopDown(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/AnimateVisitor.cpp:125
    #17 0x7fc300356978 in sofa::simulation::graph::DAGNode::executeVisitorTopDown(sofa::simulation::Visitor*, std::__cxx11::list<sofa::simulation::graph::DAGNode*, std::allocator<sofa::simulation::graph::DAGNode*> >&, std::map<sofa::simulation::graph::DAGNode*, sofa::simulation::graph::DAGNode::StatusStruct, std::less<sofa::simulation::graph::DAGNode*>, std::allocator<std::pair<sofa::simulation::graph::DAGNode* const, sofa::simulation::graph::DAGNode::StatusStruct> > >&, sofa::simulation::graph::DAGNode*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:685
    #18 0x7fc300356054 in sofa::simulation::graph::DAGNode::doExecuteVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:607
    #19 0x7fc2ff15304b in sofa::simulation::Node::executeVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp:901
    #20 0x7fc2ff12b381 in sofa::simulation::Node::execute(sofa::simulation::Visitor&, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h:191
    #21 0x7fc2ff12aa43 in sofa::simulation::DefaultAnimationLoop::step(sofa::core::ExecParams const*, double) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/DefaultAnimationLoop.cpp:113
    #22 0x7fc2ff205eb1 in sofa::simulation::Simulation::animate(sofa::simulation::Node*, double) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp:242
    #23 0x5646e6e19751 in main /home/pit/LocalApps/sofa/sofa/src/applications/projects/sofaProjectExample/Main.cpp:166
    #24 0x7fc2fd4a8082 in __libc_start_main ../csu/libc-start.c:308

Direct leak of 120 byte(s) in 15 object(s) allocated from:
    #0 0x7fc3004af587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x7fc3000d6c54 in sofa::core::collision::IntersectorCreator<sofa::component::collision::detection::intersection::DiscreteIntersection, sofa::component::collision::detection::intersection::MeshDiscreteIntersection>::addIntersectors(sofa::component::collision::detection::intersection::DiscreteIntersection*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h:95
    #2 0x7fc3000bcd82 in sofa::core::collision::IntersectorFactory<sofa::component::collision::detection::intersection::DiscreteIntersection>::addIntersectors(sofa::component::collision::detection::intersection::DiscreteIntersection*) (/home/pit/LocalApps/sofa/sofa/src/build/lib/libSofa.Component.Collision.Detection.Intersection_d.so.22.12.99+0xded82)
    #3 0x7fc3000bbbf0 in sofa::component::collision::detection::intersection::DiscreteIntersection::DiscreteIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/DiscreteIntersection.cpp:56
    #4 0x7fc3000b1bc1 in sofa::component::collision::detection::intersection::BaseProximityIntersection::BaseProximityIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/BaseProximityIntersection.cpp:31
    #5 0x7fc3000f3485 in sofa::component::collision::detection::intersection::NewProximityIntersection::NewProximityIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.cpp:47
    #6 0x5646e6e1b4b1 in sofa::core::objectmodel::New<sofa::component::collision::detection::intersection::NewProximityIntersection>::New<>() /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/objectmodel/SPtr.h:56
    #7 0x5646e6e18d86 in main /home/pit/LocalApps/sofa/sofa/src/applications/projects/sofaProjectExample/Main.cpp:96
    #8 0x7fc2fd4a8082 in __libc_start_main ../csu/libc-start.c:308

Direct leak of 120 byte(s) in 15 object(s) allocated from:
    #0 0x7fc3004af587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x7fc3000eb62a in sofa::core::collision::IntersectorCreator<sofa::component::collision::detection::intersection::NewProximityIntersection, sofa::component::collision::detection::intersection::MeshNewProximityIntersection>::addIntersectors(sofa::component::collision::detection::intersection::NewProximityIntersection*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h:95
    #2 0x7fc3000f3c9c in sofa::core::collision::IntersectorFactory<sofa::component::collision::detection::intersection::NewProximityIntersection>::addIntersectors(sofa::component::collision::detection::intersection::NewProximityIntersection*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h:71
    #3 0x7fc3000f3696 in sofa::component::collision::detection::intersection::NewProximityIntersection::init() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.cpp:63
    #4 0x7fc2ff13bd72 in sofa::simulation::InitVisitor::processNodeTopDown(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp:47
    #5 0x7fc300356978 in sofa::simulation::graph::DAGNode::executeVisitorTopDown(sofa::simulation::Visitor*, std::__cxx11::list<sofa::simulation::graph::DAGNode*, std::allocator<sofa::simulation::graph::DAGNode*> >&, std::map<sofa::simulation::graph::DAGNode*, sofa::simulation::graph::DAGNode::StatusStruct, std::less<sofa::simulation::graph::DAGNode*>, std::allocator<std::pair<sofa::simulation::graph::DAGNode* const, sofa::simulation::graph::DAGNode::StatusStruct> > >&, sofa::simulation::graph::DAGNode*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:685
    #6 0x7fc300356054 in sofa::simulation::graph::DAGNode::doExecuteVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:607
    #7 0x7fc2ff15304b in sofa::simulation::Node::executeVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp:901
    #8 0x7fc2ff15a33c in void sofa::simulation::Node::execute<sofa::simulation::InitVisitor, sofa::core::ExecParams>(sofa::core::ExecParams const*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h:206
    #9 0x7fc2ff205b75 in sofa::simulation::Simulation::initNode(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp:213
    #10 0x7fc2ff205847 in sofa::simulation::Simulation::init(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp:189
    #11 0x5646e6e194e0 in main /home/pit/LocalApps/sofa/sofa/src/applications/projects/sofaProjectExample/Main.cpp:143
    #12 0x7fc2fd4a8082 in __libc_start_main ../csu/libc-start.c:308

Direct leak of 120 byte(s) in 15 object(s) allocated from:
    #0 0x7fc3004af587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x7fc3000fca4c in sofa::core::collision::IntersectorCreator<sofa::component::collision::detection::intersection::NewProximityIntersection, sofa::component::collision::detection::intersection::RayNewProximityIntersection>::addIntersectors(sofa::component::collision::detection::intersection::NewProximityIntersection*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h:95
    #2 0x7fc3000f3c9c in sofa::core::collision::IntersectorFactory<sofa::component::collision::detection::intersection::NewProximityIntersection>::addIntersectors(sofa::component::collision::detection::intersection::NewProximityIntersection*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h:71
    #3 0x7fc3000f3696 in sofa::component::collision::detection::intersection::NewProximityIntersection::init() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.cpp:63
    #4 0x7fc2ff13bd72 in sofa::simulation::InitVisitor::processNodeTopDown(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/InitVisitor.cpp:47
    #5 0x7fc300356978 in sofa::simulation::graph::DAGNode::executeVisitorTopDown(sofa::simulation::Visitor*, std::__cxx11::list<sofa::simulation::graph::DAGNode*, std::allocator<sofa::simulation::graph::DAGNode*> >&, std::map<sofa::simulation::graph::DAGNode*, sofa::simulation::graph::DAGNode::StatusStruct, std::less<sofa::simulation::graph::DAGNode*>, std::allocator<std::pair<sofa::simulation::graph::DAGNode* const, sofa::simulation::graph::DAGNode::StatusStruct> > >&, sofa::simulation::graph::DAGNode*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:685
    #6 0x7fc300356054 in sofa::simulation::graph::DAGNode::doExecuteVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:607
    #7 0x7fc2ff15304b in sofa::simulation::Node::executeVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp:901
    #8 0x7fc2ff15a33c in void sofa::simulation::Node::execute<sofa::simulation::InitVisitor, sofa::core::ExecParams>(sofa::core::ExecParams const*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h:206
    #9 0x7fc2ff205b75 in sofa::simulation::Simulation::initNode(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp:213
    #10 0x7fc2ff205847 in sofa::simulation::Simulation::init(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Simulation.cpp:189
    #11 0x5646e6e194e0 in main /home/pit/LocalApps/sofa/sofa/src/applications/projects/sofaProjectExample/Main.cpp:143
    #12 0x7fc2fd4a8082 in __libc_start_main ../csu/libc-start.c:308

Direct leak of 120 byte(s) in 15 object(s) allocated from:
    #0 0x7fc3004af587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x7fc3000f9b12 in sofa::core::collision::IntersectorCreator<sofa::component::collision::detection::intersection::DiscreteIntersection, sofa::component::collision::detection::intersection::RayDiscreteIntersection>::addIntersectors(sofa::component::collision::detection::intersection::DiscreteIntersection*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h:95
    #2 0x7fc3000bcd82 in sofa::core::collision::IntersectorFactory<sofa::component::collision::detection::intersection::DiscreteIntersection>::addIntersectors(sofa::component::collision::detection::intersection::DiscreteIntersection*) (/home/pit/LocalApps/sofa/sofa/src/build/lib/libSofa.Component.Collision.Detection.Intersection_d.so.22.12.99+0xded82)
    #3 0x7fc3000bbbf0 in sofa::component::collision::detection::intersection::DiscreteIntersection::DiscreteIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/DiscreteIntersection.cpp:56
    #4 0x7fc3000b1bc1 in sofa::component::collision::detection::intersection::BaseProximityIntersection::BaseProximityIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/BaseProximityIntersection.cpp:31
    #5 0x7fc3000f3485 in sofa::component::collision::detection::intersection::NewProximityIntersection::NewProximityIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.cpp:47
    #6 0x5646e6e1b4b1 in sofa::core::objectmodel::New<sofa::component::collision::detection::intersection::NewProximityIntersection>::New<>() /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/objectmodel/SPtr.h:56
    #7 0x5646e6e18d86 in main /home/pit/LocalApps/sofa/sofa/src/applications/projects/sofaProjectExample/Main.cpp:96
    #8 0x7fc2fd4a8082 in __libc_start_main ../csu/libc-start.c:308

Direct leak of 120 byte(s) in 15 object(s) allocated from:
    #0 0x7fc3004af587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x7fc3000ff16e in sofa::core::collision::IntersectorCreator<sofa::component::collision::detection::intersection::DiscreteIntersection, sofa::component::collision::detection::intersection::TetrahedronDiscreteIntersection>::addIntersectors(sofa::component::collision::detection::intersection::DiscreteIntersection*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/IntersectorFactory.h:95
    #2 0x7fc3000bcd82 in sofa::core::collision::IntersectorFactory<sofa::component::collision::detection::intersection::DiscreteIntersection>::addIntersectors(sofa::component::collision::detection::intersection::DiscreteIntersection*) (/home/pit/LocalApps/sofa/sofa/src/build/lib/libSofa.Component.Collision.Detection.Intersection_d.so.22.12.99+0xded82)
    #3 0x7fc3000bbbf0 in sofa::component::collision::detection::intersection::DiscreteIntersection::DiscreteIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/DiscreteIntersection.cpp:56
    #4 0x7fc3000b1bc1 in sofa::component::collision::detection::intersection::BaseProximityIntersection::BaseProximityIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/BaseProximityIntersection.cpp:31
    #5 0x7fc3000f3485 in sofa::component::collision::detection::intersection::NewProximityIntersection::NewProximityIntersection() /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.cpp:47
    #6 0x5646e6e1b4b1 in sofa::core::objectmodel::New<sofa::component::collision::detection::intersection::NewProximityIntersection>::New<>() /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/objectmodel/SPtr.h:56
    #7 0x5646e6e18d86 in main /home/pit/LocalApps/sofa/sofa/src/applications/projects/sofaProjectExample/Main.cpp:96
    #8 0x7fc2fd4a8082 in __libc_start_main ../csu/libc-start.c:308

Indirect leak of 9830400 byte(s) in 15 object(s) allocated from:
    #0 0x7fc3004af587 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:104
    #1 0x7fc300297559 in __gnu_cxx::new_allocator<sofa::core::collision::DetectionOutput>::allocate(unsigned long, void const*) /usr/include/c++/9/ext/new_allocator.h:114
    #2 0x7fc3002972fe in std::allocator_traits<std::allocator<sofa::core::collision::DetectionOutput> >::allocate(std::allocator<sofa::core::collision::DetectionOutput>&, unsigned long) /usr/include/c++/9/bits/alloc_traits.h:443
    #3 0x7fc300296f03 in std::_Vector_base<sofa::core::collision::DetectionOutput, std::allocator<sofa::core::collision::DetectionOutput> >::_M_allocate(unsigned long) /usr/include/c++/9/bits/stl_vector.h:343
    #4 0x7fc3000e7ed8 in void std::vector<sofa::core::collision::DetectionOutput, std::allocator<sofa::core::collision::DetectionOutput> >::_M_realloc_insert<sofa::core::collision::DetectionOutput>(__gnu_cxx::__normal_iterator<sofa::core::collision::DetectionOutput*, std::vector<sofa::core::collision::DetectionOutput, std::allocator<sofa::core::collision::DetectionOutput> > >, sofa::core::collision::DetectionOutput&&) /usr/include/c++/9/bits/vector.tcc:440
    #5 0x7fc3000e79be in sofa::core::collision::DetectionOutput& std::vector<sofa::core::collision::DetectionOutput, std::allocator<sofa::core::collision::DetectionOutput> >::emplace_back<sofa::core::collision::DetectionOutput>(sofa::core::collision::DetectionOutput&&) /usr/include/c++/9/bits/vector.tcc:121
    #6 0x7fc3000e72a9 in std::vector<sofa::core::collision::DetectionOutput, std::allocator<sofa::core::collision::DetectionOutput> >::push_back(sofa::core::collision::DetectionOutput&&) /usr/include/c++/9/bits/stl_vector.h:1201
    #7 0x7fc3000e5abb in sofa::component::collision::detection::intersection::NewProximityIntersection::doIntersectionPointPoint(double, sofa::type::Vec<3u, double> const&, sofa::type::Vec<3u, double> const&, sofa::type::vector<sofa::core::collision::DetectionOutput, sofa::type::CPUMemoryManager<sofa::core::collision::DetectionOutput> >*, int) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/NewProximityIntersection.inl:51
    #8 0x7fc3000e33f8 in sofa::component::collision::detection::intersection::MeshNewProximityIntersection::computeIntersection(sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >&, sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >&, sofa::type::vector<sofa::core::collision::DetectionOutput, sofa::type::CPUMemoryManager<sofa::core::collision::DetectionOutput> >*) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Intersection/src/sofa/component/collision/detection/intersection/MeshNewProximityIntersection.cpp:105
    #9 0x7fc3000eb369 in sofa::core::collision::MemberElementIntersector<sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::geometry::TPoint<sofa::defaulttype::StdVectorTypes<sofa::type::Vec<3u, double>, sofa::type::Vec<3u, double>, double> >, sofa::component::collision::detection::intersection::MeshNewProximityIntersection>::intersect(sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator, sofa::core::collision::DetectionOutputVector*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/Intersection.inl:70
    #10 0x7fc300243c13 in sofa::component::collision::detection::algorithm::BVHNarrowPhase::finalCollisionPairs(std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > const&, bool, sofa::core::collision::ElementIntersector*, sofa::core::collision::DetectionOutputVector*&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BVHNarrowPhase.cpp:322
    #11 0x7fc30024386e in sofa::component::collision::detection::algorithm::BVHNarrowPhase::visitExternalChildren(sofa::core::CollisionElementIterator const&, sofa::core::CollisionElementIterator const&, sofa::core::collision::ElementIntersector*, sofa::component::collision::detection::algorithm::BVHNarrowPhase::FinestCollision const&, std::queue<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::deque<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::allocator<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > > > >&, sofa::core::collision::DetectionOutputVector*&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BVHNarrowPhase.cpp:278
    #12 0x7fc30024368b in sofa::component::collision::detection::algorithm::BVHNarrowPhase::visitCollisionElements(std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > const&, sofa::core::collision::ElementIntersector*, sofa::component::collision::detection::algorithm::BVHNarrowPhase::FinestCollision const&, std::queue<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::deque<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::allocator<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > > > >&, std::stack<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::deque<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::allocator<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > > > >&, sofa::core::collision::DetectionOutputVector*&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BVHNarrowPhase.cpp:251
    #13 0x7fc300243254 in sofa::component::collision::detection::algorithm::BVHNarrowPhase::processInternalCell(std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > const&, sofa::core::collision::ElementIntersector*, sofa::component::collision::detection::algorithm::BVHNarrowPhase::FinestCollision const&, std::queue<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::deque<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::allocator<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > > > >&, std::stack<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::deque<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::allocator<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > > > >&, sofa::core::collision::DetectionOutputVector*&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BVHNarrowPhase.cpp:196
    #14 0x7fc3002430a2 in sofa::component::collision::detection::algorithm::BVHNarrowPhase::processExternalCell(std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > const&, sofa::core::CollisionModel*&, sofa::core::CollisionModel*&, sofa::core::collision::ElementIntersector*, sofa::component::collision::detection::algorithm::BVHNarrowPhase::FinestCollision const&, sofa::component::collision::detection::algorithm::MirrorIntersector*, std::queue<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::deque<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> >, std::allocator<std::pair<std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator>, std::pair<sofa::core::CollisionElementIterator, sofa::core::CollisionElementIterator> > > > >&, sofa::core::collision::DetectionOutputVector*&) const /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BVHNarrowPhase.cpp:176
    #15 0x7fc3002428a4 in sofa::component::collision::detection::algorithm::BVHNarrowPhase::addCollisionPair(std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*> const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/BVHNarrowPhase.cpp:97
    #16 0x7fc2fea01259 in sofa::core::collision::NarrowPhaseDetection::addCollisionPairs(sofa::type::vector<std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*>, sofa::type::CPUMemoryManager<std::pair<sofa::core::CollisionModel*, sofa::core::CollisionModel*> > > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Core/src/sofa/core/collision/NarrowPhaseDetection.cpp:41
    #17 0x7fc300261107 in sofa::component::collision::detection::algorithm::DefaultPipeline::doCollisionDetection(sofa::type::vector<sofa::core::CollisionModel*, sofa::type::CPUMemoryManager<sofa::core::CollisionModel*> > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/Component/Collision/Detection/Algorithm/src/sofa/component/collision/detection/algorithm/DefaultPipeline.cpp:238
    #18 0x7fc2ff1ec0e0 in sofa::simulation::PipelineImpl::computeCollisionDetection() /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/PipelineImpl.cpp:117
    #19 0x7fc2ff12923f in sofa::simulation::CollisionVisitor::processCollisionPipeline(sofa::simulation::Node*, sofa::core::collision::Pipeline*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionVisitor.cpp:78
    #20 0x7fc2ff129ac6 in void sofa::simulation::Visitor::runVisitorTask<sofa::simulation::CollisionVisitor, sofa::simulation::Node, sofa::core::collision::Pipeline>(sofa::simulation::CollisionVisitor*, sofa::simulation::Node*, void (sofa::simulation::CollisionVisitor::*)(sofa::simulation::Node*, sofa::core::collision::Pipeline*), sofa::core::collision::Pipeline*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h:246
    #21 0x7fc2ff129829 in void sofa::simulation::Visitor::for_each<sofa::simulation::CollisionVisitor, sofa::simulation::Node, sofa::simulation::NodeSingle<sofa::core::collision::Pipeline, true>, sofa::core::collision::Pipeline>(sofa::simulation::CollisionVisitor*, sofa::simulation::Node*, sofa::simulation::NodeSingle<sofa::core::collision::Pipeline, true> const&, void (sofa::simulation::CollisionVisitor::*)(sofa::simulation::Node*, sofa::core::collision::Pipeline*), std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Visitor.h:286
    #22 0x7fc2ff12911b in sofa::simulation::CollisionVisitor::processNodeTopDown(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/CollisionVisitor.cpp:38
    #23 0x7fc300356978 in sofa::simulation::graph::DAGNode::executeVisitorTopDown(sofa::simulation::Visitor*, std::__cxx11::list<sofa::simulation::graph::DAGNode*, std::allocator<sofa::simulation::graph::DAGNode*> >&, std::map<sofa::simulation::graph::DAGNode*, sofa::simulation::graph::DAGNode::StatusStruct, std::less<sofa::simulation::graph::DAGNode*>, std::allocator<std::pair<sofa::simulation::graph::DAGNode* const, sofa::simulation::graph::DAGNode::StatusStruct> > >&, sofa::simulation::graph::DAGNode*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:685
    #24 0x7fc300356054 in sofa::simulation::graph::DAGNode::doExecuteVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:607
    #25 0x7fc2ff15304b in sofa::simulation::Node::executeVisitor(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.cpp:901
    #26 0x7fc2ff10c119 in sofa::simulation::Node::execute(sofa::simulation::Visitor*, bool) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/Node.h:197
    #27 0x7fc2ff109df1 in sofa::simulation::AnimateVisitor::processCollisionPipeline(sofa::simulation::Node*, sofa::core::collision::Pipeline*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/AnimateVisitor.cpp:94
    #28 0x7fc2ff10a179 in sofa::simulation::AnimateVisitor::processNodeTopDown(sofa::simulation::Node*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Core/src/sofa/simulation/AnimateVisitor.cpp:125
    #29 0x7fc300356978 in sofa::simulation::graph::DAGNode::executeVisitorTopDown(sofa::simulation::Visitor*, std::__cxx11::list<sofa::simulation::graph::DAGNode*, std::allocator<sofa::simulation::graph::DAGNode*> >&, std::map<sofa::simulation::graph::DAGNode*, sofa::simulation::graph::DAGNode::StatusStruct, std::less<sofa::simulation::graph::DAGNode*>, std::allocator<std::pair<sofa::simulation::graph::DAGNode* const, sofa::simulation::graph::DAGNode::StatusStruct> > >&, sofa::simulation::graph::DAGNode*) /home/pit/LocalApps/sofa/sofa/src/Sofa/framework/Simulation/Graph/src/sofa/simulation/graph/DAGNode.cpp:685

SUMMARY: AddressSanitizer: 9831480 byte(s) leaked in 105 allocation(s).
somefoo commented 1 year ago

At the moment it looks like the object created here src/Sofa/framework/Core/src/sofa/core/collision/Intersection.h line 48 is never deleted.

image

ScheiklP commented 1 year ago
void NarrowPhaseDetection::endNarrowPhase()
{
    for (auto it = m_outputsMap.begin(); it != m_outputsMap.end();)
    {
        DetectionOutputVector *do_vec = (it->second);
        if (!do_vec || do_vec->empty())
        {
            if (do_vec)
            {
                do_vec->release();
            }
            m_outputsMap.erase(it++);
        }
        else
        {
            ++it;
        }
    }
}

The intended behavior of this is "if the vector is empty, or it's a nullpointer, remove it from the map. If it is not a nullpointer, also release the vector", right?

Since the do_vec->clear() is in beginNarrowPhase, the vector is never released correctly.

ScheiklP commented 1 year ago

It was indeed the TDetectionOutputVector* but in a completely different location than expected. :D

epernod commented 1 year ago

good work @ScheiklP . Just for the records, you can directly put the keyword: "fix #PRnumber" inside the comment of your PR. Thus when it is merged, the issue is automatically closed with a link to the PR.