gst/Makefile
gst/gstconfig.h
gst/gstversion.h
+libs/gst/helpers/libgstreamer-gdb.py
gst/parse/Makefile
gst/printf/Makefile
libs/Makefile
gst-plugin-scanner
gst-completion-helper
gst-ptp-helper
+libgstreamer-gdb.py
*.o
endif
EXTRA_DIST = ptp_helper_post_install.sh
+
+# install gdb scripts
+gdbdir = $(datadir)/gstreamer-@GST_API_VERSION@/gdb
+dist_gdb_DATA = gst_gdb.py glib_gobject_helper.py
+
+install-data-hook:
+ $(INSTALL) -D $(builddir)/libgstreamer-gdb.py $(DESTDIR)$(datadir)/gdb/auto-load$(libdir)/libgstreamer-@GST_API_VERSION@.so.0.$(GST_CURRENT).$(GST_REVISION)-gdb.py
--- /dev/null
+##
+## imported from glib: glib/glib_gdb.py
+##
+import gdb
+import sys
+
+if sys.version_info[0] >= 3:
+ long = int
+
+# This is not quite right, as local vars may override symname
+def read_global_var (symname):
+ return gdb.selected_frame().read_var(symname)
+
+def g_quark_to_string (quark):
+ if quark is None:
+ return None
+ quark = long(quark)
+ if quark == 0:
+ return None
+ try:
+ val = read_global_var ("quarks")
+ max_q = long(read_global_var ("quark_seq_id"))
+ except:
+ try:
+ val = read_global_var ("g_quarks")
+ max_q = long(read_global_var ("g_quark_seq_id"))
+ except:
+ return None;
+ if quark < max_q:
+ return val[quark].string()
+ return None
+
+##
+## imported from glib: gobject/gobject_gdb.py
+##
+
+def g_type_to_typenode (gtype):
+ def lookup_fundamental_type (typenode):
+ if typenode == 0:
+ return None
+ val = read_global_var ("static_fundamental_type_nodes")
+ if val is None:
+ return None
+ return val[typenode >> 2].address
+
+ gtype = long(gtype)
+ typenode = gtype - gtype % 4
+ if typenode > (255 << 2):
+ typenode = gdb.Value(typenode).cast (gdb.lookup_type("TypeNode").pointer())
+ else:
+ typenode = lookup_fundamental_type (typenode)
+ return typenode
+
+def g_type_to_name (gtype):
+ typenode = g_type_to_typenode(gtype)
+ if typenode != None:
+ return g_quark_to_string (typenode["qname"])
+ return None
+
+def g_type_name_from_instance (instance):
+ if long(instance) != 0:
+ try:
+ inst = instance.cast (gdb.lookup_type("GTypeInstance").pointer())
+ klass = inst["g_class"]
+ gtype = klass["g_type"]
+ name = g_type_to_name (gtype)
+ return name
+ except RuntimeError:
+ pass
+ return None
--- /dev/null
+import gdb
+import sys
+import re
+
+from glib_gobject_helper import g_type_to_name, g_type_name_from_instance
+
+if sys.version_info[0] >= 3:
+ long = int
+
+def is_gst_type (val, klass):
+ def _is_gst_type (type):
+ if str(type) == klass:
+ return True
+
+ while type.code == gdb.TYPE_CODE_TYPEDEF:
+ type = type.target()
+
+ if type.code != gdb.TYPE_CODE_STRUCT:
+ return False
+
+ fields = type.fields()
+ if len (fields) < 1:
+ return False
+
+ first_field = fields[0]
+ return _is_gst_type (first_field.type)
+
+
+ type = val.type
+ if type.code != gdb.TYPE_CODE_PTR:
+ return False
+ type = type.target()
+ return _is_gst_type (type)
+
+class GstMiniObjectPrettyPrinter:
+ "Prints a GstMiniObject instance pointer"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ try:
+ inst = self.val.cast (gdb.lookup_type("GstMiniObject").pointer())
+ gtype = inst["type"]
+ name = g_type_to_name (gtype)
+ return "0x%x [%s]" % (long(self.val), name)
+ except RuntimeError:
+ return "0x%x" % long(self.val)
+
+class GstObjectPrettyPrinter:
+ "Prints a GstObject instance"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ try:
+ name = g_type_name_from_instance (self.val)
+ if not name:
+ name = str(self.val.type.target())
+ if long(self.val) != 0:
+ inst = self.val.cast (gdb.lookup_type("GstObject").pointer())
+ inst_name = inst["name"].string()
+ if inst_name:
+ name += "|" + inst_name
+ return ("0x%x [%s]") % (long(self.val), name)
+ except RuntimeError:
+ return "0x%x" % long(self.val)
+
+class GstClockTimePrinter:
+ "Prints a GstClockTime / GstClockTimeDiff"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ GST_SECOND = 1000000000
+ GST_CLOCK_TIME_NONE = 2**64-1
+ GST_CLOCK_STIME_NONE = -2**63
+ n = int(self.val)
+ prefix = ""
+ invalid = False
+ if str(self.val.type) == "GstClockTimeDiff":
+ if n == GST_CLOCK_STIME_NONE:
+ invalid = True
+ prefix = "+" if n >= 0 else "-"
+ n = abs(n)
+ else:
+ if n == GST_CLOCK_TIME_NONE:
+ invalid = True
+
+ if invalid:
+ return str(n) + " [99:99:99.999999999]"
+
+ return str(n) + " [%s%u:%02u:%02u.%09u]" % ( prefix,
+ n / (GST_SECOND * 60 * 60),
+ (n / (GST_SECOND * 60)) % 60,
+ (n / GST_SECOND) % 60,
+ n % GST_SECOND )
+
+def gst_pretty_printer_lookup (val):
+ if is_gst_type (val, "GstMiniObject"):
+ return GstMiniObjectPrettyPrinter (val)
+ if is_gst_type (val, "GstObject"):
+ return GstObjectPrettyPrinter (val)
+ if str(val.type) == "GstClockTime" or str(val.type) == "GstClockTimeDiff":
+ return GstClockTimePrinter (val)
+ return None
+
+def register (obj):
+ if obj == None:
+ obj = gdb
+
+ # Make sure this is always used befor the glib lookup function.
+ # Otherwise the gobject pretty printer is used for GstObjects
+ obj.pretty_printers.insert(0, gst_pretty_printer_lookup)
--- /dev/null
+import sys
+import gdb
+
+# Update module path.
+dir_ = '@DATADIR@/gstreamer-@GST_API_VERSION@/gdb'
+if not dir_ in sys.path:
+ sys.path.insert(0, dir_)
+
+from gst_gdb import register
+register (gdb.current_objfile ())
helpers_install_dir, with_ptp_helper_permissions,
setcap.found() ? setcap.path() : '')
endif
+
+install_data(['gst_gdb.py', 'glib_gobject_helper.py'],
+ install_dir : join_paths(get_option('datadir'), 'glib-2.0', 'gdb'))
+
+gdbconf = configuration_data()
+gdbconf.set('GST_API_VERSION', apiversion)
+gdbconf.set('DATADIR', '@0@/@1@'.format(get_option('prefix'), get_option('datadir')))
+
+if host_system != 'windows'
+ # XXX: We add a leading './' because prefix is an absolute path and we
+ # need it to be a relative path so that join_paths appends it to the end.
+ gdb_install_dir = join_paths(get_option('datadir'), 'gdb', 'auto-load', './' + get_option('prefix'), get_option('libdir'))
+else
+ # FIXME: Cannot install on Windows because the path will contain a drive
+ # letter and colons are not allowed in paths.
+ gdb_install_dir = disabler()
+endif
+configure_file(input : 'libgstreamer-gdb.py.in',
+ output : 'libgstreamer-@0@.so.@1@-gdb.py'.format(apiversion, libversion),
+ install_dir : gdb_install_dir,
+ configuration : gdbconf)