~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/signal_handler.cc

Merge Joe, plus I updated the tests.

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
24
24
#include "drizzled/signal_handler.h"
25
25
#include "drizzled/drizzled.h"
26
26
#include "drizzled/session.h"
27
 
#include "drizzled/session/cache.h"
28
27
#include "drizzled/internal/my_sys.h"
29
28
#include "drizzled/probes.h"
30
29
#include "drizzled/plugin.h"
31
30
#include "drizzled/plugin/scheduler.h"
32
 
 
33
 
#include "drizzled/util/backtrace.h"
 
31
#include "plugin/myisam/keycache.h"
34
32
 
35
33
using namespace drizzled;
36
34
 
49
47
void drizzled_print_signal_warning(int sig)
50
48
{
51
49
  if (global_system_variables.log_warnings)
52
 
    errmsg_printf(error::WARN, _("Got signal %d from thread %"PRIu32),
 
50
    errmsg_printf(ERRMSG_LVL_WARN, _("Got signal %d from thread %"PRIu64),
53
51
                  sig, global_thread_id);
54
52
#ifndef HAVE_BSD_SIGNALS
55
53
  sigset_t set;
68
66
/** Called when a thread is aborted. */
69
67
void drizzled_end_thread_signal(int )
70
68
{
71
 
  Session *session= current_session;
 
69
  Session *session=current_session;
72
70
  if (session)
73
71
  {
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());
 
72
    statistic_increment(killed_threads, &LOCK_status);
 
73
    session->scheduler->killSessionNow(session);
 
74
    DRIZZLE_CONNECTION_DONE(session->thread_id);
83
75
  }
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
 
76
  return;
103
77
}
104
78
 
105
79
void drizzled_handle_segfault(int sig)
142
116
                    "will hopefully help diagnose\n"
143
117
                    "the problem, but since we have already crashed, "
144
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);
145
121
  fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
146
122
  fprintf(stderr, "max_used_connections=%"PRIu64"\n", current_global_counters.max_used_connections);
147
123
  fprintf(stderr, "connection_count=%u\n", uint32_t(connection_count));
148
124
  fprintf(stderr, _("It is possible that drizzled could use up to \n"
149
 
                    "(read_buffer_size + sort_buffer_size)*thread_count\n"
 
125
                    "key_buffer_size + (read_buffer_size + "
 
126
                    "sort_buffer_size)*thread_count\n"
150
127
                    "bytes of memory\n"
151
128
                    "Hope that's ok; if not, decrease some variables in the "
152
129
                    "equation.\n\n"));
153
130
 
154
 
  drizzled::util::custom_backtrace();
155
 
 
156
 
  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
157
208
 
158
209
  exit(1);
159
210
}