mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +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>
|
2003-12-02 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
* fix documentation build using docbook2..., works on fc1 and rh9
|
* 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;
|
static gboolean _gst_initialization_failure = FALSE;
|
||||||
extern gint _gst_trace_on;
|
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;
|
extern GThreadFunctions gst_thread_dummy_functions;
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,6 +99,7 @@ enum {
|
||||||
ARG_PLUGIN_SPEW,
|
ARG_PLUGIN_SPEW,
|
||||||
ARG_PLUGIN_PATH,
|
ARG_PLUGIN_PATH,
|
||||||
ARG_PLUGIN_LOAD,
|
ARG_PLUGIN_LOAD,
|
||||||
|
ARG_SEGFAULT_ENABLE,
|
||||||
ARG_SCHEDULER,
|
ARG_SCHEDULER,
|
||||||
ARG_REGISTRY
|
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-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-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-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-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"},
|
{"gst-registry", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY, N_("registry to use") , "REGISTRY"},
|
||||||
POPT_TABLEEND
|
POPT_TABLEEND
|
||||||
|
@ -700,6 +705,9 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
|
||||||
case ARG_PLUGIN_LOAD:
|
case ARG_PLUGIN_LOAD:
|
||||||
split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
|
split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL);
|
||||||
break;
|
break;
|
||||||
|
case ARG_SEGFAULT_ENABLE:
|
||||||
|
_gst_enable_segfault = TRUE;
|
||||||
|
break;
|
||||||
case ARG_SCHEDULER:
|
case ARG_SCHEDULER:
|
||||||
gst_scheduler_factory_set_default_name (arg);
|
gst_scheduler_factory_set_default_name (arg);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include "gst_private.h"
|
#include "gst_private.h"
|
||||||
|
|
||||||
|
@ -39,6 +40,11 @@
|
||||||
static GModule *main_module = NULL;
|
static GModule *main_module = NULL;
|
||||||
static GList *_gst_plugin_static = 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.
|
/* list of valid licenses.
|
||||||
* One of these must be specified or the plugin won't be loaded
|
* One of these must be specified or the plugin won't be loaded
|
||||||
* Contact gstreamer-devel@lists.sourceforge.net if your license should be
|
* 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;
|
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:
|
* gst_plugin_load_file:
|
||||||
* @plugin: The plugin to load
|
* @plugin: The plugin to load
|
||||||
|
@ -201,7 +272,7 @@ gst_plugin_register_func (GstPlugin *plugin, GModule *module, GstPluginDesc *des
|
||||||
*
|
*
|
||||||
* Load the given plugin.
|
* 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 *
|
GstPlugin *
|
||||||
gst_plugin_load_file (const gchar *filename, GError **error)
|
gst_plugin_load_file (const gchar *filename, GError **error)
|
||||||
|
@ -229,8 +300,8 @@ gst_plugin_load_file (const gchar *filename, GError **error)
|
||||||
GST_PLUGIN_ERROR,
|
GST_PLUGIN_ERROR,
|
||||||
GST_PLUGIN_ERROR_MODULE,
|
GST_PLUGIN_ERROR_MODULE,
|
||||||
"Problem opening file %s\n",
|
"Problem opening file %s\n",
|
||||||
filename);
|
filename);
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
module = g_module_open (filename, G_MODULE_BIND_LAZY);
|
module = g_module_open (filename, G_MODULE_BIND_LAZY);
|
||||||
|
@ -278,10 +349,19 @@ gst_plugin_load_file (const gchar *filename, GError **error)
|
||||||
desc->name);
|
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)) {
|
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);
|
GST_INFO ("plugin \"%s\" loaded", plugin->filename);
|
||||||
return plugin;
|
return plugin;
|
||||||
} else {
|
} else {
|
||||||
|
/* remove signal handler */
|
||||||
|
_gst_plugin_fault_handler_restore ();
|
||||||
GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename);
|
GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename);
|
||||||
/* plugin == NULL */
|
/* plugin == NULL */
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
|
|
Loading…
Reference in a new issue