<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> | |
<link href="style.css" rel="stylesheet" type="text/css" /> | |
<title>LLDB Homepage</title> | |
</head> | |
<body> | |
<div class="www_title"> | |
The <strong>LLDB</strong> Debugger | |
</div> | |
<div id="container"> | |
<div id="content"> | |
<!--#include virtual="sidebar.incl"--> | |
<div id="middle"> | |
<div class="post"> | |
<h1 class ="postheader">Variable display</h1> | |
<div class="postcontent"> | |
<p>LLDB was recently modified to allow users to define the | |
format of the variables display on a per-type basis.</p> | |
<p>Usually, when you type <code>frame | |
variable</code> or run some <code>expression</code> | |
LLDB will automatically choose the <i>best</i> way | |
to display your results according to its own | |
logic:</p> <p> <code> (SimpleWithPointers [3]) | |
sparray = {<br/> (SimpleWithPointers) [0] = {<br/> | |
(int *) x = 0x00000001001000f0<br/> (float *) y = | |
0x0000000100100100<br/> (char *) z = | |
0x0000000100100110 "3"<br/> | |
}<br/> | |
(SimpleWithPointers) [1] = {<br/> (int *) x = | |
0x0000000100100120<br/> (float *) y = | |
0x0000000100100130<br/> (char *) z = | |
0x0000000100100140 "6"<br/> | |
}<br/> | |
(SimpleWithPointers) [2] = {<br/> (int *) x = | |
0x0000000100100150<br/> (float *) y = | |
0x0000000100100160<br/> (char *) z = | |
0x0000000100100170 "9"<br/> | |
}<br/> | |
}<br/> | |
</code> </p> | |
<p>However, there are cases in which your idea of | |
<i>best</i> is different from LLDB's. Now there are two | |
new commands that enable you to give hints to the debugger | |
as to how datatypes should be displayed.</p> | |
<p>Using them you can obtain a format like this one for | |
<code>sparray</code>, instead of the default shown above: | |
</p> | |
<p> | |
<code> | |
(SimpleWithPointers [3]) sparray = {<br/> | |
[0] = (x=0x00000001001000f0 -> -1, y=0x0000000100100100 -> -2, z="3")<br/> | |
[1] = (x=0x0000000100100120 -> -4, y=0x0000000100100130 -> -5, z="6")<br/> | |
[2] = (x=0x0000000100100150 -> -7, y=0x0000000100100160 -> -8, z="9")<br/> | |
}<br/> | |
</code> | |
</p> | |
<p>Variable formatting can be set using the <b>type</b> commands:</p> | |
<p><code>type format</code></p> | |
<p><code>type summary</code></p> | |
<p>Each of these commands has four subcommands:</p> | |
<p><code>add</code>: adds a new entry</p> | |
<p><code>delete</code>: deletes an existing entry</p> | |
<p><code>list</code>: provides a listing of all entries</p> | |
<p><code>clear</code>: deletes all entries</p> | |
</div> | |
<div class="postfooter"></div> | |
</div> | |
<div class="post"> | |
<h1 class ="postheader">type format</h1> | |
<div class="postcontent"> | |
<p>Type formats enable you to quickly override the default format for displaying primitive types (the usual basic C/C++/ObjC types: int, float, char, ...).</p> | |
<p>LLDB has a list of formatting options available out of which you can pick:</p> | |
<table border="1"> | |
<tr valign=top><td width=23%><b>Format name</b></td><td><b>Abbreviation</b></td><td><b>Description</b></td></tr> | |
<tr valign=top><td><b>default</b></td><td></td><td>the default LLDB algorithm is used to pick a format</td></tr> | |
<tr valign=top><td><b>boolean</b></td><td>B</td><td>show this as a true/false boolean, using the customary rule that 0 is false and everything else is true</td></tr> | |
<tr valign=top><td><b>binary</b></td><td>b</td><td>show this as a sequence of bits</td></tr> | |
<tr valign=top><td><b>bytes</b></td><td>y</td><td>show the bytes one after the other<br/>e.g. <code>(int) s.x = 07 00 00 00</code></td></tr> | |
<tr valign=top><td><b>bytes with ASCII</b></td><td>Y</td><td>show the bytes, but try to print them as ASCII characters<br/>e.g. <code>(int *) c.sp.x = 50 f8 bf 5f ff 7f 00 00 P.._....</code></td></tr> | |
<tr valign=top><td><b>character</b></td><td>c</td><td>show the bytes printed as ASCII characters<br/>e.g. <code>(int *) c.sp.x = P\xf8\xbf_\xff\x7f\0\0</code></td></tr> | |
<tr valign=top><td><b>printable character</b></td><td>C</td><td>show the bytes printed as printable ASCII characters<br/> e.g. <code>(int *) c.sp.x = P.._....</code></td></tr> | |
<tr valign=top><td><b>complex float</b></td><td>F</td><td>interpret this value as the real and imaginary part of a complex floating-point number<br/>e.g. <code>(int *) c.sp.x = 2.76658e+19 + 4.59163e-41i</code></td></tr> | |
<tr valign=top><td><b>c-string</b></td><td>s</td><td>show this as a 0-terminated C string</td></tr> | |
<tr valign=top><td><b>signed decimal</b></td><td>i</td><td>show this as a signed integer number (this does not perform a cast, it simply shows the bytes as signed integer)</td></tr> | |
<tr valign=top><td><b>enumeration</b></td><td>E</td><td>show this as an enumeration, printing the value's name if available or the integer value otherwise<br/>e.g. <code>(enum enumType) val_type = eValue2</code></td></tr> | |
<tr valign=top><td><b>hex</b></td><td>x</td><td>show this as in hexadecimal notation (this does not perform a cast, it simply shows the bytes as hex)</td></tr> | |
<tr valign=top><td><b>float</b></td><td>f</td><td>show this as a floating-point number (this does not perform a cast, it simply interprets the bytes as an IEEE754 floating-point value)</td></tr> | |
<tr valign=top><td><b>octal</b></td><td>o</td><td>show this in octal notation</td></tr> | |
<tr valign=top><td><b>OSType</b></td><td>O</td><td>show this as a MacOS OSType<br/>e.g. <code>(float) *c.sp.y = '\n\x1f\xd7\n'</code></td></tr> | |
<tr valign=top><td><b>unicode16</b></td><td>U</td><td>show this as UTF-16 characters<br/> e.g. <code>(float) *c.sp.y = 0xd70a 0x411f</code></td></tr> | |
<tr valign=top><td><b>unicode32</b></td><td></td><td>show this as UTF-32 characters<br/> e.g. <code>(float) *c.sp.y = 0x411fd70a</code></td></tr> | |
<tr valign=top><td><b>unsigned decimal</b></td><td>u</td><td>show this as an unsigned integer number (this does not perform a cast, it simply shows the bytes as unsigned integer)</td></tr> | |
<tr valign=top><td><b>pointer</b></td><td>p</td><td>show this as a native pointer (unless this is really a pointer, the resulting address will probably be invalid)</td></tr> | |
<tr valign=top><td><b>char[]</b></td><td></td><td>show this as an array of characters<br/>e.g. <code>(char) *c.sp.z = {X}</code></td></tr> | |
<tr valign=top><td><b>int8_t[], uint8_t[]<br/>int16_t[], uint16_t[]<br/>int32_t[], uint32_t[]<br/>int64_t[], uint64_t[]<br>uint128_t[]</b></td><td></td><td>show this as an array of the corresponding integer type<br/>e.g.<br/><code>(int) sarray[0].x = {1 0 0 0}</code><br/><code>(int) sarray[0].x = {0x00000001}</code></td></tr> | |
<tr valign=top><td><b>float32[], float64[]</b></td><td></td><td>show this as an array of the corresponding floating-point type<br/>e.g. <code>(int *) pointer = {1.46991e-39 1.4013e-45}</code></td></tr> | |
<tr valign=top><td><b>complex integer</b></td><td>I</td><td>interpret this value as the real and imaginary part of a complex integer number<br/> e.g. <code>(int *) pointer = 1048960 + 1i</code></td></tr> | |
<tr valign=top><td><b>character array</b></td><td>a</td><td>show this as a character array<br/>e.g. <code>(int *) pointer = \x80\x01\x10\0\x01\0\0\0</code></td></tr> | |
</table> | |
<p>Some of the examples shown are willingfully | |
unnatural ways to print some values, and meant to | |
show that there is no casting or data-loss occurring | |
when you change the format of a type. All that lldb | |
does when you ask it to change format is reinterpret | |
the bytes for display, leaving the original value | |
unaltered.</p> | |
<p>There are two ways to modify the format, one is | |
temporary and per-variable, the other is permanent | |
and per-type.</p> <p>In the first case you can simply | |
use the <code>-f</code> option to <b><code>frame | |
variable</code></b>, passing it one of the format | |
names or abbreviations in the previous table:</p> | |
<p><code>frame variable counter -f hex</code></p> | |
<p>This has the effect of displaying the value of | |
<code>counter</code> as an hexadecimal number, and | |
will keep showing it this way until you either pick a | |
different format or a subsequent stoppoint is | |
hit.</p> <p>Obviously, if you have two | |
<code>int</code> variables, and you format one as | |
hex, the other will be left untouched. If for some | |
reason, you want all <code>int</code> variables to | |
print out as hex, you must add a format to the | |
<code>int</code> type.</p> <p>This is done by typing | |
<code>type format add -f hex int</code> at the LLDB | |
command line.</p> <p>The <code>-f</code> option | |
accepts one of the format names or abbreviations, and | |
after that you can give out a list of names to which | |
you want the new format applied.</p> <p>A frequent | |
scenario is that your program has a | |
<code>typedef</code> for a numeric type that you know | |
represents something that must be printed in a | |
certain way. Again, you can add a format just to that | |
typedef by using <code>type format add</code> with | |
the name alias.</p> <p>But things can quickly get | |
hierarchical. Let's say you have a situation like the | |
following:</p> <p><code>typedef int A;<br/>typedef A | |
B;<br/>typedef B C;<br/>typedef C D;</code></p> | |
<p>and you want to show all <code>A</code>s as hex, | |
all <code>C</code>s as pointers and leave the | |
defaults untouched for other types.</p> <p>If you | |
simply type <br/><code>type format add -f hex | |
A<br/>type format add -f pointer C</code><br/> values | |
of type <code>B</code> will be shown as hex and | |
values of type <code>D</code> as pointers.</p> | |
<p>This is because by default LLDB <i>cascades</i> | |
formats through typedef chains. In order to avoid | |
that you can use the option <code>-C no</code> to | |
prevent cascading, thus making the two commands | |
required to achieve your goal:<br/> <code> type | |
format add -f hex -C no A<br/> type format add -f | |
pointer -C no C </code></p> <p>Two additional options | |
that you will want to look at are <code>-p</code> and | |
<code>-r</code>. These two options prevent LLDB from | |
applying a format for type <code>T</code> to values | |
of type <code>T*</code> and <code>T&</code> | |
respectively.</p> | |
<p> | |
<code> | |
<b>(lldb)</b> type format add -f float32[] int<br/> | |
<b>(lldb)</b> fr var pointer *pointer -T<br/> | |
(int *) pointer = {1.46991e-39 1.4013e-45}<br/> | |
(int) *pointer = {1.53302e-42}<br/> | |
<b>(lldb)</b> type format add -f float32[] int -p<br/> | |
<b>(lldb)</b> fr var pointer *pointer -T<br/> | |
(int *) pointer = 0x0000000100100180<br/> | |
(int) *pointer = {1.53302e-42}<br/> | |
</code> | |
</p> | |
<p>As the previous example highlights, you will most | |
probably want to use <code>-p</code> for your | |
formats.</p> <p>If you need to delete a custom format | |
simply type <code>type format delete</code> followed | |
by the name of the type to which the format applies. | |
To delete ALL formats, use <code>type format | |
clear</code>. To see all the formats defined, type | |
<code>type format list</code>.</p> | |
</div> <div class="postfooter"></div> </div> | |
<div class="post"> <h1 class ="postheader">type | |
summary</h1> <div class="postcontent"> | |
<p>Type summaries enable you to add more information | |
to the default viewing format for a type, or to | |
completely replace it with your own display option. | |
Unlike formats which only apply to basic types, | |
summaries can be used on every type (basic types, | |
classes (C++ and Objective-C), arrays, ...).</p> | |
<p>The basic idea beneath type summaries is | |
extracting information from variables and arranging | |
it in a format that is suitable for display:</p> <p> | |
<i>before adding a summary...</i><br/> <code> <b>(lldb)</b> | |
fr var -T one<br/> (i_am_cool) one = {<br/> (int) | |
integer = 3<br/> (float) floating = 3.14159<br/> | |
(char) character = 'E'<br/> | |
}<br/> | |
</code> <br/> <i>after adding a summary...</i><br/> | |
<code> <b>(lldb)</b> fr var one<br/> (i_am_cool) one = int | |
= 3, float = 3.14159, char = 69<br/> </code> </p> | |
<p>Evidently, somehow we managed to tell LLDB to grab | |
the three member variables of the | |
<code>i_am_cool</code> datatype, mix their values | |
with some text, and even ask it to display the | |
<code>character</code> member using a custom | |
format.</p> <p>The way to do this is add a <i>summary | |
string</i> to the datatype using the <code>type | |
summary add</code> command.</p> <p>Its syntax is | |
similar to <code>type format add</code>, but some | |
more options are supported that will be described in | |
the follow-up.</p> <p>The main option to <code>type | |
summary add</code> is <code>-f</code> which accepts | |
as parameter a summary string. After that, you can | |
type as many type names as you want to associate the | |
given summary string to them.</p> | |
</div> | |
<div class="postfooter"></div> | |
</div> | |
<div class="post"> | |
<h1 class ="postheader">Summary Strings</h1> | |
<div class="postcontent"> | |
<p>So what is the format of the summary strings? | |
Summary strings can contain plain text, control | |
characters and special symbols that have access to | |
information about the current object and the overall | |
program state.</p> | |
<p>Normal characters are any text that doesn't | |
contain a <code><b>'{'</b></code>, | |
<code><b>'}'</b></code>, <code><b>'$'</b></code>, or | |
<code><b>'\'</b></code> character.</p> | |
<p>Variable names are found in between a | |
<code><b>"${"</b></code> prefix, and end with a | |
<code><b>"}"</b></code> suffix. In other words, a | |
variable looks like | |
<code>"<b>${frame.pc}</b>"</code>.</p> | |
<p>Basically, all the variables described in <a | |
href="formats.html">Frame and Thread Formatting</a> | |
are accepted. Also acceptable are the control | |
characters and scoping features described in that | |
page. Additionally, <code>${var</code> and | |
<code>${*var</code> become acceptable symbols in this | |
scenario.</p> <p>The simplest thing you can do is | |
grab a member variable of a class or structure by | |
typing its <i>expression path</i>. In the previous | |
example, the expression path for the floating member | |
is simply <code>.floating</code>, because all you | |
have to do to get at it given an object of type | |
<code>i_am_cool</code> is access it straight away. | |
Thus, to ask the summary string to display | |
<code>floating</code> you would type | |
<code>${var.floating}</code> (<code>${var</code> is a | |
placeholder token replaced with whatever variable is | |
being displayed).</p> <p>If you have code like the | |
following: <br/> <code> struct A {<br/> int x;<br/> | |
int y;<br/> | |
};<br/> | |
struct B {<br/> A x;<br/> A y;<br/> int z;<br/> | |
};<br/> | |
</code> the expression path for the <code>y</code> | |
member of the <code>x</code> member of an object of | |
type <code>B</code> would be <code>.x.y</code> and | |
you would type <code>${var.x.y}</code> to display it | |
in a summary string for type <code>B</code>. </p> | |
<p>As you could be using a summary string for both | |
displaying objects of type <code>T</code> or | |
<code>T*</code> (unless <code>-p</code> is used to | |
prevent this), the expression paths do not | |
differentiate between <code>.</code> and | |
<code>-></code>, and the above expression path | |
<code>.x.y</code> would be just as good if you were | |
displaying a <code>B*</code>, or even if the actual | |
definition of <code>B</code> were: | |
<code><br/> | |
struct B {<br/> | |
A *x;<br/> | |
A y;<br/> | |
int z;<br/> | |
};<br/> | |
</code> | |
</p> | |
<p>This is unlike the behaviour of <code>frame | |
variable</code> which, on the contrary, will enforce | |
the distinction. As hinted above, the rationale for | |
this choice is that waiving this distinction enables | |
one to write a summary string once for type | |
<code>T</code> and use it for both <code>T</code> and | |
<code>T*</code> instances. As a summary string is | |
mostly about extracting nested members' information, | |
a pointer to an object is just as good as the object | |
itself for the purpose.</p> | |
<p>Of course, you can have multiple entries in one | |
summary string. For instance, the command used to | |
produce the above summary string for i_am_cool was: | |
<br/><code>type summary add -f "int = ${var.integer}, | |
float = ${var.floating}, char = ${var.character%u}" | |
i_am_cool </code> </p> <p>As you can see, the last | |
expression path also contains a <code>%u</code> | |
symbol which is nowhere to be found in the actual | |
member variable name. The symbol is reminding of a | |
<code>printf()</code> format symbol, and in fact it | |
has a similar effect. If you add a % sign followed by | |
any one format name or abbreviation from the above | |
table after an expression path, the resulting object | |
will be displyed using exactly that format instead of | |
the LLDB default one. | |
</p> | |
<p>There are two more special format symbols that you | |
can use only as part of a summary string: | |
<code>%V</code> and <code>%@</code>. The first one | |
tells LLDB to ignore summary strings for the type of | |
the object referred by the expression path and | |
instead print the object's value. The second is only | |
applicable to Objective-C classes, and tells LLDB to | |
get the object's description from the Objective-C | |
runtime. By default, if no format is provided, LLDB | |
will try to get the object's summary, and if empty | |
the object's value. If neither can be obtained, | |
nothing will be displayed.</p> | |
<p>As previously said, pointers and values are | |
treated the same way when getting to their members in | |
an expression path. However, if your expression path | |
leads to a pointer, LLDB will not automatically | |
dereference it. In order to obtain The deferenced | |
value for a pointer, your expression path must start | |
with <code>${*var</code> instead of | |
<code>${var</code>. Because there is no need to | |
dereference pointers along your way, the | |
dereferencing symbol only applies to the result of | |
the whole expression path traversing. | |
<br/> | |
e.g. | |
<code> | |
<br/> | |
<b>(lldb)</b> fr var -T c<br/> | |
(Couple) c = {<br/> | |
(SimpleWithPointers) sp = {<br/> | |
(int *) x = 0x00000001001000b0<br/> | |
(float *) y = 0x00000001001000c0<br/> | |
(char *) z = 0x00000001001000d0 "X"<br/> | |
}<br/> | |
(Simple *) s = 0x00000001001000e0<br/> | |
}<br/> | |
<b>(lldb)</b> type summary add -f "int = ${*var.sp.x}, float = ${*var.sp.y}, char = ${*var.sp.z%u}, Simple = ${*var.s}" Couple<br/> | |
<b>(lldb)</b> type summary add -c -p Simple<br/> | |
<b>(lldb)</b> fr var c<br/> | |
(Couple) c = int = 9, float = 9.99, char = 88, Simple = (x=9, y=9.99, z='X')<br/> | |
</code> | |
</p> | |
<p>Option <code>-c</code> to <code>type summary | |
add</code> tells LLDB not to look for a summary | |
string, but instead to just print a listing of all | |
the object's children on one line, lay out as in the | |
previous example. The <code>-p</code> flag is used as | |
a trick to show that aggregate types can be | |
dereferenced as well as primitive ones. The above | |
output would be shown even by typing <code>type | |
summary add -f "int = ${*var.sp.x}, float = | |
${*var.sp.y}, char = ${*var.sp.z%u}, Simple = | |
${var.s}" Couple</code> if one took away the | |
<code>-p</code> flag from the summary for type | |
<code>Simple</code>. </p> | |
</div> | |
<div class="postfooter"></div> | |
</div> | |
<div class="post"> | |
<h1 class ="postheader">More on summary strings</h1> | |
<div class="postcontent"> | |
<p>What was described above are the main features | |
that you can use in summary strings. However, there | |
are three more features to them.</p> <p>Sometimes, a | |
basic type's value actually represents several | |
different values packed together in a bitfield. With | |
the classical view, there is no way to look at them. | |
Hexadecimal display can help, but if the bits | |
actually span byte boundaries, the help is limited. | |
Binary view would show it all without ambiguity, but | |
is often too detailed and hard to read for real-life | |
scenarios. To cope with the issue, LLDB supports | |
native bitfield formatting in summary strings. If | |
your expression paths leads to a so-called <i>scalar | |
type</i> (the usual int, float, char, double, short, | |
long, long long, double, long double and unsigned | |
variants), you can ask LLDB to only grab some bits | |
out of the value and display them in any format you | |
like. The syntax is similar to that used for arrays, | |
just you can also give a pair of indices separated by | |
a <code>-</code>. <br/> | |
e.g. | |
<br/> | |
<code> | |
<b>(lldb)</b> fr var float_point<br/> | |
(float) float_point = -3.14159<br/> | |
<b>(lldb)</b> type summary add -f "Sign: ${var[31]%B} Exponent: ${var[30-23]%x} Mantissa: ${var[0-22]%u}" float<br/> | |
<b>(lldb)</b> fr var float_point<br/> | |
(float) float_point = -3.14159 Sign: true Exponent: 0x00000080 Mantissa: 4788184<br/> | |
</code> | |
In this example, LLDB shows the internal | |
representation of a <code>float</code> variable by | |
extracting bitfields out of a float object. If you | |
give a single index, only that one bit will be | |
extracted. If you give a pair of indices, all the | |
bits in the range (extremes included) will be | |
extracted. Ranges can be specified either by giving | |
the lower index first, or higher index first (as is | |
often customary in describing packed data-type | |
formats). </p> | |
<p>The second additional feature allows you to | |
display array members inside a summary string. For | |
instance, you may want to display all arrays of a | |
given type using a more compact notation than the | |
default, and then just delve into individual array | |
members that prove interesting to your debugging | |
task. You can use a similar syntax to the one used | |
for bitfields to tell LLDB to format arrays in | |
special ways. | |
<br/> | |
e.g. | |
<br/> | |
<code> | |
<b>(lldb)</b> fr var sarray<br/> | |
(Simple [3]) sarray = {<br/> | |
[0] = {<br/> | |
x = 1<br/> | |
y = 2<br/> | |
z = '\x03'<br/> | |
}<br/> | |
[1] = {<br/> | |
x = 4<br/> | |
y = 5<br/> | |
z = '\x06'<br/> | |
}<br/> | |
[2] = {<br/> | |
x = 7<br/> | |
y = 8<br/> | |
z = '\t'<br/> | |
}<br/> | |
}<br/> | |
<b>(lldb)</b> type summary add -f "${var[].x}" "Simple [3]"<br/> | |
<b>(lldb)</b> fr var sarray<br/> | |
(Simple [3]) sarray = [1,4,7]<br/> | |
</code> | |
The <code>[]</code> symbol amounts to: <i>if | |
<code>var</code> is an array and I knows its size, | |
apply this summary string to every element of the | |
array</i>. Here, we are asking LLDB to display | |
<code>.x</code> for every element of the array, and | |
in fact this is what happens. If you find some of | |
those integers anomalous, you can then inspect that | |
one item in greater detail, without the array format | |
getting in the way: | |
<br/> | |
<code> | |
<b>(lldb)</b> fr var sarray[1]<br/> | |
(Simple) sarray[1] = {<br/> | |
x = 4<br/> | |
y = 5<br/> | |
z = '\x06'<br/> | |
}<br/> | |
</code> | |
</p> | |
<p>You can also ask LLDB to only print a subset of | |
the array range by using the same syntax used to | |
extract bit for bitfields.</p> <p>The same logic | |
works if you are printing a pointer instead of an | |
array, however in this latter case, <code>[]</code> | |
cannot be used and you need to give exact range | |
limits.</p> <p>The third, and last, additional | |
feature does not directly apply to the summary | |
strings themselves, but is an additional option to | |
the <code>type summary add</code> command: | |
<code>-x</code></p> <p>As you noticed, in order to | |
associate the custom summary string to the array | |
types, one must give the array size as part of the | |
typename. This can long become tiresome when using | |
arrays of different sizes, <code>Simple [3]</code>, | |
<code>Simple [9]</code>, <code>Simple [12]</code>, | |
...</p> <p>If you use the <code>-x</code> option, | |
type names are treated as regular expressions instead | |
of type names. This would let you rephrase the above | |
example as: | |
<br/> | |
<code> | |
<b>(lldb)</b> type summary add -f "${var[].x}" -x "Simple \[[0-9]+\]"<br/> | |
<b>(lldb)</b> fr var sarray<br/> | |
(Simple [3]) sarray = [1,4,7]<br/> | |
</code> | |
The above scenario works for <code>Simple [3]</code> | |
as well as for any other array of | |
<code>Simple</code> objects. </p> <p>While this | |
feature is mostly useful for arrays, you could also | |
use regular expressions to catch other type sets | |
grouped by name. However, as regular expression | |
matching is slower than normal name matching, LLDB | |
will first try to match by name in any way it can, | |
and only when this fails, will it resort to regular | |
expression matching. Thus, if your type has a base | |
class with a cascading summary, this will be | |
preferred over any regular expression match for your | |
type itself.</p> | |
</div> <div class="postfooter"></div> </div> | |
<div class="post"> <h1 class ="postheader">Finding | |
summaries 101</h1> <div class="postcontent"> | |
<p>While the rules for finding an appropriate | |
format for a type are relatively simple (just go | |
through typedef hierarchies), summaries follow a | |
more complicated process in finding the right | |
summary string for a variable. Namely, what | |
happens is:</p> <ul> <li>If there is a summary for | |
the type of the variable, use it</li> <li>If this | |
object is a pointer, and there is a summary for | |
the pointee type that does not skip pointers, use | |
it</li> <li>If this object is a reference, and | |
there is a summary for the pointee type that does | |
not skip references, use it</li> <li>If this | |
object is an Objective-C class with a parent | |
class, look at the parent class (and parent of | |
parent, ...)</li> <li>If this object is a C++ | |
class with base classes, look at base classes (and | |
bases of bases, ...)</li> <li>If this object is a | |
C++ class with virtual base classes, look at the | |
virtual base classes (and bases of bases, | |
...)</li> <li>If this object's type is a typedef, | |
go through typedef hierarchy</li> <li>If | |
everything has failed, repeat the above search, | |
looking for regular expressions instead of exact | |
matches</li> </ul> </div> <div | |
class="postfooter"></div> </div> | |
<div class="post"> <h1 class ="postheader">TODOs</h1> | |
<div class="postcontent"> | |
<ul> <li>There's no way to do multiple dereferencing, | |
and you need to be careful what the dereferencing | |
operation is binding to in complicated scenarios</li> | |
<li>There is no way to call functions inside summary | |
strings, not even <code>const</code> ones</li> | |
<li><code>type format add</code> does not support the | |
<code>-x</code> option</li> <li>Object location cannot | |
be printed in the summary string</li> </ul> | |
</div> | |
<div class="postfooter"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |