~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/signal_handler.cc

Merged in old drizzled-as-lib patch.

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
 
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/internal/my_sys.h"
 
28
#include "drizzled/probes.h"
 
29
#include "drizzled/plugin.h"
 
30
#include "drizzled/plugin/scheduler.h"
 
31
#include "plugin/myisam/keycache.h"
 
32
 
 
33
using namespace drizzled;
 
34
 
 
35
static uint32_t killed_threads;
 
36
static bool segfaulted= false;
 
37
 
 
38
/*
 
39
 * We declare these extern "C" because they are passed to system callback functions
 
40
 * and Sun Studio does not like it when those don't have C linkage. We prefix them
 
41
 * because extern "C"-ing something effectively removes the namespace from the
 
42
 * linker symbols, meaning they would be exporting symbols like "print_signal_warning
 
43
 */
 
44
extern "C"
 
45
{
 
46
 
 
47
void drizzled_print_signal_warning(int sig)
 
48
{
 
49
  if (global_system_variables.log_warnings)
 
50
    errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64),
 
51
                  sig, global_thread_id);
 
52
#ifndef HAVE_BSD_SIGNALS
 
53
  sigset_t set;
 
54
  sigemptyset(&set);
 
55
 
 
56
  struct sigaction sa;
 
57
  sa.sa_handler= drizzled_print_signal_warning;
 
58
  sa.sa_mask= set;
 
59
  sa.sa_flags= 0;
 
60
  sigaction(sig, &sa, NULL);  /* int. thread system calls */
 
61
#endif
 
62
  if (sig == SIGALRM)
 
63
    alarm(2);                                   /* reschedule alarm */
 
64
}
 
65
 
 
66
/** Called when a thread is aborted. */
 
67
void drizzled_end_thread_signal(int )
 
68
{
 
69
  Session *session=current_session;
 
70
  if (session)
 
71
  {
 
72
    statistic_increment(killed_threads, &LOCK_status);
 
73
    session->scheduler->killSessionNow(session);
 
74
    DRIZZLE_CONNECTION_DONE(session->thread_id);
 
75
  }
 
76
  return;
 
77
}
 
78
 
 
79
void drizzled_handle_segfault(int sig)
 
80
{
 
81
  time_t curr_time;
 
82
  struct tm tm;
 
83
 
 
84
  /*
 
85
    Strictly speaking, one needs a mutex here
 
86
    but since we have got SIGSEGV already, things are a mess
 
87
    so not having the mutex is not as bad as possibly using a buggy
 
88
    mutex - so we keep things simple
 
89
  */
 
90
  if (segfaulted)
 
91
  {
 
92
    fprintf(stderr, _("Fatal signal %d while backtracing\n"), sig);
 
93
    exit(1);
 
94
  }
 
95
 
 
96
  segfaulted= true;
 
97
 
 
98
  curr_time= time(NULL);
 
99
  if(curr_time == (time_t)-1)
 
100
  {
 
101
    fprintf(stderr, _("Fatal: time() call failed\n"));
 
102
    exit(1);
 
103
  }
 
104
 
 
105
  localtime_r(&curr_time, &tm);
 
106
  
 
107
  fprintf(stderr,_("%02d%02d%02d %2d:%02d:%02d - drizzled got signal %d;\n"
 
108
          "This could be because you hit a bug. It is also possible that "
 
109
          "this binary\n or one of the libraries it was linked against is "
 
110
          "corrupt, improperly built,\n or misconfigured. This error can "
 
111
          "also be caused by malfunctioning hardware.\n"),
 
112
          tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
 
113
          tm.tm_hour, tm.tm_min, tm.tm_sec,
 
114
          sig);
 
115
  fprintf(stderr, _("We will try our best to scrape up some info that "
 
116
                    "will hopefully help diagnose\n"
 
117
                    "the problem, but since we have already crashed, "
 
118
                    "something is definitely wrong\nand this may fail.\n\n"));
 
119
  fprintf(stderr, "key_buffer_size=%u\n",
 
120
          (uint32_t) dflt_key_cache->key_cache_mem_size);
 
121
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
 
122
  fprintf(stderr, "max_used_connections=%u\n", max_used_connections);
 
123
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
 
124
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
 
125
                    "key_buffer_size + (read_buffer_size + "
 
126
                    "sort_buffer_size)*thread_count\n"
 
127
                    "bytes of memory\n"
 
128
                    "Hope that's ok; if not, decrease some variables in the "
 
129
                    "equation.\n\n"));
 
130
 
 
131
#ifdef HAVE_STACKTRACE
 
132
  Session *session= current_session;
 
133
 
 
134
  if (! (test_flags.test(TEST_NO_STACKTRACE)))
 
135
  {
 
136
    fprintf(stderr,"session: 0x%lx\n",(long) session);
 
137
    fprintf(stderr,_("Attempting backtrace. You can use the following "
 
138
                     "information to find out\n"
 
139
                     "where drizzled died. If you see no messages after this, "
 
140
                     "something went\n"
 
141
                     "terribly wrong...\n"));
 
142
    print_stacktrace(session ? (unsigned char*) session->thread_stack : (unsigned char*) 0,
 
143
                     my_thread_stack_size);
 
144
  }
 
145
  if (session)
 
146
  {
 
147
    const char *kreason= "UNKNOWN";
 
148
    switch (session->killed) {
 
149
    case Session::NOT_KILLED:
 
150
      kreason= "NOT_KILLED";
 
151
      break;
 
152
    case Session::KILL_BAD_DATA:
 
153
      kreason= "KILL_BAD_DATA";
 
154
      break;
 
155
    case Session::KILL_CONNECTION:
 
156
      kreason= "KILL_CONNECTION";
 
157
      break;
 
158
    case Session::KILL_QUERY:
 
159
      kreason= "KILL_QUERY";
 
160
      break;
 
161
    case Session::KILLED_NO_VALUE:
 
162
      kreason= "KILLED_NO_VALUE";
 
163
      break;
 
164
    }
 
165
    fprintf(stderr, _("Trying to get some variables.\n"
 
166
                      "Some pointers may be invalid and cause the "
 
167
                      "dump to abort...\n"));
 
168
    safe_print_str("session->query", session->query, 1024);
 
169
    fprintf(stderr, "session->thread_id=%"PRIu32"\n", (uint32_t) session->thread_id);
 
170
    fprintf(stderr, "session->killed=%s\n", kreason);
 
171
  }
 
172
  fflush(stderr);
 
173
#endif /* HAVE_STACKTRACE */
 
174
 
 
175
  if (calling_initgroups)
 
176
    fprintf(stderr, _("\nThis crash occurred while the server was calling "
 
177
                      "initgroups(). This is\n"
 
178
                      "often due to the use of a drizzled that is statically "
 
179
                      "linked against glibc\n"
 
180
                      "and configured to use LDAP in /etc/nsswitch.conf. "
 
181
                      "You will need to either\n"
 
182
                      "upgrade to a version of glibc that does not have this "
 
183
                      "problem (2.3.4 or\n"
 
184
                      "later when used with nscd), disable LDAP in your "
 
185
                      "nsswitch.conf, or use a\n"
 
186
                      "drizzled that is not statically linked.\n"));
 
187
 
 
188
  if (internal::thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
 
189
    fprintf(stderr,
 
190
            _("\nYou are running a statically-linked LinuxThreads binary "
 
191
              "on an NPTL system.\n"
 
192
              "This can result in crashes on some distributions due "
 
193
              "to LT/NPTL conflicts.\n"
 
194
              "You should either build a dynamically-linked binary, or force "
 
195
              "LinuxThreads\n"
 
196
              "to be used with the LD_ASSUME_KERNEL environment variable. "
 
197
              "Please consult\n"
 
198
              "the documentation for your distribution on how to do that.\n"));
 
199
 
 
200
#ifdef HAVE_WRITE_CORE
 
201
  if (test_flags.test(TEST_CORE_ON_SIGNAL))
 
202
  {
 
203
    fprintf(stderr, _("Writing a core file\n"));
 
204
    fflush(stderr);
 
205
    write_core(sig);
 
206
  }
 
207
#endif
 
208
 
 
209
  exit(1);
 
210
}
 
211
 
 
212
} /* extern "C" */