Cleanup.
This commit is contained in:
@@ -26,22 +26,22 @@
|
|||||||
extern uint64_t GetInvalidThreadId();
|
extern uint64_t GetInvalidThreadId();
|
||||||
extern const char *g_pCrashHandlerArgv0;
|
extern const char *g_pCrashHandlerArgv0;
|
||||||
|
|
||||||
static void safe_print(int fd, ...)
|
static void safe_print( int fd, ... )
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fd);
|
va_start( ap, fd );
|
||||||
|
|
||||||
while(1)
|
while( true )
|
||||||
{
|
{
|
||||||
const char *p = va_arg(ap, const char *);
|
const char *p = va_arg( ap, const char * );
|
||||||
if(p == NULL)
|
if( p == NULL )
|
||||||
break;
|
break;
|
||||||
write(fd, p, strlen(p));
|
write( fd, p, strlen(p) );
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end( ap );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *itoa(unsigned n)
|
static const char *itoa( unsigned n )
|
||||||
{
|
{
|
||||||
static char ret[32];
|
static char ret[32];
|
||||||
char *p = ret;
|
char *p = ret;
|
||||||
@@ -89,13 +89,13 @@ static void NORETURN spawn_child_process( int from_parent )
|
|||||||
{
|
{
|
||||||
/* We need to re-exec ourself, to get a clean process. Close all
|
/* We need to re-exec ourself, to get a clean process. Close all
|
||||||
* FDs except for 0-2 and to_child, and then assign to_child to 3. */
|
* FDs except for 0-2 and to_child, and then assign to_child to 3. */
|
||||||
for(int fd = 3; fd < 1024; ++fd)
|
for( int fd = 3; fd < 1024; ++fd )
|
||||||
if(fd != from_parent) close(fd);
|
if( fd != from_parent ) close(fd);
|
||||||
|
|
||||||
if(from_parent != 3)
|
if( from_parent != 3 )
|
||||||
{
|
{
|
||||||
dup2(from_parent, 3);
|
dup2( from_parent, 3 );
|
||||||
close(from_parent);
|
close( from_parent );
|
||||||
}
|
}
|
||||||
|
|
||||||
char path[1024];
|
char path[1024];
|
||||||
@@ -108,7 +108,7 @@ static void NORETURN spawn_child_process( int from_parent )
|
|||||||
|
|
||||||
/* If we got here, the exec failed. We can't call strerror. */
|
/* If we got here, the exec failed. We can't call strerror. */
|
||||||
// safe_print(fileno(stderr), "Crash handler execl(", path, ") failed: ", strerror(errno), "\n", NULL);
|
// safe_print(fileno(stderr), "Crash handler execl(", path, ") failed: ", strerror(errno), "\n", NULL);
|
||||||
safe_print(fileno(stderr), "Crash handler execl(", path, ") failed: ", itoa( errno ), "\n", NULL);
|
safe_print( fileno(stderr), "Crash handler execl(", path, ") failed: ", itoa( errno ), "\n", NULL );
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,18 +125,18 @@ static int retried_write( int fd, const void *buf, size_t count )
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parent_write(int to_child, const void *p, size_t size)
|
static bool parent_write( int to_child, const void *p, size_t size )
|
||||||
{
|
{
|
||||||
int ret = retried_write(to_child, p, size);
|
int ret = retried_write( to_child, p, size );
|
||||||
if( ret == -1 )
|
if( ret == -1 )
|
||||||
{
|
{
|
||||||
safe_print(fileno(stderr), "Unexpected write() result (", strerror(errno), ")\n", NULL);
|
safe_print( fileno(stderr), "Unexpected write() result (", strerror(errno), ")\n", NULL );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(size_t(ret) != size)
|
if( size_t(ret) != size )
|
||||||
{
|
{
|
||||||
safe_print(fileno(stderr), "Unexpected write() result (", itoa(ret), ")\n", NULL);
|
safe_print( fileno(stderr), "Unexpected write() result (", itoa(ret), ")\n", NULL );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,7 @@ static void parent_process( int to_child, const CrashData *crash )
|
|||||||
|
|
||||||
/* 2. Write info. */
|
/* 2. Write info. */
|
||||||
const char *p = RageLog::GetInfo();
|
const char *p = RageLog::GetInfo();
|
||||||
int size = strlen(p)+1;
|
int size = strlen( p )+1;
|
||||||
if( !parent_write(to_child, &size, sizeof(size)) )
|
if( !parent_write(to_child, &size, sizeof(size)) )
|
||||||
return;
|
return;
|
||||||
if( !parent_write(to_child, p, size) )
|
if( !parent_write(to_child, p, size) )
|
||||||
@@ -159,7 +159,7 @@ static void parent_process( int to_child, const CrashData *crash )
|
|||||||
|
|
||||||
/* 3. Write AdditionalLog. */
|
/* 3. Write AdditionalLog. */
|
||||||
p = RageLog::GetAdditionalLog();
|
p = RageLog::GetAdditionalLog();
|
||||||
size = strlen(p)+1;
|
size = strlen( p )+1;
|
||||||
if( !parent_write(to_child, &size, sizeof(size)) )
|
if( !parent_write(to_child, &size, sizeof(size)) )
|
||||||
return;
|
return;
|
||||||
if( !parent_write(to_child, p, size) )
|
if( !parent_write(to_child, p, size) )
|
||||||
@@ -184,19 +184,19 @@ static void parent_process( int to_child, const CrashData *crash )
|
|||||||
/* 5. Write CHECKPOINTs. */
|
/* 5. Write CHECKPOINTs. */
|
||||||
static char buf[1024*32];
|
static char buf[1024*32];
|
||||||
Checkpoints::GetLogs( buf, sizeof(buf), "\n" );
|
Checkpoints::GetLogs( buf, sizeof(buf), "\n" );
|
||||||
size = strlen(buf)+1;
|
size = strlen( buf )+1;
|
||||||
if( !parent_write(to_child, &size, sizeof(size)) )
|
if( !parent_write(to_child, &size, sizeof(size)) )
|
||||||
return;
|
return;
|
||||||
if( !parent_write(to_child, buf, size) )
|
if( !parent_write(to_child, buf, size) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* 6. Write the crashed thread's name. */
|
/* 6. Write the crashed thread's name. */
|
||||||
p = RageThread::GetCurThreadName();
|
p = RageThread::GetCurThreadName();
|
||||||
size = strlen(p)+1;
|
size = strlen( p )+1;
|
||||||
if( !parent_write(to_child, &size, sizeof(size)) )
|
if( !parent_write(to_child, &size, sizeof(size)) )
|
||||||
return;
|
return;
|
||||||
if( !parent_write(to_child, p, size) )
|
if( !parent_write(to_child, p, size) )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -256,8 +256,8 @@ static void RunCrashHandler( const CrashData *crash )
|
|||||||
{
|
{
|
||||||
if( g_pCrashHandlerArgv0 == NULL )
|
if( g_pCrashHandlerArgv0 == NULL )
|
||||||
{
|
{
|
||||||
safe_print(fileno(stderr), "Crash handler failed: CrashHandlerHandleArgs was not called\n", NULL);
|
safe_print( fileno(stderr), "Crash handler failed: CrashHandlerHandleArgs was not called\n", NULL );
|
||||||
_exit(1);
|
_exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Block SIGPIPE, so we get EPIPE. */
|
/* Block SIGPIPE, so we get EPIPE. */
|
||||||
@@ -266,7 +266,7 @@ static void RunCrashHandler( const CrashData *crash )
|
|||||||
sa.sa_handler = SIG_IGN;
|
sa.sa_handler = SIG_IGN;
|
||||||
if( sigaction( SIGPIPE, &sa, NULL ) != 0 )
|
if( sigaction( SIGPIPE, &sa, NULL ) != 0 )
|
||||||
{
|
{
|
||||||
safe_print(fileno(stderr), "sigaction() failed: %s", strerror(errno), NULL);
|
safe_print( fileno(stderr), "sigaction() failed: %s", strerror(errno), NULL );
|
||||||
/* non-fatal */
|
/* non-fatal */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +298,7 @@ static void RunCrashHandler( const CrashData *crash )
|
|||||||
else if( active == 2 )
|
else if( active == 2 )
|
||||||
safe_print( fileno(stderr), " while in the crash handler child\n", NULL);
|
safe_print( fileno(stderr), " while in the crash handler child\n", NULL);
|
||||||
|
|
||||||
_exit(1);
|
_exit( 1 );
|
||||||
}
|
}
|
||||||
active = 1;
|
active = 1;
|
||||||
received = getpid();
|
received = getpid();
|
||||||
@@ -310,28 +310,28 @@ static void RunCrashHandler( const CrashData *crash )
|
|||||||
/* We need to be very careful, since we're under crash conditions. Let's fork
|
/* We need to be very careful, since we're under crash conditions. Let's fork
|
||||||
* a process and exec ourself to get a clean environment to work in. */
|
* a process and exec ourself to get a clean environment to work in. */
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if(pipe(fds) != 0)
|
if( pipe(fds) != 0 )
|
||||||
{
|
{
|
||||||
safe_print(fileno(stderr), "Crash handler pipe() failed: ", strerror(errno), "\n", NULL);
|
safe_print( fileno(stderr), "Crash handler pipe() failed: ", strerror(errno), "\n", NULL );
|
||||||
exit(1);
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t childpid = fork();
|
pid_t childpid = fork();
|
||||||
if( childpid == -1 )
|
if( childpid == -1 )
|
||||||
{
|
{
|
||||||
safe_print(fileno(stderr), "Crash handler fork() failed: ", strerror(errno), "\n", NULL);
|
safe_print( fileno(stderr), "Crash handler fork() failed: ", strerror(errno), "\n", NULL );
|
||||||
_exit(1);
|
_exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( childpid == 0 )
|
if( childpid == 0 )
|
||||||
{
|
{
|
||||||
active = 2;
|
active = 2;
|
||||||
close(fds[1]);
|
close( fds[1] );
|
||||||
spawn_child_process(fds[0]);
|
spawn_child_process( fds[0] );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
close(fds[0]);
|
close( fds[0] );
|
||||||
parent_process( fds[1], crash );
|
parent_process( fds[1], crash );
|
||||||
close( fds[1] );
|
close( fds[1] );
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ static void RunCrashHandler( const CrashData *crash )
|
|||||||
RageThread::ResumeAllThreads();
|
RageThread::ResumeAllThreads();
|
||||||
|
|
||||||
if( WIFSIGNALED(status) )
|
if( WIFSIGNALED(status) )
|
||||||
safe_print( fileno(stderr), "Crash handler child exited with signal ", itoa(WTERMSIG(status)), "\n", NULL);
|
safe_print( fileno(stderr), "Crash handler child exited with signal ", itoa(WTERMSIG(status)), "\n", NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +412,7 @@ void ForceCrashHandlerDeadlock( CString reason, uint64_t iID )
|
|||||||
|
|
||||||
RunCrashHandler( &crash );
|
RunCrashHandler( &crash );
|
||||||
|
|
||||||
_exit(1);
|
_exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX test for recursive crashes here (eg. GetBacktrace crashing) */
|
/* XXX test for recursive crashes here (eg. GetBacktrace crashing) */
|
||||||
|
|||||||
Reference in New Issue
Block a user