xBimTeam / XbimGeometry

XbimGeometry contains the CLR interop libraries and the c++ engine used to compute the 3D geometry of models.
https://xbimteam.github.io/
Other
255 stars 128 forks source link

Multi-Threading Crash (AccessViolationException) #489

Open WalchAndreas opened 2 months ago

WalchAndreas commented 2 months ago

While loading Ifc-projects, an AccessViolationException is thrown (often), but investigations conclude it is a multi-threading issue.

Assemblies and versions affected:

official nuget-packages:

local nuget-packages from source (branch feature/netcore)

remote: https://www.myget.org/F/xbim-develop/api/v3/index.json

Stacktrace

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Repeat 2 times:
--------------------------------
   at <Module>.BRepBuilderAPI_MakeEdge2d.{ctor}(BRepBuilderAPI_MakeEdge2d*, opencascade.handle<Geom2d_Curve>*)
--------------------------------
   at <Module>.NWireFactory.BuildWire(NWireFactory*, TopoDS_Wire*, NCollection_Sequence<opencascade::handle<Geom2d_BoundedCurve> >*, Double, Double)
   at Xbim.Geometry.Factories.WireFactory.BuildWire(TopoDS_Wire*, Xbim.Ifc4.Interfaces.IIfcIndexedPolyCurve, Boolean)
   at Xbim.Geometry.Factories.WireFactory.BuildWire(TopoDS_Wire*, Xbim.Ifc4.Interfaces.IIfcCurve, Boolean)
   at Xbim.Geometry.Factories.ProfileFactory.BuildProfileWire(TopoDS_Wire*, Xbim.Ifc4.Interfaces.IIfcArbitraryClosedProfileDef)
   at Xbim.Geometry.Factories.ProfileFactory.BuildProfileFace(TopoDS_Face*, Xbim.Ifc4.Interfaces.IIfcArbitraryClosedProfileDef)
   at Xbim.Geometry.Factories.ProfileFactory.BuildProfileFace(TopoDS_Face*, Xbim.Ifc4.Interfaces.IIfcProfileDef)
   at Xbim.Geometry.Factories.SolidFactory.BuildExtrudedAreaSolid(TopoDS_Shape*, Xbim.Ifc4.Interfaces.IIfcExtrudedAreaSolid, Xbim.Ifc4.Interfaces.IIfcProfileDef)
   at Xbim.Geometry.XbimSolid.Init(Xbim.Ifc4.Interfaces.IIfcExtrudedAreaSolid, Xbim.Ifc4.Interfaces.IIfcProfileDef, Microsoft.Extensions.Logging.ILogger)
   at Xbim.Geometry.XbimSolid.Init(Xbim.Ifc4.Interfaces.IIfcSweptAreaSolid, Xbim.Ifc4.Interfaces.IIfcProfileDef, Microsoft.Extensions.Logging.ILogger)
   at Xbim.Geometry.XbimSolid.Init(Xbim.Ifc4.Interfaces.IIfcSolidModel, Microsoft.Extensions.Logging.ILogger)
   at Xbim.Geometry.XbimSolid..ctor(Xbim.Ifc4.Interfaces.IIfcSweptAreaSolid, Microsoft.Extensions.Logging.ILogger, Xbim.Geometry.Services.ModelGeometryService)
   at Xbim.Geometry.XbimGeometryCreator.CreateSolid(Xbim.Ifc4.Interfaces.IIfcExtrudedAreaSolid, Microsoft.Extensions.Logging.ILogger)
   at Xbim.Geometry.XbimGeometryCreator.CreateSolid(Xbim.Ifc4.Interfaces.IIfcSweptAreaSolid, Microsoft.Extensions.Logging.ILogger)
   at Xbim.Geometry.XbimGeometryCreator.Create(Xbim.Ifc4.Interfaces.IIfcGeometricRepresentationItem, Xbim.Ifc4.Interfaces.IIfcAxis2Placement3D, Microsoft.Extensions.Logging.ILogger)
   at Xbim.Geometry.XbimGeometryCreator.Create(Xbim.Ifc4.Interfaces.IIfcGeometricRepresentationItem, Microsoft.Extensions.Logging.ILogger)
   at Xbim.ModelGeometry.Scene.Xbim3DModelContext+<>c__DisplayClass44_0.<WriteShapeGeometries>b__0(Int32)
   at System.Threading.Tasks.Parallel+<>c__DisplayClass43_0`2[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<PartitionerForEachWorker>b__1(System.Collections.IEnumerator ByRef, Int64, Boolean ByRef)
   at System.Threading.Tasks.TaskReplicator+Replica.Execute()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(System.Threading.Thread, System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef, System.Threading.Thread)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()

Minimal file to reproduce the issue:

Loading the Minimal Test Project crashes (very often) in a multi threading (standard) environment.

var model = IfcStore.Open(filePath, editor);

// enable caching - we only load once and do not change the project
model.BeginInverseCaching(); 
model.BeginEntityCaching();

if (model.GeometryStore.IsEmpty)
{
    var context = new Xbim3DModelContext(model);
    //upgrade to new geometry representation, uses the default 3D model
    context.CreateContext(null, true, false);
}

Workaround - Single Threading

Enforce single threading by setting Xbim3DModelContext.MaxThreads = 1.

var context = new Xbim3DModelContext(model);
context.MaxThreads = 1; // <--------------------------USE THIS TO ENFORCE SINGLE-THREADING
context.CreateContext(null, true, false);