Help building and using a shared object (x64)


 
Thread Tools Search this Thread
Top Forums Programming Help building and using a shared object (x64)
# 8  
Old 03-28-2012
I just realized the implications of mapping in variables, not just functions. That's not guaranteed to work. There may be funky linker options to force variables to be exported, but I almost never see that done. Usually, you only export functions.

What people usually do is just keep a function around, which returns a pointer to all your relevant variables.

Something like this:

Code:
// shared.h
#ifndef __SHARED_H__
#define __SHARED_H__

struct everything
{
        const char **strings_a, **strings_b;
};

struct everything *get_everything(void);

#endif/*__SHARED_H__*/

Code:
// shared.c
#include "shared.h"

static const char *strings_a[]={ "string1", "string2", "string3", "string4" };
static const char *strings_b[]={ "string1", "string2", "string3", "string4" };
static const struct everything e={ strings_a, strings_b };

struct everything *get_everything(void) { return(&e); }

Then you load get_everything from your library, and call it to get pointers to all that shared data.

This sort of dynamic loading should be portable across not just linux but some other systems as well...

Last edited by Corona688; 03-28-2012 at 01:22 PM..
# 9  
Old 03-29-2012
Thank you for that remark.

However, the reason why my stuff works on CentOS 32bit, and not on CentOS 64bit is way beyond my comprehension.

The code for loading the so and accessing the data insisde using dlsym is exactly the same (no ifdef/else constructs there).

The onyl thing that differs between the two platforms is the way I compile my shared object:
Quote:
gcc -g -m[32|64] -Wall -fPIC -c bigfile.c
gcc -m[32|64] -shared -Wl -o <custom_new_name>.so bigfile.o
I used gdb on x64. (don't bother with the formatting about the code samples below, they are different in my code)
What I do is I first try to get my hands on a string in the so :
Quote:
const char decorator[] = "\x65\x65\x65\0";
After this, I need to use this to generate the name of the next symbol I need to load from the shared object:
Quote:
char sym_name[128+1];
memset (sym_name, 0, sizeof(sym_name));
snprintf (sym_name, 128, "var1_%s", local_decorator);
char* v = (char*) dlsym(lh, sym_name);
With gdb I realized that the decorator previously retrieved via address from the so, I actualy get some garbage address, and not the one I need. I can't do a print on the decorator from the gdb because it tells me that the address is out of bounds.

Any clue about this ?


EDIT:
Somehow, I found some weird behavior.
Currently, I have a platform independent function for loading a library:
Code:
int
util_load_library (const char *lib_file, void **handle)
{
  int err_status = NO_ERROR;
  char err_msg[ERR_MSG_SIZE];

  assert (lib_file != NULL);

  *handle =
#if defined(WINDOWS)
    LoadLibrary (lib_file);
#else
    dlopen (lib_file, RTLD_NOW);
#endif

  if (*handle == NULL)
    {
      err_status = ER_LOC_INIT;
      snprintf (err_msg, sizeof (err_msg) - 1,
		"Error loading library %s", lib_file);
      LOG_LOCALE_ERROR (err_msg, err_status, true);
    }
  return err_status;
}

The code above is in library.c, the declaration for the function is in library.h.
In util.c I include library.h, and open the so using the function above.

Somehow, if I lose the function, and simply dump the dlopen where I need it, it works fine on x64 as well.

Apparently, now I also have to determine the reason for this behavior, since it is not acceptable to duplicate the code (I am calling util_load_library in several places)

Last edited by Maelstrom; 03-29-2012 at 12:56 PM..
# 10  
Old 03-29-2012
Make absolutely sure that this function is declared everywhere you're using it. Including the right header is no longer optional when dealing with 64-bit systems.

In 32-bit x86, you can get away with passing a pointer to undeclared externals because the assumed integer parameters are big enough to hold a pointer.

In 64-bit x86, integers are still 32-bits, but pointers are 64! It will still assume the parameters are 32-bit integers, and mutilate the 64-bit pointer into fitting in the 32-bit variable, causing crashes or weird misbehavior.

Even worse problems are when you have the function declared two ways in different places; for instance having one parameter be a long in one file, and just an int in another. This works in 32-bit because int and long are the same size, but in 64, long is suddenly 64-bits, and the parameters get mangled again. This can be very hard to track down because, unlike undefined externals, it's not a compiler error, it's a linker problem, and the linker has no way to warn you about it.
# 11  
Old 03-29-2012
Well, it is declared in util.h as
Code:
int util_load_library (const char *lib_file, void **handle);

Then the function code from the previous post is placed inside util.c, which includes util.h.

After this, all the C files which call util_load_library include util.h

EDIT: could my problems be caused by the fact that some C files are compiled into another so, and loaded from there by the main app ?
# 12  
Old 03-29-2012
Using #include that way makes it possible to put nearly anything in your code so without seeing the code, I really can't tell.

I still think there's linkage problems if it works outside the function but not inside. I'd add trace statements in the function itself like
Code:
int
util_load_library (const char *lib_file, void **handle)
{
  int err_status = NO_ERROR;
  char err_msg[ERR_MSG_SIZE];

  fprintf(stderr, "util_load_library('%s', %p)\n", lib_file, handle);
  if(handle) fprintf(stderr, "\thandle points to %p\n", *handle);

  assert (lib_file != NULL);

  *handle =
#if defined(WINDOWS)
    LoadLibrary (lib_file);
#else
    dlopen (lib_file, RTLD_NOW);
#endif

  if (*handle == NULL)
    {
      err_status = ER_LOC_INIT;
      snprintf (err_msg, sizeof (err_msg) - 1,
		"Error loading library %s", lib_file);
      LOG_LOCALE_ERROR (err_msg, err_status, true);
    }
  return err_status;
}

# 13  
Old 03-30-2012
just a side note: why not to use shared memory (shmop,shmctl,shmget)?
# 14  
Old 03-30-2012
1) because SHM is RAM; suddenly corruption is possible, and you have to initialize things.
2) shm is persistent. If you're insufficiently clever in setting things up, you can get junk from before or 'permission denied'.
3) Not as convenient as "give me variable x and let the system handle what's shared or not".

