halbux / sparselizard

C++ FEM library | user-friendly | multi-physics | hp-adaptive | HPC
http://www.sparselizard.org
Other
332 stars 62 forks source link

free(): invalid pointer when Loading mesh from 'api' with the gmsh mesh reader #55

Closed pointhi closed 2 years ago

pointhi commented 2 years ago

I cannot read a gmsh 4.9 file using gmsh:api as well as by storing the file first and then loading it with gmsh:filename.msh2 again. I use https://github.com/halbux/sparselizard/tree/v.2021.11:

Thread 1 "sparselizard_DC" received signal SIGABRT, Aborted.
0x00007ffff3710d22 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff3710d22 in raise () at /usr/lib/libc.so.6
#1  0x00007ffff36fa862 in abort () at /usr/lib/libc.so.6
#2  0x00007ffff3752d28 in __libc_message () at /usr/lib/libc.so.6
#3  0x00007ffff375a92a in  () at /usr/lib/libc.so.6
#4  0x00007ffff375bcfc in _int_free () at /usr/lib/libc.so.6
#5  0x00007ffff375f9e8 in free () at /usr/lib/libc.so.6
#6  0x00007ffff4b7db5a in element::~element() () at /usr/lib/libgmsh.so.4.9
#7  0x00007ffff3e82983 in elements::explode() () at /usr/lib/libsparselizard.so
#8  0x00007ffff3eda7a0 in rawmesh::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, int) () at /usr/lib/libsparselizard.so
#9  0x00007ffff3ec1a26 in mesh::mesh(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int) () at /usr/lib/libsparselizard.so
#10 0x0000555555e0bb65 in SPARSELIZARD_SOLVER::Run_DC(FEM_DESCRIPTOR*) (this=0x55555878ca00, aDescriptor=0x555558788130) at /home/thomas/Projekte/Kicad/kicad-source-mirror/pcbnew/fem/sparselizard/sparselizard_solver.cpp:900
#11 0x0000555555924170 in SparselizardDC::simulTrackResistance(double, double, double, double, double, FEM_SIMULATION_DIMENSION, bool)
    (rho=1.7199999999999999e-08, L=0.20000000000000001, h=3.4999999999999997e-05, w=0.029999999999999999, max_error=1e-08, aDim=aDim@entry=FEM_SIMULATION_DIMENSION::SIMUL2D5, overshoot=<optimized out>)
    at /home/thomas/Projekte/Kicad/kicad-source-mirror/qa/fem_proto/sparselizard_DC.cpp:528
#12 0x0000555555924e12 in SparselizardDC::trackResistanceTest(FEM_SIMULATION_DIMENSION) (aDim=aDim@entry=FEM_SIMULATION_DIMENSION::SIMUL2D5) at /home/thomas/Projekte/Kicad/kicad-source-mirror/qa/fem_proto/sparselizard_DC.cpp:689
#13 0x0000555555926fda in SparselizardDC::TestTrackResistance::test_method() (this=<optimized out>) at /home/thomas/Projekte/Kicad/kicad-source-mirror/qa/fem_proto/sparselizard_DC.cpp:771
#14 SparselizardDC::TestTrackResistance_invoker() () at /home/thomas/Projekte/Kicad/kicad-source-mirror/qa/fem_proto/sparselizard_DC.cpp:769
#15 0x00007ffff701d66e in  () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#16 0x00007ffff701bf5d in boost::execution_monitor::catch_signals(boost::function<int ()> const&) () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#17 0x00007ffff701bfe7 in boost::execution_monitor::execute(boost::function<int ()> const&) () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#18 0x00007ffff701c099 in boost::execution_monitor::vexecute(boost::function<void ()> const&) () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#19 0x00007ffff704a8d7 in boost::unit_test::unit_test_monitor_t::execute_and_translate(boost::function<void ()> const&, unsigned long) () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#20 0x00007ffff7022514 in  () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#21 0x00007ffff70227d8 in  () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#22 0x00007ffff70227d8 in  () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#23 0x00007ffff7026e5c in boost::unit_test::framework::run(unsigned long, bool) () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#24 0x00007ffff7049450 in boost::unit_test::unit_test_main(bool (*)(), int, char**) () at /usr/lib/libboost_unit_test_framework.so.1.78.0
#25 0x000055555591cb02 in main(int, char**) (argc=-20160, argv=0x0) at /home/thomas/Projekte/Kicad/kicad-source-mirror/qa/fem_proto/test_module.cpp:41

The code can be found in https://gitlab.com/pointhi/kicad/-/tree/sparselizard_fem, and I can reproduce the failure with qa/fem_proto/sparselizard_DC

halbux commented 2 years ago

Hi Thomas,

Could you also attach the .msh file and the .msh2 file?

Alex

pointhi commented 2 years ago

I suspect we might have a name collision with perhaps https://gitlab.onelab.info/gmsh/gmsh/-/blob/master/src/post/shapeFunctions.h#L12

Simply because you and gmsh define the element datatype, and sparselizards elements should not interact with gmsh I think, but it does according the the stacktrace. This leads to an incorrect free. tmp_written_gmsh_v2.zip

The proper solution would be to wrap the sparselizard codebase into a namespace.

pointhi commented 2 years ago

It really looks that way, both libraries define the same symbol name for the destructor:

$ objdump /usr/lib/libgmsh.so.4.9 -T | grep _ZN7elementD1Ev  
00000000009f1b30  w   DF .text  0000000000000052  Base        _ZN7elementD1Ev
$ objdump /usr/lib/libsparselizard.so -T | grep _ZN7elementD1Ev
0000000000103cc0  w   DF .text  0000000000000032  Base        _ZN7elementD1Ev
halbux commented 2 years ago

Thanks for the details. Sparselizard has both an 'element' and 'elements' class... Could it be that gmsh has added the element class quite recently? Can you rather easily work around for now or not?

Note: SL can natively read gmsh 2 format so there is no need to use the mesh('gmsh:file.msh2'), just use mesh('file.msh2'). Could that help?

pointhi commented 2 years ago

Loading sparselizard first into the application seems to solve the problem locally: LD_PRELOAD=/usr/lib/libsparselizard.so, but that's only a workaround. The cleanest solution would be to have sparselizard inside a namespace, which would automatically lead to unique symbol names.

halbux commented 2 years ago

Duly noted! Hope you can live with it for some time though, but let me know if it becomes a seriously blocking issue for you.

halbux commented 2 years ago

@pointhi I get the errors as well. I can only recommend using the only yet validated gmsh version for sparselizard:

http://gmsh.info/bin/Linux/gmsh-4.5.2-Linux64-sdk.tgz

With the 4.9.1 I even tried without any call to sparselizard, just an Ax = b resolution using the latest petsc (see code below). I am a little surprised that even with petsc-only calls it crashes, even if there should be at no moment a gmsh or SL call.

Code:

include "petsc.h"

include

int main(void) {

PetscInitialize(0,{},0,0);

std::vector<int> Arows = {0,1,2};
std::vector<int> Acols = {0,1};
std::vector<double> Avals = {10,20};

Mat Amat;

MatCreateSeqAIJWithArrays(PETSC_COMM_SELF, 2, 2, Arows.data(), Acols.data(), Avals.data(), &Amat);
MatAssemblyBegin(Amat, MAT_FINAL_ASSEMBLY);
MatAssemblyEnd(Amat, MAT_FINAL_ASSEMBLY);

MatView(Amat, PETSC_VIEWER_STDOUT_SELF);

Vec myvec;

VecCreate(PETSC_COMM_SELF, &myvec);
VecSetSizes(myvec, PETSC_DECIDE, 2);
VecSetFromOptions(myvec);   
VecSet(myvec, 0.0);

VecView(myvec, PETSC_VIEWER_STDOUT_SELF);

KSP ksp;

PC pc;
KSPCreate(PETSC_COMM_SELF, &ksp);
KSPSetOperators(ksp, Amat, Amat);

KSPSetFromOptions(ksp);

KSPGetPC(ksp,&pc);

PCSetType(pc,PCLU);
PCFactorSetMatSolverType(pc, "mumps");

KSPSolve(ksp, myvec, myvec);

PetscFinalize();

}