LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-06-2008, 05:28 AM   #1
roby1984
LQ Newbie
 
Registered: Mar 2008
Posts: 6

Rep: Reputation: 0
C++ Dynamically Loaded Libraries & Automake (invalid ELF library error)


Hi, I'm in big big troubles using dynamically loaded libraries under Linux. I've created a source tree using the acmkdir tool, then I decided to structure my project as follows:
src/ /* source code of main program */
src/libLine/ /* source code of dyn-loaded library */
The program I'm going to develop should use wxWidgets and their wrapper for OpenGL to draw geometric primitives as stated in a XML file or instructed through a Unix socket. I thought to put all OpenGL-related stuff in separate classes loaded at runtime (so that, if anyone wants to provide another geometric primitive, it just has to develop one accordingly to the known interface and put the library file in the proper directory).
I wanted to load the library using dlopen() and the other tools, but I was not sure of compiling options, so I've made a test program and tried them. The 'reconf' script complained about the fact that the library wasn't give a ".la" name, so I've changed it and changed accordingly the names in Makefile.am, then I've compiled the whole thing.

File: src/main.cc
Code:
#include <iostream>
#include <dlfcn.h>

int
main(int argc, char** argv)
{
  void* handle = dlopen("libLine.la", RTLD_LAZY);
  if(handle == 0) {
    std::cerr << dlerror() << std::endl;
    return(-1);
  }

  typedef void (*test_t)();

  test_t test = (test_t) dlsym(handle, "my_function");
  const char *dlsym_error = dlerror();
  (*test)();
  dlclose(handle);

  return(0);
}
File: src/libLine/line.cc
Code:
#include <iostream>

extern "C" {
  void
  my_function()
  {
    std::cout << "Successfully loaded lib!" << std::endl;
  }
}
The Makefile.am and configure.ac follows:

File: Makefile.am
Code:
EXTRA_DIST = reconf configure
SUBDIRS = src/libLine testcases m4 src doc
File: configure.ac
Code:
AC_INIT([3DVisor],
        [0.0.1],
        [Roby1984],
        [3DVisor])
AC_CONFIG_AUX_DIR(config)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE([dist-bzip2])

AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
AC_PROG_RANLIB
AC_PROG_CC
AC_PROG_CXX

AC_CONFIG_FILES([
   Makefile
   README
   doc/Makefile
   m4/Makefile
   src/Makefile
   src/libLine/Makefile
   testcases/Makefile
])

AC_OUTPUT( )
File: src/Makefile.am
Code:
bin_PROGRAMS = 3DVisor
3DVisor_SOURCES = main.cc
3DVisor_LDADD = "-dlopen" ./libLine/libLine.la
3DVisor_DEPENDENCIES = ./libLine/libLine.la


AM_CXXFLAGS = -O2 `wx-config --cxxflags` -export-dynamic
AM_LDFLAGS = `wx-config --gl-libs` -lglut -ldl -Wl,-rpath,./libLine -lSockets
File: src/libLine/Makefile.am
Code:
lib_LTLIBRARIES = libLine.la
libLine_la_SOURCES = line.cc line.hh

libLine_la_CXXFLAGS = -O2 -fPIC -shared -fpic -Wl,-soname=libLine.so
libLine_la_LDFLAGS = -module
It should be pointed out that several options were tried before the ones that you can see, I've searched around the web for hours and experimented different values, but either refuses to compile (and the 'reconf' script complains about wrong parameters) or compiles successfully but, when the executable is run, it prompts out the error:
roby@archimedes:~/3DVisor/src$ ./3DVisor
./libLine/libLine.la: invalid ELF header

I'm literally going insane with it! Thanks in advance to anyone who is willing to help me.
 
Old 03-06-2008, 05:39 AM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
You need to use -ldl instead of -dlopen. Also, you never need to supply the library and compilation flags when using automake, so you can essentially clear *_CXXFLAGS and *_LDFLAGS since their options won't port to all versions of cc. Try those things and see where you get.
ta0kira

Last edited by ta0kira; 03-06-2008 at 05:41 AM.
 
Old 03-06-2008, 06:36 AM   #3
roby1984
LQ Newbie
 
Registered: Mar 2008
Posts: 6

Original Poster
Rep: Reputation: 0
I've changed the Makefile.am files as follows

