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