2011-11-30 41 views
7

Tôi muốn tạo ra một thư viện chia sẻ mà có thể được nạp theo hai cách khác nhau vào các mục tiêu:Tự động tải các thư viện được chia sẻ Linux?

  1. LD_PRELOAD
  2. động tải qua dlsym

thư viện chia sẻ của tôi trông như thế này:

#include "stdio.h" 

void __attribute__ ((constructor)) my_load(void); 

void my_load(void) { 
    printf("asdf"); 
} 

void someFunc(void) { 
    printf("someFunc called"); 
} 

Tôi đang biên dịch nó như sau:

all: 
    gcc -fPIC -g -c -Wall MyLib.c 
    gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

Tôi không muốn cài đặt nó với ldconfig vv Quá trình mục tiêu trông như thế này:

#include <stdio.h> 
#include <dlfcn.h> 

void func1() { 
    printf("%d\n", 1); 
} 

void func2() { 
    printf("%d\n", 2); 
} 

void func3() { 
    printf("%d\n", 3); 
} 

int main() { 
    void* lib_handle = dlopen("/home/mike/Desktop/TargetProcess/MyLib.so.1.0.1", 
         RTLD_NOW|RTLD_GLOBAL); 

    if(lib_handle == NULL) { 
    printf("Failed loading lib\n"); 
    } else { 
    printf("Loaded lib successfully\n"); 

    void (*some_func)() = dlsym(lib_handle, "someFunc"); 
    printf("%p\n", some_func); 

    dlclose(lib_handle); 
    } 

    func1(); 
    func2(); 
    func3(); 

    return 0; 
} 

Mục tiêu được biên dịch như vậy:

all: 
    gcc TestProg.c -ldl -o TestProg 

Câu hỏi của tôi là:

  1. Với tải động với dlopen như trên, tại sao my_load không xuất hiện để được gọi?
  2. Với cùng một phương pháp, tại sao dlsym luôn trả lại nil mặc dù dlopen trả về không null? Tương tự, nm không liệt kê hoặc là my_load hoặc someFunc làm biểu tượng của .so.
  3. Có thể sử dụng LD_PRELOAD để tải thư viện không? Tôi đã thử sao chép .so vào cùng một thư mục với mục tiêu sau đó gọi LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg nhưng lại một lần nữa my_load dường như không được gọi.

Trả lời

6

file đối tượng của bạn đã không liên kết vào thư viện của bạn:

gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

Thay đổi nó để bao gồm MyLib.o tập tin đối tượng của bạn:

gcc MyLib.o -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

UPDATE: chỉ tryed lệnh của bạn tại địa phương (không có bất kỳ MyLib.c hoặc MyLib.o):

$ gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc && echo ok 
ok 
$ nm MyLib.so.1.0.1 
xxxxxxxx a _DYNAMIC 
xxxxxxxx a _GLOBAL_OFFSET_TABLE_ 
     w _Jv_RegisterClasses 
xxxxxxxx A __bss_start 
     w [email protected]@xxxxxxxxxxx 
xxxxxxxx d __dso_handle 
     w __gmon_start__ 
xxxxxxxx t __i686.get_pc_thunk.bx 
xxxxxxxx A _edata 
xxxxxxxx A _end 
xxxxxxxx T _fini 
xxxxxxxx T _init 

Nó là một thư viện động trống.

+0

Hoạt động hoàn hảo. Nó được nạp như mong đợi bởi cả LR_PRELOAD cũng như động. 'my_load' cũng được gọi trong cả hai trường hợp. Cảm ơn! –

+1

Trên thực tế nó không có sản phẩm nào, nó chứa một số công cụ libc. Liên kết sẽ thất bại nếu bạn không chỉ định '-lc'. :) – ninjalj

Các vấn đề liên quan