Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shared object can't find symbols in main binary, C++

I'm experimenting with making a kind of plugin architecture for a program I wrote, and at my first attempt I'm having a problem. Is it possible to access symbols from the main executable from within the shared object? I thought the following would be fine:

testlib.cpp:

void foo();
void bar() __attribute__((constructor));
void bar(){ foo(); }

testexe.cpp:

#include <iostream>
#include <dlfcn.h>

using namespace std;

void foo()
{
    cout << "dynamic library loaded" << endl;    
}

int main()
{
    cout << "attempting to load" << endl;
    void* ret = dlopen("./testlib.so", RTLD_LAZY);
    if(ret == NULL)
        cout << "fail: " << dlerror() << endl;
    else
        cout << "success" << endl;
    return 0;
}

Compiled with:

g++ -fPIC -o testexe testexe.cpp -ldl
g++ --shared -fPIC -o testlib.so testlib.cpp

Output:

attempting to load
fail: ./testlib.so: undefined symbol: _Z3foov

So obviously, it's not fine. So I guess I have two questions: 1) Is there a way to make the shared object find symbols in the executable it's loaded from 2) If not, how do programs that use plugins typically work that they manage to get code in arbitrary shared objects to run inside their programs?

like image 529
cheshirekow Avatar asked Sep 02 '10 02:09

cheshirekow


People also ask

How do I view the contents of a .so file?

However, you might be able to read the SO file as a text file by opening it in a text editor like Leafpad, gedit, KWrite, or Geany if you're on Linux, or Notepad++ on Windows.

What is shared library in c?

Shared libraries (also called dynamic libraries) are linked into the program in two stages. First, during compile time, the linker verifies that all the symbols (again, functions, variables and the like) required by the program, are either linked into the program, or in one of its shared libraries.

How are shared libraries loaded?

Shared libraries are the most common way to manage dependencies on Linux systems. These shared resources are loaded into memory before the application starts, and when several processes require the same library, it will be loaded only once on the system. This feature saves on memory usage by the application.

Where to put shared library Linux?

According to the FHS, most libraries should be installed in /usr/lib, but libraries required for startup should be in /lib and libraries that are not part of the system should be in /usr/local/lib.


1 Answers

Try:

g++ -fPIC -rdynamic -o testexe testexe.cpp -ldl

Without the -rdynamic (or something equivalent, like -Wl,--export-dynamic), symbols from the application itself will not be available for dynamic linking.

like image 114
Chris Jester-Young Avatar answered Oct 26 '22 22:10

Chris Jester-Young