[lldb-dev] Structure variable names

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Tue Jun 7 10:36:05 PDT 2016


> On Jun 7, 2016, at 9:56 AM, Jiten Thakkar via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> Hi All,
> I am working on a project as part of my graduate study which uses LLVM.
> I am new to LLVM and lldb to be particular.
> My goal is to get names of the parameters to functions. If the parameter is a variable in a structure, it is represented as an offset in the structure.

This is possible. First you will want to get a lldb::SBFunction that represents the function whose parameters you want. If you use the current frame, you can get this info quickly in python:

% lldb a.out
(lldb) b main
(lldb) r

... run and hit breakpoint

(lldb) script
>>> func = lldb.frame.GetFunction()
>>> print func
SBFunction: id = 0x0000002e, name = main, type = main

Now we can ask the function for its top lexical block and ask that block to fetch a list of SBValue objects that represent the parameters only (no locals, or statics):

>>> get_parameters = True
>>> get_locals = False
>>> get_statics = False
>>> parameters = func.GetBlock().GetVariables(lldb.frame, get_parameters, get_locals, get_statics, lldb.eDynamicDontRunTarget)
>>> print parameters
(int) argc = 1
(const char **) argv = 0x00007fff5fbff8f8
(const char **) envp = 0x00007fff5fbff908
(const char **) aapl = 0x00007fff5fbffa30


"parameters" is a SBValueList so you can iterate through it by index:

>>> num_params = params.GetSize()
>>> print num_params
4
>>> for i in range(num_params):
...   param = params.GetValueAtIndex(i)
...   print param
... 
(int) argc = 1
(const char **) argv = 0x00007fff5fbff8f8
(const char **) envp = 0x00007fff5fbff908
(const char **) aapl = 0x00007fff5fbffa30

Now you want to explore the types of each parameter:

>>> for i in range(num_params):
...   param = params.GetValueAtIndex(i)
...   param_type = param.GetType()
...   print param_type
... 

You now "param_type" that has a SBType object that represents the type of each parameter. You can ask it:

>>> print param_type.GetTypeClass()

This will return an enum that is one of:

eTypeClassInvalid           
eTypeClassArray             
eTypeClassBlockPointer      
eTypeClassBuiltin           
eTypeClassClass             
eTypeClassComplexFloat      
eTypeClassComplexInteger    
eTypeClassEnumeration       
eTypeClassFunction          
eTypeClassMemberPointer     
eTypeClassObjCObject        
eTypeClassObjCInterface     
eTypeClassObjCObjectPointer 
eTypeClassPointer           
eTypeClassReference         
eTypeClassStruct            
eTypeClassTypedef           
eTypeClassUnion             
eTypeClassVector            


If this value is eTypeClassClass, eTypeClassStruct or eTypeClassUnion, you can access the fields:

type_class = param_type.GetTypeClass()
if type_class == lldb.eTypeClassClass or type_class == lldb.eTypeClassStruct or type_class == lldb.eTypeClassUnion:
    num_fields = param_type.GetNumberOfFields()
    for field_idx in range(num_fields):
        member = param_type.GetFieldAtIndex(field_idx)

This class is a SBTypeMember which can tell you the info you want:

class SBTypeMember
{
public:
    SBTypeMember ();
    
    SBTypeMember (const lldb::SBTypeMember& rhs);
    
    ~SBTypeMember();

    lldb::SBTypeMember&
    operator = (const lldb::SBTypeMember& rhs);

    bool
    IsValid() const;
    
    const char *
    GetName ();
    
    lldb::SBType
    GetType ();
    
    uint64_t
    GetOffsetInBytes();
    
    uint64_t
    GetOffsetInBits();

    bool
    IsBitfield();
    
    uint32_t
    GetBitfieldSizeInBits();

    bool
    GetDescription (lldb::SBStream &description, 
                    lldb::DescriptionLevel description_level);
}




> I want to get the names of all those parameters. I assume that debug info should provide this but so far I am unable to find any documentation regarding which would describe how to do it. 
> Is there a way to do this using debug info? Is this even possible?
> Please let me know if any of this is confusing and I will try to describe it in detail.

This should get you started. There is also an example that checks for padding within types:

svn cat http://llvm.org/svn/llvm-project/lldb/trunk/examples/python/types.py

This checks for padding within a type to show you gaps in your classes and structs.

All of the example above are in python, but this same API is available in C++ if you need it. We have docs covering our APIs here:

Python:

http://lldb.llvm.org/python_reference/index.html

C++:

http://lldb.llvm.org/cpp_reference/html/index.html


You will be interested in SBFunction, SBType and SBTypeMember.

Let me know if you have any questions,

Greg Clayton




More information about the lldb-dev mailing list