~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/signal_handler.cc

  • Committer: Brian Aker
  • Date: 2010-06-05 00:15:57 UTC
  • mfrom: (1589.1.1 drizzle_events)
  • Revision ID: brian@gaz-20100605001557-j1k41ni5k9mis891
Merge in Barry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
 
20
#include "config.h"
21
21
 
22
22
#include <signal.h>
23
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
 
#include <drizzled/current_session.h>
33
 
 
34
 
#include <drizzled/util/backtrace.h>
 
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"
35
32
 
36
33
using namespace drizzled;
37
34
 
50
47
void drizzled_print_signal_warning(int sig)
51
48
{
52
49
  if (global_system_variables.log_warnings)
53
 
    errmsg_printf(error::WARN, _("Got signal %d from thread %"PRIu32),
 
50
    errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64),
54
51
                  sig, global_thread_id);
55
52
#ifndef HAVE_BSD_SIGNALS
56
53
  sigset_t set;
69
66
/** Called when a thread is aborted. */
70
67
void drizzled_end_thread_signal(int )
71
68
{
72
 
  Session *session= current_session;
 
69
  Session *session=current_session;
73
70
  if (session)
74
71
  {
75
 
    Session::shared_ptr session_ptr(session::Cache::singleton().find(session->getSessionId()));
76
 
    if (not session_ptr) // We need to make we have a lock on session before we do anything with it.
77
 
      return;
78
 
 
79
 
    killed_threads++;
80
 
 
81
 
    // We need to get the ID before we kill off the session
82
 
    session_ptr->scheduler->killSessionNow(session_ptr);
83
 
    DRIZZLE_CONNECTION_DONE(session_ptr->getSessionId());
 
72
    statistic_increment(killed_threads, &LOCK_status);
 
73
    session->scheduler->killSessionNow(session);
 
74
    DRIZZLE_CONNECTION_DONE(session->thread_id);
84
75
  }
85
 
}
86
 
 
87
 
static void write_core(int sig)
88
 
{
89
 
  signal(sig, SIG_DFL);
90
 
#ifdef HAVE_gcov
91
 
  /*
92
 
    For GCOV build, crashing will prevent the writing of code coverage
93
 
    information from this process, causing gcov output to be incomplete.
94
 
    So we force the writing of coverage information here before terminating.
95
 
  */
96
 
  extern void __gcov_flush(void);
97
 
  __gcov_flush();
98
 
#endif
99
 
  pthread_kill(pthread_self(), sig);
100
 
#if defined(P_MYID) && !defined(SCO)
101
 
  /* On Solaris, the above kill is not enough */
102
 
  sigsend(P_PID,P_MYID,sig);
103
 
#endif
 
76
  return;
104
77
}
105
78
 
106
79
void drizzled_handle_segfault(int sig)
143
116
                    "will hopefully help diagnose\n"
144
117
                    "the problem, but since we have already crashed, "
145
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);
146
121
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
147
 
  fprintf(stderr, "max_used_connections=%"PRIu64"\n", current_global_counters.max_used_connections);
 
122
  fprintf(stderr, "max_used_connections=%u\n", current_global_counters.max_used_connections);
148
123
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
149
124
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
150
 
                    "(read_buffer_size + sort_buffer_size)*thread_count\n"
 
125
                    "key_buffer_size + (read_buffer_size + "
 
126
                    "sort_buffer_size)*thread_count\n"
151
127
                    "bytes of memory\n"
152
128
                    "Hope that's ok; if not, decrease some variables in the "
153
129
                    "equation.\n\n"));
154
130
 
155
 
  drizzled::util::custom_backtrace();
156
 
 
157
 
  write_core(sig);
 
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
158
208
 
159
209
  exit(1);
160
210
}