Skip to content

Conversation

@RunnerScrab
Copy link
Contributor

Written again using the 1.14.74 code as reference. Starfield 1.15.222 always seems to create BSScript::Objects in memory allocated/deallocated by the functions at 0x14224d5f0 (123785) and 0x14224d830 (123786) which wrap CRT malloc and free, but also do something with TLS. I've tested doing the same and also just newing and deleting them, and both ways seem to work.

I actually don't know why you would want to create an Object yet (I see them used fairly early in game initialization being bound to what seem to be script types), but IVirtualMachine::CreateObject will also do it and apparently manage the object's entire lifecycle for you.

Remove forgotten REX::INFO call
@RunnerScrab RunnerScrab force-pushed the RunnerScrab_ObjectDtor branch from c55bdd8 to 30fb498 Compare October 31, 2025 09:25
@RunnerScrab
Copy link
Contributor Author

Just realized my comment about that ObjectTypeInfo release function preventing double free is not correct, and need to find some other way to do it.

@RunnerScrab
Copy link
Contributor Author

RunnerScrab commented Oct 31, 2025

If the BSScript::Object has the last reference of its ObjectTypeInfo, the smart pointer is going to double free it / dereference a dangling pointer because the game's ObjectTypeInfo cleanup function will delete it but not clear the pointer.

I think that cleanup function could be equivalent to ~ObjectTypeInfo() when called with an argument of 0, and if that's true, implementing it as the destructor and letting the smart pointer perform the release may be a better option. Going to look into that.

[Update 1:]
It is actually a very small function in which ~ObjectTypeInfo() has been inlined which could be used as the destructor when called with 0, but not in ~Object(), which needs to call it with a 1. This is because, unfortunately in that cleanup function, the free() call which 0 disables is entangled with a bunch of actions on global variables and probably TLS that look like they have to happen.

I think incrementing the Object::type reference count then resetting the smart pointer just before calling the cleanup function will prevent the smart pointer from trying to delete an already deleted ObjectTypeInfo at the end of ~Object(), and while this seems dumb it may be the only option here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant