FS-3615 --resolve

Please Test !
This commit is contained in:
Marc Olivier Chouinard 2011-12-15 17:23:48 -05:00
parent 53d694eb59
commit bb461ce50d
1 changed files with 103 additions and 5 deletions

View File

@ -26,12 +26,14 @@
* Brian Fertig <brian.fertig@convergencetek.com>
* Johny Kadarisman <jkr888@gmail.com>
* Traun Leyden <tleyden@branchcut.com>
* Heimo Stieg <heimo.stieg@nextiraone.eu>
*
* mod_python.c -- Python Module
*
*/
#include <Python.h>
#include <frameobject.h>
#ifndef _REENTRANT
#define _REENTRANT
@ -43,6 +45,7 @@
#include <switch.h>
#include "mod_python_extra.h"
#include <string.h>
PyThreadState *mainThreadState = NULL;
@ -50,6 +53,7 @@ void init_freeswitch(void);
int py_thread(const char *text);
static void set_max_recursion_depth(void);
static switch_api_interface_t python_run_interface;
static void print_python_error(const char * script);
SWITCH_MODULE_LOAD_FUNCTION(mod_python_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_python_shutdown);
@ -70,6 +74,100 @@ struct switch_py_thread {
struct switch_py_thread *thread_pool_head = NULL;
static switch_mutex_t *THREAD_POOL_LOCK = NULL;
/**
* This function is similiar to PyErr_Print. It uses the freeswitch print/log mechanism instead of the python sys.stderr
*/
static void print_python_error(const char * script)
{
PyObject *pyType = NULL, *pyValue = NULL, *pyTraceback = NULL, *pyString = NULL;
PyObject *pyModule=NULL, *pyFunction = NULL, *pyResult = NULL;
char * buffer = (char*) malloc( 20 * 1024 * sizeof(char));
/* Variables for the traceback */
PyTracebackObject * pyTB = NULL/*, *pyTB2 = NULL*/;
char sTemp[256];
if (buffer == NULL ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not enough Memory to create the error buffer");
}
/* just for security that we will always have a string terminater */
memset(buffer, 0, 20 * 1024 * sizeof(char) );
/*Get the errordata*/
PyErr_Fetch(&pyType, &pyValue, &pyTraceback);
PyErr_NormalizeException(&pyType, &pyValue, &pyTraceback);
/* Printing header*/
sprintf(buffer, "Python Error by calling script \"%s\": ", script );
if (pyType != NULL && (pyString=PyObject_Str(pyType))!=NULL && (PyString_Check(pyString))) {
strcat(buffer, PyString_AsString(pyString));
} else {
strcat(buffer, "<unknown exception type> ");
}
Py_XDECREF(pyString);
/*Print error message*/
if (pyValue != NULL && (pyString=PyObject_Str(pyValue))!=NULL && (PyString_Check(pyString))) {
strcat(buffer, "\nMessage: ");
strcat(buffer, PyString_AsString(pyString));
} else {
strcat(buffer, "\nMessage: <unknown exception date> ");
}
Py_XDECREF(pyString);
/* Print the traceback */
if (pyTraceback != NULL && PyTraceBack_Check(pyTraceback)) {
/*loading traceback module to create the exception data*/
pyModule = PyImport_ImportModule("traceback");
if (pyModule) {
strcat(buffer, "\nException: ");
pyFunction = PyObject_GetAttrString(pyModule, "format_exc");
if (pyFunction) {
pyResult = PyObject_CallObject(pyFunction, NULL);
if (pyResult && PyString_Check(pyResult)) {
strcat(buffer, PyString_AsString(pyResult));
} else {
strcat(buffer, "<exception not available>");
}
Py_XDECREF(pyFunction);
}
Py_XDECREF(pyModule);
}
/* Print traceback header */
strcat(buffer, "\nTraceback (most recent call last)");
pyTB = (PyTracebackObject*) pyTraceback;
/* Traceback */
do {
sprintf((char*)sTemp, "\n\tFile: \"%s\", line %i, in %s",
PyString_AsString(pyTB->tb_frame->f_code->co_filename),
pyTB->tb_lineno,
PyString_AsString(pyTB->tb_frame->f_code->co_name) );
strcat(buffer, (char*)sTemp);
pyTB=pyTB->tb_next;
} while(pyTB != NULL);
}
PyErr_Restore(pyType,pyValue,pyTraceback);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", buffer);
/* free the resources, we dont need memory leaks here */
free(buffer);
}
static void eval_some_python(const char *funcname, char *args, switch_core_session_t *session, switch_stream_handle_t *stream, switch_event_t *params,
char **str, struct switch_py_thread *pt)
{
@ -131,7 +229,7 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi
module = PyImport_ImportModule((char *) script);
if (!module) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n");
PyErr_Print();
print_python_error(script);
PyErr_Clear();
goto done_swap_out;
}
@ -139,7 +237,7 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi
module = PyImport_ReloadModule(module);
if (!module) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n");
PyErr_Print();
print_python_error(script);
PyErr_Clear();
goto done_swap_out;
}
@ -147,7 +245,7 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi
function = PyObject_GetAttrString(module, (char *) funcname);
if (!function) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define %s\n", funcname);
PyErr_Print();
print_python_error(script);
PyErr_Clear();
goto done_swap_out;
}
@ -193,7 +291,7 @@ static void eval_some_python(const char *funcname, char *args, switch_core_sessi
} else if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
// Print error, but ignore SystemExit
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n");
PyErr_Print();
print_python_error(script);
PyErr_Clear();
PyRun_SimpleString("python_makes_sense");
PyGC_Collect();
@ -310,7 +408,7 @@ static void set_max_recursion_depth(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set python recursion limit to %d\n", newMaxRecursionDepth);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set recursion limit to %d\n", newMaxRecursionDepth);
PyErr_Print();
print_python_error("_freeswitch");
PyErr_Clear();
PyRun_SimpleString("python_makes_sense");
PyGC_Collect();