c - dlopen: detect undefined symbols with cyclic dependencies -


i have handful of shared libraries cyclic dependencies, want load dlopen. this, call dlopen rtld_lazy | rtld_global flags.

this works fine.

now, want check symbols in shared libraries resolved, , therefore call dlopen again rtld_now, should fail if symbols can not resolved.

at least, how understand man page:

however, subsequent dlopen() call loads same shared object rtld_now may force symbol resolution shared object earlier loaded rtld_lazy.

here simple example illustrates problem:

main.h

#include <stdio.h> #include <dlfcn.h> #include <stdlib.h>  #include "h.h"  #define cnt 3 static const char *libs[cnt] = {"./liba.so", "./libb.so", "./libc.so"};  typedef int (*f_ptr)();  int main() {     void *h[cnt];     f_ptr f[cnt];      (int = 0; < cnt; i++) {         printf("dlopen: %s\n", libs[i]);         h[i] = dlopen(libs[i], rtld_lazy | rtld_global);         if (!h[i]) {             fprintf(stderr, "%d %s: %s\n", __line__, libs[i], dlerror());             exit(exit_failure);         }     }      (int = 0; < cnt; i++) {         printf("dlopen again: %s\n", libs[i]);         void *xx = dlopen(libs[i], rtld_now | rtld_global);         if (!xx) {             fprintf(stderr, "%d %s: %s\n", __line__, libs[i], dlerror());             dlclose(h[i]);             h[i] = 0;         } else {             dlclose(xx);         }     }      (int = 0; < cnt; i++) {         if (h[i]) {             f[i] = (int (*)())dlsym(h[i], "init");              if (!f[i]) {                 fprintf(stderr, "%d %s: %s\n", __line__, libs[i], dlerror());                 exit(exit_failure);             }         }     }      (int = 0; < cnt; i++) {         if (f[i]) {             printf("%s %08d\n", libs[i], f[i]());         }     }      return 0; } 

a.c

#include "h.h"  int init() { return 1 + b_(); } int a_() { return 10; } 

b.c

#include "h.h"  int init() { return 100 + a_(); } int b_() { return 1000; } 

c.c

#include "h.h"  int init() { return 10000 + x_(); } int c_() { return 100000; } 

h.h

int init(); int a_(); int b_(); int x_(); 

cmakelists.txt

project(xx)  add_library(a shared a.c) add_library(b shared b.c) add_library(c shared c.c)  add_executable(main main.c) target_link_libraries(main dl) 

compile , run:

$ mkdir b && cd b && cmake .. && make && ./main ... [100%] built target b dlopen: ./liba.so dlopen: ./libb.so dlopen: ./libc.so dlopen again: ./liba.so dlopen again: ./libb.so dlopen again: ./libc.so ./liba.so 00001001 ./libb.so 00000110 ./main: symbol lookup error: ./libc.so: undefined symbol: x_ 

how can detect libc.so not loaded - before calling symbol cause crash?

ideally you'd want put burden of symbol cross-matching on static linker suggested others (via --no-allow-shlib-undefined) rather delaying startup. it's bit complicated cyclic dependencies solaris (of linux shlibs bleak copy) has come clever solution - shlib filters. idea link against dummy shlibs export equally dummy symbols , have same sonames final production libraries. these of course used @ link time verify dependencies.

as side note, i'm pretty sure generation of dummy libs can automated, following:

  • build lib without --no-allow-shlib-undefined
  • use readelf or whatever extract exported symbols
  • generate dummy c (or asm) file defines empty stubs symbols previous item
  • build lib , voila - you've built first filter

hm, sounds nice mini-project evening.


Comments

Popular posts from this blog

php - How to add and update images or image url in Volusion using Volusion API -

javascript - IE9 error '$'is not defined -