From 7b1a5a17b8255c697c027b96e8f0df1cd624f602 Mon Sep 17 00:00:00 2001 From: Claudio dos Santos Fernandes Date: Wed, 29 Aug 2018 22:17:21 -0300 Subject: [PATCH] Add debugging tools to aid the creation of giwtypes Issue: #41 --- README.md | 12 ++++-- resources/giwscripts/debuggers/gdbbridge.py | 5 ++- resources/giwscripts/giwtypes/eigen3.py | 2 +- resources/giwscripts/giwtypes/interface.py | 41 ++++++++++++++++++--- resources/giwscripts/giwtypes/opencv.py | 4 +- resources/giwscripts/typebridge.py | 6 +-- 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 42f8810..8980764 100644 --- a/README.md +++ b/README.md @@ -339,9 +339,15 @@ fields: buffer in the interface. Can be very useful if your data structure represents transposition with an internal metadata. -The function `is_symbol_observable()` receives a gdb symbol and must only return -`True` if that symbol is of the observable type (the buffer you are dealing -with). +The function `is_symbol_observable()` receives a gdb symbol and a string +containing the variable name, and must only return `True` if that symbol is of +the observable type (the buffer you are dealing with). + +It is possible to debug your custom inspector methods by using the python +decorators `@interface.debug_buffer_metadata` and +`@interface.debug_symbol_observable` in the methods `get_buffer_metadata` and +`is_symbol_observable`, respectively. This will print information about all +analyzed symbols in the debugger console every time a breakpoint is hit. For more information on how to customize this file, check out this [more detailed blog post](https://csantosbh.wordpress.com/2016/10/15/configuring-gdb-imagewatch-to-visualize-custom-buffer-types/). diff --git a/resources/giwscripts/debuggers/gdbbridge.py b/resources/giwscripts/debuggers/gdbbridge.py index 1fe4d82..4f094a9 100644 --- a/resources/giwscripts/debuggers/gdbbridge.py +++ b/resources/giwscripts/debuggers/gdbbridge.py @@ -70,7 +70,7 @@ def get_fields_from_type(self, this_type, observable_symbols): observable_symbols) observable_symbols.update(type_fields) elif ((field_name not in observable_symbols) and - (self._type_bridge.is_symbol_observable(field_val))): + (self._type_bridge.is_symbol_observable(field_val, field_name))): try: observable_symbols.add(field_name) except Exception: @@ -92,6 +92,7 @@ def get_available_symbols(self): for symbol in block: if symbol.is_argument or symbol.is_variable: name = symbol.name + # Get struct/class fields if name == 'this': # The GDB API is a bit convoluted, so I have to do some @@ -104,7 +105,7 @@ def get_available_symbols(self): observable_symbols) observable_symbols.update(type_fields) elif ((name not in observable_symbols) and - (self._type_bridge.is_symbol_observable(symbol))): + (self._type_bridge.is_symbol_observable(symbol, name))): try: observable_symbols.add(name) except Exception: diff --git a/resources/giwscripts/giwtypes/eigen3.py b/resources/giwscripts/giwtypes/eigen3.py index a72e80d..b5e751a 100644 --- a/resources/giwscripts/giwtypes/eigen3.py +++ b/resources/giwscripts/giwtypes/eigen3.py @@ -99,7 +99,7 @@ def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge): 'transpose_buffer': transpose_buffer } - def is_symbol_observable(self, symbol): + def is_symbol_observable(self, symbol, symbol_name): """ Returns true if the given symbol is of observable type (the type of the buffer you are working with). Make sure to check for pointers of your diff --git a/resources/giwscripts/giwtypes/interface.py b/resources/giwscripts/giwtypes/interface.py index 101fecd..4d53912 100644 --- a/resources/giwscripts/giwtypes/interface.py +++ b/resources/giwscripts/giwtypes/interface.py @@ -8,6 +8,37 @@ import abc +def debug_buffer_metadata(func): + def wrapper(self, obj_name, picked_obj, debugger_bridge): + try: + metadata = func(self, obj_name, picked_obj, debugger_bridge) + + print('[%s] [%s] was parsed by giwtype [%s]' % + (str(picked_obj.type), obj_name, type(self).__name__)) + except Exception as error: + print('[%s] [%s] raised exception when parsed by giwtype [%s]:' % + (str(picked_obj.type), obj_name, type(self).__name__)) + print(' %s' % str(error)) + + raise error + + return wrapper + +def debug_symbol_observable(func): + def wrapper(self, symbol_obj, symbol_name): + is_observable = func(self, symbol_obj, symbol_name) + + if is_observable: + is_observable_str = 'is observable' + else: + is_observable_str = 'is NOT observable' + + print('[' + str(symbol_obj.type) + '] [' + symbol_name + '] ' + + is_observable_str + ' by [' + type(self).__name__ + ']') + + return is_observable + + return wrapper class TypeInspectorInterface(): """ @@ -41,11 +72,11 @@ def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge): pass @abc.abstractmethod - def is_symbol_observable(self, symbol_obj): + def is_symbol_observable(self, symbol_obj, symbol_name): """ - Given the debugger with its internal fields and type symbol_obj, this - method must return True if symbol_obj corresponds to an observable - variable (i.e. if its type corresponds to the type of the buffers that - you want to plot). + Given the debugger with its internal fields and type symbol_obj, and + its name symbol_name, this method must return True if symbol_obj + corresponds to an observable variable (i.e. if its type corresponds to + the type of the buffers that you want to plot). """ pass diff --git a/resources/giwscripts/giwtypes/opencv.py b/resources/giwscripts/giwtypes/opencv.py index dd87774..4f7cb1b 100644 --- a/resources/giwscripts/giwtypes/opencv.py +++ b/resources/giwscripts/giwtypes/opencv.py @@ -66,7 +66,7 @@ def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge): 'transpose_buffer' : False } - def is_symbol_observable(self, symbol): + def is_symbol_observable(self, symbol, symbol_name): """ Returns true if the given symbol is of observable type (the type of the buffer you are working with). Make sure to check for pointers of your @@ -123,7 +123,7 @@ def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge): 'transpose_buffer': False } - def is_symbol_observable(self, symbol): + def is_symbol_observable(self, symbol, symbol_name): symbol_type = str(symbol.type) type_regex = r'(const\s+)?CvMat(\s+?[*&])?' return re.match(type_regex, symbol_type) is not None diff --git a/resources/giwscripts/typebridge.py b/resources/giwscripts/typebridge.py index d6bf1c4..6a256e9 100644 --- a/resources/giwscripts/typebridge.py +++ b/resources/giwscripts/typebridge.py @@ -35,20 +35,20 @@ def get_buffer_metadata(self, symbol_name, picked_obj, debugger_bridge): purpose of plotting it in the giwwindow """ for module in self._type_inspectors: - if module.is_symbol_observable(picked_obj): + if module.is_symbol_observable(picked_obj, symbol_name): return module.get_buffer_metadata(symbol_name, picked_obj, debugger_bridge) return None - def is_symbol_observable(self, symbol_obj): + def is_symbol_observable(self, symbol_obj, symbol_name): """ Returns true if any available module is able to process this particular symbol """ for module in self._type_inspectors: - if module.is_symbol_observable(symbol_obj): + if module.is_symbol_observable(symbol_obj, symbol_name): return True return False