gpt4 book ai didi

c++ - 在使用 g++ 创建的共享库中隐藏实例化模板

转载 作者:IT老高 更新时间:2023-10-28 22:59:52 25 4
gpt4 key购买 nike

我有一个包含以下内容的文件:

#include <map>

class A {};

void doSomething() {
std::map<int, A> m;
}

当使用 g++ 编译成共享库时,该库包含 std::map<int, A> 的所有方法的动态符号.从 A是该文件私有(private)的,不可能 std::map将在具有相同参数的任何其他共享库中实例化,因此我想隐藏模板实例化(出于 this document 中描述的某些原因)。

我认为我应该能够通过添加模板类的显式实例并将其标记为隐藏来做到这一点,如下所示:

#include <map>

class A {};
template class __attribute__((visibility ("hidden"))) std::map<int, A>;

void doSomething() {
std::map<int, A> m;
}

但是,这没有任何效果:符号仍然全部导出。我还尝试使用以下命令包围整个文件:

#pragma GCC visibility push(hidden)
...
#pragma GCC visibility pop

但这也不会影响 std::map<int, A> 方法的可见性(尽管它确实隐藏了 doSomething )。同样,使用 -fvisibility=hidden 编译对 std::map<int, A> 的方法的可见性没有影响.

我上面链接的文档描述了使用导出 map 来限制可见性,但这似乎很乏味。

有没有办法在 g++ 中做我想做的事情(除了使用导出映射)?如果是这样,它是什么?如果没有,是否有充分的理由为什么必须始终导出这些符号,或者这只是 g++ 中的一个遗漏?

最佳答案

来自 GCC 错误报告 #36022 ,标记为 INVALID,Benjamin Kosnik 评论道:

[A]n 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."

另外,查看 std::map 的 libstdc++ 源代码(我的在 /usr/include/c++/4.4.4/bits/stl_map.h 中),看来 libstdc++ 强制默认可见性的方式是使用 _GLIBCXX_BEGIN_NESTED_NAMESPACE stl_map.h 顶部使用的宏:

# define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ (#V)))
# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) _GLIBCXX_BEGIN_NAMESPACE(X)
# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY_ATTR(default) {

因此,您的 STL 实现明确覆盖了 -fvisibility=hidden#pragma GCC visibility push(hidden)/#pragma GCC visibility pop .

如果你真的想强制 std::map成员具有隐藏的可见性,那么我认为您可以使用以下内容:

// ensure that default visibility is used with any class that is used as an exception type
#include <memory>
#include <new>
#include <stdexcept>

// now include the definition of `std::map` using hidden visibility
#include <bits/c++config.h>
#undef _GLIBCXX_VISIBILITY_ATTR
#define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ ("hidden")))
#include <map>
#undef _GLIBCXX_VISIBILITY_ATTR
#define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ (#V))) // restore `_GLIBCXX_VISIBILITY_ATTR`

然后,以下一系列命令将验证 std::map<int, A>可以从共享对象中剥离成员:

  1. g++ -c -fPIC -fvisibility=hidden test.cpp
  2. g++ -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0 test.o
  3. strip -x libtest.so.1.0
  4. readelf -s libtest.so.1.0

请注意,在第 3 步之前,readelf -s libtest.so.1.0打印(对我而言):

Symbol table '.dynsym' contains 23 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
3: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv@GLIBCXX_3.4 (2)
4: 00000000 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@CXXABI_1.3 (3)
5: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@GCC_3.0 (4)
6: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3 (5)
7: 00000d02 5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev
8: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt
9: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
10: 000023bc 0 NOTYPE GLOBAL DEFAULT ABS _end
11: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS _edata
12: 00000d5e 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
13: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
14: 00000bac 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
15: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
16: 000007f4 0 FUNC GLOBAL DEFAULT 10 _init
17: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS
18: 00000df8 0 FUNC GLOBAL DEFAULT 13 _fini
19: 00000dba 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
20: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev
21: 00000d90 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
22: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS

Symbol table '.symtab' contains 84 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000f4 0 SECTION LOCAL DEFAULT 1
2: 00000118 0 SECTION LOCAL DEFAULT 2
3: 000001c0 0 SECTION LOCAL DEFAULT 3
4: 0000022c 0 SECTION LOCAL DEFAULT 4
5: 0000039c 0 SECTION LOCAL DEFAULT 5
6: 000006b6 0 SECTION LOCAL DEFAULT 6
7: 000006e4 0 SECTION LOCAL DEFAULT 7
8: 00000754 0 SECTION LOCAL DEFAULT 8
9: 0000077c 0 SECTION LOCAL DEFAULT 9
10: 000007f4 0 SECTION LOCAL DEFAULT 10
11: 00000824 0 SECTION LOCAL DEFAULT 11
12: 00000930 0 SECTION LOCAL DEFAULT 12
13: 00000df8 0 SECTION LOCAL DEFAULT 13
14: 00000e14 0 SECTION LOCAL DEFAULT 14
15: 00000ef8 0 SECTION LOCAL DEFAULT 15
16: 00001240 0 SECTION LOCAL DEFAULT 16
17: 0000225c 0 SECTION LOCAL DEFAULT 17
18: 00002264 0 SECTION LOCAL DEFAULT 18
19: 0000226c 0 SECTION LOCAL DEFAULT 19
20: 00002270 0 SECTION LOCAL DEFAULT 20
21: 00002358 0 SECTION LOCAL DEFAULT 21
22: 00002364 0 SECTION LOCAL DEFAULT 22
23: 000023ac 0 SECTION LOCAL DEFAULT 23
24: 000023b4 0 SECTION LOCAL DEFAULT 24
25: 00000000 0 SECTION LOCAL DEFAULT 25
26: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
27: 0000225c 0 OBJECT LOCAL DEFAULT 17 __CTOR_LIST__
28: 00002264 0 OBJECT LOCAL DEFAULT 18 __DTOR_LIST__
29: 0000226c 0 OBJECT LOCAL DEFAULT 19 __JCR_LIST__
30: 00000930 0 FUNC LOCAL DEFAULT 12 __do_global_dtors_aux
31: 000023b4 1 OBJECT LOCAL DEFAULT 24 completed.5942
32: 000023b8 4 OBJECT LOCAL DEFAULT 24 dtor_idx.5944
33: 000009b0 0 FUNC LOCAL DEFAULT 12 frame_dummy
34: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
35: 00002260 0 OBJECT LOCAL DEFAULT 17 __CTOR_END__
36: 0000123c 0 OBJECT LOCAL DEFAULT 15 __FRAME_END__
37: 0000226c 0 OBJECT LOCAL DEFAULT 19 __JCR_END__
38: 00000dc0 0 FUNC LOCAL DEFAULT 12 __do_global_ctors_aux
39: 00000000 0 FILE LOCAL DEFAULT ABS test.cpp
40: 00000d64 8 FUNC LOCAL HIDDEN 12 _ZNKSt8_Rb_treeIiSt4pairI
41: 000023b0 4 OBJECT LOCAL HIDDEN 23 DW.ref.__gxx_personality_
42: 00000b40 11 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
43: 00000bc8 129 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
44: 00000bb1 11 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
45: 00000b4c 96 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
46: 00000ca0 62 FUNC LOCAL HIDDEN 12 _ZNKSt8_Rb_treeIiSt4pairI
47: 00000ab2 19 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
48: 00002364 0 OBJECT LOCAL HIDDEN ABS _GLOBAL_OFFSET_TABLE_
49: 00000a56 92 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
50: 000009ec 30 FUNC LOCAL HIDDEN 12 _Z11doSomethingv
51: 00000c6e 49 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
52: 00000a32 35 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
53: 000023ac 0 OBJECT LOCAL HIDDEN 23 __dso_handle
54: 00000a0a 19 FUNC LOCAL HIDDEN 12 _ZNSt3mapIi1ASt4lessIiESa
55: 00002268 0 OBJECT LOCAL HIDDEN 18 __DTOR_END__
56: 00000bbc 11 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
57: 00000a1e 19 FUNC LOCAL HIDDEN 12 _ZNSt3mapIi1ASt4lessIiESa
58: 00000d2c 50 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
59: 00000aea 85 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK
60: 000009e7 0 FUNC LOCAL HIDDEN 12 __i686.get_pc_thunk.bx
61: 00002270 0 OBJECT LOCAL HIDDEN ABS _DYNAMIC
62: 00000d02 5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev
63: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS
64: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
65: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
66: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv@@GLIBCXX_3.4
67: 00000df8 0 FUNC GLOBAL DEFAULT 13 _fini
68: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt
69: 00000dba 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
70: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev
71: 00000d5e 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
72: 00000d90 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
73: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
74: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
75: 00000bac 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
76: 000023bc 0 NOTYPE GLOBAL DEFAULT ABS _end
77: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS _edata
78: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS
79: 00000000 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@@CXX
80: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@@GCC_3.0
81: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.1
82: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
83: 000007f4 0 FUNC GLOBAL DEFAULT 10 _init

然后:

Symbol table '.dynsym' contains 23 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
3: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv@GLIBCXX_3.4 (2)
4: 00000000 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@CXXABI_1.3 (3)
5: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@GCC_3.0 (4)
6: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3 (5)
7: 00000d02 5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev
8: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt
9: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
10: 000023bc 0 NOTYPE GLOBAL DEFAULT ABS _end
11: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS _edata
12: 00000d5e 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
13: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
14: 00000bac 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
15: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
16: 000007f4 0 FUNC GLOBAL DEFAULT 10 _init
17: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS
18: 00000df8 0 FUNC GLOBAL DEFAULT 13 _fini
19: 00000dba 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
20: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev
21: 00000d90 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
22: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS

Symbol table '.symtab' contains 51 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000f4 0 SECTION LOCAL DEFAULT 1
2: 00000118 0 SECTION LOCAL DEFAULT 2
3: 000001c0 0 SECTION LOCAL DEFAULT 3
4: 0000022c 0 SECTION LOCAL DEFAULT 4
5: 0000039c 0 SECTION LOCAL DEFAULT 5
6: 000006b6 0 SECTION LOCAL DEFAULT 6
7: 000006e4 0 SECTION LOCAL DEFAULT 7
8: 00000754 0 SECTION LOCAL DEFAULT 8
9: 0000077c 0 SECTION LOCAL DEFAULT 9
10: 000007f4 0 SECTION LOCAL DEFAULT 10
11: 00000824 0 SECTION LOCAL DEFAULT 11
12: 00000930 0 SECTION LOCAL DEFAULT 12
13: 00000df8 0 SECTION LOCAL DEFAULT 13
14: 00000e14 0 SECTION LOCAL DEFAULT 14
15: 00000ef8 0 SECTION LOCAL DEFAULT 15
16: 00001240 0 SECTION LOCAL DEFAULT 16
17: 0000225c 0 SECTION LOCAL DEFAULT 17
18: 00002264 0 SECTION LOCAL DEFAULT 18
19: 0000226c 0 SECTION LOCAL DEFAULT 19
20: 00002270 0 SECTION LOCAL DEFAULT 20
21: 00002358 0 SECTION LOCAL DEFAULT 21
22: 00002364 0 SECTION LOCAL DEFAULT 22
23: 000023ac 0 SECTION LOCAL DEFAULT 23
24: 000023b4 0 SECTION LOCAL DEFAULT 24
25: 00000000 0 SECTION LOCAL DEFAULT 25
26: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
27: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
28: 00000000 0 FILE LOCAL DEFAULT ABS test.cpp
29: 00000d02 5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev
30: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS
31: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
32: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
33: 00000000 0 FUNC GLOBAL DEFAULT UND _ZdlPv@@GLIBCXX_3.4
34: 00000df8 0 FUNC GLOBAL DEFAULT 13 _fini
35: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt
36: 00000dba 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
37: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev
38: 00000d5e 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
39: 00000d90 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
40: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
41: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
42: 00000bac 5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
43: 000023bc 0 NOTYPE GLOBAL DEFAULT ABS _end
44: 000023b4 0 NOTYPE GLOBAL DEFAULT ABS _edata
45: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS
46: 00000000 0 FUNC GLOBAL DEFAULT UND __gxx_personality_v0@@CXX
47: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume@@GCC_3.0
48: 00000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.1
49: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca
50: 000007f4 0 FUNC GLOBAL DEFAULT 10 _init

另见:

关于c++ - 在使用 g++ 创建的共享库中隐藏实例化模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2920275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com