2012-06-12 40 views
7

Tôi đã chia sẻ đối tượng A.so liên kết tĩnh với libssl.a & đối tượng chia sẻ khác B.so cũng liên kết tĩnh libssl.a.Thư viện tĩnh được tải hai lần

A.so & B.so có các ký hiệu từ libssl.a trong phạm vi GLOBAL. Tôi đã kiểm tra điều này bằng readelf -s A.so

Tôi có tệp a.out thực thi tải A.so và B.so. Khi a.out chấm dứt tôi nhận được một lỗi miễn phí đôi trong một trong các biểu tượng từ libssl.a trong A.so.

Mặc dù libssl.a được liên kết tĩnh với từng đối tượng dùng chung, vì chúng được hiển thị trên toàn cầu là có thể cùng một biểu tượng được chia sẻ thay vì chọn bản sao cục bộ.

Giải pháp này là gì? Làm thế nào để làm cho các biểu tượng địa phương ở đây?

Vui lòng giúp

+0

Tôi khuyên bạn nên sử dụng trình gỡ lỗi để xác nhận lý thuyết của mình. – jdigital

+0

Bạn có thể xây dựng? – KodeWarrior

+0

Chỉ là một điều nhỏ, bởi vì tôi không có ý tưởng làm thế nào để áp dụng nó vào tình huống của bạn: 'dlopen' có một lá cờ RTLD_LOCAL mà trong một số trường hợp sẽ giúp đỡ trong chính xác tình trạng này. Vì vậy, nếu bạn mở các thư viện đó với 'dlopen', có lẽ chúng không nên can thiệp vào đó. – liori

Trả lời

5

Điều này thực sự được mong đợi. Một ví dụ của libssl.a xen kẽ (có thể là tập hợp con của) cái kia và kết quả không đẹp. Bạn có thể sử dụng tập lệnh phiên bản (--version-script để ld, với -Wl, cho cc) để kiểm soát nội dung được xuất từ ​​A.soB.so. Nếu một cái gì đó không được xuất khẩu, nó cũng không thể xen kẽ được.

Hoặc, bạn có thể biên dịch libssl.a với cờ hiển thị như -fvisibility=hidden. Những cờ này chỉ ảnh hưởng đến liên kết động và không liên kết tĩnh. Tuy nhiên, bạn có thể cần tự biên dịch vì các tệp .a được vận chuyển có xu hướng chứa mã phụ thuộc vào vị trí, có nghĩa là để liên kết thành các tệp thực thi. Chỉ một số nền tảng như x86 32 bit cho phép bạn thoát khỏi việc liên kết mã như vậy thành các đối tượng được chia sẻ và chỉ với chi phí chuyển đổi văn bản.

dlopen với RTLD_LOCAL như được đề xuất trong nhận xét cũng nên hoạt động nhưng có vẻ như bị hack để sử dụng dlopen cho mục đích này.

Một tùy chọn khác là sử dụng cùng một chia sẻ libssl.so trong cả hai thư viện.

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