Question

I have the following code which simply loads the library test.so from the current directory and executes the version function within that library. What should be returned is a string. What is instead returned is junk from the stack(a pointer location maybe?). Does anyone have any idea why the following code would be failing.

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(int argc, char **argv){
    void *handler;
    char *(*version);
    char *error;

    handler = dlopen("./test.so", RTLD_LAZY);
    if(!handler){
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    dlerror(); //Flushes any existing error

    *(void **)(&version) = dlsym(handler, "version");

    if((error = dlerror()) != NULL){
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }
    printf("%s\n", version);
    dlclose(handler);
    exit(EXIT_SUCCESS);
}
Was it helpful?

Solution

Change the declaration:

char *(*version); // this is not a function pointer

to:

char *(*version)(); // but this is

then, change the line:

printf("%s\n", version);

to:

printf("%s\n", version());

OTHER TIPS

dlsym just returns a function pointer. You still need to actually call it, which you can do by casting the (void*) to a function pointer of the appropriate type and calling that.

There are two errors in your code:

The declaration of version: it is a pointer to a pointer to char in your code, which led you to a weird conversion in:

*(void **)(&version) = dlsym(handler, "version");

Instead use a pointer to function returning pointer to char, like so:

char *(*version)();

and use a regular assignment:

version = dlsym(handler, "version");

You are not calling the function, when you print the result. In C, writing just the function name returns its address, so version and &version are equivalent. Your code should be like:

printf("%s\n", version());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top