]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-3615 --resolve
authorMarc Olivier Chouinard <mochouinard@moctel.com>
Thu, 15 Dec 2011 22:23:48 +0000 (17:23 -0500)
committerMarc Olivier Chouinard <mochouinard@moctel.com>
Thu, 15 Dec 2011 22:23:48 +0000 (17:23 -0500)
Please Test !

src/mod/languages/mod_python/mod_python.c

index 1245dea86749bba742b879ce363837892d613cde..b92526e13568b59eeb3ef58c3832c304880335bf 100644 (file)
  * 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();