ctypes.cdll.LoadLibrary() freezes when loading a .so that contains dlopen()

Russell russell at infiniteio.com
Fri Feb 13 23:49:11 EST 2015


On Friday, February 13, 2015 at 7:27:54 PM UTC-6, Ian wrote:
> On Fri, Feb 13, 2015 at 8:39 AM, Russell  wrote:
> > I have a shared library, libfoo.so, that references another .so which isn't linked but instead loaded at runtime with myso=dlopen("/usr/local/lib/libbar.so", RTLD_NOW); when I try to load it with ctypes, the call hangs and I have to ctl-c.
> >
> > (build)[dev]$ export LD_LIBRARY_PATH=/usr/local/bin
> > (build)[dev]$ python
> > Python 2.7.6 (default, Mar 22 2014, 22:59:56)
> > [GCC 4.8.2] on linux2
> > Type "help", "copyright", "credits" or "license" for more information.
> >>>> import ctypes
> >>>> ctypes.cdll.LoadLibrary ('/usr/local/lib/libfoo.so')   <--- This call hangs and have to ctl-C
> > ^CTraceback (most recent call last):
> >   File "<stdin>", line 1, in <module>
> >   File "/usr/lib/python2.7/ctypes/__init__.py", line 443, in LoadLibrary
> >    return self._dlltype(name)
> >   File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__
> >     self._handle = _dlopen(self._name, mode)
> > KeyboardInterrupt
> >>>>
> >
> >
> > My first thought was that It couldn't find libbar.so, but if I remove that file, python seg faults: /usr/local/lib/libbar.so: cannot open shared object file: No such file or directorySegmentation fault (core dumped), so it appears that it finds the dlopen() file but freezes waiting for ???
> >
> > This is on ubuntu 14.4 server. C code is compiled with -std=gnu11 -Wall -Werror -m64 -march=x86-64 -mavx -g -fPIC
> 
> This seems to work for me (Mint 17).
> 
> 
> $ cat a.c
> #include <dlfcn.h>
> #include <stdio.h>
> 
> void _init() {
>   printf("a.so._init\n");
>   dlopen("./b.so", RTLD_NOW);
> }
> $ cat b.c
> #include <stdio.h>
> 
> void _init() {
>   printf("b.so._init\n");
> }
> $ gcc -std=gnu11 -Wall -Werror -m64 -march=x86-64 -mavx -g -fPIC
> -shared -nostartfiles -o a.so a.c
> $ gcc -std=gnu11 -Wall -Werror -m64 -march=x86-64 -mavx -g -fPIC
> -shared -nostartfiles -o b.so b.c
> $ python
> Python 2.7.6 (default, Mar 22 2014, 22:59:56)
> [GCC 4.8.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>> import ctypes
> >>> ctypes.cdll.LoadLibrary('./a.so')
> a.so._init
> b.so._init
> <CDLL './a.so', handle 2860060 at 7f795ad936d0>
> 
> 
> Can you boil down the issue that you're seeing into a minimal
> reproducible example?


Thanks Ian, that's a good way to examine my problem.
Your code worked for me also.  I've taken your code and expanded it to be more representative of my issue.  One twist that i found was that I'm calling back into a.so from b.so.   I've captured that in the following code.  Note that this works for me
without error!!  There must be something else in my libs, that is causing this.  I'm still working to find my issue but I'm just replying to thank you and give anyone an update  :)


(build)[w]$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.cdll.LoadLibrary('./a.so')
a.so._init
b.so._init
b.so recived: called from a.so
in a_function
<CDLL './a.so', handle 24ab540 at 7f984bbc2350>
>>>



[w]$ cat a.c
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>


void (*mymessage)(char *message);
void *myso;

__attribute__((constructor)) void Init(void) {
  printf("a.so._init\n");

  char* error;
  myso = dlopen("./b.so", RTLD_NOW);
  if (!myso) {
     fputs (dlerror(), stderr);
     exit(1);
  }
  mymessage = dlsym(myso, "printMessage");
  if ((error = dlerror()) != NULL)  {
      fputs(error, stderr);
      exit(1);
  }
  mymessage("called from a.so");
}

void a_function(void) {
  printf("in a_function\n");
}

__attribute__((destructor)) void Close(void) {
  dlclose(myso);
}

[w]$ cat b.c
#include <stdio.h>
extern void a_function(void);

__attribute__((constructor)) void Init(void) {
  printf("b.so._init\n");
}

void printMessage(char *message) {
  printf("b.so recived: %s\n", message);
  a_function();
}

__attribute__((destructor)) void Close(void) {

}


[w]$ cat build
/usr/bin/gcc -o ./a.os -c -std=gnu11 -Wall -Werror -Wa,-ahl=./a.os.s -m64 -march=x86-64 -mavx -g -DDEBUG -fPIC a.c
/usr/bin/gcc -o ./a.so -Wl,--export-dynamic -shared -Wl,-rpath=./ -ldl ./a.os
/usr/bin/gcc -o ./b.os -c -std=gnu11 -Wall -Werror -Wa,-ahl=./b.os.s -m64 -march=x86-64 -mavx -g -DDEBUG -fPIC b.c
/usr/bin/gcc -o ./b.so -Wl,--export-dynamic -shared -Wl,-rpath=./  b.os a.so



More information about the Python-list mailing list