Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Referencing garbage collected objects causes crashes #64

Open
apple1417 opened this issue Oct 9, 2019 · 0 comments
Open

Referencing garbage collected objects causes crashes #64

apple1417 opened this issue Oct 9, 2019 · 0 comments
Labels
bug Something isn't working

Comments

@apple1417
Copy link
Contributor

If you have a reference to an object in Python and the object gets garbage collected in game, then trying to access the object in Python again will sometimes cause crashes.

Here is some example code to cause the crash.

import bl2sdk

bl2sdk.LoadPackage("GD_Mercenary_Streaming_SF")
GCObj = bl2sdk.FindObject("SkillDefinition", "GD_Mercenary_Skills.Brawn.Incite")

# Use a hook so we can try reference the object later
def HookMainMenuInput(caller: bl2sdk.UObject, function: bl2sdk.UFunction, params: bl2sdk.FStruct) -> bool:
    if params.ukey == "F1":
        bl2sdk.Log(str(GCObj))
        bl2sdk.Log(str(GCObj.SkillName))
    return True

bl2sdk.RemoveHook("WillowGame.FrontendGFxMovie.SharedHandleInputKey", "GCDemo")
bl2sdk.RegisterHook("WillowGame.FrontendGFxMovie.SharedHandleInputKey", "GCDemo", HookMainMenuInput)

To test this code run it on the main menu, then wait for the next GC cycle and press F1. While waiting you can run getall SkillDefinition Name in console to see what objects are loaded. Once the object has been removed pressing F1 might crash the game. The crash is not consistent, but still relatively common. If the game doesn't crash then it will never crash using that reference (so re-execute the file), and the log file will contain the following.

>>> pyexec GCDemo.py <<<
[HookManager] (EngineHooks) ERROR: Failed to remove hook "GCDemo" for "WillowGame.FrontendGFxMovie.SharedHandleInputKey"
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
Incite
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
Incite
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
None
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
None


>>> pyexec GCDemo.py <<<
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
Incite
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
Incite

<Game Crashes>

Note that the hook fires on both key press and release, hence the double logging.

Removing the second log line sometimes gives the following output instead. I have never seen it happen with both log calls, but as the crash is inconsistent anyway it might still happen.

>>> pyexec GCDemo.py <<<
[HookManager] (EngineHooks) ERROR: Failed to remove hook "GCDemo" for "WillowGame.FrontendGFxMovie.SharedHandleInputKey"
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
SkillDefinition GD_Mercenary_Skills.Brawn.Incite
SkillDefinition UnknownName.ByteProperty.Incite
SkillDefinition UnknownName.ByteProperty.Incite

<Game Crashes>

I believe making UObject::GetProperty() and UObject::SetProperty() check if the object has been GCed will probably prevent this, though the inconsistent nature of the crash may mean the issue is hidden deeper somewhere.

On a related note, the SDK doesn't have a good way for mods to check if an object has been GCed. Even if this crash gets fixed, mods that are working with objects that may be GCed will need to know this to prevent themselves from causing exceptions.

@apple1417 apple1417 added the bug Something isn't working label Jul 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant