What I Got Stuck On
Today’s article is a memo recording a problem I encountered recently. By the way, I still don’t know the exact cause and am currently using a workaround.
In the Plugin I’m currently creating, I wanted to override functions in both C++ and Blueprint, so I implemented the pattern below in various places.
UFUNCTION(BlueprintNativeEvent, Category = "ObjectDeliverer")
void Start();
virtual void Start_Implementation();
In the example above, Start()
is expected to be called from another C++ class.
The intention was that a C++ class inheriting this class would override Start_Implementation()
, and a Blueprint would override Start()
, making it okay to inherit the class in either way.
After implementing and running it, it seemed to work fine for a while, but I noticed it occasionally crashed when Start()
was called.
うーん、このProcessEventのIsUnreachableにひっかかって落ちる問題なんだ?
— ayuma (@ayuma_x) January 29, 2019
BlueprintNativeEventの関数使っているところが該当するってことはわかったんだけど、どう直したらよいのか不明だ。
Debugging and tracing it, I found that ProcessEvent
was called within Start()
, and the function was being executed via reflection.
I understood that it was crashing at the check(!IsUnreachable)
within it, but I have no idea why that was happening.
Does IsUnreachable
mean it became a target for Garbage Collection (GC)??? I thought, and checked the code, but it was properly held by a variable specified with UPROPERTY()
.
Just in case, I decided to try another approach and also tried the content of the article below, but the phenomenon didn’t change.
How to prevent an object from being garbage collected without using UPROPERTY - Qiita
Even among the places using BlueprintNativeEvent
, it crashed at two different timings: sometime after startup, and during BeginDestroy
.
BeginDestroy
is still understandable, perhaps such function calls shouldn’t be made during termination, but I don’t understand the other pattern.
However, what’s slightly unusual is that it crashes within a worker thread run using FRunnableThread
, so I wonder if that’s related.
In the end, I couldn’t figure out the cause or how to fix it, leading to the pathetic conclusion of giving up on Blueprint overriding and removing BlueprintNativeEvent
, changing it to a normal virtual function.
After that, it stopped crashing completely, which is good for now, but it’s bothering me, so I want to take the time to investigate it properly somewhere.
The fact that it doesn’t crash afterwards means it wasn’t collected by GC, which makes it even more confusing…