mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-17 09:12:25 +00:00
FS-3615 --resolve
Please Test !
This commit is contained in:
parent
53d694eb59
commit
bb461ce50d
@ -26,12 +26,14 @@
|
|||||||
* Brian Fertig <brian.fertig@convergencetek.com>
|
* Brian Fertig <brian.fertig@convergencetek.com>
|
||||||
* Johny Kadarisman <jkr888@gmail.com>
|
* Johny Kadarisman <jkr888@gmail.com>
|
||||||
* Traun Leyden <tleyden@branchcut.com>
|
* Traun Leyden <tleyden@branchcut.com>
|
||||||
|
* Heimo Stieg <heimo.stieg@nextiraone.eu>
|
||||||
*
|
*
|
||||||
* mod_python.c -- Python Module
|
* mod_python.c -- Python Module
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
#include <frameobject.h>
|
||||||
|
|
||||||
#ifndef _REENTRANT
|
#ifndef _REENTRANT
|
||||||
#define _REENTRANT
|
#define _REENTRANT
|
||||||
@ -43,6 +45,7 @@
|
|||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include "mod_python_extra.h"
|
#include "mod_python_extra.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
PyThreadState *mainThreadState = NULL;
|
PyThreadState *mainThreadState = NULL;
|
||||||
|
|
||||||
@ -50,6 +53,7 @@ void init_freeswitch(void);
|
|||||||
int py_thread(const char *text);
|
int py_thread(const char *text);
|
||||||
static void set_max_recursion_depth(void);
|
static void set_max_recursion_depth(void);
|
||||||
static switch_api_interface_t python_run_interface;
|
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_LOAD_FUNCTION(mod_python_load);
|
||||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_python_shutdown);
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_python_shutdown);
|
||||||
@ -70,6 +74,100 @@ struct switch_py_thread {
|
|||||||
struct switch_py_thread *thread_pool_head = NULL;
|
struct switch_py_thread *thread_pool_head = NULL;
|
||||||
static switch_mutex_t *THREAD_POOL_LOCK = 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,
|
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)
|
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);
|
module = PyImport_ImportModule((char *) script);
|
||||||
if (!module) {
|
if (!module) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n");
|
||||||
PyErr_Print();
|
print_python_error(script);
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
goto done_swap_out;
|
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);
|
module = PyImport_ReloadModule(module);
|
||||||
if (!module) {
|
if (!module) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n");
|
||||||
PyErr_Print();
|
print_python_error(script);
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
goto done_swap_out;
|
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);
|
function = PyObject_GetAttrString(module, (char *) funcname);
|
||||||
if (!function) {
|
if (!function) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define %s\n", funcname);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define %s\n", funcname);
|
||||||
PyErr_Print();
|
print_python_error(script);
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
goto done_swap_out;
|
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)) {
|
} else if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
|
||||||
// Print error, but ignore SystemExit
|
// Print error, but ignore SystemExit
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n");
|
||||||
PyErr_Print();
|
print_python_error(script);
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
PyRun_SimpleString("python_makes_sense");
|
PyRun_SimpleString("python_makes_sense");
|
||||||
PyGC_Collect();
|
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);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set python recursion limit to %d\n", newMaxRecursionDepth);
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set recursion limit to %d\n", newMaxRecursionDepth);
|
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();
|
PyErr_Clear();
|
||||||
PyRun_SimpleString("python_makes_sense");
|
PyRun_SimpleString("python_makes_sense");
|
||||||
PyGC_Collect();
|
PyGC_Collect();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user