[eigen] gdb Eigen Pretty printers |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
Hi
Finally a real contribution to eigen - it was about time. I just wrote a
pretty printer for Eigen::Matrix gdb-7.0 and later.
To use it:
* create a directory and put the file as well as an empty __init__.py in
that directory
* Create a ~/.gdbinit file, that contains the following:
python
import sys
sys.path.insert(0, '/path/to/eigen/printer/directory')
from printers import register_eigen_printers
register_eigen_printers (None)
end
Notes:
- It currently only supports Eigen::Matrix and no other type (such as
quaternions etc). Patches welcome :)
- I wrote it using the stable branch of eigen. I don't know whether it
works with hg
- It's still kind of hacky, mostly because of the limitations of the
gdb.python framework
It seems that the gdb hackers want the pretty printer scripts included
in the respective patches, so my final goal would be to have it in eigen-hg
Cheers
Benjamin
# Pretty printers for Eigen::Matrix
# Author: Benjamin Schindler <bschindler@xxxxxxxxxxx>
# This is still pretty basic as the python extension to gdb is still pretty basic.
# It cannot handle complex eigen types and it doesn't support any of the other eigen types
# Such as quaternion or some other type.
# This code supports fixed size as well as dynamic size matrices
# Licence - ment to be included in Eigen, so dual GPLv3 or LGPL
# NOTE: This code was only tested with the stable branch of eigen!
import gdb
import re
import itertools
class EigenMatrixPrinter:
"Print Eigen Matrix of some kind"
def __init__(self, val):
"Extract all the necessary information"
# The gdb extension does not support value template arguments - need to extract them by hand
self.type = val.type.unqualified().strip_typedefs()
tag = self.type.tag
regex = re.compile('\<.*\>')
m = regex.findall(tag)[0][1:-1]
template_params = m.split(',')
template_params = map(lambda x:x.replace(" ", ""), template_params)
self.rows = int(template_params[1])
self.cols = int(template_params[2])
if self.rows == 10000:
self.rows = val['m_storage']['m_rows']
if self.cols == 10000:
self.cols = val['m_storage']['m_cols']
self.innerType = self.type.template_argument(0)
self.val = val
class _iterator:
def __init__ (self, rows, cols, dataPtr):
self.rows = rows
self.cols = cols
self.dataPtr = dataPtr
self.currentRow = 0
self.currentCol = 0
def __iter__ (self):
return self
def next(self):
if self.currentCol >= self.cols:
raise StopIteration
row = self.currentRow
col = self.currentCol
self.currentRow = self.currentRow + 1
if self.currentRow >= self.rows:
self.currentRow = 0
self.currentCol = self.currentCol + 1
item = self.dataPtr.dereference()
self.dataPtr = self.dataPtr + 1
return ('[%d, %d]' % (row, col), item)
def children(self):
data = self.val['m_storage']['m_data']
# Fixed size matrices have a struct as their storage, so we need to walk through this
if data.type.code == gdb.TYPE_CODE_STRUCT:
data = data['array']
data = data.cast(self.innerType.pointer())
return self._iterator(self.rows, self.cols, data)
def to_string(self):
return "Eigen::Matrix<%s,%d,%d>" % (self.innerType, self.rows, self.cols)
def build_eigen_dictionary ():
pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter(val)
def register_eigen_printers(obj):
"Register eigen pretty-printers with objfile Obj"
if obj == None:
obj = gdb
obj.pretty_printers.append(lookup_function)
def lookup_function(val):
"Look-up and return a pretty-printer that can print va."
type = val.type
if type.code == gdb.TYPE_CODE_REF:
type = type.target()
type = type.unqualified().strip_typedefs()
typename = type.tag
if typename == None:
return None
for function in pretty_printers_dict:
if function.search(typename):
return pretty_printers_dict[function](val)
return None
pretty_printers_dict = {}
build_eigen_dictionary ()