Last edited by Corona688; 03-30-2012 at 09:02 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

Shared Object Question

Hello, I am new to programming shared objects and I was hoping someone could tell me if what I want to do is possible, or else lead me in the right direction. I have a main program that contains an abstract base class. I also have a subclass that I'm compiling as a shared object. The subclass... (13 Replies)
Discussion started by: dorik
13 Replies

2. Red Hat

shared object

Hi, I would like to create a shared object ( .so). This shared object 1. uses the functions from a library. 2. Also it should be able to use the global variable in an app To achieve this what should I do ? 1) To use the functions in the library should I give the -ld option while... (1 Reply)
Discussion started by: rvan
1 Replies

3. Programming

Error while running shared object

Hello, While running a c++ shared object on AIX I am facing below error - rtld: 0712-001 Symbol __ct__3ETDFv was referenced from module /bancs/aml/lib/libmonitor.so(), but a runtime definition of the symbol was not found. rtld: 0712-001 Symbol etd_insert__3ETDFv was... (3 Replies)
Discussion started by: yatrik007
3 Replies

4. AIX

AIX 5.2 C++ shared object issue

Hi all, I am developing an application with two components. One "c" binary and one "C++" shared object. While execution, the shared object crashes out and core dump is created whenever "new" is executed. But if i use malloc this will work perfectly. I tried to use dbx. Below given was... (1 Reply)
Discussion started by: itssujith
1 Replies

5. Shell Programming and Scripting

Any way to access shared object using shell

Hi, I have created a shared object (abc.so) which has a function sum(int a, int b). Is there any way to load the "abc.so" and use the sum function using shell script.. thanks in advance (2 Replies)
Discussion started by: yhacks
2 Replies

6. UNIX for Advanced & Expert Users

Issue with shared object in AIX

Hi All, I have a problem with the shared objects setup in AIX. We have a customized shell written by the developers over here. When i issue a MQ Series command (mqsilist) it is giving the error as . All the commands making use of this libImbCmdLib.a.so is failing. But when executed in normal... (1 Reply)
Discussion started by: dhanamurthy
1 Replies

7. Programming

calling a shared object from a daemon

Hi I have a multithreaded daemon(server) which will accept connections from various clients and sends back results to them. In order to serve my daemon clients, it has to establish a TCP connection to another server(vendor supplied which is listening on a specific TCP port) and gets the... (11 Replies)
Discussion started by: axes
11 Replies

8. AIX

Shared Object library problem

Hi, When using shared objects on AIX 4.3 i am getting runtime problems. I have a small sample program which links to a shared object libray, oracle and system related libraries. At runtime it fails (gives segmentation fault and coredump ) in one proc file when executing login statement. But... (0 Replies)
Discussion started by: suman_jakkula
0 Replies

9. Linux

Shared Object File

Hi All, I created the share object file using gcc -shared -fpic mypp.cpp -o myp.so but, pls tell me how to link this .so file to my client program. Thanks (0 Replies)
Discussion started by: sarwan
0 Replies

10. Programming

Does my ld support shared object creation

Hi, I have been trying to create a sharef object on my HP UX 11 machine (HP-UX <myhostname> B.11.00 A 9000/879 ...... two-user license) to create the shared object first I am creating the object file using cc -Aa -c +z dyn.c (I use -Aa and +z as per HP's manual on linkers ) to create the... (0 Replies)
Discussion started by: linuxpenguin
0 Replies
Login or Register to Ask a Question