URL: https://github.com/freeipa/bind-dyndb-ldap/pull/5
Author: pspacek
 Title: #5: Add GDB pretty-printers for plugin data structures to contrib.
Action: opened

PR body:
"""
These are convenience scripts I created over time to ease digging in 
bind-dyndb-ldap data structures. It might make sense to include these in the 
main repo...
"""

To pull the PR as Git branch:
git remote add ghbind-dyndb-ldap https://github.com/freeipa/bind-dyndb-ldap
git fetch ghbind-dyndb-ldap pull/5/head:pr5
git checkout pr5
From e9aae86c5ff874af3a7f85667767a9912b47ce86 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Tue, 13 Dec 2016 11:20:04 +0100
Subject: [PATCH] Add GDB pretty-printers for plugin data structures to
 contrib.

---
 contrib/gdb_extensions/README            | 16 +++++++++
 contrib/gdb_extensions/ldap_attribute.py | 59 ++++++++++++++++++++++++++++++++
 contrib/gdb_extensions/ldap_entry.py     | 45 ++++++++++++++++++++++++
 contrib/gdb_extensions/ldap_valuelist.py | 50 +++++++++++++++++++++++++++
 4 files changed, 170 insertions(+)
 create mode 100644 contrib/gdb_extensions/README
 create mode 100644 contrib/gdb_extensions/ldap_attribute.py
 create mode 100644 contrib/gdb_extensions/ldap_entry.py
 create mode 100644 contrib/gdb_extensions/ldap_valuelist.py

diff --git a/contrib/gdb_extensions/README b/contrib/gdb_extensions/README
new file mode 100644
index 0000000..23c8406
--- /dev/null
+++ b/contrib/gdb_extensions/README
@@ -0,0 +1,16 @@
+This directory contains pretty-printers which make easier to read
+bind-dyndb-ldap data structures in GDB with Python support.
+
+To use them, simply source the files into GDB:
+(gdb) source /path/to/pretty/printer.py
+
+BEWARE:
+The pretty printers work well if memory is not corrupted.
+Disable pretty printers if you suspect memory corruption:
+(gdb) disable pretty-printer
+
+Pretty-printers for BIND 9 data structures might be handy, too:
+https://github.com/pspacek/bind-gdb-pretty-printers
+
+For further information see
+https://sourceware.org/gdb/onlinedocs/gdb/Python-API.html
diff --git a/contrib/gdb_extensions/ldap_attribute.py b/contrib/gdb_extensions/ldap_attribute.py
new file mode 100644
index 0000000..757e8e1
--- /dev/null
+++ b/contrib/gdb_extensions/ldap_attribute.py
@@ -0,0 +1,59 @@
+import os
+import sys
+import json
+
+def gdb_printer_decorator(fn):
+    gdb.pretty_printers.append(fn)
+    return fn
+
+class ldap_attribute_Printer(object):
+    def __init__(self, val):
+        self.val = val
+        self.values_pp = gdb.default_visualizer(val['values'])
+        self.l = self._enumerate_children()
+    
+    def singleton(self):
+        return self.values_pp and len(self.l) <= 1
+
+    def display_hint(self):
+        if self.singleton():
+            return "string"
+        else:
+            return "array"
+
+    def _enumerate_children(self):
+        values = self.val['values']
+        # pretty printer for ldap_valuelist returns array so [('0', values)]
+        # results in list inside list which is not pretty
+        # -> remove inner list
+        if not self.values_pp:
+            # prettyprinter for ldap_valuelist is not available
+            return False
+
+        l = []
+        for v in self.values_pp.children():
+            l.append(v)
+        return l
+
+    def to_string(self):
+        out = "attribute: %s" % self.val['name'].string()
+        if self.singleton():
+            out += ' = { %s }' % self.values_pp.to_string()
+
+        return out
+
+    def children(self):
+        if self.singleton():
+            return []
+        l = self._enumerate_children()
+        if not l: # pretty printer is not available - cannot enumerate children
+            return [('0', self.val['values'])]
+        else:
+            return l
+
+# register pretty printers
+@gdb_printer_decorator
+def dns_rbt_printer(val):
+    if str(val.type) == 'ldap_attribute_t':
+        return ldap_attribute_Printer(val)
+    return None
diff --git a/contrib/gdb_extensions/ldap_entry.py b/contrib/gdb_extensions/ldap_entry.py
new file mode 100644
index 0000000..4b91c49
--- /dev/null
+++ b/contrib/gdb_extensions/ldap_entry.py
@@ -0,0 +1,45 @@
+import os
+import sys
+import json
+
+def gdb_printer_decorator(fn):
+    gdb.pretty_printers.append(fn)
+    return fn
+
+class ldap_entry_Printer(object):
+    def __init__(self, val):
+        self.val = val
+
+    def display_hint(self):
+        return 'array'
+
+    def to_string(self):
+        out = "entry DN: %s" % self.val['dn'].string()
+        return out
+
+    def children(self):
+        i = 0
+        l = []
+        head = self.val['attrs']['head'].dereference()
+        while head:
+            l.append((str(i), head))
+            if head['link']['next']:
+                head = head['link']['next'].dereference()
+            else:
+                head = None
+            i += 1
+        return l
+
+class TestPrinter(object):
+    def __init__(self, val):
+        self.val = val
+
+    def to_string(self):
+        return str(self.val.type)
+
+# register pretty printers
+@gdb_printer_decorator
+def ldap_entry_printer(val):
+    if str(val.type) == 'ldap_entry_t' or str(val.type) == 'const ldap_entry_t':
+        return ldap_entry_Printer(val)
+    return None
diff --git a/contrib/gdb_extensions/ldap_valuelist.py b/contrib/gdb_extensions/ldap_valuelist.py
new file mode 100644
index 0000000..1ed8e9d
--- /dev/null
+++ b/contrib/gdb_extensions/ldap_valuelist.py
@@ -0,0 +1,50 @@
+import os
+import sys
+import json
+
+def gdb_printer_decorator(fn):
+    gdb.pretty_printers.append(fn)
+    return fn
+
+class ldap_valuelist_Printer(object):
+    def __init__(self, val):
+        self.val = val
+
+    def singleton(self):
+        return self.val['head'] == self.val['tail']
+
+    def display_hint(self):
+        if self.singleton():
+            return "string"
+        else:
+            return "array"
+
+    def to_string(self):
+        head = self.val['head']
+        if not head:
+            return "(empty value list)"
+        if self.singleton():
+            return head['value'].string()
+        return None
+
+    def children(self):
+        if self.singleton():
+            return []
+        i = 0
+        l = []
+        head = self.val['head']
+        while head:
+            l.append((str(i), '"%s"' % head['value'].string()))
+            if head['link']['next']:
+                head = head['link']['next'].dereference()
+            else:
+                head = None
+            i += 1
+        return l
+
+# register pretty printers
+@gdb_printer_decorator
+def dns_rbt_printer(val):
+    if str(val.type) == 'ldap_valuelist_t':
+        return ldap_valuelist_Printer(val)
+    return None
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to