Consider this program.cpp
:
struct Foo {
int field1;
int field2;
};
int main() {
Foo foo{.field1 = -1, .field2 = -2};
return 0;
}
I've implemented a custom LLDB data formatter for the Foo
type:
class Foo:
def __init__(self, valobj, internal_dict):
self.valobj = valobj
def num_children(self):
return 2
def get_child_index(self, name):
match name:
case "bar":
return 0
case "[baz]":
return 1
def get_child_at_index(self, idx):
match idx:
case 0:
return self.bar
case 1:
return self.baz
def update(self):
self.bar = self.valobj.GetChildMemberWithName("field1").Clone("bar")
self.baz = self.valobj.GetChildMemberWithName("field2").Clone("[baz]")
def has_children(self):
return True
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("type synthetic add Foo -l example.Foo")
As you can see, one of these children is named bar
which has no special characters, and the other is named [baz]
which does have special characters.
I can access bar
just fine:
$ clang++ -g program.cpp -o program && lldb ./program
(lldb) command script import example.py
(lldb) b program.cpp:8
(lldb) run
(lldb) v
(Foo) foo = (bar = -1, [baz] = -2)
(lldb) v foo.bar
(int) foo.bar = -1
But I can't figure out how to access [baz]
. Here's what I've tried:
(lldb) v foo.[baz]
error: incomplete expression path after "foo" in "foo.[baz]"
(lldb) v foo.'[baz]'
error: incomplete expression path after "foo" in "foo.[baz]"
(lldb) v foo."[baz]"
error: incomplete expression path after "foo" in "foo.[baz]"
(lldb) v foo.\[baz\]
error: "\" is not a member of "(Foo) foo"
Using LLDB, how can I access a synthetic child whose name contains special characters?
Addendum regarding pointers: a hacky workaround is to just refer to the children by their indices of their names:
(lldb) v foo[0]
(int) foo[0] = -1
(lldb) v foo[1]
(int) foo[1] = -2
But then I don't know what to do if foo
is a pointer:
struct Foo {
int field1;
int field2;
};
int main() {
Foo *foo = new Foo{.field1 = -1, .field2 = -2};
return 0;
}
(lldb) v foo->bar
(int) foo->bar = -1
(lldb) foo->[1]
error: 'foo-' is not a valid command.
(lldb) v foo->[1]
error: incomplete expression path after "foo" in "foo->[1]"
(lldb) v (*foo)[1]
error: no variable named '(*foo)' found in this frame
(lldb) v *foo[1]
error: not a pointer or reference type: (Foo) *(foo)
It's not the most convenient, but you can always use Python:
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>> lldb.frame.FindVariable("foo").GetChildMemberWithName("bar")
(int) bar = -1
>>> lldb.frame.FindVariable("foo").GetChildMemberWithName("[baz]")
(int) [baz] = -2
>>> ^D
now exiting InteractiveConsole...
(lldb)