Open ChernyshevDS opened 2 years ago
Thanks @ChernyshevDS, I'll be looking into geometry in the coming days as a few other issues have surfaced. Feel free to get in touch with a PR if you find a solution.
Can you clarify what you mean with the following?
but only in this method: Xbim crashed in XbimEdge::Init(IIfcCurve^ curve, ILogger^ logger) 🤦.
I think you say that the issue is gone in some place but resurfaces in the init of XbimEdge? Thnaks, Claudio
Thanks for the reply!
I think you say that the issue is gone in some place but resurfaces in the init of XbimEdge?
Yes. I've added GC::KeepAlive
at the end of the XbimSolid::Init
method, and I haven't got any exceptions in this method. But after running several tests converting the same problematic IFC model I've got another AccessViolation, in different place (XbimEdge::Init
), but for the same exact reason. So I've added GC::KeepAlive
in this method too, and I think it resolved the issue for me, because I can not reproduce it anymore.
So my only concern is that GC::KeepAlive
may be easily missed in some other places around Xbim codebase. This issue may arise in specific conditions, when memory consumption is high and GC is very active, so it can be hard to reproduce.
By the way, I could not reproduce the issue when building the Xbim.Geometry
binary in Debug mode. I guess that is because compiler optimizations are disabled in Debug, and somehow GC is not so aggressive when reclaiming managed memory.
That's great. Would you mind preparing a PR for this?
So my only concern is that GC::KeepAlive may be easily missed in some other places around Xbim codebase. This issue may arise in specific conditions, when memory consumption is high and GC is very active, so it can be hard to reproduce.
Sure that's a possibility, it does depend on the aggressiveness of GC. In production we generally convert the model in batches to reduce this risk, but we are also keen of removing places where this might be a problem
Thanks.
Would you mind preparing a PR for this?
Sure, I can try. Which branch should I target for? development
branch is... in development state.
Yes, development would be good.
On Tue, 1 Mar 2022 at 14:58, ChernyshevDS @.***> wrote:
Would you mind preparing a PR for this?
Sure, I can try. Which branch should I target for? development branch is... in development state.
— Reply to this email directly, view it on GitHub https://github.com/xBimTeam/XbimGeometry/issues/370#issuecomment-1055467896, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJY7MMKZDEJRPK4ID6IVFLU5YO7JANCNFSM5PRB7NOQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you commented.Message ID: @.***>
PR is ready, you are welcome: #371
I've just run into this issue, is there any chance I can get this in the master branch?
Hello. I'm facing a problem with Xbim: when loading certain models I get AccessViolationException somewhere inside geometry core of Xbim (stacktrace is in the end of this issue). The issue repeats on different models irregularly - a model may load successfully 9 times of 10.
Here I'll provide some investigations.
Stacktrace mentions
Tasks.Parallel
, so my first guess was the concurrency issues. Code I'm using to open IFC models looks like this:The crashed method is
CreateContext
.Xbim3DModelContext
allows to set maximum number of processing threads, and indeed, when settingMaxThreads
to 1 the issue does not show up. Unfortunately, it's not an option, because processing time becomes too large.I'm loading models which contain a lot of reinforcing bars. In IFC these bars are defined as a circle swept along a curve, so the most used method is
XbimSolid::Init(IIfcSweptDiskSolid^ repItem, ILogger^ logger)
.Here is the code to demonstrate my point, stripped of any irrelevant details:
The exception is raised inside
BuildSweptDiskSolid
, becausedirectrixWire
is not initialized. But it was verified right afterCreateDirectrix
(IsValid checks entity state)!I've noticed, that
XbimWire
is not a subclass ofTopoDS_Wire
, that's required byBuildSweptDiskSolid
- this code compiles becauseXbimWire
has an implicit conversion operator:Please notice that returned
TopoDS_Wire
instance is created in unmanaged memory and stored in IntPtr field, so it can not be tracked by GC.My point is:
XbimWire
instance gets destroyed by garbage collector right afteroperator TopoDS_Wire
execution, destroying wrapped native object referenced byptrContainer
, causing null pointer dereference in native code.XbimWire
object in not referenced anywhere after operator call inXbimSolid::Init
, so GC can rightfully destroy it.It can be fixed by adding
GC.KeepAlive(sweep);
at the end ofXbimSolid::Init
. I've tried it, and indeed the issue was gone, but only in this method: Xbim crashed inXbimEdge::Init(IIfcCurve^ curve, ILogger^ logger)
:facepalm:.Conclusion
I'm not sure, why this issue has appeared just now. MS had an analyzer warning regarding usage of unmanaged resources in managed code. As far as I can see, there are another places like this in Xbim codebase, where GC can reclaim managed memory destroying native resources underneath, while they are still in use. Maybe it's just I'm tryin to load rather large models in limited environment that causes GC to act a lot more often, causing issues like this one.
Thank you for your attention, I hope I can get some insight from devs.
Assemblies and versions affected:
I'm using XbimGeometry 5.1.403.
Additional Details
Crash stacktrace: