Setup to debug OCCT

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
abdullah
Posts: 3837
Joined: Sun May 04, 2014 3:16 pm

Setup to debug OCCT

Postby abdullah » Sat May 30, 2020 2:39 pm

Hi folks!

There is probably nothing special in what I am going to write here, but I think it may make sense to share it with you.

Since quite a while I wanted to be able to debug FreeCAD with a debug version of OpenCascade, so that I could investigate OpenCascade bugs. Finally today I have gone for it.

Opencascade GIT

It is possible to publicly clone the Opencascade git like this:

Code: Select all

git clone https://git.dev.opencascade.org/repos/occt.git
There are instructions to build Opencascade here:
https://www.opencascade.com/doc/occt-6. ... cmake.html

The advise of using 3 directories, one for sources, one for build and a third one for installation is very useful. This allows to have the installation on a local folder and to not interfere with system libraries.

I have used ccmake as they recommend to configure the build options. I used Kurt's balsa settings as reference:
https://salsa.debian.org/science-team/o ... bian/rules

But setting the build type to Debug and my INSTALL_DIR to /mylocalfolder/usr.

After make and make install, you are set to configure FreeCAD to use this library.

Building FreeCAD

I build FreeCAD out of tree, so I use this:

Code: Select all

cmake -DBUILD_QT5=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DCMAKE_BUILD_TYPE=Debug -DOCC_INCLUDE_DIR=/mylocalfolder/usr/include/opencascade ../free-cad-code
I was having problems that cmake wanted to use my OCCT build directory instead of the install directory even with the commands above, because it was finding the .cmake files of the build directory instead of the ones from the install directory. The only solution I could find was to delete the cmake files in the OCCT build directory.

N.B: Make sure you use a current version of master, as OCCT has introduced a change to a function in current master and Werner just pushed a fix for this today (I could have avoided having to do it myself if I waited just some hours...)

Running FreeCAD

Now you have a locally built FreeCAD compiled against your locally built OCCT, but when you run it, it will take your system OCCT library (and it will eventually crash). To avoid this, you can use:

Code: Select all

env LD_LIBRARY_PATH=/mylocalfolder/usr/lib ./FreeCAD
I use kdevelop and have created an environment for launch which sets this variable.

Now you can start debugging FreeCAD and it will jump to OCCT code, which you could fix, recompile OCCT, recompile FreeCAD,...

Example

Today I was looking at this:
https://tracker.freecadweb.org/view.php?id=4129

And I ended up filing a report and a possible patch with them to solve a crash:
https://tracker.dev.opencascade.org/view.php?id=31585

As I was saying, nothing special, just trying to show it is actually easier than it looks.
User avatar
Kunda1
Posts: 9185
Joined: Thu Jan 05, 2017 9:03 pm

Re: Setup to debug OCCT

Postby Kunda1 » Sat May 30, 2020 3:28 pm

Great! I'll add a section on Debugging OCC/OCCT to the Debugging page.

Edit:
Debugging#Debugging_OpenCasCade
Alone you go faster. Together we go farther
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
wmayer
Site Admin
Posts: 16841
Joined: Thu Feb 19, 2009 10:32 am

Re: Setup to debug OCCT

Postby wmayer » Sat May 30, 2020 6:17 pm

abdullah wrote:
Sat May 30, 2020 2:39 pm
Now you have a locally built FreeCAD compiled against your locally built OCCT, but when you run it, it will take your system OCCT library (and it will eventually crash). To avoid this, you can use:
I wonder why this happens. On my old Linux box I once locally built OCC 7.3 and a FreeCAD version that links this OCC version. I could start the application without dealing with LD_LIBRARY_PATH.

For example open the link.txt file for Part.so of the build directory. There you should be able to find the content "-rpath" followed by a list of paths which should include the path of your OCC installation.

If the path is listed then ldd Part.so should be able to locate the OCC libraries. To get the embedded paths you can do:

Code: Select all

objdump -p Part.so | grep RUNPATH
For more details see:
https://www.man7.org/training/download/ ... slides.pdf
https://gitlab.kitware.com/cmake/commun ... H-handling
https://software.intel.com/sites/defaul ... ohowto.pdf (page 40)
abdullah
Posts: 3837
Joined: Sun May 04, 2014 3:16 pm

Re: Setup to debug OCCT

Postby abdullah » Sun May 31, 2020 4:56 am

wmayer wrote:
Sat May 30, 2020 6:17 pm
I wonder why this happens. On my old Linux box I once locally built OCC 7.3 and a FreeCAD version that links this OCC version. I could start the application without dealing with LD_LIBRARY_PATH.

For example open the link.txt file for Part.so of the build directory. There you should be able to find the content "-rpath" followed by a list of paths which should include the path of your OCC installation.

If the path is listed then ldd Part.so should be able to locate the OCC libraries. To get the embedded paths you can do:

Code: Select all

objdump -p Part.so | grep RUNPATH
For more details see:
https://www.man7.org/training/download/ ... slides.pdf
https://gitlab.kitware.com/cmake/commun ... H-handling
https://software.intel.com/sites/defaul ... ohowto.pdf (page 40)
FreeCAD starts without the env variable. But it crashes for example when loading a file due to an undefined symbol:

