Discussion:
dlsym fails to find existing symbol
(too old to reply)
Tron Thomas
2004-08-22 00:06:58 UTC
Permalink
I am working with a program that loads libraries (*.dylib) dynamically
via dlopen. When I ask the program to look for a specific symbol in
the loaded library using dlsym, the call fails returning NULL.

I've used "nm <library name> | grep <symbol name>" to verify that the
symbol does exist in the library.

What could possibly be preventing dlsym from finding a valid symbol
that actually exists in a library?
Eric Albert
2004-08-22 04:23:52 UTC
Permalink
Post by Tron Thomas
I am working with a program that loads libraries (*.dylib) dynamically
via dlopen. When I ask the program to look for a specific symbol in
the loaded library using dlsym, the call fails returning NULL.
I've used "nm <library name> | grep <symbol name>" to verify that the
symbol does exist in the library.
What could possibly be preventing dlsym from finding a valid symbol
that actually exists in a library?
You might have to put an underscore ('_') in front of the symbol name
you pass to dlsym.

-Eric
--
Eric Albert ***@cs.stanford.edu
http://rescomp.stanford.edu/~ejalbert/
Tron Thomas
2004-08-23 17:16:54 UTC
Permalink
Post by Eric Albert
You might have to put an underscore ('_') in front of the symbol name
you pass to dlsym.
-Eric
Placing an underscore before the symbol name does not solve the problem.
Tron Thomas
2004-08-23 19:13:05 UTC
Permalink
I am really confused now.
It appears that if I launch the application from the Xcode environment
the program will successfully find the loaded symbol. If I launch the
program from the command line, the program fails to load the symbol.

I have studies all the Xcode settings that are applied to launching
the program. I cannot figure out the difference between running the
program from Xcode or the command line.

If anyone has any suggestions or ideas, I would really appreciate the
feedback.
M. Uli Kusterer
2004-08-23 20:04:57 UTC
Permalink
Post by Tron Thomas
I am really confused now.
It appears that if I launch the application from the Xcode environment
the program will successfully find the loaded symbol. If I launch the
program from the command line, the program fails to load the symbol.
I have studies all the Xcode settings that are applied to launching
the program. I cannot figure out the difference between running the
program from Xcode or the command line.
If anyone has any suggestions or ideas, I would really appreciate the
feedback.
I believe linking in the debugger implicitly loads a few other libraries
that aren't usually loaded. Make sure you've added all the right
libraries to your project, in this case the library from which you're
loading the symbol.

HTH,
-- Uli
http://www.zathras.de
Tron Thomas
2004-08-24 18:12:20 UTC
Permalink
Post by M. Uli Kusterer
I believe linking in the debugger implicitly loads a few other libraries
that aren't usually loaded. Make sure you've added all the right
libraries to your project, in this case the library from which you're
loading the symbol.
HTH,
-- Uli
http://www.zathras.de
Do libraries get loaded even if I don't debug the application? I can
launch the program from the Xcode IDE without debugging it (i.e.
running instead of debugging the program) and the program still
successfully loads the symbols. If I use the command line GDB
debugger, the program fails to link the symbols.

The whole point of this was to get the program to link to libraries at
runtime, as it doesn't know until it starts running what libraries it
is going to want to use. Adding these libraries to the project
configuration would defeat the whole purpose of this.
Glenn Andreas
2004-08-24 19:48:23 UTC
Permalink
Post by Tron Thomas
Post by M. Uli Kusterer
I believe linking in the debugger implicitly loads a few other libraries
that aren't usually loaded. Make sure you've added all the right
libraries to your project, in this case the library from which you're
loading the symbol.
HTH,
-- Uli
http://www.zathras.de
Do libraries get loaded even if I don't debug the application? I can
launch the program from the Xcode IDE without debugging it (i.e.
running instead of debugging the program) and the program still
successfully loads the symbols. If I use the command line GDB
debugger, the program fails to link the symbols.
The whole point of this was to get the program to link to libraries at
runtime, as it doesn't know until it starts running what libraries it
is going to want to use. Adding these libraries to the project
configuration would defeat the whole purpose of this.
Is this a Cocoa app? If so, use gandbug
<http://projects.gandreas.com/gandbug> which, among other things, can
print out all the libraries that are currently loaded (and where).
M. Uli Kusterer
2004-08-25 04:09:54 UTC
Permalink
Post by Tron Thomas
Do libraries get loaded even if I don't debug the application? I can
launch the program from the Xcode IDE without debugging it (i.e.
running instead of debugging the program) and the program still
successfully loads the symbols. If I use the command line GDB
debugger, the program fails to link the symbols.
I didn't test it out. I just noticed that I had some missing libraries
in one of my programs, and it worked fine while I was debugging, but
crashed as it should have when I was running it in 'deployment' style.
My guess was that the debugger somehow causes libraries to be loaded
that the non-debugging build style doesn't add.

So, if you were loading libraries manually and they were system
libraries, chances are that your loading code doesn't work, but you
didn't notice because the debugger loaded the library for you.

I also remember that CFBundle had some calls for getting at bundles
that only gave you a CFBundleRef if the bundle was actually already
loaded. Which caught many people off-guard because the docs didn't say
so. So, make sure you're actually loading the bundle, and not using that
call that looks like it loads but doesn't.

Just a guess...

-- Uli
http://www.zathras.de
j***@yahoo.com
2004-08-25 20:23:55 UTC
Permalink
Post by Tron Thomas
It appears that if I launch the application from the Xcode environment
the program will successfully find the loaded symbol. If I launch the
program from the command line, the program fails to load the symbol.
According to 'man dlsym' it is implemented in terms of the dyld
system. 'man 1 dyld' informs me that :

The dynamic linker uses the following environment
variables. They affect any program that uses the
dynamic linker.

One of those variables is:

DYLD_LIBRARY_PATH
This is a colon separated list of directories that
contain libraries. The dynamic linker searches these
directories before it searches the default locations for
libraries.

Perhaps this or some other significant environment variable is
different in the two execution environments.

Robert
Tron Thomas
2004-08-27 02:45:33 UTC
Permalink
Post by j***@yahoo.com
According to 'man dlsym' it is implemented in terms of the dyld
The dynamic linker uses the following environment
variables. They affect any program that uses the
dynamic linker.
DYLD_LIBRARY_PATH
This is a colon separated list of directories that
contain libraries. The dynamic linker searches these
directories before it searches the default locations for
libraries.
Perhaps this or some other significant environment variable is
different in the two execution environments.
Robert
I figured out what the problem was.

All the libraries the application tries to load dynamically using
dlopen link to another dynamic library.

Using the otool utility to list all the libraries used by any of the
libraries the application try to load with dlopen reveals that their
paths to this additional libarary were not correct.

So for example if the application uses a library name foo, which links
to another library named bar, the command:
otool -L libfoo.dylib

would spit out something like:
...
/usr/local/lib/libbar.dylib
...

even though libbar.dylib was not installed in the /usr/local/lib
directory.

To correct the path referring to bar in foo I used the
install_name_tool utility like this:
install_name_tool -change /usr/local/lib/libbar.dylib
/my/path/to/libbar.dylib libfoo.dylib

Now the call to dlsym succeeds for each library opened by the
application.

Loading...