celix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Menno van der Graaf <mennovandergr...@hotmail.com>
Subject RE: Celix debugging tools
Date Fri, 29 Jan 2016 15:05:33 GMT
Since this mail list bot seems to ingore the seccond attachement, heres the documentation in
text...

Accessing the variables
To print the specified Celix structure, first its data fields must be retrieved and inspected.
The data fields are represented by gdb.value objects, which is an object defined in the gdb
module (this module needs to be imported). The gdb module implements a “to string” function
for standard C types, so all that’s needed is to select the wanted variables and to convert
the gdb.values to the desired type. For some of the type’s functionality a module called
gdb.types has to be imported.
The selection part is completely subjective, and mostly has to do with which data the programmer
finds interesting enough to print.
Converting the gdb.values is done in multiple ways, for pointers there’s the gdb.value.dereference
method, which returns another gdb.value, of the referenced object.
bundle_struct = bundle_pointer.dereference()
To convert types (i.e. from void pointer to bundle_pt), the gdb.value.cast method can be used.
To get a specified type (bundle_pt is not known by gdb), gdb.lookup_type is used. This will
resolve the type name at run time, and pass back a gdb.type object.
bundle_pointer = some_void_pt.cast(gdb.lookup_type("bundle_pt"))
To convert the final acquired value to a string that can be printed, the default str method
is used. (i.e. “str(value)” ).

Outputting strings
Initially the printers to string function was implemented to print out the entire struct,
however, when such an output is printed, it is truncated. GDB expects a short string back,
with simply the object name, or key information. The actual structures data fields, are implemented
in the “children” method. This method returns a list (or any other python iterable object)
This list contains tuple pairs of strings, where the template for the strings is:
tuple_object = (str_object_name, str_object_value)
children_list.append(tuple_object)
The brackets around the two objects returns a tuple, which can then be appended to the list
(or assigned to an intermediate variable if needed).

Printing nested structures
Celix framework structures are quite complex and are almost always constructed of other, nested
structures. This means that in order to print all the relevant information, sometimes an abbreviated
representation of another struct must be used. For this purpose, the student created other
pretty printers, with an added method, “short_string”. This returns the key information
of a structure, i.e. in the case of the module, it prints the modules “symbolic_name”
and “id”, which in many cases is enough for the programmer to identify the module.
module_str = module_printer(module).to_short_string()
If additional information is needed, the user can call the full printer for the actual object,
which would call the normal toString method.

Printing lists
A combination of casting and printing nested structures is needed when printing a list of
structs. For example, the “module” used in the example for printing nested structures,
is stored in an arraylist called modules “bundle->modules”. All Celix lists/maps store
void pointers, which need to be explicitly casted by the programmer in each use, this makes
it impossible to make a generic printer for such objects. A solution is to access the data
in the printer, and then call the associated printer (combining the casting, and the printing
nested structures examples). See celix_printers.py, line 21 to 35, for an example of printing
an arraylist of modules.

From: mennovandergraaf@hotmail.com
To: dev@celix.apache.org
Subject: Celix debugging tools
Date: Fri, 29 Jan 2016 15:54:04 +0100




Hello,
Menno van der Graaf here, you might have seen me post patches on the Celix-Jira.
I was advised to send a mail about some work I did recently (although as it stands right now,
its mostly a small experiment). 
To help with debugging the framework, I wrote some gdb extentions to enhance printing of the
bundle structure, and the bundle archive structure.
Meaning that it shows more relevant data, and less irrelevant data.

For those that are interested, they are implemented in python, with the gdb python API.
Through this API I implemented so called "pretty printers" for the structures, these "pretty
printers" are basicly fancy toString functions.
The files can be found attached to this message.

To install the printers, execute the script "load.py"

(gdb) python execfile("load.py")

(please note that you might need to edit the first line to specify a include directory)
there are ways to autoload it with gdb, or put it in your gdb init file
now, to check if they are installed (and for which types)

(gdb) info pretty-printer

Once loaded, gdb will automatically call the toString whenever you try to print a instance
of the type. i.e.:

(gdb) print *context->bundle

for the struct bundle, the printer goes into the arraylist of modules, fetches and prints
the names and id of each module, and shows the location of the archive.
for the struct bundleArchive, it prints the revisions from the linkedlist.
there are more types partially implemented, but these are only used internally as of yet.

for those interested in extending the functionality, i attached some documentation on how
i implemented them.
you can also read the gdb python API documentation

Any way, hope that someone finds this usefull, 

Menno van der Graaf
 		 	   		   		 	   		  
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message