Code: Select all

FreeCAD 0.19, Libs: 0.19R21328 (Git)
© Juergen Riegel, Werner Mayer, Yorik van Havre and others 2001-2020
FreeCAD is free and open-source software licensed under the terms of LGPL2+ license.
FreeCAD wouldn't be possible without FreeCAD community.
  #####                 ####  ###   ####  
  #                    #      # #   #   # 
  #     ##  #### ####  #     #   #  #   # 
  ####  # # #  # #  #  #     #####  #   # 
  #     #   #### ####  #    #     # #   # 
  #     #   #    #     #    #     # #   #  ##  ##  ##
  #     #   #### ####   ### #     # ####   ##  ##  ##

libpng warning: iCCP: known incorrect sRGB profile
libpng warning: iCCP: known incorrect sRGB profile
connect failed: No existe el archivo o el directorio
Cannot create object 'Body': (/usr/lib/x86_64-linux-gnu/libTKGeomBase.so.7: undefined symbol: _ZN19Geom_BSplineSurface15CheckAndSegmentEdddd)
Program received signal SIGSEGV, Segmentation fault.
The path is indeed there:

Code: Select all

RUNPATH              /usr/lib/x86_64-linux-gnu/hdf5/openmpi:/usr/lib/openmpi/lib:/usr/lib/x86_64-linux-gnu/openmpi/lib:/mylocalfolder/usr/lib:/home/abdullah/github/freecad-build/lib:
Using the dynamic linker output on FreeCAD executable (LD_DEBUG, see last slide of your first link), this is the library search:

Part.so

Code: Select all

      3338:     find library=Part.so [0]; searching
      3338:      search path=/usr/lib/x86_64-linux-gnu/hdf5/openmpi:/usr/lib/x86_64-linux-gnu/openmpi/lib:/mylocalfolder/usr/lib:/home/abdullah/github/freecad-build/Mod/Part/tls/haswell/x86_64:/home/abdullah/github/freecad-buil
d/Mod/Part/tls/haswell:/home/abdullah/github/freecad-build/Mod/Part/tls/x86_64:/home/abdullah/github/freecad-build/Mod/Part/tls:/home/abdullah/github/freecad-build/Mod/Part/haswell/x86_64:/home/abdullah/github/freecad-build/Mod
/Part/haswell:/home/abdullah/github/freecad-build/Mod/Part/x86_64:/home/abdullah/github/freecad-build/Mod/Part:/home/abdullah/github/freecad-build/lib:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86
_64:           (RUNPATH from file ./FreeCAD)
      3338:       trying file=/usr/lib/x86_64-linux-gnu/hdf5/openmpi/Part.so
      3338:       trying file=/usr/lib/x86_64-linux-gnu/openmpi/lib/Part.so
      3338:       trying file=/mylocalfolder/usr/lib/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/tls/haswell/x86_64/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/tls/haswell/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/tls/x86_64/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/tls/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/haswell/x86_64/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/haswell/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/x86_64/Part.so
      3338:       trying file=/home/abdullah/github/freecad-build/Mod/Part/Part.so
libTKGeomBase.so (the one creating the segmentation fault above):

Code: Select all

      3338:     find library=libTKGeomBase.so.7 [0]; searching
      3338:      search cache=/etc/ld.so.cache
      3338:       trying file=/usr/lib/x86_64-linux-gnu/libTKGeomBase.so.7
libTKMesh.so

Code: Select all

      3338:     find library=libTKMesh.so.7 [0]; searching
      3338:      search path=/usr/lib/x86_64-linux-gnu/hdf5/openmpi:/usr/lib/x86_64-linux-gnu/openmpi/lib:/mylocalfolder/usr/lib:/home/abdullah/github/freecad-build/lib:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:               (RUNPATH from file ./FreeCAD)
      3338:       trying file=/usr/lib/x86_64-linux-gnu/hdf5/openmpi/libTKMesh.so.7
      3338:       trying file=/usr/lib/x86_64-linux-gnu/openmpi/lib/libTKMesh.so.7
      3338:       trying file=/mylocalfolder/usr/lib/libTKMesh.so.7
In the case of libTKGeomBase.so, it appears to be found on the ld.so.cache, which appears to have lower priority than RUNPATH:
https://www.man7.org/linux/man-pages/man8/ld.so.8.html

This however does not happen for (for example) libTKMesh.so, in which the RUNPATH order is followed and the library found in the right directory.
wmayer
Site Admin
Posts: 16841
Joined: Thu Feb 19, 2009 10:32 am

Re: Setup to debug OCCT

Postby wmayer » Sun May 31, 2020 6:29 am

IIRC the system wide OCC on my old Linux box was 6.x and because the major version is added to the linking library name it didn't pick up the system version.

Now in your case both of your OCC versions are 7.x. I wonder whether there is a way that also the minor version number can be added to the linking library.
wmayer
Site Admin
Posts: 16841
Joined: Thu Feb 19, 2009 10:32 am