File: src/Makefile.am:
Code:
bin_PROGRAMS = 3DVisor
3DVisor_SOURCES = main.cc
3DVisor_LDADD = -ldl
File: src/libLine/Makefile.am:
Code:
lib_LTLIBRARIES = lib3DVisline.la
lib3DVisline_la_SOURCES = line.cc line.hh
I've exported the LD_LIBRARY_PATH variable (otherwise I could only obtain
roby@archimedes:~$ 3DVisor
libLine.la: cannot open shared object file: No such file or directory
)
but the error remains the same:
roby@archimedes:~$ 3DVisor
/usr/local/lib/libLine.la: invalid ELF header

Using strace I obtain the following
Code:
roby@archimedes:~$ strace 3DVisor
execve("/usr/local/bin/3DVisor", ["3DVisor"], [/* 38 vars */]) = 0
brk(0)                                  = 0x602000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b1685e20000
uname({sys="Linux", node="archimedes", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b1685e21000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/usr/local/lib/tls/x86_64/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/local/lib/tls/x86_64", 0x7fff24ca3720) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/tls/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/local/lib/tls", 0x7fff24ca3720) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/x86_64/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/local/lib/x86_64", 0x7fff24ca3720) = -1 ENOENT (No such file or directory)
open("/usr/local/lib/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/local/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=151601, ...}) = 0
mmap(NULL, 151601, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b1685e23000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libdl.so.2", O_RDONLY)       = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \16\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=14624, ...}) = 0
mmap(NULL, 2109728, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b1686021000
mprotect(0x2b1686023000, 2097152, PROT_NONE) = 0
mmap(0x2b1686223000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x2b1686223000
close(3)                                = 0
open("/usr/local/lib/libstdc++.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/libstdc++.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 I\5\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=1014808, ...}) = 0
mmap(NULL, 3186696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b1686225000
mprotect(0x2b1686315000, 2093056, PROT_NONE) = 0
mmap(0x2b1686514000, 36864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xef000) = 0x2b1686514000
mmap(0x2b168651d000, 73736, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b168651d000
close(3)                                = 0
open("/usr/local/lib/libm.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libm.so.6", O_RDONLY)        = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320>\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=526568, ...}) = 0
mmap(NULL, 2621672, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b1686530000
mprotect(0x2b16865b0000, 2093056, PROT_NONE) = 0
mmap(0x2b16867af000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7f000) = 0x2b16867af000
close(3)                                = 0
open("/usr/local/lib/libgcc_s.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240!\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=56072, ...}) = 0
mmap(NULL, 2151816, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b16867b1000
mprotect(0x2b16867be000, 2097152, PROT_NONE) = 0
mmap(0x2b16869be000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd000) = 0x2b16869be000
close(3)                                = 0
open("/usr/local/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\334\1\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1408312, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b16869bf000
mmap(NULL, 3514744, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b16869c0000
mprotect(0x2b1686b12000, 2093056, PROT_NONE) = 0
mmap(0x2b1686d11000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x151000) = 0x2b1686d11000
mmap(0x2b1686d16000, 16760, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b1686d16000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b1686d1b000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b1686d1c000
arch_prctl(ARCH_SET_FS, 0x2b1686d1bb10) = 0
mprotect(0x2b1686d11000, 12288, PROT_READ) = 0
mprotect(0x2b1686514000, 24576, PROT_READ) = 0
munmap(0x2b1685e23000, 151601)          = 0
open("/usr/local/lib/lib3DVisline.la", O_RDONLY) = 3
read(3, "# lib3DVisline.la - a libtool li"..., 832) = 832
close(3)                                = 0
brk(0)                                  = 0x602000
brk(0x623000)                           = 0x623000
write(2, "/usr/local/lib/lib3DVisline.la: "..., 50/usr/local/lib/lib3DVisline.la: invalid ELF header) = 50
write(2, "\n", 1
)                       = 1
exit_group(-1)                          = ?
Process 11153 detached
and with ltrace
Code:
__libc_start_main(0x400a30, 1, 0x7fffea22b8a8, 0x400b20, 0x400b10 <unfinished ...>
_ZNSt8ios_base4InitC1Ev(0x6014f4, 65535, 0x7fffea22b8b8, 0x400b20, 0)                            = 0
__cxa_atexit(0x400a20, 0, 0x601298, 0x2b06c0f94d20, 0x2b06c178d580)                              = 0
dlopen("lib3DVisline.la", 1)                                                                     = NULL
dlerror()                                                                                        = "/usr/local/lib/lib3DVisline.la: "...
_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(0x6012c0, 0x602050, 0x602010, 65, 0x602010/usr/local/lib/lib3DVisline.la: invalid ELF header) = 0x6012c0
_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(0x6012c0, 0, 0x2b06c178e950, 0x2b06c0f8fe78, 0x2b06c1793b10
) = 0x6012c0
_ZNSt8ios_base4InitD1Ev(0x6014f4, 0xffffffff, 0x2b06c178e2d0, -1, 0x2b06c1793b10)                = 0x2b06c0f94f60
+++ exited (status 255) +++

Any clue? Thanks!

Last edited by roby1984; 03-06-2008 at 06:41 AM. Reason: added ltrace output
 
Old 03-06-2008, 08:35 AM   #4
roby1984
LQ Newbie
 
Registered: Mar 2008
Posts: 6

Original Poster
Rep: Reputation: 0
Unhappy

I've experimented a bit more. It seems like it wants to be linked against a .so file, but those are generated only during the "make install" phase, and even in that case it always requires a ".la" library. I've used readelf to try to figure out what happens, it returns me an error:
readelf: Error: Unable to read in 0x6e65 bytes of section headers
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

when run on the ".la" file, but it returns as expected when run on the ".so" file extracted from it. Being close to desperation, I tried to compile/link it by hand, but no way, it requests me the dam*ed ".la" file just to complain that it is not an ELF file...
 
Old 03-06-2008, 09:34 AM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
No, you need to link to the .la files since automake is meant to decide between static and shared versions (because some systems don't have shared libs.) You need to add ./libLine/libLine.la (or ./libLine/lib3DVisline.la, whichever) back into 3DVisor_LDADD. Also, add this line to src/Makefile.am:
Code:
SUBDIRS = libLine
ta0kira
 
Old 03-06-2008, 09:54 AM   #6
roby1984
LQ Newbie
 
Registered: Mar 2008
Posts: 6

Original Poster
Rep: Reputation: 0
I had already fixed the SUBDIRS issue because I found it in one of the tutorials I read trying to fix the problem. The problem however remains even with those changes. I've uploaded the source tree on the web, it can be downloaded from here: Source tree
Thank you very much!
 
Old 03-07-2008, 03:13 AM   #7
roby1984
LQ Newbie
 
Registered: Mar 2008
Posts: 6

Original Poster
Rep: Reputation: 0
Smile

I finally solved the issue, it was just a wrong library name left in main.cc while trying to get right compile options
I'd like to give a big thank to ta0kira for the help!
 
Old 09-12-2008, 07:41 AM   #8
BiGNoRm6969
LQ Newbie
 
Registered: Sep 2008
Posts: 1

Rep: Reputation: 0
I have a similar problem. I need to specify which .so libraries to use for the linking process. In which file do I need to include this information (makefile.am ??). And what exactly do I need to write (I saw a lot of things in your makefile.am sample) ?

Thanks

Normand Bedard (normand.bedardATgmail.com)
 
Old 09-12-2008, 08:59 AM   #9
roby1984
LQ Newbie
 
Registered: Mar 2008
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by BiGNoRm6969 View Post
I have a similar problem. I need to specify which .so libraries to use for the linking process. In which file do I need to include this information (makefile.am ??). And what exactly do I need to write (I saw a lot of things in your makefile.am sample) ?

Thanks

Normand Bedard (normand.bedardATgmail.com)
For dynamical linking you have to specify in the Makefile.am file of your application the "-rdynamic" flag in this way
Code:
programname_CXXFLAGS = -rdynamic
Then, in the linking part of the Makefile.am file, you must specify where the library to link against to is located
Code:
programname_LDFLAGS = -Wl,-rpath,/path/to/your/lib/dir
In the directory of your library simply put a Makefile.am with a content similar to the following one
Code:
lib_LTLIBRARIES = libName.la
libName_la_SOURCES = Name.cc Name.hh
If you use Libtool, you have to set the corresponding flags in the configure.ac file in your sources' root directory, and you must also tell Autotools that you're going to use dl_open()
Code:
AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
AC_PROG_RANLIB
If you want I can send you the entire (working) version of my project, so that you can simply do some cut&paste to solve your problem...
Hope this helps!

Roberto
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
libpcre invalid ELF header error. geoffd4 Linux - Software 2 01-18-2022 05:12 PM
Linux Dynamically Loaded Libraries and Global Variables Millenniumman Programming 3 06-13-2007 11:37 AM
Invalid ELF Header Error when Compiling - Dell Inspiron 600m rudane Linux - Desktop 0 10-03-2006 05:12 PM
Invalid ELF header when using Automake/Autoconf Zotty Programming 1 09-17-2004 01:23 PM
Linux Emulation problem "ELF file OS ABI invalid Error" man26 *BSD 0 08-03-2004 11:57 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration