diff options
Diffstat (limited to 'tools/debug/gdb')
-rw-r--r-- | tools/debug/gdb/.gitignore | 1 | ||||
-rw-r--r-- | tools/debug/gdb/README.md | 40 | ||||
-rw-r--r-- | tools/debug/gdb/gdbinit | 25 | ||||
-rw-r--r-- | tools/debug/gdb/icingadbg.py | 64 |
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) |