Tôi có một hệ thống Ubuntu 13.04 với phiên bản SVN mới nhất của thư viện Boost C++ được cài đặt. Việc cài đặt Boost được xây dựng bằng cách sử dụng phiên bản gcc
gốc của hệ thống, v4.7.3. Tôi sử dụng Boost khá rộng rãi, và nó hoạt động rất tốt khi tôi biên dịch bằng cách sử dụng gcc
; Tôi đã sử dụng nhiều người trong số họ, bao gồm Boost.Thread (mà tôi sẽ nói về nhiều hơn dưới đây), mà không có bất kỳ vấn đề.Segfault trong khi khởi tạo tĩnh khi liên kết Boost gcc được xây dựng thành một chương trình được biên dịch bởi Intel C++
Sự cố của tôi xảy ra nếu tôi cố gắng tạo chương trình bằng trình biên dịch C++ của Intel (tôi đã sử dụng một vài phiên bản khác nhau trong chuỗi v13.x) liên kết với thư viện Boost đã cài đặt. Khi tôi làm như vậy, tôi nhận được một lỗi phân đoạn ngay sau khi khởi động chương trình; nó xuất hiện xảy ra trong khi khởi tạo tĩnh của thư viện Boost.Thread. Dưới đây là một chương trình đơn giản ví dụ:
#include <boost/version.hpp>
#include <boost/thread.hpp>
int main()
{
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
tôi biên dịch nó bằng cách sử Intel C++:
icpc test.cc -lboost_thread -lboost_system -I/path/to/boost/inc/dir -L/path/to/boost/lib/dir
Như tôi đã nói, khi tôi chạy chương trình kết quả, tôi nhận được một segfault gần như ngay lập tức. Via gdb
, stack trace từ quan điểm của segfault là như sau:
#0 0x00007ffff79b6351 in boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()() from ./libboost_thread.so.1.55.0
#1 0x00007ffff79b02e1 in _GLOBAL__sub_I_thread.cpp() from ./libboost_thread.so.1.55.0
#2 0x00007ffff7de9876 in call_init ([email protected]=0x7ffff7ff9a10, [email protected]=1,
[email protected]=0x7fffffffe0b8, [email protected]=0x7fffffffe0c8) at dl-init.c:84
#3 0x00007ffff7de9930 in call_init (env=<optimized out>, argv=<optimized out>,
argc=<optimized out>, l=0x7ffff7ff9a10) at dl-init.c:55
#4 _dl_init (main_map=0x7ffff7ffe268, argc=1, argv=0x7fffffffe0b8, env=0x7fffffffe0c8)
at dl-init.c:133
#5 0x00007ffff7ddb68a in _dl_start_user() from /lib64/ld-linux-x86-64.so.2
#6 0x0000000000000001 in ??()
#7 0x00007fffffffe391 in ??()
#8 0x0000000000000000 in ??()
Không rất sáng tỏ, nhưng nó chết rõ ràng trong thời gian khởi tạo của libboost_thread.so
. Nếu tôi xây dựng lại Boost bao gồm ký hiệu gỡ lỗi, sau đó tôi nhận được một bức tranh tốt hơn một chút:
#0 shared_count (r=..., this=0x7ffff7bbc5f8 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep+8>)
at ./boost/smart_ptr/shared_ptr.hpp:328
#1 shared_ptr (this=0x7ffff7bbc5f0 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep>) at ./boost/smart_ptr/shared_ptr.hpp:328
#2 exception_ptr (ptr=..., this=0x7ffff7bbc5f0 <boost::exception_ptr boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>()::ep>)
at ./boost/exception/detail/exception_ptr.hpp:53
#3 boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_exception_>() at ./boost/exception/detail/exception_ptr.hpp:130
#4 0x00007ffff79b02e1 in __static_initialization_and_destruction_0 (__initialize_p=<optimized out>, __priority=<optimized out>) at ./boost/exception/detail/exception_ptr.hpp:143
#5 _GLOBAL__sub_I_thread.cpp(void)() at libs/thread/src/pthread/thread.cpp:767
#6 0x00007ffff7de9876 in call_init ([email protected]=0x7ffff7ff9a10, [email protected]=1, [email protected]=0x7fffffffe0b8, [email protected]=0x7fffffffe0c8) at dl-init.c:84
#7 0x00007ffff7de9930 in call_init (env=<optimized out>, argv=<optimized out>, argc=<optimized out>, l=0x7ffff7ff9a10) at dl-init.c:55
#8 _dl_init (main_map=0x7ffff7ffe268, argc=1, argv=0x7fffffffe0b8, env=0x7fffffffe0c8) at dl-init.c:133
#9 0x00007ffff7ddb68a in _dl_start_user() from /lib64/ld-linux-x86-64.so.2
#10 0x0000000000000001 in ??()
#11 0x00007fffffffe391 in ??()
#12 0x0000000000000000 in ??()
Đó là chưa rõ ràng cho tôi những gì tĩnh/đối tượng toàn cầu đang gây ra vấn đề xảy ra, vì vậy tôi không chắc chắn làm thế nào để tiến hành. Tôi đã sao chép hành vi này bằng cách sử dụng một số phiên bản Tăng cường và một vài phiên bản khác nhau của trình biên dịch C++ của Intel trong chuỗi v13.x, đây là bản phát hành duy nhất mà tôi có quyền truy cập vào lúc này. Tôi đã thử mọi hoán vị của trình biên dịch (tức là tôi đã xây dựng Boost với cả hai gcc
và icpc
và tôi đã xây dựng ứng dụng thử nghiệm của mình với cả hai); các hoán vị duy nhất thất bại là nơi Boost được xây dựng với gcc
và ứng dụng thử nghiệm của tôi được xây dựng bằng cách sử dụng icpc
. Trong mọi trường hợp khác, ứng dụng thử nghiệm chạy thành công.
Với những gì đã nói, bạn có thể dẫn đến câu trả lời rõ ràng:
- Tại sao không chỉ xây dựng lại Boost sử dụng
icpc
và gọi nó là một ngày? Cách tiếp cận đó dường như có hiệu quả, với thử nghiệm của tôi, nhưng tôi có những khách hàng muốn sử dụngicpc
để xây dựng phần mềm của tôi. Những khách hàng tương tự này có khả năng cài đặt gói Boost do Linux cung cấp; chúng không có bất kỳ sự kiểm soát nào đối với môi trường xây dựng đã được sử dụng để tạo ra gói đó (và, trong tất cả khả năng, nó được biên dịch bằng cách sử dụnggcc
anyway). Do đó, nếu có thể hỗ trợ cấu hình trình biên dịch hỗn hợp như vậy, điều đó sẽ tối ưu.
Có ai có bất kỳ đề xuất nào về cách tôi có thể giải quyết vấn đề khởi tạo tĩnh này không?
Tôi thực sự không biết icpc nhưng bạn đã thử liên kết với pthread chưa? Chỉ là một dự đoán hoang dã. – PeterT