[lldb-dev] Assert in DYLDRendezvous::UpdateSOEntries

Michael Sartain mikesart at gmail.com
Sun Jul 14 17:25:27 PDT 2013


I've come up with a consistent repro for this.

#include <stdio.h>
> #include <dlfcn.h>
> int main( int argc, char *argv[] )
> {
>     printf( "hello world\n" );
>     void *blah = dlopen("/usr/lib/libbfd.so", RTLD_NOW);
>     printf("blah is %p\n", blah);
>     if (blah)
>         dlclose(blah);
> }


1. Compile the above program.
2. run "lldb -x -- blah"
3. b main
4. r
5. expr argc = 2
6. n
7. n

You should hit the assert on step 7 when you "next" over the dlopen()
statement. If you don't do step 5, everything is fine. The difference is
info.state comes in as add in the assert case and consistent otherwise.

I'll look at this more tomorrow.
 -Mike

On Fri, Jun 14, 2013 at 9:54 AM, Kopec, Matt <matt.kopec at intel.com> wrote:

> Unfortunately, the original author of the majority of the original
> POSIX/Linux code isn't around anymore.
>
> However, looking into the issue, I think the code here is expecting an
> eConsistent state after an eAdd/eDelete since the library entries don't get
> updated until you actually get the eConsistent state. This is probably why
> there is an m_previous and m_current.
>
> Maybe the behaviour you see is ok. I'm not sure. I think better
> understanding of the system dynamic linker/loader behaviour here may be
> needed.
>
> Curiously, do you get the same assert without a step? i.e. just running?
>
> Thanks,
> Matt
>
> On 2013-06-13, at 9:50 PM, Michael Sartain <mikesart at gmail.com> wrote:
>
> > I just hit the below assert on line 138 stepping over a dlclose().
> >
> > 120| bool
> > 121| DYLDRendezvous::UpdateSOEntries()
> > 122| {
> > 123|     SOEntry entry;
> > 124|
> > 125|     if (m_current.map_addr == 0)
> > 126|         return false;
> > 127|
> > 128|     // When the previous and current states are consistent this is
> the first
> > 129|     // time we have been asked to update.  Just take a snapshot of
> the currently
> > 130|     // loaded modules.
> > 131|     if (m_previous.state == eConsistent && m_current.state ==
> eConsistent)
> > 132|         return TakeSnapshot(m_soentries);
> > 133|
> > 134|     // If we are about to add or remove a shared object clear out
> the current
> > 135|     // state and take a snapshot of the currently loaded images.
> > 136|     if (m_current.state == eAdd || m_current.state == eDelete)
> > 137|     {
> > 138+>        assert(m_previous.state == eConsistent);
> > 139|         m_soentries.clear();
> > 140|         m_added_soentries.clear();
> > 141|         m_removed_soentries.clear();
> > 142|         return TakeSnapshot(m_soentries);
> > 143|     }
> >
> > It's called by this code in DYLDRendezvous::Resolve():
> >
> > 106|     // The rendezvous was successfully read.  Update our internal
> state.
> > 107|     m_rendezvous_addr = info_addr;
> > 108|     m_previous = m_current;
> > 109|     m_current = info;
> > 110|
> > 111+>    return UpdateSOEntries();
> >
> > m_previous is being set to m_current and both are eDelete now, but that
> assert above is claiming it should be eConsistent.
> >
> > Is this a bogus assert, or is the Resolve() function messing with
> m_previous when it shouldn't be?
> >  -Mike
> > _______________________________________________
> > 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/20130714/5f4c18c8/attachment.html>


More information about the lldb-dev mailing list