00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <signal.h>
00023
00024 #include <drizzled/signal_handler.h>
00025 #include <drizzled/drizzled.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/session/cache.h>
00028 #include <drizzled/internal/my_sys.h>
00029 #include <drizzled/probes.h>
00030 #include <drizzled/plugin.h>
00031 #include <drizzled/plugin/scheduler.h>
00032 #include <drizzled/current_session.h>
00033 #include <drizzled/util/backtrace.h>
00034 #include <drizzled/statistics_variables.h>
00035 #include <drizzled/system_variables.h>
00036
00037 using namespace drizzled;
00038
00039 static uint32_t killed_threads;
00040 static bool segfaulted= false;
00041
00042
00043
00044
00045
00046
00047
00048 extern "C"
00049 {
00050
00051 void drizzled_print_signal_warning(int sig)
00052 {
00053 if (global_system_variables.log_warnings)
00054 errmsg_printf(error::WARN, _("Got signal %d from thread %"PRIu32),
00055 sig, global_thread_id);
00056 #ifndef HAVE_BSD_SIGNALS
00057 sigset_t set;
00058 sigemptyset(&set);
00059
00060 struct sigaction sa;
00061 sa.sa_handler= drizzled_print_signal_warning;
00062 sa.sa_mask= set;
00063 sa.sa_flags= 0;
00064 sigaction(sig, &sa, NULL);
00065 #endif
00066 if (sig == SIGALRM)
00067 alarm(2);
00068 }
00069
00071 void drizzled_end_thread_signal(int )
00072 {
00073 Session *session= current_session;
00074 if (session)
00075 {
00076 Session::shared_ptr session_ptr(session::Cache::find(session->getSessionId()));
00077 if (not session_ptr)
00078 return;
00079
00080 killed_threads++;
00081
00082
00083 session_ptr->scheduler->killSessionNow(session_ptr);
00084 DRIZZLE_CONNECTION_DONE(session_ptr->getSessionId());
00085 }
00086 }
00087
00088 static void write_core(int sig)
00089 {
00090 signal(sig, SIG_DFL);
00091 #ifdef HAVE_gcov
00092
00093
00094
00095
00096
00097 extern void __gcov_flush(void);
00098 __gcov_flush();
00099 #endif
00100 pthread_kill(pthread_self(), sig);
00101 #if defined(P_MYID) && !defined(SCO)
00102
00103 sigsend(P_PID,P_MYID,sig);
00104 #endif
00105 }
00106
00107 void drizzled_handle_segfault(int sig)
00108 {
00109 time_t curr_time;
00110 struct tm tm;
00111
00112
00113
00114
00115
00116
00117
00118 if (segfaulted)
00119 {
00120 fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
00121 exit(1);
00122 }
00123
00124 segfaulted= true;
00125
00126 curr_time= time(NULL);
00127 if(curr_time == (time_t)-1)
00128 {
00129 fprintf(stderr, _("Fatal: time() call failed\n"));
00130 exit(1);
00131 }
00132
00133 localtime_r(&curr_time, &tm);
00134
00135 fprintf(stderr,_("%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
00136 "This could be because you hit a bug. It is also possible that "
00137 "this binary\n or one of the libraries it was linked against is "
00138 "corrupt, improperly built,\n or misconfigured. This error can "
00139 "also be caused by malfunctioning hardware.\n"),
00140 tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
00141 tm.tm_hour, tm.tm_min, tm.tm_sec,
00142 sig);
00143 fprintf(stderr, _("We will try our best to scrape up some info that "
00144 "will hopefully help diagnose\n"
00145 "the problem, but since we have already crashed, "
00146 "something is definitely wrong\nand this may fail.\n\n"));
00147 fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
00148 fprintf(stderr, "max_used_connections=%"PRIu64"\n", current_global_counters.max_used_connections);
00149 fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
00150 fprintf(stderr, _("It is possible that drizzled could use up to \n"
00151 "(read_buffer_size + sort_buffer_size)*thread_count\n"
00152 "bytes of memory\n"
00153 "Hope that's ok; if not, decrease some variables in the "
00154 "equation.\n\n"));
00155
00156 call_backtrace();
00157
00158 write_core(sig);
00159
00160 exit(1);
00161 }
00162
00163 }