diff options
-rw-r--r-- | plugins/pychrysalide/bindings.c | 120 | ||||
-rw-r--r-- | plugins/pychrysalide/bindings.h | 5 | ||||
-rw-r--r-- | plugins/pychrysalide/core.c | 148 |
3 files changed, 123 insertions, 150 deletions
diff --git a/plugins/pychrysalide/bindings.c b/plugins/pychrysalide/bindings.c index 295667f..f715a8e 100644 --- a/plugins/pychrysalide/bindings.c +++ b/plugins/pychrysalide/bindings.c @@ -34,6 +34,7 @@ #include <config.h> #include <common/cpp.h> +#include <common/extstr.h> #include <plugins/pglist.h> // REMME ? #include <plugins/self.h> // REMME ? @@ -929,13 +930,130 @@ PyObject *init_python_pychrysalide_module(const pyinit_details_t *details) exit: if (result == NULL && !details->standalone) - /*log_pychrysalide_exception("Loading failed")*/; + log_pychrysalide_exception("Python bindings loading failed"); return result; } +/****************************************************************************** +* * +* Paramètres : prefix = message d'introduction à faire apparaître à l'écran.* +* * +* Description : Présente dans le journal une exception survenue. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void log_pychrysalide_exception(const char *prefix, ...) +{ + va_list ap; /* Compléments argumentaires */ + char *msg; /* Message complet à imprimer */ + PyObject *err_type; /* Type d'erreur Python */ + PyObject *err_value; /* Instance Python d'erreur */ + PyObject *err_traceback; /* Trace Python associée */ + PyObject *err_string; /* Description Python d'erreur */ + const char *err_msg; /* Représentation humaine */ + + assert(PyGILState_Check() == 1); + + if (PyErr_Occurred()) + { + /* Base de la communication */ + + va_start(ap, prefix); + + vasprintf(&msg, prefix, ap); + + va_end(ap); + + /* Détails complémentaires */ + + PyErr_Fetch(&err_type, &err_value, &err_traceback); + + PyErr_NormalizeException(&err_type, &err_value, &err_traceback); + + if (err_traceback == NULL) + { + err_traceback = Py_None; + Py_INCREF(err_traceback); + } + + PyException_SetTraceback(err_value, err_traceback); + + if (err_value == NULL) + msg = stradd(msg, _(": no extra information is provided...")); + + else + { + err_string = PyObject_Str(err_value); + err_msg = PyUnicode_AsUTF8(err_string); + + msg = stradd(msg, ": "); + msg = stradd(msg, err_msg); + + Py_DECREF(err_string); + + } + + /** + * Bien que la documentation précise que la fonction PyErr_Fetch() + * transfère la propritété des éléments retournés, la pratique + * montre que le programme plante à la terminaison en cas d'exception. + * + * C'est par exemple le cas quand un greffon Python ne peut se lancer + * correctement ; l'exception est alors levée à partir de la fonction + * create_python_plugin() et le plantage intervient en sortie d'exécution, + * au moment de la libération de l'extension Python : + * + * ==14939== Jump to the invalid address stated on the next line + * ==14939== at 0x1A8FCBC9: ??? + * ==14939== by 0x53DCDB2: g_object_unref (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5800.3) + * ==14939== by 0x610F834: on_plugin_ref_toggle (pglist.c:370) + * ==14939== by 0x610F31A: exit_all_plugins (pglist.c:153) + * ==14939== by 0x10AD19: main (main.c:440) + * ==14939== Address 0x1a8fcbc9 is not stack'd, malloc'd or (recently) free'd + * + * Curieusement, un appel à PyErr_PrintEx(1) corrige l'effet, alors qu'un + * appel à PyErr_PrintEx(0) ne change rien. + * + * La seule différence de l'instruction set_sys_last_vars réside en quelques + * lignes dans le code de l'interpréteur Python : + * + * if (set_sys_last_vars) { + * _PySys_SetObjectId(&PyId_last_type, exception); + * _PySys_SetObjectId(&PyId_last_value, v); + * _PySys_SetObjectId(&PyId_last_traceback, tb); + * } + * + * L'explication n'est pas encore déterminé : bogue dans Chrysalide ou dans Python ? + * L'ajout des éléments dans le dictionnaire du module sys ajoute une référence + * à ces éléments. + * + * On reproduit ici le comportement du code correcteur avec PySys_SetObject(). + */ + + PySys_SetObject("last_type", err_type); + PySys_SetObject("last_value", err_value); + PySys_SetObject("last_traceback", err_traceback); + + Py_XDECREF(err_traceback); + Py_XDECREF(err_value); + Py_XDECREF(err_type); + + log_plugin_simple_message(LMT_EXT_ERROR, msg); + + free(msg); + + } + +} + + /* ---------------------------------------------------------------------------------- */ /* FONCTIONS GLOBALES DE CHRYSALIDE */ diff --git a/plugins/pychrysalide/bindings.h b/plugins/pychrysalide/bindings.h index 1c63956..e9ee421 100644 --- a/plugins/pychrysalide/bindings.h +++ b/plugins/pychrysalide/bindings.h @@ -48,16 +48,15 @@ typedef struct _pyinit_details_t { bool standalone; /* Chargement depuis Python ? */ - bool (* populate_extra) (void); /* Ajout de types ? */ - } pyinit_details_t; /* Implémente le point d'entrée pour l'initialisation de Python. */ PyObject *init_python_pychrysalide_module(const pyinit_details_t *); - +/* Présente dans le journal une exception survenue. */ +void log_pychrysalide_exception(const char *, ...); diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c index e815e25..3c551c7 100644 --- a/plugins/pychrysalide/core.c +++ b/plugins/pychrysalide/core.c @@ -368,146 +368,6 @@ G_MODULE_EXPORT gpointer chrysalide_plugin_build_type_instance(GPluginModule *pl -/****************************************************************************** -* * -* Paramètres : prefix = message d'introduction à faire apparaître à l'écran.* -* * -* Description : Présente dans le journal une exception survenue. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void log_pychrysalide_exception(const char *prefix, ...) -{ - va_list ap; /* Compléments argumentaires */ - char *msg; /* Message complet à imprimer */ - PyObject *err_type; /* Type d'erreur Python */ - PyObject *err_value; /* Instance Python d'erreur */ - PyObject *err_traceback; /* Trace Python associée */ - PyObject *err_string; /* Description Python d'erreur */ - const char *err_msg; /* Représentation humaine */ - - assert(PyGILState_Check() == 1); - - if (PyErr_Occurred()) - { - /* Base de la communication */ - - va_start(ap, prefix); - - vasprintf(&msg, prefix, ap); - - va_end(ap); - - /* Détails complémentaires */ - - PyErr_Fetch(&err_type, &err_value, &err_traceback); - - PyErr_NormalizeException(&err_type, &err_value, &err_traceback); - - if (err_traceback == NULL) - { - err_traceback = Py_None; - Py_INCREF(err_traceback); - } - - PyException_SetTraceback(err_value, err_traceback); - - if (err_value == NULL) - msg = stradd(msg, _(": no extra information is provided...")); - - else - { - err_string = PyObject_Str(err_value); - err_msg = PyUnicode_AsUTF8(err_string); - - msg = stradd(msg, ": "); - msg = stradd(msg, err_msg); - - Py_DECREF(err_string); - - } - - /** - * Bien que la documentation précise que la fonction PyErr_Fetch() - * transfère la propritété des éléments retournés, la pratique - * montre que le programme plante à la terminaison en cas d'exception. - * - * C'est par exemple le cas quand un greffon Python ne peut se lancer - * correctement ; l'exception est alors levée à partir de la fonction - * create_python_plugin() et le plantage intervient en sortie d'exécution, - * au moment de la libération de l'extension Python : - * - * ==14939== Jump to the invalid address stated on the next line - * ==14939== at 0x1A8FCBC9: ??? - * ==14939== by 0x53DCDB2: g_object_unref (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5800.3) - * ==14939== by 0x610F834: on_plugin_ref_toggle (pglist.c:370) - * ==14939== by 0x610F31A: exit_all_plugins (pglist.c:153) - * ==14939== by 0x10AD19: main (main.c:440) - * ==14939== Address 0x1a8fcbc9 is not stack'd, malloc'd or (recently) free'd - * - * Curieusement, un appel à PyErr_PrintEx(1) corrige l'effet, alors qu'un - * appel à PyErr_PrintEx(0) ne change rien. - * - * La seule différence de l'instruction set_sys_last_vars réside en quelques - * lignes dans le code de l'interpréteur Python : - * - * if (set_sys_last_vars) { - * _PySys_SetObjectId(&PyId_last_type, exception); - * _PySys_SetObjectId(&PyId_last_value, v); - * _PySys_SetObjectId(&PyId_last_traceback, tb); - * } - * - * L'explication n'est pas encore déterminé : bogue dans Chrysalide ou dans Python ? - * L'ajout des éléments dans le dictionnaire du module sys ajoute une référence - * à ces éléments. - * - * On reproduit ici le comportement du code correcteur avec PySys_SetObject(). - */ - - PySys_SetObject("last_type", err_type); - PySys_SetObject("last_value", err_value); - PySys_SetObject("last_traceback", err_traceback); - - Py_XDECREF(err_traceback); - Py_XDECREF(err_value); - Py_XDECREF(err_type); - - log_plugin_simple_message(LMT_ERROR, msg); - - free(msg); - - } - -} - - - - - - - - - - - - - - - - - - - - - - - - - /* ---------------------------------------------------------------------------------- */ /* IMPLEMENTATION DES FONCTIONS DE CLASSE */ /* ---------------------------------------------------------------------------------- */ @@ -685,8 +545,6 @@ static GPluginModule *create_python_plugin(const char *modname, const char *file result = G_PLUGIN_MODULE(pygobject_get(instance)); - ///result->filename = strdup(filename); - /** * L'instance Python et l'objet GLib résultant sont un même PyGObject. * @@ -696,13 +554,11 @@ static GPluginModule *create_python_plugin(const char *modname, const char *file Py_DECREF(module); - printf(" -> REF: %p %u\n", result, G_OBJECT(result)->ref_count); - return result; no_instance: - //log_pychrysalide_exception(_("An error occured when building the 'AutoLoad' instance")); + log_pychrysalide_exception(_("An error occured when building the 'AutoLoad' instance")); no_class: @@ -714,7 +570,7 @@ static GPluginModule *create_python_plugin(const char *modname, const char *file Py_XDECREF(module); - //log_pychrysalide_exception(_("An error occured when importing '%s'"), modname); + log_pychrysalide_exception(_("An error occured when importing '%s'"), modname); bad_exit: |