Is it possible to display AIS objects from a thread?

I'm using several threads to speed up my app. When I try to display an AIS_Shape from one of the threads, it crashes.

I'm using MMGT_OPT=0 and I call
Standard::SetReentrant (Standard_True);
before starting any threads.

Is this unsupported, or am I doing something wrong?
using OCC 6.3.0 on amd64.
app and occ are compiled with g++ version "g++ (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"

Thank you
Mark
------------------------------------------------------------------------------------------------

%CMN-E-INVALIDPTR, Invalid pointer value passed in function cmn_freemem

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffde90b710 (LWP 29032)]
0x00007fffe34aa102 in TsmSetElementPointerAtLabel () from /opt/occ63/lib/libTKOpenGl.so
(gdb) bt
#0 0x00007fffe34aa102 in TsmSetElementPointerAtLabel () from /opt/occ63/lib/libTKOpenGl.so
#1 0x00007fffe34a1e28 in call_togl_contextstructure () from /opt/occ63/lib/libTKOpenGl.so
#2 0x00007fffe3462dcd in OpenGl_GraphicDriver::ContextStructure(CALL_DEF_STRUCTURE const&) ()
from /opt/occ63/lib/libTKOpenGl.so
#3 0x00007ffff5c7d57e in Graphic3d_Structure::SetPrimitivesAspect (this=0x7fffddf57c80, CTX=...)
at ../../../src/Graphic3d/Graphic3d_Structure.cxx:1296
#4 0x00007ffff5c9edd3 in Prs3d_Presentation (this=0x7fffddf57c80, aViewer=..., Init=1)
at ../../../src/Prs3d/Prs3d_Presentation.cxx:66
#5 0x00007ffff5cadea0 in PrsMgr_Prs (this=0x7fffddf57c80, aStructureManager=...,
aPresentation3d=@0x7fffde90ab88, aTypeOfPresentation=PrsMgr_TOP_ProjectorDependant)
at ../../../src/PrsMgr/PrsMgr_Prs.cxx:10
#6 0x00007ffff5ca8236 in PrsMgr_Presentation3d (this=0x7fffddf5bfc8, aPresentationManager=...,
aPresentableObject=...) at ../../../src/PrsMgr/PrsMgr_Presentation3d.cxx:27
#7 0x00007ffff5cacbaf in PrsMgr_PresentationManager3d::newPresentation (this=0x7fffe6dc3f58,
aPresentableObject=...) at ../../../src/PrsMgr/PrsMgr_PresentationManager3d.cxx:16
#8 0x00007ffff5caa8fc in PrsMgr_PresentationManager::AddPresentation (this=0x7fffe6dc3f58,
aPresentableObject=..., aMode=0) at ../../../src/PrsMgr/PrsMgr_PresentationManager.cxx:204
#9 0x00007ffff5ca9bb5 in PrsMgr_PresentationManager::Display (this=0x7fffe6dc3f58, aPresentableObject=...,
aMode=0) at ../../../src/PrsMgr/PrsMgr_PresentationManager.cxx:18
#10 0x00007ffff5bb0949 in AIS_InteractiveContext::Display (this=0x7fffe6dd3380, anIObj=..., updateviewer=1)
at ../../../src/AIS/AIS_InteractiveContext.cxx:475
#11 0x00007ffff32ceb07 in canonMotionless::display (this=0x7fffe0ab9bc0) at canonMotionless.cc:149
#12 0x00007ffff32c6e71 in g2m::makeSolidsThread () at g2m.cc:353
#13 0x00007ffff27348ba in start_thread (arg=) at pthread_create.c:300
#14 0x00007ffff094601d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#15 0x0000000000000000 in ?? ()
(gdb)

Mark's picture

