summaryrefslogtreecommitdiffstats
path: root/tools/debug/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debug/gdb')
-rw-r--r--tools/debug/gdb/.gitignore1
-rw-r--r--tools/debug/gdb/README.md40
-rw-r--r--tools/debug/gdb/gdbinit25
-rw-r--r--tools/debug/gdb/icingadbg.py64
4 files changed, 130 insertions, 0 deletions
diff --git a/tools/debug/gdb/.gitignore b/tools/debug/gdb/.gitignore
new file mode 100644
index 0000000..1c9c744
--- /dev/null
+++ b/tools/debug/gdb/.gitignore
@@ -0,0 +1 @@
+icingadbg.pyc
diff --git a/tools/debug/gdb/README.md b/tools/debug/gdb/README.md
new file mode 100644
index 0000000..b00f81a
--- /dev/null
+++ b/tools/debug/gdb/README.md
@@ -0,0 +1,40 @@
+# Pretty Printer Installation
+
+Requirements:
+* icinga2 debug symbols
+* boost, gcc, etc debug symbols
+
+Install the `boost`, `python` and `icinga2` pretty printers. Absolute paths are required,
+so please make sure to update the installation paths accordingly (`pwd`).
+
+Boost Pretty Printers:
+
+ $ mkdir ~/.gdb_printers && cd ~/.gdb_printers
+ $ git clone https://github.com/ruediger/Boost-Pretty-Printer.git && cd Boost-Pretty-Printer
+ $ pwd
+ /home/michi/.gdb_printers/Boost-Pretty-Printer
+
+Python Pretty Printers:
+
+ $ cd ~/.gdb_printers
+ $ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
+
+Icinga 2 Pretty Printers:
+
+ $ mkdir -p ~/.gdb_printers/icinga2 && ~/.gdb_printers/icinga2
+ $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/icingadbg.py
+
+Now you'll need to modify/setup your `~/.gdbinit` configuration file.
+You can download the one from Icinga 2 and modify all paths.
+
+> **Note**
+>
+> The path to the `pthread` library varies on distributions. Use
+> `find /usr/lib* -type f -name '*libpthread.so*'` to get the proper
+> path.
+
+ $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/gdbinit -O ~/.gdbinit
+ $ vim ~/.gdbinit
+
+
+More details in the [troubleshooting debug documentation](https://docs.icinga.com/icinga2/latest/doc/module/icinga2/chapter/troubleshooting#debug).
diff --git a/tools/debug/gdb/gdbinit b/tools/debug/gdb/gdbinit
new file mode 100644
index 0000000..a7e6b87
--- /dev/null
+++ b/tools/debug/gdb/gdbinit
@@ -0,0 +1,25 @@
+set print pretty on
+
+python
+import sys
+sys.path.insert(0, '/home/gbeutner/icinga2/tools/debug/gdb')
+from icingadbg import register_icinga_printers
+register_icinga_printers()
+end
+
+python
+import sys
+sys.path.insert(0, '/home/gbeutner/gdb_printers/python')
+from libstdcxx.v6.printers import register_libstdcxx_printers
+try:
+ register_libstdcxx_printers(None)
+except:
+ pass
+end
+
+python
+import sys
+sys.path.insert(0, '/home/gbeutner/Boost-Pretty-Printer')
+from boost.printers import register_printer_gen
+register_printer_gen(None)
+end
diff --git a/tools/debug/gdb/icingadbg.py b/tools/debug/gdb/icingadbg.py
new file mode 100644
index 0000000..d1e1c59
--- /dev/null
+++ b/tools/debug/gdb/icingadbg.py
@@ -0,0 +1,64 @@
+import gdb
+import re
+
+class IcingaStringPrinter:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return '"' + self.val['m_Data']['_M_dataplus']['_M_p'].string() + '"'
+
+class IcingaValuePrinter:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ which = self.val['m_Value']['which_']
+
+ if which == 0:
+ return 'Empty'
+ elif which == 1:
+ return self.val['m_Value']['storage_']['data_']['buf'].cast(gdb.lookup_type('double').pointer()).dereference()
+ elif which == 2:
+ return self.val['m_Value']['storage_']['data_']['buf'].cast(gdb.lookup_type('bool').pointer()).dereference()
+ elif which == 3:
+ return self.val['m_Value']['storage_']['data_']['buf'].cast(gdb.lookup_type('icinga::String').pointer()).dereference()
+ elif which == 4:
+ return self.val['m_Value']['storage_']['data_']['buf'].cast(gdb.lookup_type('icinga::Object').pointer()).dereference()
+ else:
+ return '<INVALID>'
+
+class IcingaSignalPrinter:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return '<SIGNAL>'
+
+class IcingaMutexPrinter:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ owner = self.val['__data']['__owner']
+
+ if owner == 0:
+ return '<unlocked>'
+ else:
+ return '<locked by #' + str(owner) + '>'
+
+def lookup_icinga_type(val):
+ t = val.type.unqualified()
+ if str(t) == 'icinga::String':
+ return IcingaStringPrinter(val)
+ elif str(t) == 'icinga::Value':
+ return IcingaValuePrinter(val)
+ elif re.match('^boost::signals2::signal.*<.*>$', str(t)):
+ return IcingaSignalPrinter(val)
+ elif str(t) == 'pthread_mutex_t':
+ return IcingaMutexPrinter(val)
+
+ return None
+
+def register_icinga_printers():
+ gdb.pretty_printers.append(lookup_icinga_type)