Permalink
Browse files

Partial fix for crashes when reporting an exceptional condition

As it turns out, the exception parser was calling exit() to abort the program. Unfortunately, exit() performs the cleanup of global static variables. Because an error may occur when those global variables are still in use by other threads, or during their cleanup, calling exit() at the exception parser led to undefined behavior (most often, crashes that would mask the original error).

Note that the exception parser is not yet fully safe against crashes while reporting errors: it uses printf and other non-reentrant functions. This will require more effort to cleanup.
  • Loading branch information...
frozenblit committed Feb 10, 2019
1 parent 5ecbbf6 commit 24b66a68dfa1fa9cd1bc8ef5e1b6da7296262cb3
Showing with 11 additions and 11 deletions.
  1. +8 −8 pol-core/clib/Debugging/ExceptionParser.cpp
  2. +3 −3 pol-core/pol/polwww.cpp
@@ -7,11 +7,11 @@
#include <format/format.h>

#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef WINDOWS
#include <arpa/inet.h>
@@ -240,26 +240,26 @@ void doHttpPOST( const string& host, const string& url, const string& content )
{
fprintf( stderr, "getaddrinfo() failed for \"%s\" due to \"%s\"(code: %d)\n", host.c_str(),
gai_strerror( res ), res );
exit( 1 );
std::_Exit( 1 );
}

switch ( serverAddr->ai_addr->sa_family )
{
case AF_INET:
if ( inet_ntop( AF_INET, &( (struct sockaddr_in*)serverAddr->ai_addr )->sin_addr, targetIP,
INET_ADDRSTRLEN ) == nullptr )
exit( 1 );
std::_Exit( 1 );
break;

case AF_INET6:
if ( inet_ntop( AF_INET6, &( (struct sockaddr_in*)serverAddr->ai_addr )->sin_addr, targetIP,
INET6_ADDRSTRLEN ) == nullptr )
exit( 1 );
std::_Exit( 1 );
break;

default:
fprintf( stderr, "Unknown address family found for %s\n", host.c_str() );
exit( 1 );
std::_Exit( 1 );
}

// create the socket
@@ -272,7 +272,7 @@ void doHttpPOST( const string& host, const string& url, const string& content )
{
fprintf( stderr, "connect() failed for server \"%s\"(IP: %s) due \"%s\"(%d)\n", host.c_str(),
targetIP, strerror( errno ), errno );
exit( 1 );
std::_Exit( 1 );
}

freeaddrinfo( serverAddr ); // not needed anymore
@@ -422,7 +422,7 @@ void ExceptionParser::handleExceptionSignal( int signal )
}

// finally, go to hell
exit( 1 );
std::_Exit( 1 );
}
break;
default:
@@ -646,7 +646,7 @@ void ExceptionParser::initGlobalExceptionCatching()
if ( sigaltstack( &tStack, nullptr ) == -1 )
{
printf( "Could not set signal handler stack\n" );
exit( 1 );
std::exit( 1 );
}
}
#else // _WIN32
@@ -887,9 +887,9 @@ void http_thread( void )
[=]() { http_func( client_socket ); } ); // copy socket into queue to keep it valid
}
}
// it's not safe to access mime_types on shutdown, because gamestate is being cleaned on another
// thread...
// gamestate.mime_types.clear(); // cleanup on exit

gamestate.mime_types.clear(); // cleanup on exit

#ifdef _WIN32
closesocket( http_socket );
#else

0 comments on commit 24b66a6

Please sign in to comment.