Skip to content

Xcode and Android lldb don't find correct formatter if type is in C++ struct/class #155691

@alecazam

Description

@alecazam

I'm using Xcode 16.3/.4 with lldb-1700. And also Android studio with clang-19.0. The second one worked which basically does a "p text.c_str()", but not that only works if the type is local, and not if it's in a class/struct. The debugger and variable views of structs display (None). Only a local string or ref of the struct value prints using the formatter. This used to work.

I have no idea why lldb makes it so hard to write and debug formatters. But the sample string formatter was way too complex and crashed all the time. This is also Xcode/macOS specific. With Xcode moving all these formatters to C++, there are no samples of how to do formatters. So consider adding .natvis support, since it's already provided for many libraries. It's not as expressive, but it just works.

Example formatter for std::string
https://code.ornl.gov/llvm-doe/llvm-project/-/blob/d6e65a66095cc3c93ea78669bc41d0885780e8ea/lldb/examples/synthetic/libcxx.py

Example natvis file
https://github.com/electronicarts/EASTL/blob/master/doc/EASTL.natvis

def CustomStringSummary(valobj, internal_dict):
    frame = valobj.GetFrame()
    name = valobj.GetName()

    # equivalent of expr var.c_str()
    # GetSummary() returns the string, GetValue() returns raw ptr address
    summary = frame.EvaluateExpression('{0}.c_str()'.format(name)).GetSummary()

    return summary

def __lldb_init_module(debugger, internal_dict):
     namespaceStr = os.path.splitext(os.path.basename(__file__))[0]

    debugger.HandleCommand("type summary add CustomString -F %s.CustomStringSummary" % namespaceStr)
struct TestString
{
	std::string text;
};
struct TestCustomString
{
	CustomString text;  // This is our custom std::string with a custom allocator
};

void TestStringFormatter()
{
	static TestString str1;
	static TestCustomString str2;
	static CustomString str3; 
	
        // can set a breakpoint here
	fprintf( stdout, "%s %s %s", str1.text.c_str(), str2.text.c_str(), str3.c_str() );
}

This is what lldb produces at the breakpiont of the fprintf. This is from Android Studio lldb, but Xcode displays the same output.

(lldb) p str1
(TestString)  (text = "")

(lldb) p str2
(TestCustomString)  (text = None) <- this is wrong

(lldb) p str2.text
(CustomString) ""

(lldb) p str3
(CustomString) ""

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions