~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/signal_handler.cc

  • Committer: Andrew Hutchings
  • Date: 2011-01-21 11:23:19 UTC
  • mto: (2100.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 2101.
  • Revision ID: andrew@linuxjedi.co.uk-20110121112319-nj1cvg0yt3nnf2rr
Add errors page to drizzle client docs
Add link to specific error in migration docs
Minor changes to migration docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#include "config.h"
 
21
 
 
22
#include <signal.h>
 
23
 
 
24
#include "drizzled/signal_handler.h"
 
25
#include "drizzled/drizzled.h"
 
26
#include "drizzled/session.h"
 
27
#include "drizzled/session/cache.h"
 
28
#include "drizzled/internal/my_sys.h"
 
29
#include "drizzled/probes.h"
 
30
#include "drizzled/plugin.h"
 
31
#include "drizzled/plugin/scheduler.h"
 
32
 
 
33
#include "drizzled/util/backtrace.h"
 
34
 
 
35
using namespace drizzled;
 
36
 
 
37
static uint32_t killed_threads;
 
38
static bool segfaulted= false;
 
39
 
 
40
/*
 
41
 * We declare these extern "C" because they are passed to system callback functions
 
42
 * and Sun Studio does not like it when those don't have C linkage. We prefix them
 
43
 * because extern "C"-ing something effectively removes the namespace from the
 
44
 * linker symbols, meaning they would be exporting symbols like "print_signal_warning
 
45
 */
 
46
extern "C"
 
47
{
 
48
 
 
49
void drizzled_print_signal_warning(int sig)
 
50
{
 
51
  if (global_system_variables.log_warnings)
 
52
    errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu32),
 
53
                  sig, global_thread_id);
 
54
#ifndef HAVE_BSD_SIGNALS
 
55
  sigset_t set;
 
56
  sigemptyset(&set);
 
57
 
 
58
  struct sigaction sa;
 
59
  sa.sa_handler= drizzled_print_signal_warning;
 
60
  sa.sa_mask= set;
 
61
  sa.sa_flags= 0;
 
62
  sigaction(sig, &sa, NULL);  /* int. thread system calls */
 
63
#endif
 
64
  if (sig == SIGALRM)
 
65
    alarm(2);                                   /* reschedule alarm */
 
66
}
 
67
 
 
68
/** Called when a thread is aborted. */
 
69
void drizzled_end_thread_signal(int )
 
70
{
 
71
  Session *session= current_session;
 
72
  if (session)
 
73
  {
 
74
    Session::shared_ptr session_ptr(session::Cache::singleton().find(session->getSessionId()));
 
75
    if (not session_ptr) // We need to make we have a lock on session before we do anything with it.
 
76
      return;
 
77
 
 
78
    killed_threads++;
 
79
 
 
80
    // We need to get the ID before we kill off the session
 
81
    session_ptr->scheduler->killSessionNow(session_ptr);
 
82
    DRIZZLE_CONNECTION_DONE(session_ptr->getSessionId());
 
83
  }
 
84
}
 
85
 
 
86
static void write_core(int sig)
 
87
{
 
88
  signal(sig, SIG_DFL);
 
89
#ifdef HAVE_gcov
 
90
  /*
 
91
    For GCOV build, crashing will prevent the writing of code coverage
 
92
    information from this process, causing gcov output to be incomplete.
 
93
    So we force the writing of coverage information here before terminating.
 
94
  */
 
95
  extern void __gcov_flush(void);
 
96
  __gcov_flush();
 
97
#endif
 
98
  pthread_kill(pthread_self(), sig);
 
99
#if defined(P_MYID) && !defined(SCO)
 
100
  /* On Solaris, the above kill is not enough */
 
101
  sigsend(P_PID,P_MYID,sig);
 
102
#endif
 
103
}
 
104
 
 
105
void drizzled_handle_segfault(int sig)
 
106
{
 
107
  time_t curr_time;
 
108
  struct tm tm;
 
109
 
 
110
  /*
 
111
    Strictly speaking, one needs a mutex here
 
112
    but since we have got SIGSEGV already, things are a mess
 
113
    so not having the mutex is not as bad as possibly using a buggy
 
114
    mutex - so we keep things simple
 
115
  */
 
116
  if (segfaulted)
 
117
  {
 
118
    fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
 
119
    exit(1);
 
120
  }
 
121
 
 
122
  segfaulted= true;
 
123
 
 
124
  curr_time= time(NULL);
 
125
  if(curr_time == (time_t)-1)
 
126
  {
 
127
    fprintf(stderr, _("Fatal: time() call failed\n"));
 
128
    exit(1);
 
129
  }
 
130
 
 
131
  localtime_r(&curr_time, &tm);
 
132
  
 
133
  fprintf(stderr,_("%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
 
134
          "This could be because you hit a bug. It is also possible that "
 
135
          "this binary\n or one of the libraries it was linked against is "
 
136
          "corrupt, improperly built,\n or misconfigured. This error can "
 
137
          "also be caused by malfunctioning hardware.\n"),
 
138
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
 
139
          tm.tm_hour, tm.tm_min, tm.tm_sec,
 
140
          sig);
 
141
  fprintf(stderr, _("We will try our best to scrape up some info that "
 
142
                    "will hopefully help diagnose\n"
 
143
                    "the problem, but since we have already crashed, "
 
144
                    "something is definitely wrong\nand this may fail.\n\n"));
 
145
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
 
146
  fprintf(stderr, "max_used_connections=%"PRIu64"\n", current_global_counters.max_used_connections);
 
147
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
 
148
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
 
149
                    "(read_buffer_size + sort_buffer_size)*thread_count\n"
 
150
                    "bytes of memory\n"
 
151
                    "Hope that's ok; if not, decrease some variables in the "
 
152
                    "equation.\n\n"));
 
153
 
 
154
  drizzled::util::custom_backtrace();
 
155
 
 
156
  write_core(sig);
 
157
 
 
158
  exit(1);
 
159
}
 
160
 
 
161
} /* extern "C" */