Openrct2: Ubuntu headless server segfault on exit

Created on 12 Aug 2018  路  10Comments  路  Source: OpenRCT2/OpenRCT2


OS: Ubuntu Server 18.04
Version: v0.2.0-HEAD
Commit/Build: 0aff800


Running a headless server. When I type "exit", the game crashes with Segmentation fault (core dumped) The park is not saved.
The only things printed non-verbose in the console are:
sh: 1: xdg-mime: not found
ERROR[../src/openrct2/network/TcpSocket.cpp:147 (Listen)]: IPV6_V6ONLY failed. 92
When it crashes:
openrct2 $ exit
VERBOSE: finish openrct2 loop
openrct2 $ Segmentation fault (core dumped)

  • [x] Specific to multiplayer?

Steps to reproduce:

  1. $ ./OpenRCT2/openrct2-cli host ./Megaworld.sv6 --port 11753 --headless --verbose
  2. openrct2 $ exit

Save game:

Megaworld.zip

Let me know what I else I can provide.

bug

All 10 comments

I've got the same problem on 49c3060

My Segfault:

5150 Segmentation fault      (core dumped) ./openrct2-cli host ./userdata/BotanyBreakers.sv6 --port 11753 --password *** --headless --user-data-path ./userdata/

Would you mind running the game in valgrind to print a stack trace when the game segfaults?

Yeah no problem. I posted it to termbin: http://termbin.com/6xps and also uploaded it to GitHub: output.txt

What command should I use with valgrind? Just running it with no other arguments mixes everything in the console. I don't see any dump files.

This whole time I assumed "exit" also saved, because there is no other option to save with CLI. But this is not how the windowed version works either. I don't care if the game segfaults when it quits, I just need to be able to save for server reboots.

Turns out _there is no way to save_ except autosaves. I'm expected to make a bash script to load the most recent autosave when the server starts. That's ridiculous, but I'll do the needful. Feel free to drop the priority of this (and allocate it to having a save command, geez).

@tmo7452 valgrind is a tool get stacktraces when a program segfaults

Install it with

apt install valgrind -y

and then use valgrind as prefix when running OpenRCT2

valgrind ./OpenRCT2/openrct2-cli host ./Megaworld.sv6 --port 11753 --headless --verbose

That's all, just post the output of it.

@tmo7452 Turns out there is no way to save except autosaves. I'm expected to make a bash script to load the most recent autosave when the server starts. That's ridiculous, but I'll do the needful. Feel free to drop the priority of this (and allocate it to having a save command, geez).

I hope you realise this is something we work on in our spare time and that you're not spending a single dime towards us? Complaining that something is missing is not nice. The save_game command has been suggested already, just nobody has taken it up yet. https://github.com/OpenRCT2/OpenRCT2/issues/7549

If you really want to see something, you can implement it yourself or let us know why it would have priority over other things that need to be done.

I hope you realise this is something we work on in our spare time and that you're not spending a single dime towards us?

Where is the donation link? You've already fulfilled one of my childhood fantasies in adding multiplayer, I'll throw money toward that.

If you really want to see something, you can implement it yourself or let us know why it would have priority over other things that need to be done.

Not sure how far I'll get, but I'm setting up the environment now. Got any flowcharts or specifications of program flow? I don't have much experience with larger projects.

I would consider the ability to send chat to users ("Server shutting down in 30 seconds for maintenance") and manually save the park essential features to running a headless server. Seems silly to me to have a dedicated command line binary with those features absent. Right now it works, as long as no one is changing the park when it shuts down.

I managed to capture this on 18.04.1 LTS (Bionic Beaver) (4.9.0-8-amd64 #1 SMP Debian 4.9.110-3+deb9u4 (2018-08-21) x86_64 x86_64 x86_64 GNU/Linux):

[...]
Ready for clients...
VERBOSE: begin openrct2 loop
openrct2 $
(To exit, press ^C again or type exit)
openrct2 $
VERBOSE: finish openrct2 loop
==172== Invalid read of size 8
==172==    at 0x3E019B: language_get_string(unsigned short) (in /usr/local/bin/openrct2-cli)
==172==    by 0x3E2FBA: format_string_part(char**, unsigned long*, unsigned short, char**) (in /usr/local/bin/openrct2-cli)
==172==    by 0x3E32CA: format_string(char*, unsigned long, unsigned short, void*) (in /usr/local/bin/openrct2-cli)
==172==    by 0x3F46C7: Network::CloseServerLog() (in /usr/local/bin/openrct2-cli)
==172==    by 0x3F06F7: Network::~Network() (in /usr/local/bin/openrct2-cli)
==172==    by 0x71FA040: __run_exit_handlers (exit.c:108)
==172==    by 0x71FA139: exit (exit.c:139)
==172==    by 0x71D8B9D: (below main) (libc-start.c:344)
==172==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==172==
==172==
==172== Process terminating with default action of signal 11 (SIGSEGV)
==172==  Access not within mapped region at address 0x0
==172==    at 0x3E019B: language_get_string(unsigned short) (in /usr/local/bin/openrct2-cli)
==172==    by 0x3E2FBA: format_string_part(char**, unsigned long*, unsigned short, char**) (in /usr/local/bin/openrct2-cli)
==172==    by 0x3E32CA: format_string(char*, unsigned long, unsigned short, void*) (in /usr/local/bin/openrct2-cli)
==172==    by 0x3F46C7: Network::CloseServerLog() (in /usr/local/bin/openrct2-cli)
==172==    by 0x3F06F7: Network::~Network() (in /usr/local/bin/openrct2-cli)
==172==    by 0x71FA040: __run_exit_handlers (exit.c:108)
==172==    by 0x71FA139: exit (exit.c:139)
==172==    by 0x71D8B9D: (below main) (libc-start.c:344)
==172==  If you believe this happened as a result of a stack
==172==  overflow in your program's main thread (unlikely but
==172==  possible), you can try to increase the size of the
==172==  main thread stack using the --main-stacksize= flag.
==172==  The main thread stack size used in this run was 8388608.
==172==
==172== HEAP SUMMARY:
==172==     in use at exit: 356,953 bytes in 11,534 blocks
==172==   total heap usage: 323,742 allocs, 312,208 frees, 195,031,714 bytes allocated
==172==
==172== LEAK SUMMARY:
==172==    definitely lost: 234,617 bytes in 10,486 blocks
==172==    indirectly lost: 62 bytes in 2 blocks
==172==      possibly lost: 13,919 bytes in 293 blocks
==172==    still reachable: 108,355 bytes in 753 blocks
==172==         suppressed: 0 bytes in 0 blocks
==172== Rerun with --leak-check=full to see details of leaked memory
==172==
==172== For counts of detected and suppressed errors, rerun with: -v
==172== Use --track-origins=yes to see where uninitialised values come from
==172== ERROR SUMMARY: 48 errors from 12 contexts (suppressed: 0 from 0)
Segmentation fault

Full leak check: valgrind_leak-check-full.txt

It seems that OpenRCT2::GetContext(), when called from a chain of functions starting with ~Network(), returns a null pointer, which is then tried to be dereferenced.

What is returned is a singleton on OpenRCT2 instance, and the only spot where that pointer is nullified is in ~Context().

[EDIT]
[Suggested solution by @IntelOrca](https://gitter.im/OpenRCT2/OpenRCT2?at=5b85ce31c53ee54c18b82d0e) would be to remove the global static variable gNetwork and replace it by a Network property of the Context singleton object.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

deurklink picture deurklink  路  3Comments

Superjustinbros picture Superjustinbros  路  3Comments

Wirlie picture Wirlie  路  3Comments

Ionaru picture Ionaru  路  3Comments

Ryder17z picture Ryder17z  路  3Comments