From 5891078b21ae101e04b7f0e21ecf1592f10a36b2 Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Tue, 2 Mar 2021 12:32:52 -0600 Subject: [PATCH] More server wrapper hardening --- .efrocachemap | 56 +++++++++++----------- assets/src/server/ballisticacore_server.py | 33 +++++++++---- src/ballistica/ballistica.cc | 2 +- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index c2e9eaa5..6a2cde08 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3932,26 +3932,26 @@ "assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450", "assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e", "assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f", - "build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/cf/82/719777140fd1fcde30bb1a1740bc", - "build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/a3/64/87629d2373f5976ccbd8ab042e17", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f6/97/e2ceb20fbf9b383c6b6b7f9fad2b", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/22/b8/b74e35979b737971b408d2220e01", - "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/fc/17/c93a61a777af2812ed4894d01371", - "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5c/67/630bddbe7f8979a6856da80b4fbf", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a4/2e/4b65335326e2a08ede747767f28d", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/77/35/f1999ee15f81aea7eb3d4ee86430", - "build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/4d/97/62d0a5435d78e86ee1fa8f937e78", - "build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/36/18/7697e223720102efba3a64b4a9ef", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e4/41/5a26cffb3cbde32bf02bc891a581", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/76/9f/05fc591f4f7b2dd0dff70f464c68", - "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b2/3e/0b66052f122e3e562914ce07b8ff", - "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/cd/eb/6d9a103b9daca628dc9c1e2e6534", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/70/ec/7fe66dd2a1889f8134e986074c5c", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ab/a2/d7987bd4b498bb0ffe727687ec5d", - "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c0/64/d1ff2ffc99457024ae4c9bd8ae27", - "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/09/be/01f2b6d88c29f93628f5c4b3be26", - "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/09/e8/e1a06b2a39b101d0d454b2ef97f9", - "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/a6/5e/83d42bcace65e1850ff8ca642d40", + "build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/91/bb/1ef31ad5e3cd6b6bbba8a5a7f7d1", + "build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/4b/24/de262281152cd225feccda2ce005", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d9/dd/52837822996294b695e4a326782e", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bc/44/74b2f008a6134ae1bd786160974c", + "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/0a/f5/32b5902518b3a3710b14ba1e67d8", + "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ad/9f/0fa966fdab131e48e25044ead334", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/61/d7/552bb7b0ba6fb2dc0bf9334dcf88", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/14/3c/9f08a64158f3772fbdb86d5018dc", + "build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/68/89/0b5cad5c73ede1d9fe36283fad84", + "build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/67/f8/e37f3567363b54e919afafa84780", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7e/e3/df25fbed65d0e29e2d0b5b31420f", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/98/24/692133c71131fbed1ba9ddc1b8a6", + "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f0/02/f0013b6f9756cac4a41c44959fdf", + "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f4/5f/29e114ae3fddabf4d96f887b76fe", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/04/78/133d99d9af2bfe5efbadf08891b6", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d4/28/d9d9a1cd58331fdaf76d93f01393", + "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a9/7d/04d6129614ba40a92f85e8b89e4d", + "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/01/48/fdbfb3165d04b138a52a1856081d", + "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/35/75/4ece6f6242d054636bc050c4085d", + "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/7c/97/482538973686e016d17f3dd2040f", "build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/bf/393694ea67f3d590dd2706c9955e", "build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/78/cb/bb9ae4f896f862074057c8e36e1d", "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ae/bd/39d7b885f7f01e81d0e96f0f85ce", @@ -3960,12 +3960,12 @@ "build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/d9/563a6949d2c4db5a915c54460fbc", "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/6a/42fe8d2e34f95e1b3282e8422344", "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/50/cf/bad44b07a4022aee3001002086b5", - "build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/71/eb/ad72e09d291df9d9b4685cb54aa6", - "build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7a/1a/26323a70df1141ded2d5232e7fe3", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f5/3a/fde17851c9eac36180af05764fbe", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/50/d6/eb53c0ce021de0a38796cc4381ca", - "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/96/2f/1cc42deb9241d5e3e0bb2a625652", - "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/01/64/d0498f46418fab5529631124ac4f", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4e/05/6cae06d531c021fb58dd8ca3429a", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/04/03/ed60867a5c24beb140180c252b90" + "build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/16/53/c2b0cb27fb71ac06f6485131caab", + "build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/67/1f/1668153643ae1ff4a32ba4b17189", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8e/41/244688fcdec98868f4ad0839e983", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6b/9c/0e8a2f1e85980031bd1223e0f15a", + "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/95/a6/e4c82a313a9161cfcc336dfea377", + "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/23/98/20369f4b03a712838e393e630ce8", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9f/ce/4945b4655e9bccfabac1920331b4", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5b/10/0666f41a0c1a9d0f07bd0abbf61e" } \ No newline at end of file diff --git a/assets/src/server/ballisticacore_server.py b/assets/src/server/ballisticacore_server.py index db758886..900739f4 100755 --- a/assets/src/server/ballisticacore_server.py +++ b/assets/src/server/ballisticacore_server.py @@ -83,13 +83,14 @@ class ServerManagerApp: self._last_config_mtime_check_time: Optional[float] = None self._should_report_subprocess_error = False self._running = False + self._interpreter_start_time: Optional[float] = None self._subprocess: Optional[subprocess.Popen[bytes]] = None self._subprocess_launch_time: Optional[float] = None self._subprocess_sent_config_auto_restart = False self._subprocess_sent_clean_exit = False self._subprocess_sent_unclean_exit = False self._subprocess_thread: Optional[Thread] = None - self._subprocess_exited_cleanly: bool = False + self._subprocess_exited_cleanly: Optional[bool] = None # This may override the above defaults. self._parse_command_line_args() @@ -185,7 +186,6 @@ class ServerManagerApp: def _run_interactive(self) -> None: """Run the app loop to completion interactively.""" import code - self._prerun() # Print basic usage info for interactive mode. @@ -204,6 +204,7 @@ class ServerManagerApp: # Now just sit in an interpreter. # TODO: make it possible to use IPython if the user has it available. try: + self._interpreter_start_time = time.time() code.interact(local=context, banner='', exitmsg='') except SystemExit: # We get this from the builtin quit(), our signal handler, etc. @@ -436,9 +437,9 @@ class ServerManagerApp: cls._par('Auto-restart is enabled by default, which means the' ' server manager will restart the server binary whenever' ' it exits (even when uncleanly). Disabling auto-restart' - ' will instead cause the server manager to exit after a' - ' single run, returning an error code if the binary' - ' did so.') + '\n' + ' will cause the server manager to instead exit after a' + ' single run and also to return error codes if the' + ' server binary did so.') + '\n' f'{Clr.BLD}--no-config-auto-restart{Clr.RST}\n' + cls._par( 'By default, when auto-restart is enabled, the server binary' ' will be automatically restarted if changes to the server' @@ -482,8 +483,6 @@ class ServerManagerApp: file=sys.stderr, flush=True) - time.sleep(1) - for _j in range(retry_seconds): # If the app is trying to die, drop what we're doing. if self._done: @@ -557,7 +556,7 @@ class ServerManagerApp: def _handle_term_signal(self, sig: int, frame: FrameType) -> None: """Handle signals (will always run in the main thread).""" del sig, frame # Unused. - raise SystemExit() + sys.exit(1 if self._should_report_subprocess_error else 0) def _run_server_cycle(self) -> None: """Spin up the server subprocess and run it until exit.""" @@ -588,11 +587,14 @@ class ServerManagerApp: # Launch! try: + # if bool(True): + # raise RuntimeError('test') self._subprocess = subprocess.Popen( [binary_name, '-cfgdir', self._ba_root_path], stdin=subprocess.PIPE, cwd='dist') except Exception as exc: + self._subprocess_exited_cleanly = False print( f'{Clr.RED}Error launching server subprocess: {exc}{Clr.RST}', file=sys.stderr, @@ -608,6 +610,16 @@ class ServerManagerApp: self._kill_subprocess() + assert self._subprocess_exited_cleanly is not None + + # EW: it seems that if we die before the main thread has fully started + # up the interpreter, its possible that it will not break out of its + # loop via the usual SystemExit that gets sent when we die. + if self._interactive: + while (self._interpreter_start_time is None + or time.time() - self._interpreter_start_time < 0.5): + time.sleep(0.1) + # Avoid super fast death loops. if (not self._subprocess_exited_cleanly and self._auto_restart and not self._done): @@ -819,7 +831,7 @@ class ServerManagerApp: self._subprocess_sent_clean_exit = False self._subprocess_sent_unclean_exit = False self._subprocess_force_kill_time = None - self._subprocess_exited_cleanly = False + self._subprocess_exited_cleanly = None def _kill_subprocess(self) -> None: """End the server subprocess if it still exists.""" @@ -836,7 +848,10 @@ class ServerManagerApp: self._subprocess.terminate() try: self._subprocess.wait(timeout=10) + self._subprocess_exited_cleanly = ( + self._subprocess.returncode == 0) except subprocess.TimeoutExpired: + self._subprocess_exited_cleanly = False self._subprocess.kill() print(f'{Clr.CYN}Subprocess stopped.{Clr.RST}', file=sys.stderr, diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index e7a98d77..4f6fcfbc 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,7 +21,7 @@ namespace ballistica { // These are set automatically via script; don't change here. -const int kAppBuildNumber = 20313; +const int kAppBuildNumber = 20316; const char* kAppVersion = "1.6.0"; // Our standalone globals.