[LLVMdev] Trouble Resolving Objective-C Symbols in lli

Reid Spencer rspencer at reidspencer.com
Fri Jul 20 12:08:50 PDT 2007


Hi Ralph,

On Fri, 2007-07-20 at 12:22 +0100, Ralph Corderoy wrote:
> Hi Reid,
> 
> > >     if ((err = dlerror())) {
> > >         error("earlier undetected dlerror: %s\n", err);
> > >     }
> > >     p = dlsym(handle, sym);
> > >     if ((err = dlerror())) {
> > >         error("dlsym failed: %s\n", err);
> > >     }
> > 
> > No, you're not missing anything. The correct way to check for errors
> > is with dlerror. 
> > 
> > Please note that on the "trunk" revision of llvm (soon to be 2.1), and
> > I think also 2.0, there are 0 calls to dlsym in the Intercept.cpp.
> > They have been replaced with a call to
> > 
> >   sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr)
> > 
> > Which is part of LLVM's lib/System package. That package implements
> > this using the libtool "ltdl" library, which presumably gets this
> > right in an operating system correct way.
> 
> Presumably?
> http://www.gnu.org/software/libtool/manual.html#index-lt_005fdlsym-167
> says:
> 
>     Function: lt_ptr lt_dlsym(lt_dlhandle handle, const char *name)
> 
>         Return the address in the module handle, where the symbol given
>         by the null-terminated string name is loaded. If the symbol
>         cannot be found, NULL is returned. 
> 
> And lt_dlerror() also appears to have the same behaviour as its non-lt_
> counterpart, so you'd think you'd have to do the same as above;  use
> lt_dlerror().
> 
> However, it appears things like libtool's
> 
>     static lt_ptr
>     sys_dl_sym (loader_data, module, symbol)
>          lt_user_data loader_data;
>          lt_module module;
>          const char *symbol;
>     {
>       lt_ptr address = dlsym (module, symbol);
> 
>       if (!address)
>         {
>           LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
>         }
> 
>       return address;
>     }
> 
> break the ability to detect an undefined symbol versus a symbol with a
> value of 0 because it sets the lt_dlerror() whenever dlsym() returns 0.
> Perhaps a bug in libtool, I was looking at 1.5.6, but it's a twisty
> maze and I could have taken a wrong turn.

It is a twisty mess. Function pointers in structures? Who'd ever do
THAT? :)

We're currently using 1.5.22 but it doesn't look any different than what
you ahve above. I'm about to upgrade the support module to use 1.5.24
(latest stable).  

However, I don't think the code above is necessarily wrong. If you get
an address back, there's no error (dlerror only reports and error when
dlsym returns 0). The DLERROR macro just calls dlerror. The
LT_DLMUTEX_SETERROR looks like this:

#define LT_DLMUTEX_SETERROR(errormsg)           LT_STMT_START { \
        if (lt_dlmutex_seterror_func)                           \
                (*lt_dlmutex_seterror_func) (errormsg);         \
        else    lt_dllast_error = (errormsg);   } LT_STMT_END

So, its basically calling a function to report the error or saving the
error.  Presumably the user was supposed to set up the
lt_dlmutext_seterror_func or use lst_dlerror to access the error
message.

I think the entire problem is that the lib/System library is not using
the lt_dlerror function properly. For example:

  // Now search the libraries.
  for (std::vector<lt_dlhandle>::iterator I = OpenedHandles.begin(),
       E = OpenedHandles.end(); I != E; ++I) {
    lt_ptr ptr = lt_dlsym(*I, symbolName);
    if (ptr)
      return ptr;
  }

This needs to call lt_dlerror to clear any previous error, then call
dl_sym, then call dl_error again to see if there's an error. The lack of
this checking makes it miss the "return 0 without error" case. 

I'll fix this.

Reid.

> 
> It's clear dlsym() gives the required functionality;  the layers of
> wrapping on top of it present a broken interface.
> 
> Cheers,
> 
> 
> Ralph.
> 
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list