views:

77

answers:

4

Hi there, I'm stuck with a weird problem. I have two files a.c and b.c as follows: b.c:

#include <stdlib.h>

int *foo() {
  int *x;
  x = (int *) malloc(sizeof(int));
  *x = 4;
  return x;
}

I compile b.c to b.so using gcc: $ gcc -o b.so -shared -fpic

a.c:

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

int main() {
  void *hdl;
  hdl = dlopen("./b.so", RTLD_LAZY);
  int *((*fn)(void));
  int *x;
  x = (*fn)();
  fn = dlsym(hdl, "foo");
  printf("%d", *x);
}

I compile a.c using gcc:

$ gcc -fpic -ldl a.c

Now when I run it:

$ ./a.out Segmentation fault

Where I'm I going wrong? This works when the function in b.c doesn't return a pointer.

And moreover, I tried checking for errors using dlerror(), but it reports none.

+6  A: 

By inspection, you are using fn before you have initialized it. It doesn't yet point to foo, it doesn't yet point to anything in particular, and I suspect the resultant behavior is undefined.

Beta
Initialized (or assigned a value to it), not defined. The variable `fn` is defined prior to its usage.
Georg Fritzsche
Oh thanks, that was a typo I believe.Now it works.
Nilesh
@Georg Fritzsche: Sie haben recht, danke.
Beta
+3  A: 

Could be just a problem with your example, but in the code you provide, you need to switch the following lines:

 x = (*fn)();
fn = dlsym(hdl, "foo");
ronys
+4  A: 

You are not finding the symbol and calling the function.

When you do x = (*fn)(); it doesnt make call to the function foo from b.c.

You have to first get the symbol loaded into your function pointer.

  int *x;
  fn = dlsym(hdl, "foo");
  x = fn();
  printf("%d", *x);

The above should work.

EDIT:

Sample program for dlopen,dlsym can be found here with man page info for the same.

Praveen S
I used the same source to learn how to generate .so files and use them :)
Nilesh
+3  A: 

These two lines appear to be in the wrong order:

x = (*fn)();
fn = dlsym(hdl, "foo");
Laurence Gonsalves