【发布时间】:2019-10-24 06:06:15
【问题描述】:
我正在尝试使用 strip 命令从我的共享库中删除非公共符号,但是当我之后应用“nm -C -D”时,我仍然看到所有符号。
我已经查看过这篇文章和其他帖子:Stripping linux shared libraries 以及 gcc Wiki:https://gcc.gnu.org/wiki/Visibility 但是对于我的示例代码,建议的解决方案似乎不起作用。
我声明了两个简单的类,一个用于保持可见,另一个将被删除。对于公众,我在源代码中声明__attribute__ ((visibility ("default")))。
当我使用 -fvisibility=hidden 编译和链接并随后在共享库上运行“strip --strip-all --discard-all”时,这两个类在 T(ext) 部分中仍然可见。
这是我的头文件:
#pragma once
#if __GNUC__ >= 4
#define DLL_PUBLIC __attribute__ ((visibility ("default")))
#else
#define DLL_PUBLIC
#endif
class DLL_PUBLIC PublicClass
{
public:
PublicClass() = default;
~PublicClass() = default;
void doSomethingPublic();
};
class PrivateClass
{
public:
PrivateClass() = default;
~PrivateClass() = default;
void doSomethingPrivate();
};
这是来源:
#include <iostream>
#include "test.hpp"
void PublicClass::doSomethingPublic() { std::cout << "public call" << std::endl; }
void PrivateClass::doSomethingPrivate() { std::cout << "private call" << std::endl; }
我在 Ubuntu 18.04 上编译一个目标文件并将共享库与 gcc 7.4.0 链接:
$ /usr/local/bin/c++ -fvisibility=hidden -O3 -DNDEBUG -fPIC -std=gnu++14 -c test.cpp -o test.cpp.o
$ /usr/local/bin/c++ -fvisibility=hidden -fPIC -DNDEBUG -O3 -shared -Wl,-soname,libtest.so -o libtest.so test.cpp.o
应用 strip 命令并显示符号表:
$ strip --strip-all --discard-all --verbose libtest.so
copy from `libtest.so' [elf64-x86-64] to `stSNqAeg' [elf64-x86-64]
$ nm -C -D libtest.so
0000000000201058 B __bss_start
U __cxa_atexit
w __cxa_finalize
0000000000201058 D _edata
0000000000201060 B _end
0000000000000b84 T _fini
w __gmon_start__
00000000000008a8 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000000a60 T PublicClass::doSomethingPublic()
0000000000000af0 T PrivateClass::doSomethingPrivate()
U std::ctype<char>::_M_widen_init() const
0000000000000b80 W std::ctype<char>::do_widen(char) const
U std::ostream::put(char)
U std::ostream::flush()
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
U std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
U std::__throw_bad_cast()
U std::cout
strip 命令实际上重写了共享库(日期和大小已更改),但我仍然看到私有符号。我希望 PrivateClass::doSomethingPrivate 方法可以从符号表中删除。
如果有任何提示,我将不胜感激。
【问题讨论】:
-
这是否使用股票
g++而不是/usr/local/bin/c++复制?
标签: c++ shared-libraries visibility hidden strip