Ralph Corderoy
2007-Jul-20 11:22 UTC
[LLVMdev] Trouble Resolving Objective-C Symbols in lli
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's clear dlsym() gives the required functionality; the layers of wrapping on top of it present a broken interface. Cheers, Ralph.
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
Ralph Corderoy
2007-Jul-22 10:13 UTC
[LLVMdev] Trouble Resolving Objective-C Symbols in lli
Hi Reid,> > 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? :)If I know the right way to use dlsym() I can probably handle a function pointer or two. ;-)> 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).If you mean sys_dl_sym() then I think you've taken the wrong twisty passage. It seems broken to me. It sets its internal error code to SYMBOL_NOT_FOUND if dlsym() returns 0. It too should do the double shuffle with dlerror() to correctly detect a missing symbol but doesn't. I've mailed the libtool guys to see if they concur.> 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 agree LLVM has bugs too, and that it needs to do its own double-shuffle due to the overloaded API originated by dlsym(). But at the moment libtool dlsym()-wrapper seems buggy and since it sets its internal error code when it shouldn't, LLVM will see that on the second call to lt_dlerror(). Cheers, Ralph.
Reasonably Related Threads
- [LLVMdev] Trouble Resolving Objective-C Symbols in lli
- [LLVMdev] Trouble Resolving Objective-C Symbols in lli
- [LLVMdev] Trouble Resolving Objective-C Symbols in lli
- [LLVMdev] Trouble Resolving Objective-C Symbols in lli
- [LLVMdev] Trouble Resolving Objective-C Symbols in lli