|
Home > Archive > Unix Programming > January 2006 > [LONG] Error calling function in a shared lib
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
[LONG] Error calling function in a shared lib
|
|
|
| Hi,
Since it appears from an earlier thread that I can't use the LD_PRELOAD
mechanism to augment an existing shared lib that I have (but don't have
the source for), I am trying to create a wrapper shared lib instead, but
I'm having trouble calling functions in the existing shared lib.
This is going to be a bit more complicated because it turns out that
some functions the original SO ("Orig.so") call functions in another
existing SO ("another.so").
I am using Sun Studio 11/cc.
I'm just getting started, and I haven't worked with shared libs before,
but in Sun Studio, I created a .C file for my shared lib.
What I have thus far is shown below.
In the code below, what I was trying to do in the 'init' section was to
load the original SO, and then populate a global pointer
('real_dm_init') to the 'dm_init' function in the original SO.
Then, when my 'dm_init' function gets called by the server, it calls the
dm_init function in the original SO.
The function prototype for 'dm_init' is:
int dm_init(const void *, void *);
However, I am having a problem in the part of my "so_initialization"
function where I am trying to populate 'real_dm_init'. When I try that,
I am getting an error:
ld.so.1: server: fatal: relocation error: file /jim/C-projects/Orig.so:
symbol xxxxxxxxx: referenced symbol not found
"xxxxxxxxx" is one of the functions in "another.so". I guess this all
should look something like:
server my.so Orig.so another.so
=============== ============== =============== ==============
-load my.so -loads Orig.so -loads another.so
-calls dm_init =>-calls
(*real_dm_init)=>-calls xxxxxxx =>
I followed information in "man dlopen" and "man dlsym" when writing the
code below, but as mentioned above, I've not worked with shared libs
before, and I'm puzzled about why this problem is occurring, and what to
do about it.
I thought that maybe I had to include the "another.so" in the cc/link
command line, but when I did that I got a "segmentation violation"
runtime error, so I am starting to think that the code below for
populating the "real_dm_init" pointer is wrong.
So, as a first question, I was wondering if any can tell me what's wrong
with this?
Thanks,
Jim
=============== My code thus far ===================================
#include <stdio.h>
#include <stdlib.h>
#include "dmauthplug.h"
#include <dlfcn.h>
// GLOBAL variables to hold handle and function pointers
void *so_handle;
int (*real_dm_init)(const void *, void *);
// init & fini
#pragma init (so_initialization)
#pragma fini (so_finilization)
// init - load original SO, and populate function pointer(s)
void so_initialization() {
printf("IN SO init: 0000000000000000000000000000000000000000
00\n");
// get handle to original SO
so_handle = dlopen("/jim/C-projects/Orig.so", RTLD_LAZY);
if (!so_handle) {
printf("*** ERROR IN SO init: Could not get handle for
Orig.so\n");
}
else {
printf("IN SO init: Got handle for Orig.so\n");
}
// get function pointer to 'real' dm_init function in original SO
real_dm_init = (int(*)(int))dlsym(so_handle, "dm_init");
if (dlerror() != NULL) {
printf("*** ERROR SO init: Couldn't get pointer to real
dm_init\n");
}
else {
printf("IN SO init: Got pointer to function dm_init\n");
}
}
void so_finilization() {
printf("IN _FINI:
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZ\n");
}
// Wrap 'dm_init' - this gets called by 'server' program, and then
// calls the 'real' dm_init in the original SO
int dm_init(const void *inPropBag, void *outPropBag) {
return (int)(*real_dm_init)(inPropBag, outPropBag);
}
| |
| Thomas Maier-Komor 2006-01-13, 10:41 pm |
| ohaya wrote:
> Hi,
>
> Since it appears from an earlier thread that I can't use the LD_PRELOAD
> mechanism to augment an existing shared lib that I have (but don't have
> the source for), I am trying to create a wrapper shared lib instead, but
> I'm having trouble calling functions in the existing shared lib.
>
> This is going to be a bit more complicated because it turns out that
> some functions the original SO ("Orig.so") call functions in another
> existing SO ("another.so").
>
> I am using Sun Studio 11/cc.
>
> I'm just getting started, and I haven't worked with shared libs before,
> but in Sun Studio, I created a .C file for my shared lib.
>
> What I have thus far is shown below.
>
> In the code below, what I was trying to do in the 'init' section was to
> load the original SO, and then populate a global pointer
> ('real_dm_init') to the 'dm_init' function in the original SO.
>
> Then, when my 'dm_init' function gets called by the server, it calls the
> dm_init function in the original SO.
>
> The function prototype for 'dm_init' is:
>
> int dm_init(const void *, void *);
>
> However, I am having a problem in the part of my "so_initialization"
> function where I am trying to populate 'real_dm_init'. When I try that,
> I am getting an error:
>
> ld.so.1: server: fatal: relocation error: file /jim/C-projects/Orig.so:
> symbol xxxxxxxxx: referenced symbol not found
>
> "xxxxxxxxx" is one of the functions in "another.so". I guess this all
> should look something like:
>
> server my.so Orig.so another.so
> =============== ============== =============== ==============
> -load my.so -loads Orig.so -loads another.so
> -calls dm_init =>-calls
> (*real_dm_init)=>-calls xxxxxxx =>
>
> I followed information in "man dlopen" and "man dlsym" when writing the
> code below, but as mentioned above, I've not worked with shared libs
> before, and I'm puzzled about why this problem is occurring, and what to
> do about it.
>
> I thought that maybe I had to include the "another.so" in the cc/link
> command line, but when I did that I got a "segmentation violation"
> runtime error, so I am starting to think that the code below for
> populating the "real_dm_init" pointer is wrong.
>
> So, as a first question, I was wondering if any can tell me what's wrong
> with this?
>
> Thanks,
> Jim
>
>
> =============== My code thus far ===================================
> #include <stdio.h>
> #include <stdlib.h>
> #include "dmauthplug.h"
> #include <dlfcn.h>
>
> // GLOBAL variables to hold handle and function pointers
> void *so_handle;
> int (*real_dm_init)(const void *, void *);
>
> // init & fini
> #pragma init (so_initialization)
> #pragma fini (so_finilization)
>
> // init - load original SO, and populate function pointer(s)
> void so_initialization() {
> printf("IN SO init: 0000000000000000000000000000000000000000
00\n");
>
> // get handle to original SO
> so_handle = dlopen("/jim/C-projects/Orig.so", RTLD_LAZY);
> if (!so_handle) {
> printf("*** ERROR IN SO init: Could not get handle for
> Orig.so\n");
> }
> else {
> printf("IN SO init: Got handle for Orig.so\n");
> }
>
> // get function pointer to 'real' dm_init function in original SO
> real_dm_init = (int(*)(int))dlsym(so_handle, "dm_init");
> if (dlerror() != NULL) {
> printf("*** ERROR SO init: Couldn't get pointer to real
> dm_init\n");
> }
> else {
> printf("IN SO init: Got pointer to function dm_init\n");
> }
>
> }
>
> void so_finilization() {
> printf("IN _FINI:
> ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZ\n");
> }
>
> // Wrap 'dm_init' - this gets called by 'server' program, and then
> // calls the 'real' dm_init in the original SO
> int dm_init(const void *inPropBag, void *outPropBag) {
> return (int)(*real_dm_init)(inPropBag, outPropBag);
> }
First of all I would suggest using RTLD_NOW instead of RTLD_LAZY. This
will ease tracking of errors concerning dynamic linking.
Additionally check that your shared library is built correctly (flag
-G). Why didn't you investigate the cause of the segment violation? You
should enable core dumps (e.g. ulimit -cS 100000). Then you can use
pstack on the core dump or open it in dbx and analyze the stack trace
and variables that might have caused the error.
You should also check the man page of ld.so.1(1). There are a couple of
environment variables that can be used to analyze failures concerning
dynamic linking.
HTH,
Tom
|
|
|
|
|