From d55b7fa6c948c010417057b7f350954cff401aad Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Wed, 23 Jun 2021 05:51:40 +0200 Subject: [PATCH] Don't use stringDataAllocator in idStr, it's not thread-safe idStr is used in both the main thread and the async sound thread, so it should better be thread-safe.. idDynamicBlockAlloc is not. Use realloc() and free() instead. For some reason this caused a lot more crashes (due to inconsistencies in the allocator's heap) with newer Linux distros (like XUbuntu 20.04) and when using GCC9, while they rarely reproduced with GCC7 or on XUbuntu 18.04 fixes #391 --- neo/idlib/Str.cpp | 29 ++++++++++++++++++++--------- neo/sys/posix/posix_main.cpp | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/neo/idlib/Str.cpp b/neo/idlib/Str.cpp index 4ccfb967..9bd6b1b9 100644 --- a/neo/idlib/Str.cpp +++ b/neo/idlib/Str.cpp @@ -33,7 +33,11 @@ If you have questions concerning this license or the applicable additional terms #include "idlib/Str.h" -#if !defined( ID_REDIRECT_NEWDELETE ) && !defined( MACOS_X ) +// DG: idDynamicBlockAlloc isn't thread-safe and idStr is used both in the main thread +// and the async thread! For some reason this seems to cause lots of problems on +// newer Linux distros if dhewm3 is built with GCC9 or newer (see #391). +// No idea why it apparently didn't cause that (noticeable) issues before.. +#if 0 // !defined( ID_REDIRECT_NEWDELETE ) && !defined( MACOS_X ) #define USE_STRING_DATA_ALLOCATOR #endif @@ -100,23 +104,30 @@ void idStr::ReAllocate( int amount, bool keepold ) { #ifdef USE_STRING_DATA_ALLOCATOR newbuffer = stringDataAllocator.Alloc( alloced ); -#else - newbuffer = new char[ alloced ]; -#endif if ( keepold && data ) { data[ len ] = '\0'; strcpy( newbuffer, data ); } if ( data && data != baseBuffer ) { -#ifdef USE_STRING_DATA_ALLOCATOR stringDataAllocator.Free( data ); -#else - delete [] data; -#endif } data = newbuffer; +#else + if ( data && data != baseBuffer ) { + data = (char *)realloc( data, newsize ); + } else { + newbuffer = (char *)malloc( newsize ); + if ( data && keepold ) { + memcpy( newbuffer, data, len ); + newbuffer[ len ] = '\0'; + } else { + newbuffer[ 0 ] = '\0'; + } + data = newbuffer; + } +#endif } /* @@ -129,7 +140,7 @@ void idStr::FreeData( void ) { #ifdef USE_STRING_DATA_ALLOCATOR stringDataAllocator.Free( data ); #else - delete[] data; + free( data ); #endif data = baseBuffer; } diff --git a/neo/sys/posix/posix_main.cpp b/neo/sys/posix/posix_main.cpp index 0f64207a..e05a2030 100644 --- a/neo/sys/posix/posix_main.cpp +++ b/neo/sys/posix/posix_main.cpp @@ -493,7 +493,7 @@ static void signalhandlerCrash(int sig) printf(" %s\n", strings[i]); } - printf("\n"); + printf("\n(Sorry it's not overly useful, build with libbacktrace support to get function names)\n"); free(strings);