Kode / Kha

Ultra-portable, high performance, open source multimedia framework.
http://kha.tech
zlib License
1.48k stars 171 forks source link

Intermittent crashes if HXCPP_GC_MOVING is enabled. #1451

Open davidmaletz opened 1 year ago

davidmaletz commented 1 year ago

Describe the bug If you enable the HXCPP_GC_MOVING flag (which makes the garbage collector more efficient/able to decrease fragmentation), then you'll get intermittent crashes due to kinc storing currentPipeline to the address of a potentially moved object (and perhaps other similar safety issues).

To Reproduce Unfortunately, this is tough to reproduce - as even if you enable the HXCPP_GC_MOVING flag, this crash will only occur if the garbage collector runs and moves the bound shader object at the wrong time. However, it's pretty easy to see how this happens from PipelineState.hx:

Binding a shader calls: @:functionCode("kinc_g4_set_pipeline(&pipeline);")

And pipeline is a struct in the actual PipelineState object, which is a haxe object that can be moved by the garbage collector: @:headerClassCode("kinc_g4_pipeline_t pipeline;")

I've identified many other cases of passing a reference of a struct in an object that can be moved which could be unsafe, but I've only seen a crash with pipelines because currentPipeline can hold a pointer to pipeline for a while.

Expected behavior currentPipleline must be aware that the object address can change, or should be passed a pointer to a kinc_g4_pipeline_t that was created via malloc/new and therefore never touched by the garbage collector. Alternatively, the garbage collector could be paused during the renderFrame call (I think enterGCFreeZone/exitGCFreeZone can do that - although those are for multithreading).

Execution Environment: This is on windows, but theoretically any kinc-hxcpp target should have this same problem.

RobDangerous commented 1 year ago

Kinc has nothing to do with hxcpp. Moving this to Kha.