Dumper-7 should be using FindFunctionChecked on ProcessEvent calls to account for overrides. #447

Open
opened 2025-11-25 07:51:58 +01:00 by ghjaiz · 2 comments
ghjaiz commented 2025-11-25 07:51:58 +01:00 (Migrated from github.com)

Dumper-7 does not call UFunctions properly.

Currently, this is the generator's FunctionImplementation string.

static class UFunction* Func = nullptr;

if (Func == nullptr)
	Func = {}->GetFunction({}, {});

By "hardcoding" the C++ class name as the first parameter of the GetFunction call, it's explicitly telling Unreal to get the function from a specific class, even when the actual instance might have an override.

Using FixedOuterName is not a foolproof solution in this scenario. Sometimes FixedOuterName gets the Blueprint class name when dumping Blueprint classes, but it can't know if that function will be overridden later.

FixedOuterName is just whatever class owned the function during the dump, not necessarily the right class to call it from at runtime.

FindFunctionChecked

FindFunctionChecked handles this dynamically. It just finds the right function to call. If there's an override, it finds it. If not, it uses the parent version. I believe this is the only way to correctly handle blueprint overrides that you can't predict when generating code.

Dumper-7's generator output should look something like this:

static class UFunction* Func = nullptr;

if (Func == nullptr)
    Func = Class->FindFunctionChecked(FName("FunctionName"));

The code above resembles what the engine itself does, as shown through this screenshot from IDA:

Image

If there's no FName constructor, UKismetStringLibrary::Conv_StringToName could be used.

For compatibility, you can find the address to FindFunctionChecked using a single string reference in memory. I have confirmed the existence of that string starting at least from UE4.16 -> latest UE5. It's very likely that it exists on earlier engine versions.

The string ref is: "Failed to find function %s in %s".

Why does this matter?

It matters because this is not intended behavior. Blueprint overrides, if any, are not supposed to be ignored.

With this issue, I intend to bring attention to this problem to Fischsalat, the project's main developer. I will make a pull request eventually if I need to, I just need to learn this codebase fully.

### **Dumper-7 does not call UFunctions properly.** Currently, this is the generator's FunctionImplementation string. ``` static class UFunction* Func = nullptr; if (Func == nullptr) Func = {}->GetFunction({}, {}); ``` By "hardcoding" the C++ class name as the first parameter of the GetFunction call, it's explicitly telling Unreal to get the function from a specific class, even when the actual instance might have an override. Using FixedOuterName is not a foolproof solution in this scenario. Sometimes FixedOuterName gets the Blueprint class name when dumping Blueprint classes, but it can't know if that function will be overridden later. FixedOuterName is just whatever class owned the function during the dump, not necessarily the right class to call it from at runtime. ### **FindFunctionChecked** FindFunctionChecked handles this dynamically. It just finds the right function to call. If there's an override, it finds it. If not, it uses the parent version. I believe this is the only way to correctly handle blueprint overrides that you can't predict when generating code. Dumper-7's generator output should look something like this: ``` static class UFunction* Func = nullptr; if (Func == nullptr) Func = Class->FindFunctionChecked(FName("FunctionName")); ``` The code above resembles what the engine itself does, as shown through this screenshot from IDA: <img width="743" height="183" alt="Image" src="https://github.com/user-attachments/assets/39f2425d-868d-4035-a565-59648da388d6" /> **If there's no FName constructor, UKismetStringLibrary::Conv_StringToName could be used.** For compatibility, you can find the address to FindFunctionChecked using a single string reference in memory. I have confirmed the existence of that string starting at least from UE4.16 -> latest UE5. It's very likely that it exists on earlier engine versions. The string ref is: "Failed to find function %s in %s". ### **Why does this matter?** It matters because this is not intended behavior. Blueprint overrides, if any, are not supposed to be ignored. With this issue, I intend to bring attention to this problem to Fischsalat, the project's main developer. I will make a pull request eventually if I need to, I just need to learn this codebase fully.
igromanru commented 2025-11-25 15:04:48 +01:00 (Migrated from github.com)

I think you missed the point that the function pointer is cached with static class UFunction* Func.
You can’t use FindFunctionChecked in a base class, the first call will cache the pointer to the UFunction of the object’s class and may call the wrong function later.
I don't see a good way to solve this in the Dumper, since not all Blueprint classes are loaded at all times and the Dumper can't know how many child classes a parent class has.

I think you're better off making your own function-wrapper, and call the function you need.

I think you missed the point that the function pointer is cached with `static class UFunction* Func`. You can’t use `FindFunctionChecked` in a base class, the first call will cache the pointer to the UFunction of the object’s class and may call the wrong function later. I don't see a good way to solve this in the Dumper, since not all Blueprint classes are loaded at all times and the Dumper can't know how many child classes a parent class has. I think you're better off making your own function-wrapper, and call the function you need.
ghjaiz commented 2025-11-26 01:52:18 +01:00 (Migrated from github.com)

I think you missed the point that the function pointer is cached with static class UFunction* Func. You can’t use FindFunctionChecked in a base class, the first call will cache the pointer to the UFunction of the object’s class and may call the wrong function later. I don't see a good way to solve this in the Dumper, since not all Blueprint classes are loaded at all times and the Dumper can't know how many child classes a parent class has.

I think you're better off making your own function-wrapper, and call the function you need.

You are right, and the only workaround in this situation to me is to not cache the function pointers. Unreal calls FindFunctionChecked with cached FNames (ones that are already in memory), but the function pointer is entirely local per call.

> I think you missed the point that the function pointer is cached with `static class UFunction* Func`. You can’t use `FindFunctionChecked` in a base class, the first call will cache the pointer to the UFunction of the object’s class and may call the wrong function later. I don't see a good way to solve this in the Dumper, since not all Blueprint classes are loaded at all times and the Dumper can't know how many child classes a parent class has. > > I think you're better off making your own function-wrapper, and call the function you need. You are right, and the only workaround in this situation to me is to not cache the function pointers. Unreal calls FindFunctionChecked with cached FNames (ones that are already in memory), but the function pointer is entirely local per call.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
software-migration-backups/Dumper-7-17-05-2026#447
No description provided.