2012-12-18 14 views
5

Tôi đang cố gắng xây dựng một chương trình trong C có nhiều tính năng tùy chọn phụ thuộc vào nhiều thư viện được chia sẻ khác nhau.Phát hiện các tính năng thư viện khi chạy trong C

Trong cụm máy tính không đồng nhất của chúng tôi, không phải tất cả các thư viện đó đều có sẵn (hoặc cập nhật) trên tất cả các hệ thống.

Ví dụ như biểu tượng từ glibc mới hơn ([email protected]@GLIBC_2.6, [email protected]@GLIBC_2.6) hoặc toàn bộ thư viện chia sẻ mà có thể hoặc không có thể có sẵn (libnuma, libR, libpbs).

Tôi biết rằng tôi có thể sử dụng libdl để tải các biểu tượng với dlopendlsym, nhưng làm điều này cho một số lượng ngày càng tăng của các biểu tượng (khoảng 30 tại thời điểm này) là tẻ nhạt.

Theo như tôi hiểu các thư viện được chia sẻ trong Linux được tải theo mặc định, vì vậy biểu tượng không cần thiết cho đến khi nó thực sự được sử dụng.

Nhưng nếu tôi cố gắng kiểm tra cho rằng trước sau đó nó bị lỗi khi khởi động thực hiện:

#define _GNU_SOURCE 
#include <stdlib.h> 
#include <stdio.h> 
#include <stdint.h> 
#include <dlfcn.h> 
#include <sched.h> 

int main() { 

    void *lib_handle; 
    int (*fn)(void); 
    int x; 
    char *error; 

    lib_handle = dlopen("libc.so.6", RTLD_LAZY); 
    if (!lib_handle) 
    { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(1); 
    } 

    fn = dlsym(lib_handle, "sched_getcpu"); 
    if ((error = dlerror()) != NULL) 
    { 
     fprintf(stderr, "%s\n", error); 
     exit(1); 
    } 

    printf("%d\n", sched_getcpu()); 

    return 0; 
} 

Trên hệ thống biên dịch trong đó có tất cả các thư viện:

$ icc test.c 
$ ./a.out 
10 

Trên hệ thống khác trong đó có một ít phiên bản GLIBC gần đây:

$ ./a.out 
./a.out: /lib64/libc.so.6: version `GLIBC_2.6' not found (required by ./a.out) 

Nếu tôi nhận xét dòng thực sự gọi sched_getcpu sau đó tôi nhận được thay vì trên hệ thống ít hơn:

$ ./a.out 
/lib64/libc.so.6: undefined symbol: sched_getcpu 

Vì vậy, là có một cách để buộc các thư viện chỉ được nạp vào sử dụng và định kỳ kiểm tra như thế này trước khi khối sử dụng chúng?

+0

Có thể an toàn hơn trong thời gian dài để cố gắng làm cho cụm của bạn trở nên đồng nhất hơn một chút. Cách khác là giải pháp tốt nhất là liên kết tĩnh tất cả các tệp thi hành của bạn mà phải chạy trên các hệ thống không nhất quán được duy trì này và hy vọng rằng ít nhất chúng chạy các hạt tương thích một cách thô lỗ. Nếu cụm của bạn đang chạy một BSD, đặc biệt. NetBSD sau đó điều này sẽ dễ dàng, miễn là bạn đã liên kết ứng dụng trên phiên bản cũ nhất của hệ thống đang chạy trong cụm. –

+0

@ GregA.Woods Đây là những gì tôi tiếp tục nói với sysadmins của tôi. Nhưng vấn đề là: Tôi là một nhà phát triển phần mềm. Tôi cần viết mã và chạy nó. Tôi thậm chí không có quyền truy cập quản trị vào cụm, do đó, đó không phải là một tùy chọn. Hạt nhân là tất cả Linux, nhưng nó là một hỗn hợp của CentOS trong hương vị khác nhau trên các máy điện năng thấp và RedHat trên các siêu máy tính. –

+0

Sau đó, liên kết tĩnh là lựa chọn tốt nhất của bạn và có lẽ là duy nhất. Bạn có thể phải xây dựng máy xây dựng của riêng bạn để tìm một phiên bản hạt nhân mẫu số ít phổ biến nhất. Đối với hầu hết mọi thứ nó không phải là khó để làm một trong hai. –

Trả lời

1

Không có glibc. Đây là một không an toàn và nó được đặt ra để bạn sẽ không tự bắn mình vào chân. Nếu biểu tượng GLIBC_2.6 không được xác định và tra cứu, ngay cả khi không có biểu tượng thiếu nào khác, bạn có thể nhận được kết quả rác từ glibc (hỏng dữ liệu và sự cố) vì nó không tương thích về phía trước.

Nếu bạn cần khả năng tương thích ở cấp độ glibc, bạn cần phải xây dựng dựa trên phiên bản phổ biến thấp nhất.

+0

OK, vì vậy tôi sẽ phải tự tải biểu tượng glibc hoặc sử dụng 'syscall' trực tiếp. Tại thời điểm này tôi chỉ không tương thích với hai biểu tượng được liệt kê. Còn các thư viện khác thì sao? –

+0

@SergeyL. Các thư viện khác hoạt động như bình thường. Nếu định nghĩa của các ký hiệu bạn cung cấp tương thích, chúng sẽ hoạt động. –

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