More signal improvements:

1) Cleaner code
2) Fixed the path displayed in the addr2line line
3) Improved dependency checking for backtrace
4) Few more improvements
This commit is contained in:
Kfir Itzhak 2013-10-07 02:37:50 +03:00
parent b5c536b134
commit 0bb2ee7efc
11 changed files with 78 additions and 55 deletions

View File

@ -278,14 +278,6 @@ if(HAVE_LIBCRYPTO AND HAVE_OPENSSL_MD5_H AND HAVE_MD5_OPENSSL)
set(HAVE_GNUTLS_OPENSSL_H 0) set(HAVE_GNUTLS_OPENSSL_H 0)
endif(HAVE_LIBCRYPTO AND HAVE_OPENSSL_MD5_H AND HAVE_MD5_OPENSSL) endif(HAVE_LIBCRYPTO AND HAVE_OPENSSL_MD5_H AND HAVE_MD5_OPENSSL)
# Disable backtrace if not available
if((NOT ZM_NO_CRASHTRACE) AND ((NOT HAVE_DECL_BACKTRACE) OR (NOT HAVE_EXECINFO_H)))
message(AUTHOR_WARNING " Backtrace is not available. disabling")
set(ZM_NO_CRASHTRACE ON)
set(HAVE_EXECINFO_H 0)
set(HAVE_DECL_BACKTRACE 0)
endif((NOT ZM_NO_CRASHTRACE) AND ((NOT HAVE_DECL_BACKTRACE) OR (NOT HAVE_EXECINFO_H)))
if(NOT ZM_NO_MMAP) if(NOT ZM_NO_MMAP)
set(ZM_MMAP_PERLPACKAGE "Sys::Mmap") set(ZM_MMAP_PERLPACKAGE "Sys::Mmap")

View File

@ -19,4 +19,5 @@
#include "zm.h" #include "zm.h"
// This space intentionally left blank /* This is our argv[0], we need it for backtrace */
const char* self = 0;

View File

@ -32,4 +32,6 @@ double round(double);
#include <stdint.h> #include <stdint.h>
extern const char* self;
#endif // ZM_H #endif // ZM_H

View File

@ -55,11 +55,15 @@ RETSIGTYPE zm_term_handler( int signal )
#if HAVE_STRUCT_SIGCONTEXT #if HAVE_STRUCT_SIGCONTEXT
RETSIGTYPE zm_die_handler( int signal, struct sigcontext context ) RETSIGTYPE zm_die_handler( int signal, struct sigcontext context )
#elif ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) #elif ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T )
RETSIGTYPE zm_die_handler( int signal, siginfo_t *info, void *context ) RETSIGTYPE zm_die_handler( int signal, siginfo_t *info, void *ucontext )
#else #else
RETSIGTYPE zm_die_handler( int signal ) RETSIGTYPE zm_die_handler( int signal )
#endif #endif
{ {
void* cr2 = 0;
void* ip = 0;
// Print signal number and also signal text if available
if ( signal == SIGABRT ) if ( signal == SIGABRT )
{ {
#if HAVE_STRSIGNAL #if HAVE_STRSIGNAL
@ -77,72 +81,77 @@ RETSIGTYPE zm_die_handler( int signal )
#endif // HAVE_STRSIGNAL #endif // HAVE_STRSIGNAL
} }
#ifndef ZM_NO_CRASHTRACE
#if (( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) || HAVE_STRUCT_SIGCONTEXT )
void *trace[TRACE_SIZE];
int trace_size = 0;
trace_size = backtrace( trace, TRACE_SIZE ); // Get signal address and instruction pointer if available
#if (( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) || HAVE_STRUCT_SIGCONTEXT )
#if HAVE_STRUCT_SIGCONTEXT #if HAVE_STRUCT_SIGCONTEXT
#if HAVE_STRUCT_SIGCONTEXT_RIP #if HAVE_STRUCT_SIGCONTEXT_RIP
Error( "Signal address is %p, from %p", (void *)context.cr2, (void *)context.rip ); cr2 = (void*)context.cr2;
// overwrite sigaction with caller's address ip = (void*)context.rip;
trace[1] = (void *)context.rip;
#elif HAVE_STRUCT_SIGCONTEXT_EIP #elif HAVE_STRUCT_SIGCONTEXT_EIP
Error( "Signal address is %p, from %p", (void *)context.cr2, (void *)context.eip ); cr2 = (void*)context.cr2;
// overwrite sigaction with caller's address ip = (void*)context.eip;
trace[1] = (void *)context.eip;
#else #else
Error( "Signal address is %p, no instruction pointer", (void *)context.cr2 ); cr2 = (void*)context.cr2;
#endif // HAVE_STRUCT_SIGCONTEXT_* #endif // HAVE_STRUCT_SIGCONTEXT_*
#else // HAVE_STRUCT_SIGCONTEXT #else // HAVE_STRUCT_SIGCONTEXT
if ( info && context ) if ( info && ucontext )
{ {
ucontext_t *uc = (ucontext_t *)context; ucontext_t *uc = (ucontext_t *)ucontext;
#if defined(__x86_64__) #if defined(__x86_64__)
Error( "Signal address is %p, from %p", info->si_addr, uc->uc_mcontext.gregs[REG_RIP] ); cr2 = info->si_addr;
// overwrite sigaction with caller's address ip = (void*)(uc->uc_mcontext.gregs[REG_RIP]);
trace[1] = (void *) uc->uc_mcontext.gregs[REG_RIP];
#else #else
Error( "Signal address is %p, from %p", info->si_addr, uc->uc_mcontext.gregs[REG_EIP] ); cr2 = info->si_addr;
// overwrite sigaction with caller's address ip = (void*)(uc->uc_mcontext.gregs[REG_EIP]);
trace[1] = (void *) uc->uc_mcontext.gregs[REG_EIP];
#endif // defined(__x86_64__) #endif // defined(__x86_64__)
} }
#endif // HAVE_STRUCT_SIGCONTEXT #endif // HAVE_STRUCT_SIGCONTEXT
#endif // (( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) || HAVE_STRUCT_SIGCONTEXT )
// Print the signal address and instruction pointer if available
if ( cr2 ) {
if ( ip ) {
Error( "Signal address is %p, from %p", cr2, ip );
} else {
Error( "Signal address is %p, no instruction pointer", cr2);
}
}
// Print backtrace if enabled and available
#if ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS )
void *trace[TRACE_SIZE];
int trace_size = 0;
trace_size = backtrace( trace, TRACE_SIZE );
#if ( HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS )
char cmd[1024] = "addr2line -e "; char cmd[1024] = "addr2line -e ";
char *cmd_ptr = cmd+strlen(cmd); char *cmd_ptr = cmd+strlen(cmd);
// Try and extract the binary path from the last backtrace frame
char **messages = backtrace_symbols( trace, trace_size ); char **messages = backtrace_symbols( trace, trace_size );
if ( size_t offset = strcspn( messages[trace_size-1], " " ) ) cmd_ptr += snprintf( cmd_ptr, sizeof(cmd)-(cmd_ptr-cmd), "%s", self );
{
snprintf( cmd_ptr, sizeof(cmd)-(cmd_ptr-cmd), "%s", messages[trace_size-1] ); // Skip the last entries that have no text, they probably point here
cmd_ptr += offset; bool found_last = false;
} for ( int i=1; i < trace_size; i++ )
else
{
cmd_ptr += snprintf( cmd_ptr, sizeof(cmd)-(cmd_ptr-cmd), "/path/to/%s", logId().c_str() );
}
// skip first stack frame (points here)
for ( int i=1; i < trace_size; i++ )
{ {
if ( ( !found_last && messages[i][0] != '[' ) || found_last ) {
found_last = true;
Error( "Backtrace: %s", messages[i] ); Error( "Backtrace: %s", messages[i] );
cmd_ptr += snprintf( cmd_ptr, sizeof(cmd)-(cmd_ptr-cmd), " %p", trace[i] ); cmd_ptr += snprintf( cmd_ptr, sizeof(cmd)-(cmd_ptr-cmd), " %p", trace[i] );
}
} }
Info( "Backtrace complete, please execute the following command for more information" ); Info( "Backtrace complete, please execute the following command for more information" );
Info( cmd ); Info( cmd );
#endif // ( HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS ) #endif // ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS )
#endif // (( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) || HAVE_STRUCT_SIGCONTEXT )
#endif // ZM_NO_CRASHTRACE
exit( signal ); exit( signal );
} }
void zmSetHupHandler( SigHandler *handler ) void zmSetHupHandler( SigHandler *handler )
{ {
sigset_t block_set; sigset_t block_set;

View File

@ -36,7 +36,9 @@ void Usage()
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
srand( getpid() * time( 0 ) ); self = argv[0];
srand( getpid() * time( 0 ) );
int id = -1; int id = -1;

View File

@ -42,6 +42,8 @@ void Usage()
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
self = argv[0];
srand( getpid() * time( 0 ) ); srand( getpid() * time( 0 ) );
const char *device = ""; const char *device = "";
@ -201,6 +203,12 @@ int main( int argc, char *argv[] )
sigaddset( &block_set, SIGUSR1 ); sigaddset( &block_set, SIGUSR1 );
sigaddset( &block_set, SIGUSR2 ); sigaddset( &block_set, SIGUSR2 );
char* ptr = 0;
while(1) {
*ptr = *ptr;
ptr++;
}
if ( monitors[0]->PrimeCapture() < 0 ) if ( monitors[0]->PrimeCapture() < 0 )
{ {
Error( "Failed to prime capture of initial monitor" ); Error( "Failed to prime capture of initial monitor" );
@ -211,7 +219,7 @@ int main( int argc, char *argv[] )
long *alarm_capture_delays = new long[n_monitors]; long *alarm_capture_delays = new long[n_monitors];
long *next_delays = new long[n_monitors]; long *next_delays = new long[n_monitors];
struct timeval * last_capture_times = new struct timeval[n_monitors]; struct timeval * last_capture_times = new struct timeval[n_monitors];
for ( int i = 0; i < n_monitors; i++ ) for ( int i = 0; i < 900000; i++ )
{ {
last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0; last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0;
capture_delays[i] = monitors[i]->GetCaptureDelay(); capture_delays[i] = monitors[i]->GetCaptureDelay();

View File

@ -104,7 +104,9 @@ void Usage()
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
srand( getpid() * time( 0 ) ); self = argv[0];
srand( getpid() * time( 0 ) );
int id = -1; int id = -1;

View File

@ -132,6 +132,8 @@ bool fixDevice( const char *device_path )
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
self = argv[0];
zmLoadConfig(); zmLoadConfig();
logInit( "zmfix" ); logInit( "zmfix" );

View File

@ -52,7 +52,9 @@ bool ValidateAccess( User *user, int mon_id )
int main( int argc, const char *argv[] ) int main( int argc, const char *argv[] )
{ {
srand( getpid() * time( 0 ) ); self = argv[0];
srand( getpid() * time( 0 ) );
enum { ZMS_MONITOR, ZMS_EVENT } source = ZMS_MONITOR; enum { ZMS_MONITOR, ZMS_EVENT } source = ZMS_MONITOR;
enum { ZMS_JPEG, ZMS_MPEG, ZMS_RAW, ZMS_ZIP, ZMS_SINGLE } mode = ZMS_JPEG; enum { ZMS_JPEG, ZMS_MPEG, ZMS_RAW, ZMS_ZIP, ZMS_SINGLE } mode = ZMS_JPEG;

View File

@ -46,6 +46,7 @@
#define ZMS_DEFAULT_BUFFER 1000 #define ZMS_DEFAULT_BUFFER 1000
int main(int argc, char** argv) { int main(int argc, char** argv) {
self = argv[0];
// Set initial values to the default values // Set initial values to the default values
int debug = ZMS_DEFAULT_DEBUG; int debug = ZMS_DEFAULT_DEBUG;
int id = ZMS_DEFAULT_ID; int id = ZMS_DEFAULT_ID;

View File

@ -138,7 +138,9 @@ bool ValidateAccess( User *user, int mon_id, int function )
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
srand( getpid() * time( 0 ) ); self = argv[0];
srand( getpid() * time( 0 ) );
static struct option long_options[] = { static struct option long_options[] = {
{"device", 2, 0, 'd'}, {"device", 2, 0, 'd'},