validate: Implement fault_injection as a Gs(tValidate)Plugin

https://bugzilla.gnome.org/show_bug.cgi?id=743994
This commit is contained in:
Thibault Saunier 2015-02-04 14:30:05 +01:00
parent a9b27057bb
commit ed43ab1509
7 changed files with 158 additions and 27 deletions

View file

@ -188,8 +188,15 @@ GST_LICENSE="LGPL"
AC_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license])
AC_SUBST(GST_LICENSE)
dnl set location of plugin directory
AG_GST_SET_PLUGINDIR
dnl define location of plugin directory
AS_AC_EXPAND(PLUGINDIR, ${libdir}/gstreamer-$GST_API_VERSION/validate)
AC_DEFINE_UNQUOTED(PLUGINDIR, "$PLUGINDIR",
[directory where GstValidate plugins are located])
AC_MSG_NOTICE([Using $PLUGINDIR as the plugin install location for GstValidate])
dnl plugin directory configure-time variable for use in Makefile.am
plugindir="\$(libdir)/gstreamer-$GST_API_VERSION/validate"
AC_SUBST(plugindir)
# set by AG_GST_PARSE_SUBSYSTEM_DISABLES above
dnl make sure it doesn't complain about unused variables if debugging is disabled
@ -235,10 +242,6 @@ GST_CFLAGS="$GST_CFLAGS \$(GST_OPTION_CFLAGS)"
AC_SUBST(GST_CFLAGS)
AC_SUBST(GST_LIBS)
dnl Tiny library overriding calls such as socket recv / send
FAULTINJECTION_LIBS="-L\$(top_srcdir)/fault_injection/ -lfaultinjection-$GST_API_VERSION"
AC_SUBST([FAULTINJECTION_LIBS])
dnl GST_ALL_*
dnl vars common to for all internal objects (core libs, elements, applications)
dnl CFLAGS:

View file

@ -1,13 +1,13 @@
libfaultinjection_@GST_API_VERSION@_la_SOURCES = \
plugin_LTLIBRARIES = libfaultinjection.la
libfaultinjection_la_SOURCES = \
socket_interposer.c
libfaultinjection_@GST_API_VERSION@include_HEADERS = \
noinst_HEADERS = \
socket_interposer.h
lib_LTLIBRARIES = libfaultinjection-@GST_API_VERSION@.la
libfaultinjection_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)
libfaultinjection_@GST_API_VERSION@_la_LIBADD = $(GST_ALL_LIBS)
libfaultinjection_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/faultinjection
libfaultinjection_la_CFLAGS = $(GST_ALL_CFLAGS)
libfaultinjection_la_LIBADD = $(GST_ALL_LIBS) $(top_builddir)/gst/validate/libgstvalidate-@GST_API_VERSION@.la
libfaultinjection_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(GST_ALL_LDFLAGS)
CLEANFILES =

View file

@ -24,8 +24,13 @@
#define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "socket_interposer.h"
#include <gst/validate/gst-validate-scenario.h>
#include <gst/gst.h>
#include "../gst/validate/gst-validate-scenario.h"
#if defined(__gnu_linux__) && !defined(__ANDROID__) && !defined (ANDROID)
@ -329,8 +334,8 @@ _execute_corrupt_socket_recv (GstValidateScenario * scenario,
return GST_VALIDATE_EXECUTE_ACTION_ASYNC;
}
void
socket_interposer_init (void)
static gboolean
socket_interposer_init (GstPlugin * plugin)
{
gst_validate_register_action_type ("corrupt-socket-recv", "fault-injector",
_execute_corrupt_socket_recv, ((GstValidateActionParameter[]) {
@ -347,13 +352,23 @@ socket_interposer_init (void)
NULL}
}),
"corrupt the next socket receive", GST_VALIDATE_ACTION_TYPE_ASYNC);
return TRUE;
}
#else /* No LD_PRELOAD tricks on Windows */
void
socket_interposer_init (void)
static gboolean
socket_interposer_init (GstPlugin * plugin)
{
return TRUE;
}
#endif
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
faultinjector,
"Fault injector plugin for GstValidate",
socket_interposer_init, VERSION, "LGPL", GST_PACKAGE_NAME,
GST_PACKAGE_ORIGIN)

View file

@ -24,6 +24,4 @@
#ifndef _SOCKET_INTERPOSER_H_
#define _SOCKET_INTERPOSER_H_
extern void socket_interposer_init(void);
#endif /* _SOCKET_INTERPOSER_H_ */

View file

@ -46,14 +46,13 @@ noinst_HEADERS = \
lib_LTLIBRARIES = libgstvalidate-@GST_API_VERSION@.la
libgstvalidate_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)\
$(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS) -I$(top_srcdir)/fault_injection
$(GIO_CFLAGS) $(GST_PBUTILS_CFLAGS)
libgstvalidate_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) \
$(GST_LT_LDFLAGS) $(GIO_LDFLAGS) $(GST_PBUTILS_LDFAGS)
libgstvalidate_@GST_API_VERSION@_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
$(GST_ALL_LIBS) $(GIO_LIBS) $(GST_PBUTILS_LIBS) \
$(GLIB_LIBS) $(LIBM)\
$(FAULTINJECTION_LIBS)
$(GLIB_LIBS) $(LIBM)
libgstvalidate_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/validate
@ -116,7 +115,6 @@ typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
--includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-base-@GST_API_VERSION@` \
--includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-controller-@GST_API_VERSION@` \
--includedir=`$(PKG_CONFIG) --variable=girdir gio-2.0` \
--shared-library=faultinjection-@GST_API_VERSION@ \
$(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
endif

View file

@ -45,7 +45,6 @@
#include "gst-validate-utils.h"
#include <gst/validate/gst-validate-override.h>
#include <gst/validate/gst-validate-override-registry.h>
#include <socket_interposer.h>
#define GST_VALIDATE_SCENARIO_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_VALIDATE_SCENARIO, GstValidateScenarioPrivate))
@ -2653,6 +2652,4 @@ init_scenarios (void)
GST_VALIDATE_ACTION_TYPE_NONE);
/* *INDENT-ON* */
socket_interposer_init ();
/* *INDENT-ON* */
}

View file

@ -29,11 +29,129 @@
# include "config.h"
#endif
/* For g_stat () */
#include <glib/gstdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "validate.h"
#include "gst-validate-internal.h"
GST_DEBUG_CATEGORY (gstvalidate_debug);
static gboolean
gst_validate_scan_path_for_plugins (const gchar * path)
{
GDir *dir;
const gchar *dirent;
gchar *filename;
GstPlugin *plugin;
gboolean changed = FALSE;
dir = g_dir_open (path, 0, NULL);
if (!dir)
return FALSE;
while ((dirent = g_dir_read_name (dir))) {
GStatBuf file_status;
filename = g_build_filename (path, dirent, NULL);
if (g_stat (filename, &file_status) < 0) {
/* Plugin will be removed from cache after the scan completes if it
* is still marked 'cached' */
g_free (filename);
continue;
}
if (!(file_status.st_mode & S_IFREG)) {
g_free (filename);
continue;
}
if (!g_str_has_suffix (dirent, G_MODULE_SUFFIX)) {
GST_TRACE ("extension is not recognized as module file, ignoring file %s",
filename);
g_free (filename);
continue;
}
plugin = gst_plugin_load_file (filename, NULL);
if (plugin) {
GST_DEBUG ("Plugin %s loaded", filename);
gst_object_unref (plugin);
}
g_free (filename);
}
g_dir_close (dir);
return changed;
}
static void
gst_validate_init_plugins (void)
{
const gchar *plugin_path;
plugin_path = g_getenv ("GST_VALIDATE_PLUGIN_PATH");
if (plugin_path) {
char **list;
int i;
GST_DEBUG ("GST_VALIDATE_PLUGIN_PATH set to %s", plugin_path);
list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0);
for (i = 0; list[i]; i++) {
gst_validate_scan_path_for_plugins (list[i]);
}
g_strfreev (list);
} else {
GST_DEBUG ("GST_VALIDATE_PLUGIN_PATH not set");
}
if (plugin_path == NULL) {
char *home_plugins;
/* plugins in the user's home directory take precedence over
* system-installed ones */
home_plugins = g_build_filename (g_get_user_data_dir (),
"gstreamer-" GST_API_VERSION, "plugins", NULL);
GST_DEBUG ("scanning home plugins %s", home_plugins);
gst_validate_scan_path_for_plugins (home_plugins);
g_free (home_plugins);
/* add the main (installed) library path */
#ifdef G_OS_WIN32
{
char *base_dir;
char *dir;
base_dir =
g_win32_get_package_installation_directory_of_module
(_priv_gst_dll_handle);
dir = g_build_filename (base_dir,
#ifdef _DEBUG
"debug"
#endif
"lib", "gstreamer-" GST_API_VERSION, NULL);
GST_DEBUG ("scanning DLL dir %s", dir);
gst_validate_scan_path_for_plugins (dir);
g_free (dir);
g_free (base_dir);
}
#else
gst_validate_scan_path_for_plugins (PLUGINDIR);
#endif
}
}
/**
* gst_validate_init:
*
@ -55,4 +173,6 @@ gst_validate_init (void)
/* Ensure we load overrides before any use of a monitor */
gst_validate_override_registry_preload ();
gst_validate_init_plugins ();
}