crash prevention
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1281 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
24627a7a4b
commit
5ab733c606
|
@ -41,6 +41,9 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#ifdef __FORMATBUG
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <apr.h>
|
||||
|
@ -48,6 +51,7 @@ extern "C" {
|
|||
#include <apr_errno.h>
|
||||
#include <apr_general.h>
|
||||
#include <apr_thread_proc.h>
|
||||
#include <apr_portable.h>
|
||||
#include <apr_thread_mutex.h>
|
||||
#include <apr_thread_cond.h>
|
||||
#include <apr_thread_rwlock.h>
|
||||
|
@ -257,6 +261,12 @@ typedef apr_thread_cond_t switch_thread_cond_t;
|
|||
DoxyDefine(apr_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_pool_t *pool);)
|
||||
#define switch_thread_cond_create apr_thread_cond_create
|
||||
|
||||
typedef apr_os_thread_t switch_thread_id;
|
||||
|
||||
#define switch_thread_data_set apr_thread_data_set
|
||||
#define switch_thread_data_get apr_thread_data_get
|
||||
#define switch_thread_self apr_os_thread_current
|
||||
|
||||
/**
|
||||
* Put the active calling thread to sleep until signaled to wake up. Each
|
||||
* condition variable must be associated with a mutex, and that mutex must
|
||||
|
|
|
@ -514,6 +514,7 @@ typedef enum {
|
|||
SWITCH_EVENT_UNPUBLISH - UnPublish
|
||||
SWITCH_EVENT_TALK - Talking Detected
|
||||
SWITCH_EVENT_NOTALK - Not Talking Detected
|
||||
SWITCH_EVENT_SESSION_CRASH - Session Crashed
|
||||
SWITCH_EVENT_ALL - All events at once
|
||||
</pre>
|
||||
|
||||
|
@ -538,6 +539,7 @@ typedef enum {
|
|||
SWITCH_EVENT_UNPUBLISH,
|
||||
SWITCH_EVENT_TALK,
|
||||
SWITCH_EVENT_NOTALK,
|
||||
SWITCH_EVENT_SESSION_CRASH,
|
||||
SWITCH_EVENT_ALL
|
||||
} switch_event_t;
|
||||
|
||||
|
|
|
@ -48,6 +48,13 @@ static switch_status on_dtmf(switch_core_session *session, char *dtmf, void *buf
|
|||
|
||||
}
|
||||
|
||||
|
||||
static void disast_function(switch_core_session *session, char *data)
|
||||
{
|
||||
printf("%s WOOHOO\n", (char *) 42);
|
||||
}
|
||||
|
||||
|
||||
static void dirtest_function(switch_core_session *session, char *data)
|
||||
{
|
||||
char *var, *val;
|
||||
|
@ -194,11 +201,19 @@ static const switch_state_handler_table state_handlers = {
|
|||
/*.on_transmit */ NULL
|
||||
};
|
||||
|
||||
|
||||
static const switch_application_interface disast_application_interface = {
|
||||
/*.interface_name */ "disast",
|
||||
/*.application_function */ disast_function,
|
||||
NULL, NULL, NULL,
|
||||
/*.next*/ NULL
|
||||
};
|
||||
|
||||
static const switch_application_interface tts_application_interface = {
|
||||
/*.interface_name */ "tts",
|
||||
/*.application_function */ tts_function,
|
||||
NULL, NULL, NULL,
|
||||
/*.next*/ NULL
|
||||
/*.next*/ &disast_application_interface
|
||||
};
|
||||
|
||||
static const switch_application_interface dirtest_application_interface = {
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#define SWITCH_EVENT_QUEUE_LEN 256
|
||||
#define SWITCH_SQL_QUEUE_LEN 2000
|
||||
#define SWITCH_THREAD_JMP_KEY "JMP_KEY"
|
||||
|
||||
struct switch_core_session {
|
||||
uint32_t id;
|
||||
|
@ -83,6 +84,7 @@ struct switch_core_runtime {
|
|||
uint32_t session_id;
|
||||
apr_pool_t *memory_pool;
|
||||
switch_hash *session_table;
|
||||
switch_hash *stack_table;
|
||||
switch_core_db *db;
|
||||
switch_core_db *event_db;
|
||||
const struct switch_state_handler_table *state_handlers[SWITCH_MAX_STATE_HANDLERS];
|
||||
|
@ -1811,12 +1813,50 @@ SWITCH_DECLARE(unsigned int) switch_core_session_runing(switch_core_session *ses
|
|||
return session->thread_running;
|
||||
}
|
||||
|
||||
static int handle_fatality(int sig)
|
||||
{
|
||||
switch_thread_id thread_id;
|
||||
jmp_buf *env;
|
||||
|
||||
if (sig && (thread_id = switch_thread_self()) && (env = (jmp_buf *) apr_hash_get(runtime.stack_table, &thread_id, sizeof(thread_id)))) {
|
||||
longjmp(*env, sig);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Caught SEGV for unmapped thread!");
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session)
|
||||
{
|
||||
switch_channel_state state = CS_NEW, laststate = CS_HANGUP, midstate = CS_DONE;
|
||||
const switch_endpoint_interface *endpoint_interface;
|
||||
const switch_state_handler_table *driver_state_handler = NULL;
|
||||
const switch_state_handler_table *application_state_handler = NULL;
|
||||
switch_thread_id thread_id = switch_thread_self();
|
||||
jmp_buf env;
|
||||
int sig;
|
||||
|
||||
signal(SIGSEGV, (void *) handle_fatality);
|
||||
signal(SIGFPE, (void *) handle_fatality);
|
||||
#ifndef WIN32
|
||||
signal(SIGBUS, (void *) handle_fatality);
|
||||
#endif
|
||||
|
||||
if ((sig = setjmp(env)) != 0) {
|
||||
switch_event *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_LOG, 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 {
|
||||
apr_hash_set(runtime.stack_table, &thread_id, sizeof(thread_id), &env);
|
||||
}
|
||||
|
||||
/*
|
||||
Life of the channel. you have channel and pool in your session
|
||||
|
@ -1850,7 +1890,6 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session)
|
|||
int proceed = 1;
|
||||
midstate = state;
|
||||
|
||||
|
||||
switch (state) {
|
||||
case CS_NEW: /* Just created, Waiting for first instructions */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel));
|
||||
|
@ -2091,6 +2130,8 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session *session)
|
|||
}
|
||||
}
|
||||
|
||||
apr_hash_set(runtime.stack_table, &thread_id, sizeof(thread_id), NULL);
|
||||
|
||||
session->thread_running = 0;
|
||||
}
|
||||
|
||||
|
@ -2650,6 +2691,7 @@ SWITCH_DECLARE(switch_status) switch_core_init(char *console)
|
|||
runtime.session_id = 1;
|
||||
|
||||
switch_core_hash_init(&runtime.session_table, runtime.memory_pool);
|
||||
switch_core_hash_init(&runtime.stack_table, runtime.memory_pool);
|
||||
|
||||
time(&runtime.initiated);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
|
|
@ -102,6 +102,7 @@ static char *EVENT_NAMES[] = {
|
|||
"UNPUBLISH",
|
||||
"TALK",
|
||||
"NOTALK",
|
||||
"SESSION_CRASH",
|
||||
"ALL"
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue