GstMiniObject is not compatible with GLIB2 type checking
GstMiniObject is not type compatible with GObject, and therefore, usage of G_IS_OBJECT and GST_IS_OBJECT macros is not safe. It manifested with multiple crashes on SPARC during unit tests. The issue is, however, not SPARC specific, x86 crashes as well when TypeNode's ref_count is larger than 3 ('utype & ~TYPE_ID_MASK' in lookup_type_node_I resets only two lower bits).
In file gstminiobject.h:
struct _GstMiniObject { GType type; <- 32 or 64 bit integer based on platform ....
However, G_IS_OBJECT and GST_IS_OBJECT macros expect a different type format:
struct _GObject { GTypeInstance g_type_instance; <- pointer to GType ...
struct _GTypeInstance { GTypeClass *g_class; }
struct _GTypeClass { GType g_type; }
G_IS_OBJECT macro:
- converts obj* to GTypeInstance* type_instance
- calls g_type_check_instance_is_fundamentally_a(type_instance, ...)
- calls lookup_type_node_I (type_instance->g_class->g_type)
The problem is that double dereference is not valid for GstMiniObject:
type_instance->g_class (mini_obj->type)
type_instance->g_class->gtype (contents of TypeNode)
struct _TypeNode { guint volatile ref_count; #ifdef G_ENABLE_DEBUG guint volatile instance_count; #endif ...
As a result, lookup_type_node_I returns 0x|ref_count|instance_count| (e.g., 0x0000000100000000 on SPARC) as a TypeNode pointer...
The best should be to change _GstMiniObject structure to use GTypeClass instead of GType, however, it would change API and ABI of the library. As a workaround, we can avoid to use G_IS_OBJECT and GST_IS_OBJECT macros on GstMiniObject types, and in that way, preserve compatibility. I will open a pull request.
Example of an observed backtrace:
#0 g_type_check_instance_is_fundamentally_a (type_instance=type_instance@entry=0x8d822f940, fundamental_type=fundamental_type@entry=0x50 [GObject]) at ../../glib-2.66.8/gobject/gtype.c:4030 #1 0x001ffde17d60cbb0 in object_log_new (obj=obj@entry=0x8d822f940) at ../../gstreamer-1.18.4/plugins/tracers/gstleaks.c:325 #2 0x001ffde17d60d468 in handle_object_created (self=self@entry=0x8d8262020 [GstLeaksTracer], object=object@entry=0x8d822f940, type=0x8d8235350 [GstCaps], gobject=gobject@entry=0) at ../../gstreamer-1.18.4/plugins/tracers/gstleaks.c:397 #3 0x001ffde17d60d53c in mini_object_created_cb (tracer=0x8d8262020 [GstLeaksTracer], ts=3588225045, object=0x8d822f940) at ../../gstreamer-1.18.4/plugins/tracers/gstleaks.c:407 ...