[lldb-dev] Misinterpreting Symbols Issue since LLDB-310

Lei Shi cosmo.shih at gmail.com
Wed Jan 21 11:38:23 PST 2015


shortly say, the section list of target was used when it isn't available in
ObjectFileMachO::ParseSymtab.

look these:

#0  ObjectFileMachO::ParseSymtab() at
source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp:1744
#1  ObjectFileMachO::GetSymtab() at
source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp:1039
#2  SymbolFileSymtab::CalculateAbilities() at
source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp:96
#3  lldb_private::SymbolFile::GetAbilities() at
include/lldb/Symbol/SymbolFile.h:96
#4  lldb_private::SymbolFile::FindPlugin(lldb_private::ObjectFile*) at
source/Symbol/SymbolFile.cpp:55
#5
 lldb_private::SymbolVendor::AddSymbolFileRepresentation(std::__1::shared_ptr<lldb_private::ObjectFile>
const&) at source/Symbol/SymbolVendor.cpp:92
#6  SymbolVendorMacOSX::CreateInstance(...) at
source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp:291
#7  lldb_private::SymbolVendor::FindPlugin(...) at
source/Symbol/SymbolVendor.cpp:42
#8 lldb_private::Module::GetSymbolVendor(bool, lldb_private::Stream*) at
source/Core/Module.cpp:958
#9 PlatformDarwin::LocateExecutableScriptingResources(...) at
source/Plugins/Platform/MacOSX/PlatformDarwin.cpp:72
#10 lldb_private::Module::LoadScriptingResourceInTarget(...) at
source/Core/Module.cpp:1441
#11 LoadScriptingResourceForModule(...) at source/Target/Target.cpp:1006
#12 lldb_private::Target::ModuleAdded(...) at source/Target/Target.cpp:1146
#13 non-virtual thunk to lldb_private::Target::ModuleAdded(...) at
source/Target/Target.cpp:1148
#14 lldb_private::ModuleList::AppendImpl(...) at
source/Core/ModuleList.cpp:87
#15 lldb_private::ModuleList::Append(...) at source/Core/ModuleList.cpp:94
#16 lldb_private::Target::SetExecutableModule(...) at
source/Target/Target.cpp:1049
#17 DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(...) at
source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp:1349
#18 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress(...) at
source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp:805

void Target::SetExecutableModule (ModuleSP& executable_sp, bool
get_dependent_files)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
    ClearModules(false);

    if (executable_sp.get())
    {
        Timer scoped_timer (
                          __PRETTY_FUNCTION__,
                          "Target::SetExecutableModule (executable = '%s')",
                          executable_sp->GetFileSpec().GetPath().c_str()
        );

        // The first image is our exectuable file
        // If we haven't set an architecture yet, reset our architecture
based on what we found in the executable module.
        m_images.Append(executable_sp);

        ...
    }
}

size_t ObjectFileMachO::ParseSymtab ()
{
    ...

    SectionSP
 linkedit_section_sp(section_list->FindSectionByName(GetSegmentNameLINKEDIT()));
    // Reading mach file from memory in a process or core file...
    if (linkedit_section_sp)
    {
        const addr_t linkedit_load_addr =
linkedit_section_sp->GetLoadBaseAddress(&target);

        ....

        PlatformSP platform_sp (target.GetPlatform());
        if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
        {
            data_was_read = true;
            nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size,
eByteOrderLittle);
            strtab_data.SetData((void *)strtab_addr, strtab_data_byte_size,
eByteOrderLittle);
            if (function_starts_load_command.cmd)
            {
                const addr_t func_start_addr = linkedit_load_addr +
function_starts_load_command.dataoff - linkedit_file_offset;
                function_starts_data.SetData ((void *)func_start_addr,
function_starts_load_command.datasize, eByteOrderLittle);
            }
        }

    ...
}

void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection
&image_infos, uint32_t infos_count, bool update_executable)
{
    uint32_t exe_idx = UINT32_MAX;
    // Read any UUID values that we can get

    for (uint32_t i = 0; i < infos_count; i++)
    {
        if (!image_infos[i].UUIDValid())
        {
            DataExtractor data; // Load command data

            if (!ReadMachHeader (image_infos[i].address,
&image_infos[i].header, &data))
                continue;

            ParseLoadCommands (data, image_infos[i], NULL);

            if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
                exe_idx = i;
        }
    }

    Target &target = m_process->GetTarget();

    if (exe_idx < image_infos.size())
    {
        const bool can_create = true;
        ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo
(image_infos[exe_idx], can_create, NULL));


        if (exe_module_sp)
        {
            UpdateImageLoadAddress (exe_module_sp.get(),
image_infos[exe_idx]);

            if (exe_module_sp.get() != target.GetExecutableModulePointer())
            {
                // Don't load dependent images since we are in dyld where
we will know
                // and find out about all images that are loaded. Also when
setting the
                // executable module, it will clear the targets module
list, and if we
                // have an in memory dyld module, it will get removed from
the list
                // so we will need to add it back after setting the
executable module,
                // so we first try and see if we already have a weak
pointer to the
                // dyld module, make it into a shared pointer, then add the
executable,
                // then re-add it back to make sure it is always in the
list.

                ModuleSP dyld_module_sp(m_dyld_module_wp.lock());

                const bool get_dependent_images = false;
                m_process->GetTarget().SetExecutableModule (exe_module_sp,
get_dependent_images);

                if (dyld_module_sp)
                    target.GetImages().AppendIfNeeded (dyld_module_sp);
            }
        }
    }
}

There're two related problem:
1. linkedit_load_addr must be invalid, because Target::ClearsModules empty
the section list of target
2. DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress happened before
Target::SetExecutableModule.

The first problem won't fix even if we fix the second problem by
moving UpdateImageLoadAddress below.
Maybe these code need some refactory.



On Tue, Jan 20, 2015 at 8:20 AM, Greg Clayton <gclayton at apple.com> wrote:

>
> > On Jan 18, 2015, at 6:38 PM, Lei Shi <cosmo.shih at gmail.com> wrote:
> >
> > Hi, everyone
> >
> > The Target::SetExecutableModule invoke Target::ClearModules at the very
> beginning. Target::ClearModules clears the m_section_load_histroy which
> maintains the section list of the target. the following symbol parsing
> phase needs section list of the executable. Empty section list will leads
> to Misinterpreting various symbol data including Function Starts.
>
> How are you setting up your symbols prior to setting the target
> executable? Or is the dynamic loader plug-in doing this? Either way the
> target's main executable should be set, then the sections should be setup.
>
> How are you getting this to happen?
>
> >
> > I've tried to fix the issue by avoiding clear the m_section_history in
> Target::SetExecutableModule. It's work, but I not show weather it's a
> proper way to fix the issue.
>
> This isn't the right way to do things. Let me know how you are getting
> Target::SetExecutableModule() to be called and I might be able to tell you
> more.
>
> >
> > Hope someone can review the fix.
> >
> > Best,
> > Lei Shi
> > _______________________________________________
> > lldb-dev mailing list
> > lldb-dev at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20150122/e633a846/attachment.html>


More information about the lldb-dev mailing list