farewell crash protection

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14919 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-09-18 15:55:10 +00:00
parent c43c651c92
commit 14e4f0497d
4 changed files with 8 additions and 112 deletions

View File

@ -24,8 +24,6 @@
<param name="sessions-per-second" value="30"/> <param name="sessions-per-second" value="30"/>
<!-- Default Global Log Level - value is one of debug,info,notice,warning,err,crit,alert --> <!-- Default Global Log Level - value is one of debug,info,notice,warning,err,crit,alert -->
<param name="loglevel" value="debug"/> <param name="loglevel" value="debug"/>
<!--Try to catch any crashes that can be recoverable (in the context of a call)-->
<param name="crash-protection" value="false"/>
<!-- The min_dtmf_duration specifies the minimum DTMF duration to use on <!-- The min_dtmf_duration specifies the minimum DTMF duration to use on
outgoing events. Events shorter than this will be increased in duration outgoing events. Events shorter than this will be increased in duration
to match min_dtmf_duration. You cannot configure a dtmf duration on a to match min_dtmf_duration. You cannot configure a dtmf duration on a

View File

@ -231,11 +231,10 @@ typedef enum {
SCF_USE_SQL = (1 << 0), SCF_USE_SQL = (1 << 0),
SCF_NO_NEW_SESSIONS = (1 << 1), SCF_NO_NEW_SESSIONS = (1 << 1),
SCF_SHUTTING_DOWN = (1 << 2), SCF_SHUTTING_DOWN = (1 << 2),
SCF_CRASH_PROT = (1 << 3), SCF_VG = (1 << 3),
SCF_VG = (1 << 4), SCF_RESTART = (1 << 4),
SCF_RESTART = (1 << 5), SCF_SHUTDOWN_REQUESTED = (1 << 5),
SCF_SHUTDOWN_REQUESTED = (1 << 6), SCF_USE_AUTO_NAT = (1 << 6)
SCF_USE_AUTO_NAT = (1 << 7)
} switch_core_flag_enum_t; } switch_core_flag_enum_t;
typedef uint32_t switch_core_flag_t; typedef uint32_t switch_core_flag_t;

View File

@ -1379,11 +1379,7 @@ static void switch_load_core_config(const char *file)
const char *var = switch_xml_attr_soft(param, "name"); const char *var = switch_xml_attr_soft(param, "name");
const char *val = switch_xml_attr_soft(param, "value"); const char *val = switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "crash-protection")) { if (!strcasecmp(var, "loglevel")) {
if (switch_true(val)) {
switch_set_flag((&runtime), SCF_CRASH_PROT);
}
} else if (!strcasecmp(var, "loglevel")) {
int level; int level;
if (*val > 47 && *val < 58) { if (*val > 47 && *val < 58) {
level = atoi(val); level = atoi(val);
@ -1507,8 +1503,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t
} }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,
"\nFreeSWITCH Version %s Started.\nCrash Protection [%s]\nMax Sessions[%u]\nSession Rate[%d]\nSQL [%s]\n", SWITCH_VERSION_FULL, "\nFreeSWITCH Version %s Started.\nMax Sessions[%u]\nSession Rate[%d]\nSQL [%s]\n", SWITCH_VERSION_FULL,
switch_test_flag((&runtime), SCF_CRASH_PROT) ? "Enabled" : "Disabled",
switch_core_session_limit(0), switch_core_session_limit(0),
switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled"); switch_core_sessions_per_second(0), switch_test_flag((&runtime), SCF_USE_SQL) ? "Enabled" : "Disabled");

View File

@ -212,75 +212,9 @@ static void switch_core_standard_on_hibernate(switch_core_session_t *session)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard HIBERNATE\n", switch_channel_get_name(session->channel)); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Standard HIBERNATE\n", switch_channel_get_name(session->channel));
} }
#include <sqlite3.h>
#include "../../../libs/sqlite/src/hash.h"
//static switch_hash_t *stack_table = NULL;
static Hash stack_table;
static switch_mutex_t *stack_mutex = NULL;
#if defined (__GNUC__) && defined (LINUX) && defined (HAVE_EXECINFO_H)
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#define STACK_LEN 10
/* Obtain a backtrace and print it to stdout. */
static void print_trace(void)
{
void *array[STACK_LEN];
size_t size;
char **strings;
size_t i;
size = backtrace(array, STACK_LEN);
strings = backtrace_symbols(array, size);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Obtained %zd stack frames.\n", size);
for (i = 0; i < size; i++) {
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CRIT, "%s\n", strings[i]);
}
free(strings);
}
#else
static void print_trace(void)
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Trace not available =(\n");
}
#endif
static void handle_fatality(int sig)
{
switch_thread_id_t thread_id;
jmp_buf *env;
if (!sig) return;
thread_id = switch_thread_self();
switch_mutex_lock(stack_mutex);
env = (jmp_buf *) sqlite3HashFind(&stack_table, &thread_id, sizeof(thread_id));
switch_mutex_unlock(stack_mutex);
if (thread_id && env) {
print_trace();
longjmp(*env, sig);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Caught signal %d for unmapped thread!", sig);
abort();
}
}
void switch_core_state_machine_init(switch_memory_pool_t *pool) void switch_core_state_machine_init(switch_memory_pool_t *pool)
{ {
return;
if (switch_test_flag((&runtime), SCF_CRASH_PROT)) {
switch_mutex_init(&stack_mutex, SWITCH_MUTEX_NESTED, pool);
switch_mutex_lock(stack_mutex);
sqlite3HashInit(&stack_table, SQLITE_HASH_BINARY, 0);
switch_mutex_unlock(stack_mutex);
}
} }
#define STATE_MACRO(__STATE, __STATE_STR) do { \ #define STATE_MACRO(__STATE, __STATE_STR) do { \
@ -329,35 +263,9 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
const switch_endpoint_interface_t *endpoint_interface; const switch_endpoint_interface_t *endpoint_interface;
const switch_state_handler_table_t *driver_state_handler = NULL; const switch_state_handler_table_t *driver_state_handler = NULL;
const switch_state_handler_table_t *application_state_handler = NULL; const switch_state_handler_table_t *application_state_handler = NULL;
switch_thread_id_t thread_id; int silly = 0;
jmp_buf env;
int sig, silly = 0;
uint32_t new_loops = 60000; uint32_t new_loops = 60000;
if (switch_test_flag((&runtime), SCF_CRASH_PROT)) {
thread_id = switch_thread_self();
signal(SIGSEGV, handle_fatality);
signal(SIGFPE, handle_fatality);
#ifndef WIN32
signal(SIGBUS, handle_fatality);
#endif
if ((sig = setjmp(env)) != 0) {
switch_event_t *event;
if (switch_event_create(&event, SWITCH_EVENT_SESSION_CRASH) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_set_data(session->channel, event);
switch_event_fire(&event);
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Thread has crashed for channel %s\n", switch_channel_get_name(session->channel));
switch_channel_hangup(session->channel, SWITCH_CAUSE_CRASH);
} else {
switch_mutex_lock(stack_mutex);
sqlite3HashInsert(&stack_table, &thread_id, sizeof(thread_id), (void *) &env);
switch_mutex_unlock(stack_mutex);
}
}
/* /*
Life of the channel. you have channel and pool in your session Life of the channel. you have channel and pool in your session
everywhere you go you use the session to malloc with everywhere you go you use the session to malloc with
@ -474,10 +382,6 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
done: done:
switch_mutex_unlock(session->mutex); switch_mutex_unlock(session->mutex);
if (switch_test_flag((&runtime), SCF_CRASH_PROT)) {
sqlite3HashInsert(&stack_table, &thread_id, sizeof(thread_id), NULL);
//apr_hash_set(stack_table, &thread_id, sizeof(thread_id), NULL);
}
session->thread_running = 0; session->thread_running = 0;
} }