From 1d7f66462701ff58f60c4d82bcbf9c18f32b5fec Mon Sep 17 00:00:00 2001 From: Kfir Itzhak Date: Mon, 7 Oct 2013 10:37:58 +0300 Subject: [PATCH] 1) Removed the use of deprecated and undocumented sigcontext (Replaced by siginfo and ucontext) 2) Removed the checks for sigcontext, strsignal and siginfo.h 3) Added debugging code to the die handler 4) Using SA_RESTART in the hup and reload handlers to prevent certain functions returning EINTR 5) Added SIGINT and SIGQUIT to the term handler --- CMakeLists.txt | 5 --- configure.ac | 6 +-- src/zm_signal.cpp | 94 +++++++++++++++-------------------------- src/zm_signal.h | 7 +-- zoneminder-config.cmake | 5 --- 5 files changed, 35 insertions(+), 82 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f369aeaca..4a2b650aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,6 @@ set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ON) check_include_file("linux/videodev.h" HAVE_LINUX_VIDEODEV_H) check_include_file("linux/videodev2.h" HAVE_LINUX_VIDEODEV2_H) check_include_file("execinfo.h" HAVE_EXECINFO_H) -check_include_file("siginfo.h" HAVE_SIGINFO_H) check_include_file("ucontext.h" HAVE_UCONTEXT_H) check_include_file("sys/sendfile.h" HAVE_SYS_SENDFILE_H) check_include_file("sys/syscall.h" HAVE_SYS_SYSCALL_H) @@ -81,13 +80,9 @@ check_function_exists("sendfile" HAVE_SENDFILE) check_function_exists("backtrace" HAVE_DECL_BACKTRACE) check_function_exists("backtrace_symbols" HAVE_DECL_BACKTRACE_SYMBOLS) check_function_exists("posix_memalign" HAVE_POSIX_MEMALIGN) -check_function_exists("strsignal" HAVE_STRSIGNAL) check_prototype_definition("round" "double round (double x)" "0.0" "math.h" HAVE_DECL_ROUND) check_type_size("siginfo_t" HAVE_SIGINFO_T) check_type_size("ucontext_t" HAVE_UCONTEXT_T) -check_type_size("struct sigcontext" HAVE_STRUCT_SIGCONTEXT) -check_struct_has_member("struct sigcontext" eip signal.h HAVE_STRUCT_SIGCONTEXT_EIP) -check_struct_has_member("struct sigcontext" rip signal.h HAVE_STRUCT_SIGCONTEXT_RIP) # *** LIBRARY CHECKS *** diff --git a/configure.ac b/configure.ac index f13d278a1..6a1f81723 100644 --- a/configure.ac +++ b/configure.ac @@ -235,9 +235,6 @@ AC_STRUCT_TM AC_TYPE_SIGNAL AC_CHECK_TYPES(siginfo_t,,,[#include ]) -AC_CHECK_TYPES(struct sigcontext,,,[#include ]) -AC_CHECK_MEMBERS([struct sigcontext.eip],,,[#include ]) -AC_CHECK_MEMBERS([struct sigcontext.rip],,,[#include ]) AC_CHECK_TYPES(ucontext_t,,,[#include ]) # Checks for library functions. @@ -249,7 +246,7 @@ AC_FUNC_STAT AC_FUNC_STRFTIME AC_FUNC_STRTOD AC_FUNC_VPRINTF -AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday memmove memset mkdir munmap posix_memalign putenv select sendfile socket sqrt strcasecmp strchr strcspn strerror strncasecmp strrchr strsignal strspn strstr strtol strtoull]) +AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday memmove memset mkdir munmap posix_memalign putenv select sendfile socket sqrt strcasecmp strchr strcspn strerror strncasecmp strrchr strspn strstr strtol strtoull]) AC_CHECK_FUNCS([syscall sleep usleep ioctl ioctlsocket sigaction]) # Other programs @@ -303,7 +300,6 @@ AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h limits.h memory.h stddef.h stdlib.h string.h strings.h sys/param.h sys/time.h syslog.h unistd.h values.h]) AC_CHECK_HEADERS([netdb.h netinet/in.h arpa/inet.h sys/ioctl.h sys/socket.h sys/un.h glob.h sys/sendfile.h]) AC_CHECK_HEADERS(execinfo.h,,,) -AC_CHECK_HEADERS(siginfo.h,,,) AC_CHECK_HEADERS(ucontext.h,,,) AC_CHECK_HEADERS(sys/syscall.h,,,) AC_CHECK_HEADERS(pthread.h,,,) diff --git a/src/zm_signal.cpp b/src/zm_signal.cpp index c0eb41010..8a021963f 100644 --- a/src/zm_signal.cpp +++ b/src/zm_signal.cpp @@ -31,28 +31,18 @@ bool zm_terminate = false; RETSIGTYPE zm_hup_handler(int signal) { -#if HAVE_STRSIGNAL Info("Got signal %d (%s), reloading", signal, strsignal(signal)); -#else // HAVE_STRSIGNAL - Info("Got HUP signal, reloading"); -#endif // HAVE_STRSIGNAL zm_reload = true; } RETSIGTYPE zm_term_handler(int signal) { -#if HAVE_STRSIGNAL Info("Got signal %d (%s), exiting", signal, strsignal(signal)); -#else // HAVE_STRSIGNAL - Info("Got TERM signal, exiting"); -#endif // HAVE_STRSIGNAL zm_terminate = true; } -#if HAVE_STRUCT_SIGCONTEXT -RETSIGTYPE zm_die_handler(int signal, struct sigcontext context) -#elif ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) -RETSIGTYPE zm_die_handler(int signal, siginfo_t * info, void *ucontext) +#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) +RETSIGTYPE zm_die_handler(int signal, siginfo_t * info, void *context) #else RETSIGTYPE zm_die_handler(int signal) #endif @@ -60,38 +50,19 @@ RETSIGTYPE zm_die_handler(int signal) void *cr2 = 0; void *ip = 0; - // Print signal number and also signal text if available - if (signal == SIGABRT) { -#if HAVE_STRSIGNAL - Info("Got signal %d (%s), exiting and forcing backtrace", - signal, strsignal(signal)); -#else // HAVE_STRSIGNAL - Error("Got signal %d, exiting and forcing backtrace", signal); -#endif // HAVE_STRSIGNAL - } else { -#if HAVE_STRSIGNAL - Info("Got signal %d (%s), crashing", signal, strsignal(signal)); -#else // HAVE_STRSIGNAL - Error("Got signal %d, crashing", signal); -#endif // HAVE_STRSIGNAL - } + // Print signal information + Error("Got signal %d (%s), crashing", signal, strsignal(signal)); +#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) + Debug(1, + "Signal information: number %d code %d errno %d pid %d uid %d status %d", + signal, info->si_code, info->si_errno, info->si_pid, info->si_uid, + info->si_status); +#endif // 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_RIP - cr2 = (void *)context.cr2; - ip = (void *)context.rip; -#elif HAVE_STRUCT_SIGCONTEXT_EIP - cr2 = (void *)context.cr2; - ip = (void *)context.eip; -#else - cr2 = (void *)context.cr2; -#endif // HAVE_STRUCT_SIGCONTEXT_* - -#else // HAVE_STRUCT_SIGCONTEXT - if (info && ucontext) { - ucontext_t *uc = (ucontext_t *) ucontext; +#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) + if (info && context) { + ucontext_t *uc = (ucontext_t *) context; #if defined(__x86_64__) cr2 = info->si_addr; ip = (void *)(uc->uc_mcontext.gregs[REG_RIP]); @@ -100,8 +71,7 @@ RETSIGTYPE zm_die_handler(int signal) ip = (void *)(uc->uc_mcontext.gregs[REG_EIP]); #endif // defined(__x86_64__) } -#endif // HAVE_STRUCT_SIGCONTEXT -#endif // (( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) || HAVE_STRUCT_SIGCONTEXT ) +#endif // ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) // Print the signal address and instruction pointer if available if (cr2) { @@ -112,7 +82,6 @@ RETSIGTYPE zm_die_handler(int signal) cr2); } } - // Print backtrace if enabled and available #if ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS ) void *trace[TRACE_SIZE]; @@ -121,22 +90,18 @@ RETSIGTYPE zm_die_handler(int signal) char cmd[1024] = "addr2line -e "; char *cmd_ptr = cmd + strlen(cmd); - - char **messages = backtrace_symbols(trace, trace_size); cmd_ptr += snprintf(cmd_ptr, sizeof(cmd) - (cmd_ptr - cmd), "%s", self); - // Skip the last entries that have no text, they probably point here - bool found_last = false; - for (int i = 1; i < trace_size; i++) { - if ((!found_last && messages[i][0] != '[') || found_last) { - found_last = true; - Error("Backtrace: %s", messages[i]); - cmd_ptr += - snprintf(cmd_ptr, sizeof(cmd) - (cmd_ptr - cmd), - " %p", trace[i]); - } - + char **messages = backtrace_symbols(trace, trace_size); + // Print the full backtrace + for (int i = 0; i < trace_size; i++) { + Error("Backtrace %u: %s", i, messages[i]); + cmd_ptr += + snprintf(cmd_ptr, sizeof(cmd) - (cmd_ptr - cmd), " %p", + trace[i]); } + free(messages); + Info("Backtrace complete, please execute the following command for more information"); Info(cmd); #endif // ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS ) @@ -152,7 +117,7 @@ void zmSetHupHandler(SigHandler * handler) action.sa_handler = (SigHandler *) handler; action.sa_mask = block_set; - action.sa_flags = 0; + action.sa_flags = SA_RESTART; sigaction(SIGHUP, &action, &old_action); } @@ -164,8 +129,10 @@ void zmSetTermHandler(SigHandler * handler) action.sa_handler = (SigHandler *) handler; action.sa_mask = block_set; - action.sa_flags = 0; + action.sa_flags = SA_RESTART; sigaction(SIGTERM, &action, &old_action); + sigaction(SIGINT, &action, &old_action); + sigaction(SIGQUIT, &action, &old_action); } void zmSetDieHandler(SigHandler * handler) @@ -174,9 +141,14 @@ void zmSetDieHandler(SigHandler * handler) sigemptyset(&block_set); struct sigaction action, old_action; - action.sa_handler = (SigHandler *) handler; action.sa_mask = block_set; +#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) + action.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler; + action.sa_flags = SA_SIGINFO; +#else + action.sa_handler = (SigHandler *) handler; action.sa_flags = 0; +#endif sigaction(SIGBUS, &action, &old_action); sigaction(SIGSEGV, &action, &old_action); diff --git a/src/zm_signal.h b/src/zm_signal.h index faf575948..0302b47ee 100644 --- a/src/zm_signal.h +++ b/src/zm_signal.h @@ -25,9 +25,6 @@ #if HAVE_EXECINFO_H #include #endif -#if HAVE_SIGINFO_H -#include -#endif #if HAVE_UCONTEXT_H #include #endif @@ -42,9 +39,7 @@ extern bool zm_terminate; RETSIGTYPE zmc_hup_handler( int signal ); RETSIGTYPE zmc_term_handler( int signal ); -#if HAVE_STRUCT_SIGCONTEXT -RETSIGTYPE zmc_die_handler( int signal, struct sigcontext context ); -#elif ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) +#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) RETSIGTYPE zmc_die_handler( int signal, siginfo_t *info, void *context ); #else RETSIGTYPE zmc_die_handler( int signal ); diff --git a/zoneminder-config.cmake b/zoneminder-config.cmake index 6b34d28f4..577b5a343 100644 --- a/zoneminder-config.cmake +++ b/zoneminder-config.cmake @@ -7,7 +7,6 @@ #cmakedefine HAVE_LINUX_VIDEODEV_H 1 #cmakedefine HAVE_LINUX_VIDEODEV2_H 1 #cmakedefine HAVE_EXECINFO_H 1 -#cmakedefine HAVE_SIGINFO_H 1 #cmakedefine HAVE_UCONTEXT_H 1 #cmakedefine HAVE_SYS_SENDFILE_H 1 #cmakedefine HAVE_SYS_SYSCALL_H 1 @@ -16,13 +15,9 @@ #cmakedefine HAVE_DECL_BACKTRACE 1 #cmakedefine HAVE_DECL_BACKTRACE_SYMBOLS 1 #cmakedefine HAVE_POSIX_MEMALIGN 1 -#cmakedefine HAVE_STRSIGNAL 1 #cmakedefine HAVE_DECL_ROUND 1 #cmakedefine HAVE_SIGINFO_T 1 #cmakedefine HAVE_UCONTEXT_T 1 -#cmakedefine HAVE_STRUCT_SIGCONTEXT 1 -#cmakedefine HAVE_STRUCT_SIGCONTEXT_EIP 1 -#cmakedefine HAVE_STRUCT_SIGCONTEXT_RIP 1 /* Library checks and their header files */ #cmakedefine HAVE_LIBZLIB 1