Pointer error with dynamic library call

0

I want a method inside a dynamic library to read the value from inside a pointer using dlfcn.h .

But it always has a memory error when I try to access the value inside the pointer.

main.c

#include <dlfcn.h>

int main(int argc, char **argv){
    void *handle = dlopen("./lib.so", RTLD_GLOBAL);
    void (*read)();

    read = dlsym(handle, "check");

    int x = 10;
    read(&x);

    return 0;
}

check.c:

#include <stdio.h>

void check(int *i){
    printf("%d\n", *i);
}

To compile use:

gcc -shared -fPIC -O2 check.c -o lib.so
gcc -O2 main.c -o main -ldl

Is there any way you can access the value from within this memory address without using a shared address in a dynamic call from a library?

    
asked by anonymous 25.11.2016 / 02:41

1 answer

3

I do not know when the memory error occurred, but it was probably in your call to dlopen ()

Let's take a brief look at the dlopen () manual (I only translate the relevant one)
user@host:~$ man 3 dlopen :

ORIGINAL

  

...
  One of the following two values must be included in flags :

  RTLD_LAZY:
  Perform lazy binding. Only resolves symbols as the code that references them is executed. If the symbol is never referenced, then it is never resolved. (Lazy binding is performed only for function references, references to variables are always immediately bound when the shared object is loaded.) Since glibc 2.1.1, this flag is overridden by the effect of the LD_BIND_NOW environment variable.   RTLD_NOW:
                If this value is specified, or the variable environment                 LD_BIND_NOW is set to a nonempty string, all undefined symbols                 in the shared object are resolved before dlopen () returns. If                 this can not be done, an error is returned.

TRANSLATED

* There's so much more to a resume than a translation :-)

  

...
  One of the two values below needs to be included in flags :

  RTLD_LAZY:
  It only resolves the symbols when the code it references (it refers to) these runs.   RTLD_NOW:
  All non-defined symbols (as a function prototype see this link ) in the shared object are resolved before dlopen () returns.

As we can see, you need to include one of these two values above in flags of dlopen ()
void *dlopen( const char *filename, int flags );
The flag RTLD_GLOBAL you used is optional and in your case it is not required.

The code ...

I have changed some names to facilitate understanding. The code is commented on.

main.c user@host:~$ gcc -ldl -o main main.c

#include <dlfcn.h>

int
main (int argc, char **argv) {
    void *handle;
    void (*function)();

    int x = 10;

    /* vamos abrir a shared library com dlopen(..., RTLD_NOW)
     * -> RTLD_GLOBAL não é necessário porque você não vai "abrir" um
     *    symbol desta shared library em outra shared library */
    handle = dlopen("./shared.so", RTLD_NOW);
    function = dlsym(handle, "print");
    function(&x);

    /* temos que fechar a shared library :-) */
    dlclose(handle);

    return 0;
}


shared.c user@host:~$ gcc -shared -o shared.so shared.c

#include <stdio.h>

void
print (int *i) {
    printf("%d\n", *i);
}
    
25.11.2016 / 20:00