Pointer error with dynamic library calling

Asked

Viewed 75 times

0

I’m wanting a method within a dynamic library to read the value from within a pointer using dlfcn.h.

But it always has 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 that memory address without using a shared address in a dynamic library call?

  • 2

    What error does it make? It is in the call of read(&x)? Vc checked if the pointer has a valid value when it returns from the dlsym(handle, "check");? (after all, if there is an error in the symbol definition, this function returns null) Edit the question and add the details, otherwise it’s difficult for someone to help you.

  • the error occurs in the printf inside check, if I let printf("%d\n", *i); he writes the same value that will be in the main, but when I use the *, from invalid memory access error

  • 1

    I suggested that you edit the question to add the information, not that it answered as a comment. Click [Edit] and change the body of the question. Anyway, I didn’t understand the distinction you put in your comment. Which means "when I use the *"?

1 answer

3


I don’t know when the memory error you mentioned occurred, but it was probably in your call to dlopen()

Let’s take a brief look at the manual of dlopen()    (translated only the relevant)
user@host:~$ man 3 dlopen:

ORIGINAL

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

RTLD_LAZY:
Perform Lazy Binding. Only resolve 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 Environment variable LD_BIND_NOW is set to a nonempty string, all Undefined Symbols in the Shared Object are resolved before dlopen() Returns. If this cannot be done, an error is returned.

TRANSLATED

* Much more for a summary than a translation :-)

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

RTLD_LAZY:
Only solves the Symbols when the code you reference (refers to) these are executed.

RTLD_NOW:
All the Symbols undefined (as a function prototype see this link) in the Shared Object are resolved before dlopen() return.

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

The code ...


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

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);
}
  • 1

    It’s really weird but it worked, I’ve already tested with RTLD_NOW, RTLD_LAZY, RTLD_GLOBAL, RTLD_LOCAL and RTLD_NEXT and always made the same mistake.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.