Help porting OpenRCT2

As some of you may know/remember, in the last few months I’ve been trying on and off to port OpenRCT2, an engine capable of running Rollercoaster Tycoon 1 & 2 on modern OSes.


The port compiles and runs beautifully on 64bit Haiku on just software rendering.

Unfortunately the port crashes when playing certain maps or looking at certain title sequences due to a double-free related to strings.

This doesn’t happen on any other system so the OpenRCT2 devs are suspecting there may be some bug in Haiku’s C++ string implementation.

It’d be great if anybody with some knowledge on how that works gets to take a look at it. You can find a bunch of debug reports about it here: Preliminary Haiku OS support by Peppersawce · Pull Request #25659 · OpenRCT2/OpenRCT2 · GitHub

The first one is from a release build and the other 2 are from a debug build.

4 Likes

Can you share the patches and debug reports more directly? Github said I hit a rate limit (this is without having used it at all :D)

Lol, such a weird thing to happen.
But yeah, sure, here is the debug report and these are the patches used to build it.

I don’t think the issue is in the patches themselves, but maybe there’s bits of code that are needed but skipped on Haiku?

Anyway, in order to build it it has to be compiled with a recent clang version (19 is known to work) and nlohmann_json has to be patched or rolled back (3.12 has a bug that prevents compilation)
I haven’t tried building it with gcc recently but iirc that’s not supposed to work.

Sort of related, I have built myself a patched nlohmann_json to get rid of the bug but I’m not sure it’s haikuports material. The same patch will be included in nlohmann_json’s next release either way.

Rendering is done via SDL, right? Could it be a problem with Haiku SDL port?

That would actually be GCC and libstdc++ implementation, as far as I know, we make no change to that code on Haiku side. And it’s the same code that everyone else uses as well.

Did you try using the guarded heap? Something like this:

MALLOC_DEBUG=”g” LD_PRELOAD=/system/lib/libroot_debug.so ./yourProgram

It may crash earlier and nearer to where the memory is first getting corrupted.

2 Likes

I doubt it, on that front it’s actually one of the more stable SDL2 ports I’ve seen. Not everything works (“actual” fullscreen can crash) but its window can resize any way you want without crashing and that tends not to work usually.

I just ran a debug build through the guarded heap and the log does display some extra information this time around: I put it up here

You can inline debug reports here aswell :slight_smile:

This indicates pretty clearly that OpenRCT is performing a use-after-free. It looks like there might be a race of some sorts (note the freeing thread is different from the allocating thread.)

Haiku’s main malloc implementation is (now, on the nightlies) based on OpenBSD’s. Does OpenRCT2 run on OpenBSD? You can check if the same problem happens there.

1 Like

AFAIK we use the old pre-C++11 string ABI, which is not the default any more on most platforms. Maybe it wasn’t really tested with this configuration?

As far as I know, gcc supports both ABI at the same time since this was introduced in gcc5. I don’t see any patches remaining that would force the old configuration (which would fail building a lot of things in modern c++ anyways). So I assume the migration to the new ABI has been completed a long time ago?

I think it is this configure flag in the recipe: haikuports/sys-devel/gcc/gcc-13.3.0_2023_08_10.recipe at f7ab5b96fc0a663400b51921c2199f1906c63943 · haikuports/haikuports · GitHub

1 Like

Ah yes, you’re right.

Maybe we should change that, at least for new architectures like RISC-V and ARM?

I’m not sure it would make any difference to the RCT2 crash, since that just changes the internal layout of the classes. It will just make things slower, but user code shouldn’t be poking at the internal of the string class.