mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
implementing segfault handler for plugin loading
Original commit message from CVS: implementing segfault handler for plugin loading
This commit is contained in:
parent
7943699850
commit
a4f74f5eb4
3 changed files with 100 additions and 3 deletions
|
@ -1,3 +1,12 @@
|
|||
2003-12-15 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* gst/gst.c: (init_popt_callback):
|
||||
* gst/gstplugin.c: (_gst_plugin_fault_handler_restore),
|
||||
(_gst_plugin_fault_handler_sighandler),
|
||||
(_gst_plugin_fault_handler_setup), (gst_plugin_load_file):
|
||||
Implemented fault handlers for catching SIGSEGV while loading
|
||||
plug-ins
|
||||
|
||||
2003-12-02 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* fix documentation build using docbook2..., works on fc1 and rh9
|
||||
|
|
|
@ -55,6 +55,9 @@ static gboolean gst_initialized = FALSE;
|
|||
static gboolean _gst_initialization_failure = FALSE;
|
||||
extern gint _gst_trace_on;
|
||||
|
||||
/* set to TRUE when segfaults need to be left as is */
|
||||
gboolean _gst_enable_segfault = FALSE;
|
||||
|
||||
extern GThreadFunctions gst_thread_dummy_functions;
|
||||
|
||||
|
||||
|
@ -96,6 +99,7 @@ enum {
|
|||
ARG_PLUGIN_SPEW,
|
||||
ARG_PLUGIN_PATH,
|
||||
ARG_PLUGIN_LOAD,
|
||||
ARG_SEGFAULT_ENABLE,
|
||||
ARG_SCHEDULER,
|
||||
ARG_REGISTRY
|
||||
};
|
||||
|
@ -122,6 +126,7 @@ static const struct poptOption gstreamer_options[] = {
|
|||
{"gst-plugin-spew", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_SPEW, N_("enable verbose plugin loading diagnostics"), NULL},
|
||||
{"gst-plugin-path", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_PATH, N_("'" G_SEARCHPATH_SEPARATOR_S "'--separated path list for loading plugins"), "PATHS"},
|
||||
{"gst-plugin-load", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_LOAD, N_("comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH"), "PLUGINS"},
|
||||
{"gst-enable-segfault",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_SEGFAULT_ENABLE,N_("enable receiving of segmentation faults during plugin loading"), NULL},
|
||||
{"gst-scheduler", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_SCHEDULER, N_("scheduler to use ('"GST_SCHEDULER_DEFAULT_NAME"' is the default)"), "SCHEDULER"},
|
||||
{"gst-registry", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY, N_("registry to use") , "REGISTRY"},
|
||||
POPT_TABLEEND
|
||||
|
@ -700,6 +705,9 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
|
|||
case ARG_PLUGIN_LOAD:
|
||||
split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
|
||||
break;
|
||||
case ARG_SEGFAULT_ENABLE:
|
||||
_gst_enable_segfault = TRUE;
|
||||
break;
|
||||
case ARG_SCHEDULER:
|
||||
gst_scheduler_factory_set_default_name (arg);
|
||||
break;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "gst_private.h"
|
||||
|
||||
|
@ -39,6 +40,11 @@
|
|||
static GModule *main_module = NULL;
|
||||
static GList *_gst_plugin_static = NULL;
|
||||
|
||||
/* static variables for segfault handling of plugin loading */
|
||||
static char *_gst_plugin_fault_handler_filename = NULL;
|
||||
extern gboolean *_gst_enable_segfault; /* see gst.c */
|
||||
static gboolean *_gst_plugin_fault_handler_is_setup = FALSE;
|
||||
|
||||
/* list of valid licenses.
|
||||
* One of these must be specified or the plugin won't be loaded
|
||||
* Contact gstreamer-devel@lists.sourceforge.net if your license should be
|
||||
|
@ -194,6 +200,71 @@ gst_plugin_register_func (GstPlugin *plugin, GModule *module, GstPluginDesc *des
|
|||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gst_plugin_fault_handler_restore:
|
||||
* segfault handler restorer
|
||||
*/
|
||||
static void
|
||||
_gst_plugin_fault_handler_restore (void)
|
||||
{
|
||||
struct sigaction action;
|
||||
|
||||
memset (&action, 0, sizeof (action));
|
||||
action.sa_handler = SIG_DFL;
|
||||
|
||||
sigaction (SIGSEGV, &action, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* _gst_plugin_fault_handler_sighandler:
|
||||
* segfault handler implementation
|
||||
*/
|
||||
static void
|
||||
_gst_plugin_fault_handler_sighandler (int signum)
|
||||
{
|
||||
/* We need to restore the fault handler or we'll keep getting it */
|
||||
_gst_plugin_fault_handler_restore ();
|
||||
|
||||
switch (signum)
|
||||
{
|
||||
case SIGSEGV:
|
||||
g_print ("\nERROR:");
|
||||
g_print ("Caught a segmentation fault while loading plugin file:\n");
|
||||
g_print ("%s\n\n", _gst_plugin_fault_handler_filename);
|
||||
g_print ("Please either:\n");
|
||||
g_print ("- remove it and restart.\n");
|
||||
g_print ("- run with --gst-enable-segfault and debug.\n");
|
||||
exit (-1);
|
||||
break;
|
||||
default:
|
||||
g_print ("Caught unhandled signal on plugin loading\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gst_plugin_fault_handler_setup:
|
||||
* sets up the segfault handler
|
||||
*/
|
||||
static void
|
||||
_gst_plugin_fault_handler_setup (void)
|
||||
{
|
||||
struct sigaction action;
|
||||
|
||||
/* if asked to leave segfaults alone, just return */
|
||||
if (_gst_enable_segfault) return;
|
||||
|
||||
if (_gst_plugin_fault_handler_is_setup) return;
|
||||
|
||||
memset (&action, 0, sizeof (action));
|
||||
action.sa_handler = _gst_plugin_fault_handler_sighandler;
|
||||
|
||||
sigaction (SIGSEGV, &action, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_plugin_fault_handler_setup ();
|
||||
|
||||
/**
|
||||
* gst_plugin_load_file:
|
||||
* @plugin: The plugin to load
|
||||
|
@ -201,7 +272,7 @@ gst_plugin_register_func (GstPlugin *plugin, GModule *module, GstPluginDesc *des
|
|||
*
|
||||
* Load the given plugin.
|
||||
*
|
||||
* Returns: a new GstPlugin or NULL, if an error occured
|
||||
* Returns: a new GstPlugin or NULL, if an error occurred.
|
||||
*/
|
||||
GstPlugin *
|
||||
gst_plugin_load_file (const gchar *filename, GError **error)
|
||||
|
@ -230,7 +301,7 @@ gst_plugin_load_file (const gchar *filename, GError **error)
|
|||
GST_PLUGIN_ERROR_MODULE,
|
||||
"Problem opening file %s\n",
|
||||
filename);
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
module = g_module_open (filename, G_MODULE_BIND_LAZY);
|
||||
|
@ -278,10 +349,19 @@ gst_plugin_load_file (const gchar *filename, GError **error)
|
|||
desc->name);
|
||||
}
|
||||
|
||||
/* this is where we load the actual .so, so let's trap SIGSEGV */
|
||||
_gst_plugin_fault_handler_setup ();
|
||||
_gst_plugin_fault_handler_filename = plugin->filename;
|
||||
|
||||
if (gst_plugin_register_func (plugin, module, desc)) {
|
||||
/* remove signal handler */
|
||||
_gst_plugin_fault_handler_restore ();
|
||||
_gst_plugin_fault_handler_filename = NULL;
|
||||
GST_INFO ("plugin \"%s\" loaded", plugin->filename);
|
||||
return plugin;
|
||||
} else {
|
||||
/* remove signal handler */
|
||||
_gst_plugin_fault_handler_restore ();
|
||||
GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename);
|
||||
/* plugin == NULL */
|
||||
g_set_error (error,
|
||||
|
|
Loading…
Reference in a new issue