Watching a QString
(Qt5) in DBG is not directly possible like std::string
.
There are 2 solutions:
QString
member function.Add a watch for debugging a QString
called str
like
(char16_t*)str.d->data()
Create a file ${HOME}/.gdbinit
using the next available contents.
define qs5
printf "(Qt5 QString)0x%x (%i) ", &$arg0, $arg0.d->size
print (char16_t*)$arg0.d->data()
end
define qs5
set $d=$arg0.d
printf "(Qt5 QString)0x%x length=%i: \"",&$arg0,$d->size
set $i=0
set $ca=(const ushort*)(((const char*)$d)+$d->offset)
while $i < $d->size
set $c=$ca[$i++]
if $c < 32 || $c > 127
printf "\\u%04x", $c
else
printf "%c" , (char)$c
end
end
printf "\"\n"
end
define qs5
set $d=(QStringData*)$arg0.d
printf "(Qt5 QString)0x%x length=%i: \"",&$arg0,$d->size
set $i=0
while $i < $d->size
set $c=$d->data()[$i++]
if $c < 32 || $c > 127
printf "\\u%04x", $c
else
printf "%c" , (char)$c
end
end
printf "\"\n"
end
Call the macro from the DBG console.
qs5 <local-variable-name>
See kde-devel-gdb
# This file defines handy gdb macros for printing out Qt types
# To use it, add this line to your ~/.gdbinit :
# source /path/to/kde/sources/kdesdk/scripts/kde-devel-gdb
# Please don't use tabs in this file. When pasting a
# macro definition to gdb, tabs are interpreted as completion.
# Note for macro development: when working a macro,
# disable the confirmation before gdb allows to redefine a macro, using "set confirm 0".
# Disable printing of static members. Qt has too many, it clutters the output
set print static-members off
# Remember history over restarts
set history save
set history filename ~/.gdb_history
# Show the real classname of object instances - e.g. (Kded *) 0x8073440 instead of (class QObject *) 0x8073440
set print object
define printqstring
printqstringdata ($arg0).d
end
document printqstring
Prints the contents of a Qt3 QString
end
define printq4string
printq4stringdata ($arg0).d
end
document printq4string
Prints the contents of a Qt4 QString
end
define printq5string
printq5stringdata ($arg0).d
end
document printq5string
Prints the contents of a Qt5 QString
end
define printqstringdata
set $i=0
set $d = (QStringData *)($arg0)
while $i < $d->len
printf "%c", (char)($d->unicode[$i++].ucs & 0xff)
end
printf "\n"
end
document printqstringdata
Prints the contents of a QStringData
This is useful when the output of another command (e.g. printqmap)
shows {d = 0xdeadbeef} for a QString, i.e. the qstringdata address
instead of the QString object itself.
printqstring $s and printqstringdata $s.d are equivalent.
end
define printq4stringdata
set $d = ('QString::Data'*) $arg0
set $i = 0
# abort after a '-1' character, to avoid going on forever when printing a garbage string
while $i < $d->size && ($i == 0 || (char)$d->data[$i-1] != -1)
printf "%c", (char)($d->data[$i++] & 0xff)
end
printf "\n"
end
document printq4stringdata
Prints the contents of a Qt4 QString::Data
This is useful when the output of another command (e.g. printqmap)
shows {d = 0xdeadbeef} for a QString, i.e. the qstringdata address
instead of the QString object itself.
printq4string $s and printq4stringdata $s.d are equivalent.
end
define printq5stringdata
set $d = ('QString::Data'*) $arg0
set $data_char = (char*)$d + $d->offset
set $data = (unsigned short*) $data_char
set $size = $d->size
set $i = 0
while $i < $size
set $c = (char)($data[$i++] & 0xff)
printf "%c", $c
# abort after a '-1' character, to avoid going on forever when printing a garbage string
if $i != 0 && $c == -1
printf "\n<output terminated: junk data?>"
loop_break
end
end
printf "\n"
end
document printq5stringdata
Prints the contents of a Qt5 QString::Data
This is useful when the output of another command (e.g. printqmap)
shows {d = 0xdeadbeef} for a QString, i.e. the qstringdata address
instead of the QString object itself.
printq5string $s and printq5stringdata $s.d are equivalent.
end
define print_utf8_char
set $uc = $arg0
if ( $uc < 0x80 )
printf "%c", (unsigned char)($uc & 0x7f)
else
if ( $uc < 0x0800 )
printf "%c", (unsigned char)(0xc0 | ($uc >> 6))
else
printf "%c", (unsigned char)(0xe0 | ($uc >> 12)
printf "%c", (unsigned char)(0x80 | (($uc > 6) &0x3f)
end
printf "%c", (unsigned char)(0x80 | ((uchar) $uc & 0x3f))
end
end
document print_utf8_char
Prints a unicode value (stored as an unsigned short) as UTF-8.
end
define printqstring_utf8
set $i=0
set $s = $arg0
while $i < $s.d->len
set $uc = (unsigned short) $s.d->unicode[$i++].ucs
print_utf8_char $uc
end
printf "\n"
end
document printqstring_utf8
Prints the contents of a Qt3 QString encoded in utf8.
Nice if you run your debug session in a utf8 enabled terminal.
end
define printq4string_utf8
set $i=0
set $s = $arg0
while $i < $s.d->size
set $uc = (unsigned short) $s.d->data[$i++]
print_utf8_char $uc
end
printf "\n"
end
document printq4string_utf8
Prints the contents of a Qt4 QString encoded in utf8.
Nice if you run your debug session in a utf8 enabled terminal.
end
define printq5string_utf8
set $i=0
set $s = $arg0
set $d = $s.d
set $data_char = (char*)$d + $d->offset
set $data = (unsigned short*) $data_char
set $size = $d->size
while $i < $size
print_utf8_char $data[$i++]
end
printf "\n"
end
document printq5string_utf8
Prints the contents of a Qt5 QString encoded in utf8.
Nice if you run your debug session in a utf8 enabled terminal.
end
define printqcstring
print ($arg0).shd.data
print ($arg0).shd.len
end
document printqcstring
Prints the contents of a QCString (char * data, then length)
end
define printq4bytearray
print ($arg0)->d->data
end
document printq4bytearray
Prints the contents of a Qt4 QByteArray (when it contains a string)
end
define printqfont
print *($arg0).d
printqstring ($arg0).d->request.family
print ($arg0).d->request.pointSize
end
document printqfont
Prints the main attributes from a QFont, in particular the requested
family and point size
end
define printqcolor
printf "(%d,%d,%d)\n", ($arg0).red(), ($arg0).green(), ($arg0).blue()
end
document printqcolor
Prints a QColor as (R,G,B).
Usage: 'printqcolor <QColor col>
end
define printqmemarray
# Maybe we could find it out the type by parsing "whatis $arg0"?
set $arr = $arg0
set $sz = sizeof($arg1)
set $len = $arr->shd->len / $sz
output $len
printf " items in the array\n"
set $i = 0
while $i < $len
# print "%s[%d] = %s\n", $arr, $i, *($arg1 *)(($arr->vec)[$i])
print *($arg1 *)(($arr->shd->data) + ($i * $sz))
set $i++
end
end
document printqmemarray
Prints the contents of a QMemArray. Pass the type as second argument.
end
define printqptrvector
# Maybe we could find it out the type by parsing "whatis $arg0"?
set $arr = $arg0
set $len = $arr->len
output $len
printf " items in the vector\n"
set $i = 0
while $i < $len
# print "%s[%d] = %s\n", $arr, $i, *($arg1 *)(($arr->vec)[$i])
print *($arg1 *)(($arr->vec)[$i])
set $i++
end
end
document printqptrvector
Prints the contents of a QPtrVector. Pass the type as second argument.
end
define printqptrvectoritem
set $arr = $arg0
set $i = $arg2
print ($arg1 *)(($arr->vec)[$i])
print *($arg1 *)(($arr->vec)[$i])
end
document printqptrvectoritem
Print one item of a QPtrVector
Usage: printqptrvectoritem vector type index
end
define printq3map
set $map = $arg0
set $len = $map.sh->node_count
output $len
printf " items in the map\n"
set $header = $map.sh->header
# How to parse the key and value types from whatis?
set $it = (QMapNode<$arg1,$arg2> *)($header->left)
while $it != $header
printf " key="
output $it->key
printf " value="
output $it->data
printf "\n"
_qmapiterator_inc $it
set $it = (QMapNode<$arg1,$arg2> *)($ret)
end
end
document printq3map
Prints the full contents of a Qt 3 QMap
Usage: 'printq3map map keytype valuetype'
end
define printq4map
set $map = $arg0
set $len = $map.d->size
output $len
printf " items in the map\n"
set $it = $map.e->forward[0]
set $_qmap_end = $map.e
## Requires a process...
set $_qmap_payload = $map->payload()
while $it != $map.e
set $_qmap_nodeaddress = (char*)($it) - $_qmap_payload
set $_qmap_node = ('QMap<$arg1,$arg2>::Node' *)($_qmap_nodeaddress)
printf " key="
output $_qmap_node->key
printf " value="
output $_qmap_node->value
printf "\n"
# just in case the key and/or the value is a qstring, try printq4string on it
# (if this is too noisy with other types, remove it, and use
# printq4stringdata on the shown d pointers instead, by hand)
printq4string $_qmap_node->key
printq4string $_qmap_node->value
set $it = $it->forward[0]
end
end
document printq4map
Prints the full contents of a Qt 4 QMap
Usage: 'printq4map map keytype valuetype'
end
define _qmapiterator_inc
set $ret = $arg0
if $ret->right != 0
set $ret = $ret->right
while $ret->left != 0
set $ret = $ret->left
end
else
set $y = $ret->parent
while $ret == $y->right
set $ret = $y
set $y = $y->parent
end
if $ret->right != $y
set $ret = $y
end
end
end
document _qmapiterator_inc
Increment a qmap iterator (internal method, used by printq3map)
end
define printqptrlist
set $list = $arg0
set $len = $list.numNodes
output $len
printf " items in the list\n"
set $it = $list.firstNode
while $it != 0
output $it->data
printf "\n"
set $it = $it->next
end
end
document printqptrlist
Prints the contents of a QPtrList.
Usage: printqptrlist mylist
end
define printqvaluelist
set $list = $arg0
set $len = $list.sh->nodes
output $len
printf " items in the list\n"
set $it = $list.sh->node->next
set $end = $list.sh->node
while $it != $end
output $it->data
printf "\n"
set $it = $it->next
end
end
document printqvaluelist
Prints the contents of a QValueList.
Usage: printqvaluelist mylist
end
define printqstringlist
set $list = $arg0
set $len = $list.sh->nodes
output $len
printf " items in the list\n"
set $it = $list.sh->node->next
set $end = $list.sh->node
while $it != $end
printqstring $it->data
set $it = $it->next
end
end
document printqstringlist
Prints the contents of a QStringList.
Usage: printqstringlist mylist
end
define printqregion
printqmemarray ($arg0).rects() QRect
end
document printqregion
Prints the rectangles that make up a QRegion. Needs a running process.
Usage: printqregion myregion
end
# Bad implementation, requires a running process.
# Needs to be refined, i.e. figuring out the right void* pointers casts.
# Simon says: each Node contains the d pointer of the QString.
define printq4stringlist
# This is ugly, but we need to avoid conflicts with printq4string's own vars...
set $q4sl_i = 0
set $q4sl_d = & $arg0
set $q4sl_sz = $q4sl_d->size()
while $q4sl_i < $q4sl_sz
output $q4sl_i
printf " "
printq4string $q4sl_d->at($q4sl_i++)
end
end
document printq4stringlist
Prints the contents of a Qt4 QStringList.
Usage: printq4stringlist mylist
end
define identifyq4object
set $obj=$arg0
set $objectName=((QObjectPrivate *)($obj->d_ptr))->objectName
printf " name:"
printq4string $objectName
printf " class:"
# this requires a process, though
print $obj->metaObject()->className()
end
# You print QString's too often to type the long name :-)
define qs5
printq5string $arg0
end
define qs4
printq4string $arg0
end
define qs3
printqstring $arg0
end
define printqdatetime
printqdate ($arg0).d
printqtime ($arg0).t
end
document printqdatetime
Prints a QDateTime
Usage: printqdatetime myqdt
end
define printqdate
printf "(Y:%d M:%d D:%d)\n", ($arg0).year(), ($arg0).month(), ($arg0).day()
end
document printqdate
Prints a QDate
Usage: printqdate mydate
end
define printqtime
printf "(H:%d M:%d S:%d)\n", ($arg0).hour(), ($arg0).minute(), ($arg0).second()
end
document printqtime
Prints a QTime
Usage: printqtime mytime
end
# You are at f(g(h(i(), j(k(l())...) and you want to enter f: type fs <enter> <enter> <enter>
# fs=finish+step
define fs
finish
step
end