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_DEFINE_UNQUOTED(GST_LICENSE, "$GST_LICENSE", [GStreamer license])
AC_SUBST(GST_LICENSE) AC_SUBST(GST_LICENSE)
dnl set location of plugin directory dnl define location of plugin directory
AG_GST_SET_PLUGINDIR 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 # set by AG_GST_PARSE_SUBSYSTEM_DISABLES above
dnl make sure it doesn't complain about unused variables if debugging is disabled 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_CFLAGS)
AC_SUBST(GST_LIBS) 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 GST_ALL_*
dnl vars common to for all internal objects (core libs, elements, applications) dnl vars common to for all internal objects (core libs, elements, applications)
dnl CFLAGS: dnl CFLAGS:

View file

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

View file

@ -24,8 +24,13 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "socket_interposer.h" #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) #if defined(__gnu_linux__) && !defined(__ANDROID__) && !defined (ANDROID)
@ -329,8 +334,8 @@ _execute_corrupt_socket_recv (GstValidateScenario * scenario,
return GST_VALIDATE_EXECUTE_ACTION_ASYNC; return GST_VALIDATE_EXECUTE_ACTION_ASYNC;
} }
void static gboolean
socket_interposer_init (void) socket_interposer_init (GstPlugin * plugin)
{ {
gst_validate_register_action_type ("corrupt-socket-recv", "fault-injector", gst_validate_register_action_type ("corrupt-socket-recv", "fault-injector",
_execute_corrupt_socket_recv, ((GstValidateActionParameter[]) { _execute_corrupt_socket_recv, ((GstValidateActionParameter[]) {
@ -347,13 +352,23 @@ socket_interposer_init (void)
NULL} NULL}
}), }),
"corrupt the next socket receive", GST_VALIDATE_ACTION_TYPE_ASYNC); "corrupt the next socket receive", GST_VALIDATE_ACTION_TYPE_ASYNC);
return TRUE;
} }
#else /* No LD_PRELOAD tricks on Windows */ #else /* No LD_PRELOAD tricks on Windows */
void static gboolean
socket_interposer_init (void) socket_interposer_init (GstPlugin * plugin)
{ {
return TRUE;
} }
#endif #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_ #ifndef _SOCKET_INTERPOSER_H_
#define _SOCKET_INTERPOSER_H_ #define _SOCKET_INTERPOSER_H_
extern void socket_interposer_init(void);
#endif /* _SOCKET_INTERPOSER_H_ */ #endif /* _SOCKET_INTERPOSER_H_ */

View file

@ -46,14 +46,13 @@ noinst_HEADERS = \
lib_LTLIBRARIES = libgstvalidate-@GST_API_VERSION@.la lib_LTLIBRARIES = libgstvalidate-@GST_API_VERSION@.la
libgstvalidate_@GST_API_VERSION@_la_CFLAGS = $(GST_ALL_CFLAGS)\ 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) \ libgstvalidate_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) \
$(GST_LT_LDFLAGS) $(GIO_LDFLAGS) $(GST_PBUTILS_LDFAGS) $(GST_LT_LDFLAGS) $(GIO_LDFLAGS) $(GST_PBUTILS_LDFAGS)
libgstvalidate_@GST_API_VERSION@_la_LIBADD = \ libgstvalidate_@GST_API_VERSION@_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \ $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
$(GST_ALL_LIBS) $(GIO_LIBS) $(GST_PBUTILS_LIBS) \ $(GST_ALL_LIBS) $(GIO_LIBS) $(GST_PBUTILS_LIBS) \
$(GLIB_LIBS) $(LIBM)\ $(GLIB_LIBS) $(LIBM)
$(FAULTINJECTION_LIBS)
libgstvalidate_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/validate 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-base-@GST_API_VERSION@` \
--includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-controller-@GST_API_VERSION@` \ --includedir=`$(PKG_CONFIG) --variable=girdir gstreamer-controller-@GST_API_VERSION@` \
--includedir=`$(PKG_CONFIG) --variable=girdir gio-2.0` \ --includedir=`$(PKG_CONFIG) --variable=girdir gio-2.0` \
--shared-library=faultinjection-@GST_API_VERSION@ \
$(INTROSPECTION_COMPILER_OPTS) $< -o $(@F) $(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
endif endif

View file

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

View file

@ -29,11 +29,129 @@
# include "config.h" # include "config.h"
#endif #endif
/* For g_stat () */
#include <glib/gstdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "validate.h" #include "validate.h"
#include "gst-validate-internal.h" #include "gst-validate-internal.h"
GST_DEBUG_CATEGORY (gstvalidate_debug); 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: * gst_validate_init:
* *
@ -55,4 +173,6 @@ gst_validate_init (void)
/* Ensure we load overrides before any use of a monitor */ /* Ensure we load overrides before any use of a monitor */
gst_validate_override_registry_preload (); gst_validate_override_registry_preload ();
gst_validate_init_plugins ();
} }