[lldb][docs] Update Variable Formatting Documentation (#193907)

Various improvements to the LLDB Variable Formatting documentation:

1. Use consistent formatting.
2. Polish wording.
3. Add examples.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-04-30 03:57:03 -04:00
committed by GitHub
parent 9561b079ca
commit 436fbb8175

View File

@@ -60,7 +60,7 @@ result in something like:
} }
} }
which is very hard to make sense of. which is very hard to understand.
Note: ``frame variable <var>`` prints out the variable ``<var>`` in the current Note: ``frame variable <var>`` prints out the variable ``<var>`` in the current
frame. frame.
@@ -84,7 +84,8 @@ Note: you can also use ``v <var>`` instead of ``frame variable <var>``.
It's worth mentioning that the ``size=5`` string is produced by a summary It's worth mentioning that the ``size=5`` string is produced by a summary
provider and the list of children is produced by a synthetic child provider. provider and the list of children is produced by a synthetic child provider.
More information about these providers is available later in this document. More information about these providers is available in :ref:`type-summary` and
:ref:`synthetic-children`, respectively.
There are several features related to data visualization: formats, summaries, There are several features related to data visualization: formats, summaries,
@@ -129,7 +130,7 @@ This is done by typing
at the LLDB command line. at the LLDB command line.
The ``--format`` (which you can shorten to -f) option accepts a `format The ``--format`` (which you can shorten to ``-f``) option accepts a `format
name`_. Then, you provide one or more types to which you want the name`_. Then, you provide one or more types to which you want the
new format applied. new format applied.
@@ -170,8 +171,8 @@ values of type B will be shown as hex and values of type D as byte arrays, as in
(D) d = {0x04 0x00 0x00 0x00} (D) d = {0x04 0x00 0x00 0x00}
This is because by default LLDB cascades formats through typedef chains. In This is because by default LLDB cascades formats through typedef chains. In
order to avoid that you can use the option -C no to prevent cascading, thus order to prevent cascading, use the option ``-C`` with the value ``no`` when
making the two commands required to achieve your goal: defining the type format:
:: ::
@@ -179,7 +180,7 @@ making the two commands required to achieve your goal:
(lldb) type format add -C no -f uint8_t[] C (lldb) type format add -C no -f uint8_t[] C
which provides the desired output: Without cascading, the same command gives different results:
:: ::
@@ -189,7 +190,8 @@ which provides the desired output:
(C) c = {0x03 0x00 0x00 0x00} (C) c = {0x03 0x00 0x00 0x00}
(D) d = 4 (D) d = 4
Note, that qualifiers such as const and volatile will be stripped when matching types for example: Note that qualifiers such as ``const`` and ``volatile`` will be stripped when
matching types. For example:
:: ::
@@ -203,9 +205,13 @@ Note, that qualifiers such as const and volatile will be stripped when matching
(const int) y = 0x00000002 (const int) y = 0x00000002
(volatile int) z = 0x00000004 (volatile int) z = 0x00000004
Two additional options that you will want to look at are --skip-pointers (-p) Type formats *can* be applied to pointers and references by using the
and --skip-references (-r). These two options prevent LLDB from applying a ``pointer`` "adjective" before the type in the ``type format`` command.
format for type T to values of type T* and T& respectively. However, they specify the format to be applied to the pointer or reference
and not the value being referenced or pointed to. Use ``--skip-pointers`` (``-p``)
and ``--skip-references`` (``-r``) to change this behavior. These two
options prevent LLDB from applying a format defined for type ``T`` to
values of type ``T*`` and ``T&``, respectively.
:: ::
@@ -218,33 +224,31 @@ format for type T to values of type T* and T& respectively.
(int *) pointer = 0x0000000100100180 (int *) pointer = 0x0000000100100180
(int) *pointer = {1.53302e-42} (int) *pointer = {1.53302e-42}
While they can be applied to pointers and references, formats will make no If you need to delete a custom format type, use ``type format delete`` followed
attempt to dereference the pointer and extract the value before applying the by the name of the type for which to delete the format.
format, which means you are effectively formatting the address stored in the
pointer rather than the pointee value. For this reason, you may want to use the
-p option when defining formats.
If you need to delete a custom format simply type type format delete followed
by the name of the type to which the format applies.Even if you defined the
same format for multiple types on the same command, type format delete will
only remove the format for the type name passed as argument.
To delete ALL formats, use ``type format clear``. To see all the formats ::
defined, use type format list.
If all you need to do, however, is display one variable in a custom format, (lldb) type format delete int
while leaving the others of the same type untouched, you can simply type:
To delete *all* formats, use ``type format clear``.
To see all the formats defined, use ``type format list``.
Instead of installing a type format for the entire debugging session, you
can specify type formats in an ad hoc manner using the ``-f``
option to the ``frame variable`` command. For example:
:: ::
(lldb) frame variable counter -f hex (lldb) frame variable counter -f hex
This has the effect of displaying the value of counter as an hexadecimal Will display the value of counter as an hexadecimal number.
number, and will keep showing it this way until you either pick a different
format or till you let your program run again.
Finally, this is a list of formatting options available out of which you can
pick: Type Formats
++++++++++++
.. _`format name`: .. _`format name`:
@@ -323,96 +327,153 @@ pick:
| ``void`` | v | don't show anything | | ``void`` | v | don't show anything |
+-----------------------------------------------+------------------+--------------------------------------------------------------------------+ +-----------------------------------------------+------------------+--------------------------------------------------------------------------+
.. _type-summary:
Type Summary Type Summary
------------ ------------
Type formats work by showing a different kind of display for the value of a Type formats specify the way to format a variable/value with a fundamental type.
variable. However, they only work for basic types. When you want to display a When you want to display a variable/value for a user-defined type,\ [#]_ you need
class or struct in a custom format, you cannot do that using formats. another tool, type summaries.
A different feature, type summaries, works by extracting information from Type summaries work by extracting information from aggregate types and arranging it
classes, structures, ... (aggregate types) and arranging it in a user-defined in a user-defined format. Consider the following example:
format, as in the following example:
before adding a summary... Before adding a type summary, for a C++ program with a ``struct`` declared like
.. code-block:: C++
struct Person {
std::string name;
int age;
};
LLDB will format a variable that is an instance of the ``Person`` type as
:: ::
(lldb) frame variable -T one (lldb) frame variable -T p
(i_am_cool) one = { (Person) p = {
(int) x = 3 (std::string) name = "Jaime"
(float) y = 3.14159 (int) age = 44
(char) z = 'E'
} }
after adding a summary... Using a type summary, the LLDB user can specify that an instance of
the ``Person`` type be formatted as
:: ::
(lldb) frame variable one (lldb) frame variable -T p
(i_am_cool) one = int = 3, float = 3.14159, char = 69 (Person) p = The person is named "Jaime" and is 44 years old.
There are two ways to use type summaries: the first one is to bind a summary There are two methods for specifying type summaries:
string to the type; the second is to write a Python script that returns the 1. by binding a Summary String to the type; and
string to be used as summary. Both options are enabled by the type summary add 2. by writing and registering a Python script that returns the Summary String for a type.
command.
The command to obtain the output shown in the example is:
Method (1) was used to format the ``Person`` type shown above:
:: ::
(lldb) type summary add --summary-string "int = ${var.x}, float = ${var.y}, char = ${var.z%u}" i_am_cool (lldb) type summary add --summary-string "The person is named ${var.name} and is ${var.age} years old." Person
Initially, we will focus on summary strings, and then describe the Python
binding mechanism.
Summary Format Matching On Pointers Summary Format Matching On Pointers
----------------------------------- -----------------------------------
A summary formatter for a type ``T`` might or might not be appropriate to use A summary formatter for a type ``T`` may not be appropriate to use
for pointers to that type. If the formatter is only appropriate for the type and for pointers to that type.
not its pointers, use the ``-p`` option to restrict it to match SBValues of type
``T``. If you want the formatter to also match pointers to the type, you can use - If the formatter is only appropriate for the type and
the ``-d`` option to specify how many pointer layers the formatter should match. not its pointers, use the ``-p`` option to ``type summary`` to restrict it to match
The default value is 1, so if you don't specify ``-p`` or ``-d``, your formatter values of type ``T``.
will be used on SBValues of type ``T`` and ``T*``. If you want to also match - If the formatter is appropriate for the type and its pointers,
``T**`` set ``-d`` to 2, etc. In all cases, the SBValue passed to the summary use the ``-d <number>`` option to ``type summary`` to specify the number of
formatter will be the matched ValueObject. lldb doesn't dereference the matched pointer indirections the formatter should match. The default value is 1. If you want
value down to the SBValue of type ``T`` before passing it to your formatter. to also match ``T**`` set ``-d`` to 2, and so on.
In all cases, the value passed to the summary formatter for interpolation
into the Summary String (see :ref:`summary-strings`) will be dereferenced to the type ``T``
if the type ``T`` is reached in at most the number of dereferences you specify
to the ``-d`` option (or once (1), when using the default).
For example, assume that the ``Person`` struct is in the scope of a C++
program with the following declarations:
.. code-block:: C++
Person p{.name = "Jaime", .age = 44};
Person *q{new Person{.name = "Jaime", .age = 44}};
Person **r{&q};
And the following Summary String has been bound to ``Person`` type using the ``type summary``
command shown here:
::
(lldb) type summary add --summary-string "The person is named ${var.name} and is ${var.age} years old." Person
Then LLDB will produce output which, at first, is unexpected:
::
(lldb) frame var p
(Person) The person is named "Jaime" and is 44 years old.
(lldb) frame var q
(Person *) 0x00000000004172b0 The person is named "Jaime" and is 44 years old.
(lldb) frame var r
(Person **) 0x00007fffffffd658 error: summary string parsing error
Upon closer inspection, LLDB is doing exactly as instructed. ``p`` has type ``T``
and needs to be dereferenced 0 times to reach type ``T``. ``q``
has type ``*T`` and needs to be dereferenced 1 time to reach type ``T``. Because
the Summary String was installed with the default ``-d`` value of 1, the summary formatter
will use ``*q`` for interpolation.
However, ``r`` has type ``**T`` and needs to be dereferenced 2 times to reach ``T``. Because
the Summary String was installed with the default ``-d`` value of 1, the summary formatter
will use ``*r`` for interpolation. Because ``*r`` has type ``*T`` (and not ``T``), the error
above is reasonable.
.. _summary-strings:
Summary Strings Summary Strings
--------------- ---------------
A Summary String contains a sequence of tokens that are processed by LLDB to
generate the summary for a user-defined type. Summary Strings are written in
an LLDB-specific control language.\ [#]_
Summary strings are written using a simple control language, exemplified by the Summary Strings can contain
snippet above. A summary string contains a sequence of tokens that are
processed by LLDB to generate the summary.
Summary strings can contain plain text, control characters and special - references to the instance of the user-defined type being formatted by the
variables that have access to information about the current object and the Summary String
overall program state. - plain text,
- control characters, and
- special variables that have access to information about the current object
and the overall program state.
``${var}`` can be used refer to the variable being formatted by the Summary String.
Plain text is any sequence of characters that doesn't contain a ``{``, ``}``, ``$``, Plain text is any sequence of characters that doesn't contain a ``{``, ``}``, ``$``,
or ``\`` character, which are the syntax control characters. or ``\`` character, which are the syntax control characters.
The special variables are found in between a "${" prefix, and end with a "}" Special variables can be used between ``${`` prefix, and ``}`` suffix. For example,
suffix. Variables can be a simple name or they can refer to complex objects ``var`` could be used to refer to the instance of the variable being
that have subitems themselves. In other words, a variable looks like formatted by the Summary String. Children of variables can be accessed using the
``${object}`` or ``${object.child.otherchild}``. A variable can also be variable itself (e.g. ``${var.child.otherchild}`` or ``${file.basename}``). A variable
prefixed or suffixed with other symbols meant to change the way its value is can also be prefixed or suffixed with other symbols to change the way its value is
handled. An example is ``${*var.int_pointer[0-3]}``. handled. For example, ``${*var.int_pointer[0-3]}``.
Basically, the syntax is the same one described Frame and Thread Formatting The simplest thing you can do is access a member variable of a class or structure
plus additional symbols specific for summary strings. The main of them is by typing its expression path. The expression path for a field named ``y`` in a
${var, which is used refer to the variable that a summary is being created for. user-defined type is simply ``.y``. Thus, to ask the Summary String to display
field ``y`` of an instance of ``struct A`` (below) you would type ``${var.y}``.
The simplest thing you can do is grab a member variable of a class or structure If you have code in a C++ program with the following declarations:
by typing its expression path. In the previous example, the expression path for
the field float y is simply .y. Thus, to ask the summary string to display y
you would type ${var.y}.
If you have code like the following: .. code-block:: C++
::
struct A { struct A {
int x; int x;
@@ -424,17 +485,17 @@ If you have code like the following:
int *z; int *z;
}; };
the expression path for the y member of the x member of an object of type B And were writing a Summary String to format an instance of ``B``, the expression
would be .x.y and you would type ``${var.x.y}`` to display it in a summary path for the ``y`` member of the ``x`` member would be ``.x.y`` and you would
string for type B. use ``${var.x.y}`` in the Summary String.
By default, a summary defined for type T, also works for types T* and T& (you By default, a summary defined for type ``T``, also works for types ``T*`` and ``T&``
can disable this behavior if desired). For this reason, expression paths do not (as mentioned above, you can disable this behavior if desired). For this reason,
differentiate between . and ->, and the above expression path .x.y would be expression paths do not differentiate between ``.`` and ``->``, and the above
just as good if you were displaying a B*, or even if the actual definition of B expression path ``.x.y`` would be valid for displaying a value with type ``B*``,
were: ``B`` or even if the actual declaration of ``B`` were instead:
:: .. code-block:: C++
struct B { struct B {
A *x; A *x;
@@ -442,41 +503,39 @@ were:
int *z; int *z;
}; };
This is unlike the behavior of frame variable which, on the contrary, will This behavior differs from ``frame variable`` which does enforce the distinction
enforce the distinction. As hinted above, the rationale for this choice is that between ``T`` and ``T*``. The rationale for this choice is that ignoring this
waiving this distinction enables you to write a summary string once for type T distinction enables you to write a Summary String once for type ``T`` and use
and use it for both T and T* instances. As a summary string is mostly about it for both ``T`` and ``T*`` instances. As a Summary String is mostly about
extracting nested members' information, a pointer to an object is just as good extracting nested members' information, a pointer to an object is just as good
as the object itself for the purpose. as the object itself for that purpose.
If you need to access the value of the integer pointed to by B::z, you cannot If you need to access the value of the integer pointed to by ``B::z``, your
simply say ${var.z} because that symbol refers to the pointer z. In order to Summary String cannot simply use expression path ``.z`` because that symbol
dereference it and get the pointed value, you should say ``${*var.z}``. The refers to the pointer ``z``. To access the value of the integer pointed to by
``${*var`` tells LLDB to get the object that the expression paths leads to, and ``B::z`` in your Summary String, you should use the same expression path but
then dereference it. In this example is it equivalent to ``*(bObject.z)`` in dereference it: ``${*var.z}``. The ``*`` tells LLDB to get the object that
C/C++ syntax. Because ``.`` and ``->`` operators can both be used, there is no the expression path leads to and then dereference it. In this example, it is
need to have dereferences in the middle of an expression path (e.g. you do not equivalent to ``*(bObject.z)`` in C/C++ syntax. Because ``.`` and ``->``
need to type ``${*(var.x).x}``) to read A::x as contained in ``*(B::x)``. To operators can be used interchangeably, there is no need to have dereferences
achieve that effect you can simply write ``${var.x->x}``, or even in the middle of an expression path. For example, you do not need to type
``${var.x.x}``. The ``*`` operator only binds to the result of the whole ``${*(var.x).x}`` to read ``A::x`` as contained in ``*(B::x)``. Instead, you
expression path, rather than piecewise, and there is no way to use parentheses can simply write ``${var.x->x}``, or even ``${var.x.x}``. The ``*`` operator
to change that behavior. only binds to the result of the whole expression path, rather than piecewise,
and there is no way to use parentheses to change that behavior.
Of course, a summary string can contain more than one ${var specifier, and can
use ``${var`` and ``${*var`` specifiers together.
Formatting Summary Elements Formatting Summary Elements
--------------------------- ---------------------------
An expression path can include formatting codes. Much like the type formats An expression path can include formatting codes. Much like the type formats
discussed previously, you can also customize the way variables are displayed in discussed previously, you can also customize the way variables are displayed in
summary strings, regardless of the format they have applied to their types. To Summary Strings, regardless of the format they have applied to their types. To
do that, you can use %format inside an expression path, as in ${var.x->x%u}, do that, you can use %format inside an expression path, as in ${var.x->x%u},
which would display the value of x as an unsigned integer. which would display the value of x as an unsigned integer.
Additionally, custom output can be achieved by using an LLVM format string, Additionally, custom output can be achieved by using an LLVM format string,
commencing with the ``:`` marker. To illustrate, compare ``${var.byte%x}`` and commencing with the ``:`` marker. To illustrate, compare ``${var.byte%x}`` and
``${var.byte:x-}``. The former uses lldb's builtin hex formatting (``x``), ``${var.byte:x-}``. The former uses LLDB's builtin hex formatting (``x``),
which unconditionally inserts a ``0x`` prefix, and also zero pads the value to which unconditionally inserts a ``0x`` prefix, and also zero pads the value to
match the size of the type. The latter uses ``llvm::formatv`` formatting match the size of the type. The latter uses ``llvm::formatv`` formatting
(``:x-``), and will print only the hex value, with no ``0x`` prefix, and no (``:x-``), and will print only the hex value, with no ``0x`` prefix, and no
@@ -509,7 +568,7 @@ themselves, but which carry a special meaning when used in this context:
| ``%>`` | Print the expression path for this item | | ``%>`` | Print the expression path for this item |
+------------+--------------------------------------------------------------------------+ +------------+--------------------------------------------------------------------------+
Since lldb 3.7.0, you can also specify ``${script.var:pythonFuncName}``. Since LLDB 3.7.0, you can also specify ``${script.var:pythonFuncName}``.
It is expected that the function name you use specifies a function whose It is expected that the function name you use specifies a function whose
signature is the same as a Python summary function. The return string from the signature is the same as a Python summary function. The return string from the
@@ -528,7 +587,7 @@ is not valid and will cause the summary to fail to evaluate.
Element Inlining Element Inlining
---------------- ----------------
Option --inline-children (-c) to type summary add 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. Option --inline-children (-c) to type summary add 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.
As an example, given a type pair: As an example, given a type pair:
@@ -591,7 +650,7 @@ hard to read for real-life scenarios.
To cope with the issue, LLDB supports native bitfield formatting in summary To cope with the issue, LLDB supports native bitfield formatting in summary
strings. If your expression paths leads to a so-called scalar type (the usual strings. If your expression paths leads to a so-called scalar type (the usual
int, float, char, double, short, long, long long, double, long double and 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 unsigned variants), you can ask LLDB to only access some bits out of the value
and display them in any format you like. If you only need one bit you can use and display them in any format you like. If you only need one bit you can use
the [n], just like indexing an array. To extract multiple bits, you can use a the [n], just like indexing an array. To extract multiple bits, you can use a
slice-like syntax: [n-m], e.g. slice-like syntax: [n-m], e.g.
@@ -613,8 +672,11 @@ extracting bitfields out of a float object.
When typing a range, the extremes n and m are always included, and the order of When typing a range, the extremes n and m are always included, and the order of
the indices is irrelevant. the indices is irrelevant.
LLDB also allows to use a similar syntax 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 tell LLDB to format arrays in special ways, possibly independent of the way the array members' datatype is formatted. LLDB also allows to use a similar syntax to display array members inside a Summary String.
e.g. 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 tell LLDB to format arrays in special ways,
possibly independent of the way the array members' datatype is formatted. For example:
:: ::
@@ -642,7 +704,10 @@ e.g.
(lldb) frame variable sarray (lldb) frame variable sarray
(Simple [3]) sarray = [1,4,7] (Simple [3]) sarray = [1,4,7]
The [] symbol amounts to: if var is an array and I know its size, apply this summary string to every element of the array. Here, we are asking LLDB to display .x 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: The [] symbol amounts to: if ``var`` is an array and I know its size, apply this Summary String
to every element of the array. Here, we are asking LLDB to display ``.x`` 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:
:: ::
@@ -683,7 +748,7 @@ square brackets, as in:
This syntax works for char* as well as for char[] because LLDB can rely on the This syntax works for char* as well as for char[] because LLDB can rely on the
final \0 terminator to know when the string has ended. final \0 terminator to know when the string has ended.
LLDB has default summary strings for char* and char[] that use this special LLDB has default Summary Strings for char* and char[] that use this special
case. On debugger startup, the following are defined automatically: case. On debugger startup, the following are defined automatically:
:: ::
@@ -708,15 +773,15 @@ the square brackets operator to get the expected output.
Python Scripting Python Scripting
---------------- ----------------
Most of the times, summary strings prove good enough for the job of summarizing Most of the times, Summary Strings prove good enough for the job of summarizing
the contents of a variable. However, as soon as you need to do more than the contents of a variable. However, as soon as you need to do more than
picking some values and rearranging them for display, summary strings stop picking some values and rearranging them for display, Summary Strings stop
being an effective tool. This is because summary strings lack the power to being an effective tool. This is because Summary Strings lack the power to
actually perform any kind of computation on the value of variables. actually perform any kind of computation on the value of variables.
To solve this issue, you can bind some Python scripting code as a summary for To solve this issue, you can bind some Python scripting code as a summary for
your datatype, and that script has the ability to both extract children your datatype, and that script has the ability to both extract child
variables as the summary strings do and to perform active computation on the variables as the Summary Strings do, and to perform active computation on the
extracted values. As a small example, let's say we have a Rectangle class: extracted values. As a small example, let's say we have a Rectangle class:
:: ::
@@ -735,7 +800,7 @@ extracted values. As a small example, let's say we have a Rectangle class:
int GetWidth() { return width; } int GetWidth() { return width; }
}; };
Summary strings are effective to reduce the screen real estate used by the Summary Strings are effective to reduce the screen real estate used by the
default viewing mode, but are not effective if we want to display the area and default viewing mode, but are not effective if we want to display the area and
perimeter of Rectangle objects perimeter of Rectangle objects
@@ -784,8 +849,8 @@ retrieve an `SBData` object by calling ``GetData()`` and then read the object's
contents out of the `SBData`. contents out of the `SBData`.
If you need to delve into several levels of hierarchy, as you can do with If you need to delve into several levels of hierarchy, as you can do with
summary strings, you can use the method ``GetValueForExpressionPath()``, Summary Strings, you can use the method ``GetValueForExpressionPath()``,
passing it an expression path just like those you could use for summary strings passing it an expression path just like those you could use for Summary Strings
(one of the differences is that dereferencing a pointer does not occur by (one of the differences is that dereferencing a pointer does not occur by
prefixing the path with a ``*```, but by calling the ``Dereference()`` method prefixing the path with a ``*```, but by calling the ``Dereference()`` method
on the returned `SBValue`). If you need to access array slices, you cannot do on the returned `SBValue`). If you need to access array slices, you cannot do
@@ -820,7 +885,7 @@ you to input a Python script as a summary:
Regular Expression Typenames Regular Expression Typenames
---------------------------- ----------------------------
As you noticed, in order to associate the custom summary string to the array 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 types, one must give the array size as part of the typename. This can long
become tiresome when using arrays of different sizes, Simple [3], Simple [9], become tiresome when using arrays of different sizes, Simple [3], Simple [9],
Simple [12], ... Simple [12], ...
@@ -859,7 +924,7 @@ Names Summaries
For a given type, there may be different meaningful summary representations. For a given type, there may be different meaningful summary representations.
However, currently, only one summary can be associated to a type at each However, currently, only one summary can be associated to a type at each
moment. If you need to temporarily override the association for a variable, moment. If you need to temporarily override the association for a variable,
without changing the summary string for to its type, you can use named without changing the Summary String for to its type, you can use named
summaries. summaries.
Named summaries work by attaching a name to a summary when creating it. Then, Named summaries work by attaching a name to a summary when creating it. Then,
@@ -877,7 +942,7 @@ given instead of the default one.
When defining a named summary, binding it to one or more types becomes When defining a named summary, binding it to one or more types becomes
optional. Even if you bind the named summary to a type, and later change the optional. Even if you bind the named summary to a type, and later change the
summary string for that type, the named summary will not be changed by that. Summary String for that type, the named summary will not be changed by that.
You can delete named summaries by using the type summary delete command, as if You can delete named summaries by using the type summary delete command, as if
the summary name was the datatype that the summary is applied to the summary name was the datatype that the summary is applied to
@@ -885,6 +950,8 @@ A summary attached to a variable using the --summary option, has the same
semantics that a custom format attached using the -f option has: it stays semantics that a custom format attached using the -f option has: it stays
attached till you attach a new one, or till you let your program run again. attached till you attach a new one, or till you let your program run again.
.. _synthetic-children:
Synthetic Children Synthetic Children
------------------ ------------------
@@ -994,15 +1061,15 @@ Being more specific, in case of exceptions, LLDB might assume that the given
object has no children or it might skip printing some children, as they are object has no children or it might skip printing some children, as they are
printed one by one. printed one by one.
[1] The ``max_children`` argument is optional (since lldb 3.8.0) and indicates the [1] The ``max_children`` argument is optional (since LLDB 3.8.0) and indicates the
maximum number of children that lldb is interested in (at this moment). If the maximum number of children that LLDB is interested in (at this moment). If the
computation of the number of children is expensive (for example, requires computation of the number of children is expensive (for example, requires
traversing a linked list to determine its size) your implementation may return traversing a linked list to determine its size) your implementation may return
``max_children`` rather than the actual number. If the computation is cheap (e.g., the ``max_children`` rather than the actual number. If the computation is cheap (e.g., the
number is stored as a field of the object), then you can always return the true number is stored as a field of the object), then you can always return the true
number of children (that is, ignore the ``max_children`` argument). number of children (that is, ignore the ``max_children`` argument).
[2] This method is optional. Also, a boolean value must be returned (since lldb [2] This method is optional. Also, a boolean value must be returned (since LLDB
3.1.0). If ``False`` is returned, then whenever the process reaches a new stop, 3.1.0). If ``False`` is returned, then whenever the process reaches a new stop,
this method will be invoked again to generate an updated list of the children this method will be invoked again to generate an updated list of the children
for a given variable. Otherwise, if ``True`` is returned, then the value is for a given variable. Otherwise, if ``True`` is returned, then the value is
@@ -1010,11 +1077,11 @@ cached and this method won't be called again, effectively freezing the state of
the value in subsequent stops. Beware that returning ``True`` incorrectly could the value in subsequent stops. Beware that returning ``True`` incorrectly could
show misleading information to the user. show misleading information to the user.
[3] This method is optional (since lldb 3.2.0). While implementing it in terms [3] This method is optional (since LLDB 3.2.0). While implementing it in terms
of num_children is acceptable, implementors are encouraged to look for of num_children is acceptable, implementors are encouraged to look for
optimized coding alternatives whenever reasonable. optimized coding alternatives whenever reasonable.
[4] This method is optional (since lldb 3.5.2). The `SBValue` you return here [4] This method is optional (since LLDB 3.5.2). The `SBValue` you return here
will most likely be a numeric type (int, float, ...) as its value bytes will be will most likely be a numeric type (int, float, ...) as its value bytes will be
used as-if they were the value of the root `SBValue` proper. As a shortcut for used as-if they were the value of the root `SBValue` proper. As a shortcut for
this, you can inherit from lldb.SBSyntheticValueProvider, and just define this, you can inherit from lldb.SBSyntheticValueProvider, and just define
@@ -1083,7 +1150,7 @@ LLDB has synthetic children providers for a core subset of STL classes, both in
the version provided by libstdcpp and by libcxx, as well as for several the version provided by libstdcpp and by libcxx, as well as for several
Foundation classes. Foundation classes.
Synthetic children extend summary strings by enabling a new special variable: Synthetic children extend Summary Strings by enabling a new special variable:
``${svar``. ``${svar``.
This symbol tells LLDB to refer expression paths to the synthetic children This symbol tells LLDB to refer expression paths to the synthetic children
@@ -1101,8 +1168,8 @@ instead of the real ones. For instance,
} }
It's important to mention that LLDB invokes the synthetic child provider before It's important to mention that LLDB invokes the synthetic child provider before
invoking the summary string provider, which allows the latter to have access to invoking the Summary String provider, which allows the latter to have access to
the actual displayable children. This applies to both inlined summary strings the actual displayable children. This applies to both inlined Summary Strings
and python-based summary providers. and python-based summary providers.
@@ -1115,7 +1182,7 @@ won't show ``__begin`` as child anymore, even through the SB API. It will have
instead the children calculated by the provider. In case the actual raw instead the children calculated by the provider. In case the actual raw
children are needed, a call to ``value.GetNonSyntheticValue()`` is enough to children are needed, a call to ``value.GetNonSyntheticValue()`` is enough to
get a raw version of the value. It is import to remember this when implementing get a raw version of the value. It is import to remember this when implementing
summary string providers, as they run after the synthetic child provider. Summary String providers, as they run after the synthetic child provider.
In some cases, if LLDB is unable to use the real object to get a child In some cases, if LLDB is unable to use the real object to get a child
@@ -1319,7 +1386,7 @@ not-empty category.
Finding Formatters 101 Finding Formatters 101
---------------------- ----------------------
Searching for a formatter (including formats, since lldb 3.4.0) given a Searching for a formatter (including formats, since LLDB 3.4.0) given a
variable goes through a rather intricate set of rules. Namely, what happens is variable goes through a rather intricate set of rules. Namely, what happens is
that LLDB starts looking in each enabled category, according to the order in that LLDB starts looking in each enabled category, according to the order in
which they were enabled (latest enabled first). In each category, LLDB does the which they were enabled (latest enabled first). In each category, LLDB does the
@@ -1354,3 +1421,9 @@ through typedef chains, but also through inheritance chains. This feature has
been removed since it significantly degrades performance. You need to set up been removed since it significantly degrades performance. You need to set up
your formatters for every type in inheritance chains to which you want the your formatters for every type in inheritance chains to which you want the
formatter to apply. formatter to apply.
.. [#] These types of variables go by different names depending on the language. In C++, in
particular, they are known as compound types.
.. [#] If you are familiar with the syntax for Frame and Thread Formatting
you will feel right at home with the syntax for Summary Strings.