Using Debugging HelpersQt Creator is able to show complex data types in a customized, user-extensible manner. For this purpose, it takes advantage of two technologies, collectively referred to as Debugging Helpers. Using the debugging helpers is not essential for debugging with Qt Creator, but they enhance the user's ability to quickly examine complex data significantly. Debugging Helpers Based on C++This is the first and original approach to display complex data types. While it has been superseded on most platforms by the more robust and more flexible second approch using Python scripting, it is the only feasible one on Windows/MSVC, Mac OS, and old Linux distributions. Moreover, this approach will automatically be chosen as fallback in case the Python based approach fails. During debugging with the C++ based debugging helpers, Qt Creator dynamically loads a helper library in form of a DLL or a shared object into the debugged process. The Qt SDK package already contains a prebuilt debugging helper library. To create your own debugging helper library, select Tools > Options... > Qt4 > Qt Versions. As the internal data structures of Qt can change between versions, the debugging helper library is built for each Qt version. Debugging Helpers Based on PythonOn platforms featuring a Python-enabled version of the gdb debugger, the data extraction is done by a Python script. This is more robust as the script execution is separated from the debugged process. It is also easier to extend as the script is less dependend on the actual Qt version and does not need compilation. To extend the shipped Python based debugging helpers for custom types, define one Python function per user defined type in the gdb startup file. By default, the following startup file is used: ~/.gdbinit. To use another file, select Tools > Options... > Gdb and specify a filename in the Gdb startup script field. The function name has to be qdump__NS__Foo, where NS::Foo is the class or class template to be examined. Nested namespaces are possible. The debugger plugin calls this function whenever you want to display an object of this type. The function is passed the following parameters:
The function has to feed the Dumper object with certain information which is used to build up the object and its children's display in the Locals and Watchers view. Example: def qdump__QVector(d, item):
d_ptr = item.value["d"]
p_ptr = item.value["p"]
alloc = d_ptr["alloc"]
size = d_ptr["size"]
check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
check(d_ptr["ref"]["_q_value"] > 0)
innerType = item.value.type.template_argument(0)
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded(item):
p = gdb.Value(p_ptr["array"]).cast(innerType.pointer())
with Children(d, [size, 2000], innerType)
for i in d.childRange():
d.putItem(Item(p.dereference(), item.iname, i))
p += 1
Item ClassThe Item Python class is a thin wrapper around values corresponding to one line in the Locals and Watchers view. The Item members are as follows :
Dumper ClassFor each line in the Locals and Watchers view, a string like the following needs to be created and channeled to the debugger plugin. "{iname='some internal name',
addr='object address in memory',
name='contents of the name column',
value='contents of the value column',
type='contents of the type column',
numchild='number of children', // zero/nonzero is sufficient
childtype='default type of children', // optional
childnumchild='default number of grandchildren', // optional
children=[ // only needed if item is expanded in view
{iname='internal name of first child',
... },
{iname='internal name of second child',
... },
...
]}"
While in theory, you can build up the entire string above manually, it is easier to employ the Dumper Python class for that purpose. The Dumper Python class contains a complete framework to take care of the iname and addr fields, to handle children of simple types, references, pointers, enums, known and unknown structs as well as some convenience methods to handle common situations. The Dumper members are the following:
Children and SubItem ClassThe attempt to create child items might lead to errors if data is uninitialized or corrupted. To gracefully recover in such situations, use Children and SubItem Context Managers to create the nested items. The Children constructor __init__(self, dumper, numChild = 1, childType = None, childNumChild = None) uses one mandatory argument and three optional arguments. The mandatory argument refers to the current Dumper object. The optional arguments can be used to specify the number numChild of children, with type childType_ and childNumChild_ grandchildren each. If numChild_ is a list of two integers, the first one specifies the actual number of children and the second the maximum number of children to print. Similarly, using the SubItem class helps to protect individual items. Example: d.putNumChild(2)
if d.isExpanded(item):
with Children(d):
with SubItem(d):
d.putName("key")
d.putItemHelper(Item(key, item.iname, "key"))
with SubItem(d):
d.putName("value")
d.putItemHelper(Item(value, item.iname, "value"))
[Previous: Setting Up Debugger] [Next: Using the Maemo Emulator] X
|
|
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |