www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - lldb python script to print strings

(crossposted to debugger; please reply in ldc)

Having struggled with this a bit myself, I wanted to share the following 
python script for lldb to format and print dlang native string variables 
in a debugging session.

LIMITATIONS: This works for me on lldb-8 on Ubuntu18.04; does NOT work 
on my Mac though admittedly lldb is somewhat broken due to conflict with 
Homebrew-installed python version.

The python script will need further modification before it will work 
with wstring and dstring.

BACKGROUND: lldb does not recognize dlang char/wchar/dchar; this can be 
seen in lldb messages like:
error: need to add support for DW_TAG_base_type 'immutable(char)'
encoded with DW_ATE = 0x10, bit_size = 8
error: need to add support for DW_TAG_base_type 'char' encoded with 
DW_ATE = 0x10, bit_size = 8
error: need to add support for DW_TAG_base_type 'dchar' encoded with 
DW_ATE = 0x10, bit_size = 32

Pointers to these data are typed as void, and thus not displayed. 
Additionally, because D strings are not \0 terminated, lldb's built in 
string formatting (frame var stringvar.ptr -f s) will print trailing 
garbage.

(Now that C++20 has char16_t and char32_t this should be easy to hotfix 
in 
https://github.com/llvm-mirror/lldb/blob/af72c1627f754a1e75ae5a24fe33820c79b5a715/source/Symbol/ClangASTCon
ext.cpp#L1364-L1369 
until a true D plugin for lldb can be created.)

Script:
import lldb

def string(valobj,internal_dict):
     """valobj: an SBValue which you want to provide a summary for
     internal_dict: an LLDB support object not to be used"""

     lenobj = valobj.GetChildMemberWithName("length")
     strlen = lenobj.GetValueAsUnsigned(0)

     ptrobj = valobj.GetChildMemberWithName("ptr")


     charptrtype = 
ptrobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType()
     charptr = ptrobj.Cast(charptrtype)
     data = charptr.GetPointeeData(0, strlen)

     error = lldb.SBError()
     return data.GetString(error, 0)
EOF


Session:
(lldb) frame v infile
(string) infile = (length = 18, ptr = 0x00007fffffffe1ce)
(lldb) frame v infile.ptr
(void *) infile.ptr = 0x00007fffffffe1ce

  ^^^^ note that ptr is typed as void* because lldb does not recognize 
immutable(char)*

(lldb) command script import ~/dlang.py
(lldb) type summary add -F dlang.string string

(lldb) frame v infile
(string) infile = resources/hg19.bed

Commands can be placed in ~/.lldbinit file
May 29 2019