Summary: | stl templates exported as weak symbols though visibility hidden is used | ||
---|---|---|---|
Product: | gcc | Reporter: | Mike Hommey <mh+gcc> |
Component: | libstdc++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED INVALID | ||
Severity: | normal | CC: | gcc-bugs, pawel_sikora |
Priority: | P3 | ||
Version: | 4.3.0 | ||
Target Milestone: | --- | ||
Host: | x86_64-linux-gnu | Target: | |
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | ||
Attachments: |
remove visibility attribute with -D_GLIBCXX_VISIBILITY=0, run testuite with it and -fvisibility-hidden
add key functions to classes in stdexcept |
Description
Mike Hommey
2008-04-23 06:27:37 UTC
The std:: namespace is supposed to be exposed and is marked as such in the libstdc++ headers. So I don't think this is a bug. Usually, when you're using visibility hidden, that means you want to avoid exporting a lot of cruft symbols from a shared library... that the std:: namespace is always visibility default is an annoyance. Especially considering the set of exported symbols change with optimization, since some of these might end up inlined: $ g++-4.3 -O3 -shared -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -o foo.so foo.cpp $ objdump -T -C foo.so | grep std 0000000000000780 w DF .text 00000000000002fe Base void std::__introsort_loop<int*, long>(int*, int*, long) $ g++-4.3 -O2 -shared -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -o foo.so foo.cpp $ objdump -T -C foo.so | grep std 0000000000000a40 w DF .text 00000000000000a6 Base void std::__insertion_sort<int*>(int*, int*) 00000000000008d0 w DF .text 0000000000000161 Base void std::__introsort_loop<int*, long>(int*, int*, long) 00000000000007e0 w DF .text 00000000000000eb Base void std::__adjust_heap<int*, long, int>(int*, long, long, int) $ g++-4.3 -O1 -shared -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -o foo.so foo.cpp $ objdump -T -C foo.so | grep std 0000000000000c65 w DF .text 0000000000000063 Base void std::make_heap<int*>(int*, int*) 0000000000000ee0 w DF .text 0000000000000051 Base void std::__final_insertion_sort<int*>(int*, int*) 0000000000000b52 w DF .text 0000000000000024 Base void std::__unguarded_linear_insert<int*, int>(int*, int) 0000000000000b76 w DF .text 0000000000000053 Base void std::__push_heap<int*, long, int>(int*, long, long, int) 0000000000000b10 w DF .text 0000000000000042 Base int* std::__unguarded_partition<int*, int>(int*, int*, int) 0000000000000d21 w DF .text 0000000000000053 Base void std::sort_heap<int*>(int*, int*) 0000000000000cc8 w DF .text 0000000000000059 Base void std::__heap_select<int*>(int*, int*, int*) 0000000000000e72 w DF .text 000000000000006a Base void std::__insertion_sort<int*>(int*, int*) 0000000000000d80 w DF .text 00000000000000f2 Base void std::__introsort_loop<int*, long>(int*, int*, long) 0000000000000bc9 w DF .text 000000000000009c Base void std::__adjust_heap<int*, long, int>(int*, long, long, int) Created attachment 17216 [details]
remove visibility attribute with -D_GLIBCXX_VISIBILITY=0, run testuite with it and -fvisibility-hidden
This isn't a bug, but rather part of a deliberate linkage strategy. For C++, types that are to be used across shared libraries have to be visible. See: http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options And in particular: Note that `-fvisibility' does affect C++ vague linkage entities. This means that, for instance, an exception class that will be thrown between DSOs must be explicitly marked with default visibility so that the `type_info' nodes will be unified between the DSOs. Thus, the rationale for libstdc++ having namespace std have visibility "default." If you were to hack in support for allowing namespace std to have hidden visibility, and run the testsuite with -fvisibility=hidden (see attached patch) you would notice the breakdown in testresults, with mass failures. Thus, it is provided for information purposes only. In the libstdc++ source files, anonymous namespaces are used for specific entities that have both local/hidden linkage. This use of anonymous namespaces is considered superior to attribute hidden as it uses ISO C++ and is thus more portable than vendor extensions (pragmas or attributes). However, in libstdc++ header files, attribute hidden has been difficult to use. One might think that perhaps all the implementation details could be moved to say std::__detail, and then marked with attribute hidden. Then, many of these helper functions would be marked as hidden in your example below. There are some pitfalls with this approach: 1) all these implementation base types that are used by default derived classes would have to be default 2) same with implementation details that use static locals 3) same with virtual functions, etc etc. 4) thus you end up with a pretty limited set of hidden things In addition, this may exacerbate the dlopen + RTLD_LOCAL + weak symbol issue for C++. I understand this can be closed as invalid, then. Created attachment 22215 [details]
add key functions to classes in stdexcept
FWIW. This patch an top of the patch from Benjamin Kosnik against gcc-4.4.5 gets:
=== libstdc++ Summary ===
# of expected passes 5861
# of unexpected failures 1
# of expected failures 80
# of unsupported tests 338
The one failure is abi_check which is due to the new destructor symbols not being versioned properly.
With the patch, the virtual tables and typeinfo for standard exceptions are stored once in libstdc++.so, rather than having weak/comdat definitions duplicated in every object file.
This seems beneficial in it's own right.
|