2013-02-15 21 views
10

Tôi có một ứng dụng sử dụng dlopen() để tải các mô-đun bổ sung. Ứng dụng và mô-đun được xây dựng trên Ubuntu 12.04 x86_64 sử dụng gcc 4.6 nhưng cho kiến ​​trúc i386. Các tệp nhị phân sau đó được sao chép sang một máy khác có cùng hệ điều hành và hoạt động tốt.Không thể tải thêm bất kỳ đối tượng nào có TLS tĩnh

Tuy nhiên nếu họ được sao chép vào Ubuntu 12.04 i386 sau đó một số (nhưng không phải tất cả) các module không tải với thông báo sau:

dlopen: cannot load any more object with static TLS 

tôi sẽ nghi ngờ rằng điều này là do việc sử dụng __thread biến. Tuy nhiên các biến như vậy không được sử dụng trong các mô-đun được tải - chỉ trong mô-đun bộ nạp.

Ai đó có thể cung cấp bất kỳ thông tin bổ sung nào, điều gì có thể là lý do?

Tôi đang giảm số __thread biến và tối ưu hóa chúng (với -ftls-model vv), tôi chỉ tò mò tại sao nó không hoạt động trên hầu hết cùng hệ thống.

+0

Related: http://stackoverflow.com/questions/13650740/dlopen-cannot-load-any-more-object-with-static-tls – Wok

Trả lời

11

Tôi cho rằng điều này là do việc sử dụng biến __thread.

Đúng.

Tuy nhiên, các biến này không được sử dụng trong các mô-đun được tải - chỉ trong mô-đun bộ nạp.

Không chính xác. Bạn có thể không tự mình sử dụng __thread, nhưng một số thư viện bạn liên kết tĩnh vào mô-đun là sử dụng. Bạn có thể xác nhận điều này với:

readelf -l /path/to/foo.so | grep TLS 

lý do có thể là gì?

Mô-đun đang sử dụng -ftls-model=initial-exec, nhưng phải sử dụng -ftls-model=global-dynamic. Điều này thường xảy ra nhất khi (một số) mã được liên kết thành foo.so được xây dựng mà không cần -fPIC.

Liên kết mã không -fPIC vào thư viện được chia sẻ là không thể trên x86_64, nhưng được cho phép trên ix86 (và dẫn đến nhiều sự cố tinh tế, như vấn đề này).

Cập nhật:

Tôi đã 1 mô-đun được biên soạn mà không -fPIC, nhưng tôi không đặt tls-mô hình ở tất cả, như xa như tôi nhớ những giá trị mặc định là không ban đầu-exec

  • Chỉ có thể có một mô hình tls cho mỗi hình ảnh ELF (thư viện có thể thực thi hoặc được chia sẻ).
  • Mô hình TLS mặc định là initial-exec cho mã không -fPIC.

Nó sau đó nếu bạn liên kết thậm chí một đối tượng phi -fPIC sử dụng __thread vào foo.so, sau đó foo.so được initial-exec cho tất cả của TLS của nó.

Vậy tại sao nó gây ra vấn đề - bởi vì nếu sử dụng lệnh exec ban đầu thì số biến tls bị giới hạn (vì chúng không được phân bổ động)?

Đúng.

+0

Tôi không hiểu đầy đủ. Tôi có 1 mô-đun biên dịch mà không có -fPIC (Tôi đã thử nghiệm với hiệu năng), nhưng tôi không đặt tls-mô hình ở tất cả, theo như tôi nhớ giá trị mặc định không phải là ban đầu-exec? Vậy tại sao nó gây ra vấn đề - bởi vì nếu sử dụng lệnh initial-exec thì số biến tls bị giới hạn (vì chúng không được cấp phát động)? Tôi đã giải quyết vấn đề của mình bằng cách giảm số lượng __thread vars (chúng nằm trong tiêu đề .h được sử dụng trong vài module, tôi đặt tất cả thành một phần) và lỗi đã biến mất, nhưng tôi vẫn tò mò. – queen3

+1

@ queen3 Tôi đã cập nhật câu trả lời. –

+0

@EmployedRussian 'readelf -l' ->' readelf --dynamic'? –

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