Re: Setup to debug OCCT

Postby wmayer » Tue Jun 02, 2020 7:05 pm

abdullah wrote:
Sun May 31, 2020 4:56 am
ping
You may try to change the soname of the shared libraries of OCC. When you call

Code: Select all

objdump -p libTKGeomBase.so | grep SONAME
you will get libTKGeomBase.so.7, i.e. it only includes the major version number.

Now you can try to also include the minor version number. Then I hope FreeCAD will find them without using LD_LIBRARY_PATH. Therefore open the file occt_toolkit.cmake and replace the line

Code: Select all

SOVERSION     "${OCC_VERSION_MAJOR}"
with

Code: Select all

SOVERSION     "${OCC_VERSION_MAJOR}.${OCC_VERSION_MINOR}"
Now rebuild OCC and FreeCAD.
abdullah
Posts: 3837
Joined: Sun May 04, 2014 3:16 pm

Re: Setup to debug OCCT

Postby abdullah » Wed Jun 03, 2020 5:46 pm

wmayer wrote:
Tue Jun 02, 2020 7:05 pm
Now rebuild OCC and FreeCAD.
Something very interesting happens. The library is not found:

libTKGeomBase

Code: Select all

     32198:     find library=libTKGeomBase.so.7.4 [0]; searching
     32198:      search cache=/etc/ld.so.cache
     32198:      search path=/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/lib:/usr/lib              (system search path)
     32198:       trying file=/lib/x86_64-linux-gnu/libTKGeomBase.so.7.4
     32198:       trying file=/usr/lib/x86_64-linux-gnu/libTKGeomBase.so.7.4
     32198:       trying file=/lib/libTKGeomBase.so.7.4
     32198:       trying file=/usr/lib/libTKGeomBase.so.7.4
     32198:     
Cannot create object 'Body': (libTKGeomBase.so.7.4: cannot open shared object file: No such file or directory)
However, other OCCT libraries are indeed found:

libTKernel

Code: Select all

     32198:     find library=libTKernel.so.7.4 [0]; searching
     32198:      search path=/usr/lib/x86_64-linux-gnu/hdf5/openmpi:/usr/lib/x86_64-linux-gnu/openmpi/lib:/mylocalfolder/usr/lib:/home/abdullah/github/freecad-build/Mod/Part:/home/abdullah/github/freecad-build/lib:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:              (RUNPATH from file ./FreeCAD)
     32198:       trying file=/usr/lib/x86_64-linux-gnu/hdf5/openmpi/libTKernel.so.7.4
     32198:       trying file=/usr/lib/x86_64-linux-gnu/openmpi/lib/libTKernel.so.7.4
     32198:       trying file=/mylocalfolder/usr/lib/libTKernel.so.7.4
It is like if the path that I pass to FreeCAD when building is taken into account for searching some OCCT libraries but not others...
wmayer
Site Admin
Posts: 16841
Joined: Thu Feb 19, 2009 10:32 am

Re: Setup to debug OCCT

Postby wmayer » Wed Jun 03, 2020 8:43 pm

Hmm, that's bad. I don't know if there is any other way than copying the shared libraries to one of the standard search directories.

In the meantime I have built occ from git with the above change. When I do

Code: Select all

ldd libTKGeomBase.so
for the installed libraries it doesn't find the dependencies even if looking from the same directory. However, when doing so from within the build directory it finds the dependencies. With objdump you can see that RUNPATH is set for the shared libraries in the build directory but removed for the installed files.
User avatar
sgrogan
Posts: 6205
Joined: Wed Oct 22, 2014 5:02 pm

Re: Setup to debug OCCT

Postby sgrogan » Wed Jun 03, 2020 9:55 pm

Maybe the problem begins in CMake?
https://github.com/FreeCAD/FreeCAD/blob ... Cade.cmake Is heavily tuned for FreeCAD, specifying only the include directory may not find/link a consistent solution.

OCC_DIR should point to the directory containing OpenCASCADEConfig.cmake in the locally installed OCC.
A quick look on windows I can only find OCE_DIR, in my case NOT-FOUND
There is also FREECAD_USE_OCC_VARIANT, in my case Community Edition (I'm using official OCCT)
I also found OCCT_CMAKE_FALLBACK, in my case unchecked
And I found it, OpenCASCADE_DIR points to the directory containing OpenCASCADEConfig.cmake, in my case C:/Libpacks/FreeCADLibs_12.1.6_x64_VC15/cmake
"fight the good fight"
wmayer
Site Admin
Posts: 16841
Joined: Thu Feb 19, 2009 10:32 am

Re: Setup to debug OCCT

Postby wmayer » Thu Jun 04, 2020 8:15 am

This is a workaround how I got it working:
  1. From the installation directory copy the folder "cmake" to the build directory underneath lin64/gcc/lib
  2. Copy the folder include to the build directory underneath lin64/gcc
  3. When configuring FreeCAD select for OpenCASCADE_DIR lin64/gcc/lib/cmake underneath the OCC build directory
The point is that the RUNPATH section is added to the shared OCC libraries in the build directory but get removed after installing them.