In Solaris I have an exe file as per the guideline I need to add a shared library (.so) to extend the functionality. I have created a lthmyplugin.so file and added as described. Now the utlity run perfectly fine untill it calls my function After calling my function it fails.
Questions:
Is there any way to debug?
When I run the command truss it identifies aa.so
Also ldd -d lthmyplugin.so show no error except
symbol not found: __1cIMyPluginG__vtbl_ (./lthmyplugin.so)
symbol not found: __1cIThPluginG__vtbl_ (./lthmyplugin.so)
symbol not found: __1cOThLocalOptionsG__vtbl_ (./lthmyplugin.so)
symbol not found: __1cJThOptionsG__vtbl_ (./lthmyplugin.so)
Can this cause the programme to fail?
fyi, I have not used and any virtual function,constructors or destructors
What does this mean symbol not found: _1cIThPluginG_vtbl_ ?
Thanks,
You can use the nm tool to see the functions exposed by the so file. You can call:
nm -g lthmyplugin.so
... To see what functionality it exposes.
Besides that, given you've tagged this as C++, I'm going to take a stab and ask: did you specify a C style calling convention? If you didn't, it will mangle the names making them ugly, unreadable and in 99.9% of cases, unfindable. You can tell gcc not to mangle your functions by adding __attribute__((cdecl)), like so:
int not_mangled(int some_arg) __attribute__((cdecl))
{
return some_arg * 3;
}
Related
There is a class DerivedClass which inherits from both BaseClassA and BaseClassB publicly. All classes have virtual functions to make sure the virtual table is built properly.
BaseClassA and BaseClassB are located in Library1 and DerivedClass is in Library2.
One function in Library1 retrieves a DerivedClass in the form of a BaseClassA pointer and tries to dynamic_cast to BaseClassB but it fails. The same function works in different environments and compilers (visual studio for instance).
Extra information:
Reproduced with 4.1.2 and 4.5 gcc versions (read about the old gcc bug)
Derived class name is "Match" (thought it may collide with other library? python?)
There are tens of libraries compiling one after the other while linking between them.
nm -gC: Found the vtable address for Match
gdb (7.0.1): used to check the vtable address for the class but couldn't understand much. (gdb version doesnt support "info vtbl". gdb can't show direct information about the class claiming it is a typedef)
readelf -s: I saw the symbol
I figured it might be one of the following problems
duplicated symbol
HIDDEN symbol somewhere in the libraries linked
Duplicated vtables
-E and RTLD_GLOBAL dlopen flag linker flag didn't work (the linking is made using the makefile linker stage and probably not the dlopen.
non-inline function manipulation (didnt work as well - but could be my mistake with understanding what exactly has to be done)
Been farming the web trying to find a solution. But what I want to know first is What Is The Problem? How can I focus on it?
(5) looks promising even though I didnt manage to use it.
Any suggestions would be greatly appreciated (a solution would be great as well ;) )
Apparently #4 was the answer.
The was a hidden feature that loads functions dynamically and had to be handles separately. Adding the -Wl,-E flags to the linking process and changing the loader flags did the trick.
What I want to know if there is any linuxy way of understanding this is the error.
Something like "ldd" command or others (top, nm, readelf, etc) that I tried but couldn't see anything that pointed to this exact error.
Thanks SOF for continuous help in various subjects
I have an application which uses a class Foo from an .so shared library. I've come across a problem where at runtime it prints
<appname>: symbol lookup error: <appname>: undefined symbol: <mangled_Foo_symbol_name>
Now, it turned out that the unmangled symbol was for the constructor of the class Foo, and the problem was simply that an old version of the library was loaded, which didn't contain Foo yet.
My question isn't about resolving the error (that's obviously to use the correct library), but why it appears at runtime instead of at time of load / startup.
The line of code causing the error just instantiates an object of class Foo, so I'm not using anything like dlopen here, at least not explicitly / to my knowledge.
In contrast, if I remove the whole library from the load search path, I get this error at startup:
<appname>: error while loading shared libraries: libname.so.2: cannot open shared object file: No such file or directory
When the wrong version of gcc / libstdc++ is on the load path, an error also appears at starup:
<appname>: /path/to/gcc-4.8.0/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by <appname>)
This "fail fast" behavior is much more desirable, I don't want to run my application for quite awhile first, until I finally realize it's using the wrong library.
What causes the load error to appear at runtime and how can I make it appear immediately?
From the man page of ld.so:
ENVIRONMENT
LD_BIND_NOW (libc5; glibc since 2.1.1) If set to a nonempty string, causes the dynamic linker to resolve all symbols at program startup instead of deferring function call resolution to the point when they are first referenced. This is useful when using a debugger.
LD_WARN (ELF only)(glibc since 2.1.3) If set to a nonempty string, warn about unresolved symbols.
I think you can not statically link .so library. If you want to avoid load/run time errors you have to use all static libraries (.a). If you do not have static version of library and source then try to find some statifier. After googling I find few statifiers but do not know how do they work so leaving that part up to you.
I am trying to build my program in OpenCL for ARM GPU - Mali.
I have a library libMali.so, which contains necessary symbols:
arm-v7a15v4r3-linux-gnueabi-nm *root_to_lib*/libMali.so
returns lines such as
002525b4 t clCreateKernel
and many others with all the expected OpenCL symbols.
However, compiling with
arm-v7a15v4r3-linux-gnueabi-g++ -c -Wall mandelbrot.cpp -o mandelbrot.o
arm-v7a15v4r3-linux-gnueabi-g++ mandelbrot.o -o mandelbrot -L*root_to_lib* -lMali
gives me errors like
mandelbrot.cpp:(.text+0x2e4): undefined reference toclCreateKernel'`
and others with all the symbols, which are actually present in libMali.so!
So, I kept the correct order of librabies in linking command, library is on the specified path (it is indeed) and it has the symbols.
Mangling is not the issue in this case as well: extern C specifiers were used in place and you can see that the raw entries of both lib and object file are not mangled.
Trying to accomplish the same thing using the arm-v7a15v4r3-linux-gnueabi-gcc didn't bring any change apart from necessity to link more c++ libs by hand (with -L*path* -llib).
libMali.so was built with arm-v7a15v4r3-linux-gnueabi-g++/gcc/ld, so this is not the matter of toolchain version.
I've ran out of ideas. May be someone here knows more tricky parts of linking process?
EDIT:
In fact, mandelbrot.cpp is a sample code from Mali-SDK. I'm just showing my linker problem on this example, since there obviously are no problems in the code. You can see the code here:
http://malideveloper.arm.com/downloads/deved/tutorial/SDK/opencl/mandelbrot_8cpp_source.html
http://malideveloper.arm.com/downloads/deved/tutorial/SDK/opencl/mandelbrot_8cl_source.html
If you look closely at the nm output:
002525b4 t clCreateKernel
you'll notice that the symbol is marked with a lowercase 't' which indicates that the symbol has a local binding (for example a static function) so it's not considered for binding to a undefined symbol in another object file. You can find an explanation of most of the cryptic "symbol type" letters used by nm here: https://sourceware.org/binutils/docs/binutils/nm.html
The readelf utility's output is more clear about symbols types.
Maybe the library was built incorrectly?
I am attempting to build a project in Visual Studio 2012 that uses GnuTLS. I downloaded the latest official Windows build from the website, and created a link library by running lib /def:libgnutls-28.def in the bin directory form a Visual Studio command prompt.
After adding a typedef long ssize_t, the code compiles fine, but linking fails with the following error:
source_file.obj : error LNK2001: unresolved external symbol _gnutls_free
C:\Path\to\executable.exe : fatal error LNK1120: 1 unresolved externals
I am calling gnutls_free to free some memory allocated and returned by the library. If I remove the call to gnutls_free, the project links successfully. Given that gnutls_free is just a global variable (containing a function pointer) exported by the library, I'm not sure why accessing it results in an unresolved reference to a different symbol. I have verified that gnutls_free is not #defineed to anything.
As a test, I tried doing gnutls_free_function test = gnutls_free; which also resulting in the link error. Running grep -w -r _gnutls_free . on the GnuTLS source code returns nothing, so I am at a loss.
Any ideas for getting this working would be greatly appreciated.
EDIT:
Adding __declspec(dllimport) to the declaration of gnutls_free in gnutls.h allows the link to succeed. Is there any way to accomplish this without maintaining a custom version of the header file?
There doesn't seem to be a way to have the linker or import library automatically dereference the IAT's pointer to the data item the same way that is done for functions (via a small trampoline function that is statically linked into the module importing the function). The __declspec(dllimport) attribute tells that compiler that this dereferencing needs to be done so it can insert code to perform the dereferencing of the IAT pointer implicitly. This allows exported data to be accessed and for functions allows the compiler to call the imported function via an indirect call through the IAT pointer rather than by calling the trampoline function.
See a couple of Raymond Chen's articles about dllimport for a good explanation of what goes on for function calls (he didn't discuss importing data, unfortunately):
Calling an imported function, the naive way
How a less naive compiler calls an imported function
The MS linker or import library doesn't have a mechanism to help the compiler get imported data in a 'naive' way - the compiler needs the the __delcspec(dllimport) hint that an extra dereference through the IAT is needed. Anyway, the point of all this is that it seems there's no way to import data except by using the __declspec(dllimport) attribute.
If you want to avoid modifying the gnutls distribution (which I can understand), here's one rather imperfect workaround:
You can create a small object file that contains nothing but a simple wrapper for gnutls_free(); since gnutls_free() has an interface with no real dependencies, you can have the necessary declarations 'hardcoded' instead of including gnutls.h:
typedef void (*gnutls_free_function) (void *);
__declspec(dllimport) extern gnutls_free_function gnutls_free;
void xgnutls_free(void* p)
{
gnutls_free(p);
}
Have your code call xgnutls_free() instead of gnutls_free().
Not a great solution - it requires your code to call a wrapper (so it's particularly not great if you'll be incorporating 3rd party code that might depend on gnutls_free()), but it might be good enough.
I'm trying to write some small tests for a fairly small part of a fairly large project. Attempting to link this beast is unfortunately fairly impossible without linking the entire project together, which I don't want to do (it's a pretty complex system for finding all the dependencies and stuff, and I perfer not to meddle with it).
Now, I know for certain that the functions that the referenced functions won't be called during my test, the just happen to be part of functions which share file with stuff that I do test.
Is there any way to simply link these unresolved references to, let's say, abort, or something? Or is there a tool which creates the appropriate stub object file where all calls result in abort, given the set of object files that I have?
I use gcc (g++) for compiling/linking, version 3.4.4. Platform is unix (solaris/sparc if that's important).
You can just tell linker to ignore unresolved symbols. I couldn't find option that links them to abort or something like that.
The policy to ignore unresolved symbols in object files only is the most natural, I suppose:
gcc -Wl,--unresolved-symbols=ignore-in-object-files obj.o another.o etc.o
Other options include (quoting man ld):
--unresolved-symbols=method
Determine how to handle unresolved symbols. There are four possi-
ble values for method:
ignore-all
Do not report any unresolved symbols.
report-all
Report all unresolved symbols. This is the default.
ignore-in-object-files
Report unresolved symbols that are contained in shared
libraries, but ignore them if they come from regular object
files.
ignore-in-shared-libs
Report unresolved symbols that come from regular object files,
but ignore them if they come from shared libraries. This can
be useful when creating a dynamic binary and it is known that
all the shared libraries that it should be referencing are
included on the linker's command line.
The behaviour for shared libraries on their own can also be con-
trolled by the --[no-]allow-shlib-undefined option.
Normally the linker will generate an error message for each
reported unresolved symbol but the option --warn-unresolved-sym-
bols can change this to a warning.
On my Linux system attempts to call the unresolved function result in "Segmentation fault".
Trying to compile the following program
#include <iostream>
extern int bar();
int foo()
{
return bar() + 3;
}
int main()
{
std::cout << "Hello, world!" << std::endl;
// std::cout << foo() << std::endl;
return 0;
}
results in
$ g++ -o main main.cc
/tmp/ccyvuYPK.o: In function `foo()':
main.cc:(.text+0x5): undefined reference to `bar()'
collect2: ld returned 1 exit status
But we can tell the linker to ignore unresolved symbols and run it just fine:
$ g++ -Wl,--unresolved-symbols=ignore-all -o main main.cc
$ ./main
Hello, world!
Say some unresolved function is called by your test harness (simulate this by uncommenting the call to foo), it will compile and link fine, but you'll get a segfault when you execute the program. Be sure to ulimit -c unlimited so you get a core.
Well one way I can think of is to first compile the .o files for you library.
Then use a tool like nm (common on *nix systems) to get all of the symbols, in nm, all "external" (aka ones which are not found in this .o) are of type U (it may be different for non-GNU versions of nm see your documentation).
If your library is all one source file, then it is simple, pretty much all symbols of type U will be either a function found in another library or will be unresolved at link time. It is slightly more complicated if your library is going to be more than one source file since you will have inter-source file dependencies.
So now you have a a means to create a potential list of unresolved externals, then you can create a "test_stub.c" which has a stub symbols for each one, which you could fill with something like this:
void some_func() { abort(); }
where some_func is a would be unresolved external. Compile and link this with your library and all calls should result in an abort.
Try GCC alias attribute:
/* cannot directly alias to yet undefined symbols,
* so need an intermediate function.
*/
static void do_abort() { abort(); }
void func0() __attribute__ ((weak, alias ("do_abort")));
void func1() __attribute__ ((weak, alias ("do_abort")));
...