[Lldb-commits] [lldb] r236817 - This patch allows LLDB to use the $qXfer:Libraries: packet.

Tamas Berghammer tberghammer at google.com
Fri May 8 04:12:45 PDT 2015


I committed in a fix for the issue as http://reviews.llvm.org/rL236826.
Please take a look and let me know if it causing some issue for you.

Tamas

On Fri, May 8, 2015 at 11:42 AM, Tamas Berghammer <tberghammer at google.com>
wrote:

> Hi Aidan,
>
> This patch caused a regression on android-arm (remote debugging) with
> breaking the code for setting a breakpoint. I haven't found out the exact
> reason for the problem but it looks like as the location of the breakpoints
> isn't deduced correctly because of a wrong load address for the executable
> (android use position independent code what might effect this issue).
> Please take a look into it.
>
> Thanks,
> Tamas
>
> On Fri, May 8, 2015 at 10:36 AM, Aidan Dodds <aidan at codeplay.com> wrote:
>
>> Author: aidandodds
>> Date: Fri May  8 04:36:31 2015
>> New Revision: 236817
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=236817&view=rev
>> Log:
>> This patch allows LLDB to use the $qXfer:Libraries: packet.
>>
>> Differential Revision: http://reviews.llvm.org/D9471
>>
>> Modified:
>>     lldb/trunk/include/lldb/Target/Process.h
>>
>> lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
>>     lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
>>     lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
>>     lldb/trunk/source/Target/Target.cpp
>>
>> Modified: lldb/trunk/include/lldb/Target/Process.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=236817&r1=236816&r2=236817&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/include/lldb/Target/Process.h (original)
>> +++ lldb/trunk/include/lldb/Target/Process.h Fri May  8 04:36:31 2015
>> @@ -1121,6 +1121,22 @@ public:
>>      virtual const lldb::DataBufferSP
>>      GetAuxvData();
>>
>> +    //------------------------------------------------------------------
>> +    /// Sometimes processes know how to retrieve and load shared
>> libraries.
>> +    /// This is normally done by DynamicLoader plug-ins, but sometimes
>> the
>> +    /// connection to the process allows retrieving this information. The
>> +    /// dynamic loader plug-ins can use this function if they can't
>> +    /// determine the current shared library load state.
>> +    ///
>> +    /// @return
>> +    ///    The number of shared libraries that were loaded
>> +    //------------------------------------------------------------------
>> +    virtual size_t
>> +    LoadModules ()
>> +    {
>> +        return 0;
>> +    }
>> +
>>  protected:
>>      virtual JITLoaderList &
>>      GetJITLoaders ();
>>
>> Modified:
>> lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=236817&r1=236816&r2=236817&view=diff
>>
>> ==============================================================================
>> ---
>> lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
>> (original)
>> +++
>> lldb/trunk/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
>> Fri May  8 04:36:31 2015
>> @@ -120,15 +120,45 @@ DynamicLoaderPOSIXDYLD::DidAttach()
>>      if (log)
>>          log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 "
>> reloaded auxv data", __FUNCTION__, m_process ? m_process->GetID () :
>> LLDB_INVALID_PROCESS_ID);
>>
>> -    ModuleSP executable_sp = GetTargetExecutable();
>> -    ResolveExecutableModule(executable_sp);
>> +    // ask the process if it can load any of its own modules
>> +    m_process->LoadModules ();
>>
>> -    addr_t load_offset = ComputeLoadOffset();
>> +    ModuleSP executable_sp = GetTargetExecutable ();
>> +    ResolveExecutableModule (executable_sp);
>> +
>> +    // find the main process load offset
>> +    addr_t load_offset = ComputeLoadOffset ();
>>      if (log)
>>          log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 "
>> executable '%s', load_offset 0x%" PRIx64, __FUNCTION__, m_process ?
>> m_process->GetID () : LLDB_INVALID_PROCESS_ID, executable_sp ?
>> executable_sp->GetFileSpec().GetPath().c_str () : "<null executable>",
>> load_offset);
>>
>> +    // if we dont have a load address we cant re-base
>> +    bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false :
>> true;
>>
>> -    if (executable_sp && load_offset != LLDB_INVALID_ADDRESS)
>> +    // if we have a valid executable
>> +    if (executable_sp.get())
>> +    {
>> +        lldb_private::ObjectFile * obj = executable_sp->GetObjectFile();
>> +        if (obj)
>> +        {
>> +            // don't rebase if the module is not an executable
>> +            if (obj->GetType() != ObjectFile::Type::eTypeExecutable)
>> +                rebase_exec = false;
>> +
>> +            // don't rebase if the module already has a load address
>> +            Target & target = m_process->GetTarget ();
>> +            Address addr = obj->GetImageInfoAddress (&target);
>> +            if (addr.GetLoadAddress (&target) != LLDB_INVALID_ADDRESS)
>> +                rebase_exec = false;
>> +        }
>> +    }
>> +    else
>> +    {
>> +        // no executable, nothing to re-base
>> +        rebase_exec = false;
>> +    }
>> +
>> +    // if the target executable should be re-based
>> +    if (rebase_exec)
>>      {
>>          ModuleList module_list;
>>
>> @@ -537,6 +567,9 @@ DynamicLoaderPOSIXDYLD::ComputeLoadOffse
>>      if (!exe)
>>          return LLDB_INVALID_ADDRESS;
>>
>> +    if (exe->GetType() != ObjectFile::Type::eTypeExecutable)
>> +        return LLDB_INVALID_ADDRESS;
>> +
>>      Address file_entry = exe->GetEntryPointAddress();
>>
>>      if (!file_entry.IsValid())
>>
>> Modified:
>> lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=236817&r1=236816&r2=236817&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
>> (original)
>> +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri
>> May  8 04:36:31 2015
>> @@ -174,6 +174,107 @@ namespace {
>>
>>  } // anonymous namespace end
>>
>> +class ProcessGDBRemote::GDBLoadedModuleInfoList
>> +{
>> +public:
>> +
>> +    class LoadedModuleInfo
>> +    {
>> +    public:
>> +
>> +        enum e_data_point
>> +        {
>> +            e_has_name      = 0,
>> +            e_has_base      ,
>> +            e_has_dynamic   ,
>> +            e_has_link_map  ,
>> +            e_num
>> +        };
>> +
>> +        LoadedModuleInfo ()
>> +        {
>> +            for (uint32_t i = 0; i < e_num; ++i)
>> +                m_has[i] = false;
>> +        };
>> +
>> +        void set_name (const std::string & name)
>> +        {
>> +            m_name = name;
>> +            m_has[e_has_name] = true;
>> +        }
>> +        bool get_name (std::string & out) const
>> +        {
>> +            out = m_name;
>> +            return m_has[e_has_name];
>> +        }
>> +
>> +        void set_base (const lldb::addr_t base)
>> +        {
>> +            m_base = base;
>> +            m_has[e_has_base] = true;
>> +        }
>> +        bool get_base (lldb::addr_t & out) const
>> +        {
>> +            out = m_base;
>> +            return m_has[e_has_base];
>> +        }
>> +
>> +        void set_link_map (const lldb::addr_t addr)
>> +        {
>> +            m_link_map = addr;
>> +            m_has[e_has_link_map] = true;
>> +        }
>> +        bool get_link_map (lldb::addr_t & out) const
>> +        {
>> +            out = m_link_map;
>> +            return m_has[e_has_link_map];
>> +        }
>> +
>> +        void set_dynamic (const lldb::addr_t addr)
>> +        {
>> +            m_dynamic = addr;
>> +            m_has[e_has_dynamic] = true;
>> +        }
>> +        bool get_dynamic (lldb::addr_t & out) const
>> +        {
>> +            out = m_dynamic;
>> +            return m_has[e_has_dynamic];
>> +        }
>> +
>> +        bool has_info (e_data_point datum)
>> +        {
>> +            assert (datum < e_num);
>> +            return m_has[datum];
>> +        }
>> +
>> +    protected:
>> +
>> +        bool m_has[e_num];
>> +        std::string m_name;
>> +        lldb::addr_t m_link_map;
>> +        lldb::addr_t m_base;
>> +        lldb::addr_t m_dynamic;
>> +    };
>> +
>> +    GDBLoadedModuleInfoList ()
>> +        : m_list ()
>> +        , m_link_map (LLDB_INVALID_ADDRESS)
>> +    {}
>> +
>> +    void add (const LoadedModuleInfo & mod)
>> +    {
>> +        m_list.push_back (mod);
>> +    }
>> +
>> +    void clear ()
>> +    {
>> +        m_list.clear ();
>> +    }
>> +
>> +    std::vector<LoadedModuleInfo> m_list;
>> +    lldb::addr_t m_link_map;
>> +};
>> +
>>  // TODO Randomly assigning a port is unsafe.  We should get an unused
>>  // ephemeral port from the kernel and make sure we reserve it before
>> passing
>>  // it to debugserver.
>> @@ -575,7 +676,7 @@ ProcessGDBRemote::BuildDynamicRegisterIn
>>      if (reg_num == 0)
>>      {
>>          // try to extract information from servers target.xml
>> -        if ( GetGDBServerInfo( ) )
>> +        if (GetGDBServerRegisterInfo ())
>>              return;
>>
>>          FileSpec target_definition_fspec =
>> GetGlobalPluginProperties()->GetTargetDefinitionFile ();
>> @@ -2281,7 +2382,18 @@ ProcessGDBRemote::IsAlive ()
>>  addr_t
>>  ProcessGDBRemote::GetImageInfoAddress()
>>  {
>> -    return m_gdb_comm.GetShlibInfoAddr();
>> +    // request the link map address via the $qShlibInfoAddr packet
>> +    lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();
>> +
>> +    // the loaded module list can also provides a link map address
>> +    if (addr == LLDB_INVALID_ADDRESS)
>> +    {
>> +        GDBLoadedModuleInfoList list;
>> +        if (GetLoadedModuleList (list).Success())
>> +            addr = list.m_link_map;
>> +    }
>> +
>> +    return addr;
>>  }
>>
>>  //------------------------------------------------------------------
>> @@ -3855,7 +3967,7 @@ libxml2NullErrorFunc (void *ctx, const c
>>  // return:  'true'  on success
>>  //          'false' on failure
>>  bool
>> -ProcessGDBRemote::GetGDBServerInfo ()
>> +ProcessGDBRemote::GetGDBServerRegisterInfo ()
>>  {
>>
>>      // redirect libxml2's error handler since the default prints to
>> stdout
>> @@ -3928,12 +4040,140 @@ ProcessGDBRemote::GetGDBServerInfo ()
>>      return true;
>>  }
>>
>> +Error
>> +ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list)
>> +{
>> +    Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS);
>> +    if (log)
>> +        log->Printf ("ProcessGDBRemote::%s", __FUNCTION__);
>> +
>> +    // redirect libxml2's error handler since the default prints to
>> stdout
>> +    xmlGenericErrorFunc func = libxml2NullErrorFunc;
>> +    initGenericErrorDefaultFunc (&func);
>> +
>> +    GDBRemoteCommunicationClient & comm = m_gdb_comm;
>> +    GDBRemoteDynamicRegisterInfo & regInfo = m_register_info;
>> +
>> +    // check that we have extended feature read support
>> +    if (!comm.GetQXferLibrariesSVR4ReadSupported ())
>> +        return Error (0, ErrorType::eErrorTypeGeneric);
>> +
>> +    list.clear ();
>> +
>> +    // request the loaded library list
>> +    std::string raw;
>> +    lldb_private::Error lldberr;
>> +    if (!comm.ReadExtFeature (ConstString ("libraries-svr4"),
>> ConstString (""), raw, lldberr))
>> +        return Error (0, ErrorType::eErrorTypeGeneric);
>> +
>> +    // parse the xml file in memory
>> +    if (log)
>> +        log->Printf ("parsing: %s", raw.c_str());
>> +    xmlDocPtr doc = xmlReadMemory (raw.c_str(), raw.size(),
>> "noname.xml", nullptr, 0);
>> +    if (doc == nullptr)
>> +        return Error (0, ErrorType::eErrorTypeGeneric);
>> +
>> +    xmlNodePtr elm = xmlExFindElement (doc->children,
>> {"library-list-svr4"});
>> +    if (!elm)
>> +        return Error();
>> +
>> +    // main link map structure
>> +    xmlAttr * attr = xmlExFindAttribute (elm, "main-lm");
>> +    if (attr)
>> +    {
>> +        std::string val = xmlExGetTextContent (attr);
>> +        if (val.length() > 2)
>> +        {
>> +            uint32_t process_lm = std::stoul (val.c_str()+2, 0, 16);
>> +            list.m_link_map = process_lm;
>> +        }
>> +    }
>> +
>> +    // parse individual library entries
>> +    for (xmlNode * child = elm->children; child; child=child->next)
>> +    {
>> +        if (!child->name)
>> +            continue;
>> +
>> +        if (strcmp ((char*)child->name, "library") != 0)
>> +            continue;
>> +
>> +        GDBLoadedModuleInfoList::LoadedModuleInfo module;
>> +
>> +        for (xmlAttrPtr prop = child->properties; prop; prop=prop->next)
>> +        {
>> +            if (strcmp ((char*)prop->name, "name") == 0)
>> +                module.set_name (xmlExGetTextContent (prop));
>> +
>> +            // the address of the link_map struct.
>> +            if (strcmp ((char*)prop->name, "lm") == 0)
>> +            {
>> +                std::string val = xmlExGetTextContent (prop);
>> +                if (val.length() > 2)
>> +                {
>> +                    uint32_t module_lm = std::stoul (val.c_str()+2, 0,
>> 16);
>> +                    module.set_link_map (module_lm);
>> +                }
>> +            }
>> +
>> +            // the displacement as read from the field 'l_addr' of the
>> link_map struct.
>> +            if (strcmp ((char*)prop->name, "l_addr") == 0)
>> +            {
>> +                std::string val = xmlExGetTextContent (prop);
>> +                if (val.length() > 2)
>> +                {
>> +                    uint32_t module_base = std::stoul (val.c_str()+2, 0,
>> 16);
>> +                    module.set_base (module_base);
>> +                }
>> +            }
>> +
>> +            // the memory address of the libraries PT_DYAMIC section.
>> +            if (strcmp ((char*)prop->name, "l_ld") == 0)
>> +            {
>> +                std::string val = xmlExGetTextContent (prop);
>> +                if (val.length() > 2)
>> +                {
>> +                    uint32_t module_dyn = std::stoul (val.c_str()+2, 0,
>> 16);
>> +                    module.set_dynamic (module_dyn);
>> +                }
>> +            }
>> +        }
>> +
>> +        if (log)
>> +        {
>> +            std::string name ("");
>> +            lldb::addr_t lm=0, base=0, ld=0;
>> +
>> +            module.get_name (name);
>> +            module.get_link_map (lm);
>> +            module.get_base (base);
>> +            module.get_dynamic (ld);
>> +
>> +            log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%"
>> PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str());
>> +        }
>> +
>> +        list.add (module);
>> +    }
>> +
>> +    if (log)
>> +        log->Printf ("found %" PRId32 " modules in total", (int)
>> list.m_list.size());
>> +
>> +    return Error();
>> +}
>> +
>>  #else // if defined( LIBXML2_DEFINED )
>>
>> -using namespace lldb_private::process_gdb_remote;
>> +Error
>> +ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList &)
>> +{
>> +    // stub (libxml2 not present)
>> +    Error err;
>> +    err.SetError (0, ErrorType::eErrorTypeGeneric);
>> +    return err;
>> +}
>>
>>  bool
>> -ProcessGDBRemote::GetGDBServerInfo ()
>> +ProcessGDBRemote::GetGDBServerRegisterInfo ()
>>  {
>>      // stub (libxml2 not present)
>>      return false;
>> @@ -3941,6 +4181,91 @@ ProcessGDBRemote::GetGDBServerInfo ()
>>
>>  #endif // if defined( LIBXML2_DEFINED )
>>
>> +lldb::ModuleSP
>> +ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file,
>> lldb::addr_t base_addr)
>> +{
>> +    Target &target = m_process->GetTarget();
>> +    ModuleList &modules = target.GetImages();
>> +    ModuleSP module_sp;
>> +
>> +    bool changed = false;
>> +
>> +    ModuleSpec module_spec (file, target.GetArchitecture());
>> +    if ((module_sp = modules.FindFirstModule (module_spec)))
>> +    {
>> +        module_sp->SetLoadAddress (target, base_addr, true, changed);
>> +    }
>> +    else if ((module_sp = target.GetSharedModule (module_spec)))
>> +    {
>> +        module_sp->SetLoadAddress (target, base_addr, true, changed);
>> +    }
>> +
>> +    return module_sp;
>> +}
>> +
>> +size_t
>> +ProcessGDBRemote::LoadModules ()
>> +{
>> +    using lldb_private::process_gdb_remote::ProcessGDBRemote;
>> +
>> +    // request a list of loaded libraries from GDBServer
>> +    GDBLoadedModuleInfoList module_list;
>> +    if (GetLoadedModuleList (module_list).Fail())
>> +        return 0;
>> +
>> +    // get a list of all the modules
>> +    ModuleList new_modules;
>> +
>> +    for (GDBLoadedModuleInfoList::LoadedModuleInfo & modInfo :
>> module_list.m_list)
>> +    {
>> +        std::string  mod_name;
>> +        lldb::addr_t mod_base;
>> +
>> +        bool valid = true;
>> +        valid &= modInfo.get_name (mod_name);
>> +        valid &= modInfo.get_base (mod_base);
>> +        if (!valid)
>> +            continue;
>> +
>> +        // hack (cleaner way to get file name only?) (win/unix compat?)
>> +        int marker = mod_name.rfind ('/');
>> +        if (marker == std::string::npos)
>> +            marker = 0;
>> +        else
>> +            marker += 1;
>> +
>> +        FileSpec file (mod_name.c_str()+marker, true);
>> +        lldb::ModuleSP module_sp = LoadModuleAtAddress (file, mod_base);
>> +
>> +        if (module_sp.get())
>> +            new_modules.Append (module_sp);
>> +    }
>> +
>> +    if (new_modules.GetSize() > 0)
>> +    {
>> +        Target & target = m_target;
>> +
>> +        new_modules.ForEach ([&target](const lldb::ModuleSP module_sp)
>> -> bool
>> +        {
>> +            lldb_private::ObjectFile * obj = module_sp->GetObjectFile ();
>> +            if (!obj)
>> +                return true;
>> +
>> +            if (obj->GetType () != ObjectFile::Type::eTypeExecutable)
>> +                return true;
>> +
>> +            lldb::ModuleSP module_copy_sp = module_sp;
>> +            target.SetExecutableModule (module_copy_sp, false);
>> +            return false;
>> +        });
>> +
>> +        ModuleList &loaded_modules = m_process->GetTarget().GetImages();
>> +        loaded_modules.AppendIfNeeded (new_modules);
>> +        m_process->GetTarget().ModulesDidLoad (new_modules);
>> +    }
>> +
>> +    return new_modules.GetSize();
>> +}
>>
>>  class CommandObjectProcessGDBRemotePacketHistory : public
>> CommandObjectParsed
>>  {
>>
>> Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=236817&r1=236816&r2=236817&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
>> (original)
>> +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Fri
>> May  8 04:36:31 2015
>> @@ -241,15 +241,16 @@ public:
>>                    const ArchSpec& arch,
>>                    ModuleSpec &module_spec) override;
>>
>> -    // query remote gdbserver for information
>> -    bool
>> -    GetGDBServerInfo ( );
>> +    virtual size_t
>> +    LoadModules () override;
>>
>>  protected:
>>      friend class ThreadGDBRemote;
>>      friend class GDBRemoteCommunicationClient;
>>      friend class GDBRemoteRegisterContext;
>>
>> +    class GDBLoadedModuleInfoList;
>> +
>>
>>  //----------------------------------------------------------------------
>>      // Accessors
>>
>>  //----------------------------------------------------------------------
>> @@ -396,6 +397,17 @@ protected:
>>      DynamicLoader *
>>      GetDynamicLoader () override;
>>
>> +    // Query remote GDBServer for register information
>> +    bool
>> +    GetGDBServerRegisterInfo ();
>> +
>> +    // Query remote GDBServer for a detailed loaded library list
>> +    Error
>> +    GetLoadedModuleList (GDBLoadedModuleInfoList &);
>> +
>> +    lldb::ModuleSP
>> +    LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr);
>> +
>>  private:
>>      //------------------------------------------------------------------
>>      // For ProcessGDBRemote only
>>
>> Modified: lldb/trunk/source/Target/Target.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=236817&r1=236816&r2=236817&view=diff
>>
>> ==============================================================================
>> --- lldb/trunk/source/Target/Target.cpp (original)
>> +++ lldb/trunk/source/Target/Target.cpp Fri May  8 04:36:31 2015
>> @@ -1057,13 +1057,24 @@ Target::IgnoreWatchpointByID (lldb::watc
>>  ModuleSP
>>  Target::GetExecutableModule ()
>>  {
>> -    return m_images.GetModuleAtIndex(0);
>> +    // search for the first executable in the module list
>> +    for (size_t i = 0; i < m_images.GetSize(); ++i)
>> +    {
>> +        ModuleSP module_sp = m_images.GetModuleAtIndex (i);
>> +        lldb_private::ObjectFile * obj = module_sp->GetObjectFile();
>> +        if (obj == nullptr)
>> +            continue;
>> +        if (obj->GetType() == ObjectFile::Type::eTypeExecutable)
>> +            return module_sp;
>> +    }
>> +    // as fall back return the first module loaded
>> +    return m_images.GetModuleAtIndex (0);
>>  }
>>
>>  Module*
>>  Target::GetExecutableModulePointer ()
>>  {
>> -    return m_images.GetModulePointerAtIndex(0);
>> +    return GetExecutableModule().get();
>>  }
>>
>>  static void
>>
>>
>> _______________________________________________
>> lldb-commits mailing list
>> lldb-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20150508/dfff66a5/attachment.html>


More information about the lldb-commits mailing list