I put the call to AIS_InteractiveContext::Display in the main thread, and now I get various other segfaults depending on the file I read. For example:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffdadb9710 (LWP 13599)]
0x00007fffefd7ec43 in BSplCLib::BuildKnots (Degree=2, Index=3, Periodic=0, Knots=..., Mults=..., LK=@0x0)
at ../../../src/BSplCLib/BSplCLib.cxx:1408
1408 knot[0] = pkn[j]; j++;
(gdb) i thread
5 Thread 0x7fffda5b8710 (LWP 13600) 0x00007ffff7a6d420 in TColStd_Array1OfReal::operator() (
this=0x7fffd9a07c00, Index=3) at ../../../inc/TColStd_Array1OfReal.hxx:108
* 4 Thread 0x7fffdadb9710 (LWP 13599) 0x00007fffefd7ec43 in BSplCLib::BuildKnots (Degree=2, Index=3,
Periodic=0, Knots=..., Mults=..., LK=@0x0) at ../../../src/BSplCLib/BSplCLib.cxx:1408
3 Thread 0x7fffdb5ba710 (LWP 13598) AppDef_BSplineCompute::Compute (this=0x7ffff41c5c18, Line=...,
fpt=32767, lpt=-199460016, Para=..., Knots=..., Mults=...) at ../../../inc/Approx_BSplComputeLine.gxx:858
2 Thread 0x7fffdbdbb710 (LWP 13597) AppDef_BSplineCompute::Compute (this=0x7ffff41c5c18, Line=...,
fpt=32767, lpt=-199460016, Para=..., Knots=..., Mults=...) at ../../../inc/Approx_BSplComputeLine.gxx:858
1 Thread 0x7ffff7eb1780 (LWP 13591) 0x00007ffff273d0bd in read () at ../sysdeps/unix/syscall-template.S:82
(gdb) bt
#0 0x00007fffefd7ec43 in BSplCLib::BuildKnots (Degree=2, Index=3, Periodic=0, Knots=..., Mults=..., LK=@0x0)
at ../../../src/BSplCLib/BSplCLib.cxx:1408
#1 0x00007fffefd90d74 in PrepareEval (u=@0x7fffdadb6f28, index=@0x7fffdadb6f30, dim=@0x7fffdadb6f34,
rational=@0x7fffdadb6f24, Degree=2, Periodic=0, Poles=..., Weights=..., Knots=..., Mults=...)
at ../../../inc/BSplCLib_CurveComputation.gxx:410
#2 0x00007fffefd9185c in BSplCLib::DN (U=9, N=1, Index=0, Degree=2, Periodic=0, Poles=..., Weights=...,
Knots=..., Mults=..., VN=...) at ../../../inc/BSplCLib_CurveComputation.gxx:689
#3 0x00007fffef7685e9 in Geom_BSplineCurve::DN (this=0x7fffd9c6bf60, U=9, N=1)
at ../../../src/Geom/Geom_BSplineCurve_1.cxx:283
#4 0x00007ffff03c867e in GeomConvert_CompCurveToBSplineCurve::Add (this=0x7fffdadb7910, FirstCurve=...,
SecondCurve=..., After=0, WithRatio=1, MinM=0)
at ../../../src/GeomConvert/GeomConvert_CompCurveToBSplineCurve.cxx:118
#5 0x00007ffff03c83de in GeomConvert_CompCurveToBSplineCurve::Add (this=0x7fffdadb7910, NewCurve=...,
Tolerance=9.9999999999999995e-08, After=0, WithRatio=1, MinM=0)
at ../../../src/GeomConvert/GeomConvert_CompCurveToBSplineCurve.cxx:86
#6 0x00007ffff7203985 in BRepFill_SectionPlacement::Perform (this=0x7fffdadb7ba0, WithContact=0,
WithCorrection=1, Vertex=...) at ../../../src/BRepFill/BRepFill_SectionPlacement.cxx:134
#7 0x00007ffff720343b in BRepFill_SectionPlacement (this=0x7fffdadb7ba0, Law=..., Section=..., Vertex=...,
WithContact=0, WithCorrection=1) at ../../../src/BRepFill/BRepFill_SectionPlacement.cxx:82
#8 0x00007ffff71ffa0e in BRepFill_PipeShell::Place (this=0x7fffd9d6fec0, Sec=..., W=...,
param=@0x7fffdadb7ed8) at ../../../src/BRepFill/BRepFill_PipeShell.cxx:992
#9 0x00007ffff71fec36 in BRepFill_PipeShell::Prepare (this=0x7fffd9d6fec0)
at ../../../src/BRepFill/BRepFill_PipeShell.cxx:834
#10 0x00007ffff71fd920 in BRepFill_PipeShell::Build (this=0x7fffd9d6fec0)
at ../../../src/BRepFill/BRepFill_PipeShell.cxx:568
#11 0x00007ffff7710f60 in BRepOffsetAPI_MakePipeShell::Build (this=0x7fffdadb8650)
at ../../../src/BRepOffsetAPI/BRepOffsetAPI_MakePipeShell.cxx:209
#12 0x00007ffff32d1632 in canonMotion::sweepSolid (this=0x7fffdf908400) at canonMotion.cc:221
#13 0x00007ffff32d0612 in canonMotion::computeSolid (this=0x7fffdf908400) at canonMotion.cc:81
#14 0x00007ffff32c79c1 in g2m::makeSolidsThread () at g2m.cc:366
#15 0x00007ffff27358ba in start_thread (arg=) at pthread_create.c:300
#16 0x00007ffff094701d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112

I have applied some of the patches noted in the forums, so I downloaded fresh source just in case. It didn't help.

JuryS's picture

Hi, Mark. Try your code under windows.

Mark's picture

That would be a real pain, as I would have to install visual studio, figure out how to build, and probably make a number of changes to the code. Plus, it uses emc2's interpreter to decipher gcode, so I'd have to make that program work on windows as well.

I can run the program 5 times on one file, and get 5 different segfaults. That make me think that the problem is with tbb_malloc_proxy, since it probably doesn't clear freshly allocated memory like occ's mmgt does.

Andrey Betenev's picture

Hello Mark,

As soon as you are working on Linux, I would suggest you trying to run your application under Valgrind (http://valgrind.org). It can help you to detect many typical problems, including various threading issues.

Hope this helps

Andrey

Mark's picture

I disabled the threads and fiddled with the env vars.
With a single thread, any combination of MMGT_OPT and MMGT_CLEAR is fine, with or without TBB's malloc_proxy.

With threads, none of those combinations is safe. I get segfaults except when malloc_proxy is disabled, MMGT_OPT=0, and MMGT_CLEAR=0. In that one case, I always get "double free or corruption (fasttop)"

I expected occ to handle threads much better than this! :(
I hope it's addressed in 6.4.

If anyone wants to look into it, see http://code.google.com/p/cam-occ/wiki/CompileOnUbuntu for how to get the source and compile.

Roman Lygin's picture

Hi Mark,

AIS is not thread-safe, there are multiple uses of static variables (often without any good reason). It cannot be concurrently used from several threads. I'm not sure if attempt to use visualization from multiple threads can bring any speed up even theoretically - given calls to OpenGL are still have to be ordered.
If you are just trying to call AIS from another thread and this thread is a single one, then it should presumably be fine. I don't remember there is any requirement/dependence that it must be the main thread only (which the process started).

As soon as Intel Inspector XE is available on Linux (it's currently in Beta and I'm not sure if it's publicly available), you might to try to see where you get data races.

I also don't think that your issue has anything to do with TBB directly - it's likely the consequence of data races in AIS.

Hope this helps.
Roman
---
opencascade.blogspot.com - the Open CASCADE blog
www.cadexchanger.com - CAD Exchanger, your 3D data translator

JuryS's picture

Also don't anybody use the Intel Inspector and don't anybody found any ways with next. Because there is more problem with default opengl driver that you think.

JuryS's picture

Mark, if you see my post is previous of yours than you can find simple project for OCC sources with QT IDE. Try with next:

comment the function until your bug is going and you need to recompile the librarys of OCC for all times that you trying it.
Also, MMGT_OPT and MMGT_CLEAR is don't working for me. I don't found where this options is used in OCC sources. If only with WORK or JAVA, because I don't use this librarys.

You may take me your code on my e-mail and I try to help you .
Also sorry for my bad English.

Mark's picture

JuryS, I've done a fair amount with OCC in the past and didn't have much trouble until I tried to use multithreading. So trying another app - or another way to compile - isn't going to help me very much.

"comment the function until your bug is gone"
This won't help because I get a different error each time I run: a sure sign that the problem is deep within occ, and/or there are many points of failure.

"I don't found where this options is used in OCC sources"
$ cd OpenCASCADE6.3.0/ros/src
$ grep -inr MMGT_CLEAR *
Standard/Standard.cxx:44: bClear = atoi((var = getenv("MMGT_CLEAR" )) ? var : "1" );