分离出符号,同时剥离不需要的符号
Separating out symbols and stripping unneeded symbols at the same time
我有兴趣创建一个外部符号文件,我使用 objcopy --add-gnu-debuglink=...
从我的 ELF 文件中引用它。
现在我知道如何仅提取调试符号(objcopy --only-keep-debug
)以及如何仅去除调试符号(objcopy --strip-debug
).
但是,我想去掉 所有不需要的符号。我知道这可以通过 objcopy --strip-unneeded
完成。调试符号和不需要的符号是两个不同的类别和两个不同的命令行开关这一事实表明可能存在不重叠的符号。
由于不需要的符号似乎比调试符号包含 更多,我担心这样做时会丢失一些符号信息(在 GNU make 中):
stripped/%: %
objcopy --only-keep-debug $@ $@.dbg
objcopy --strip-unneeded $@
objcopy --add-gnu-debuglink=$@.dbg $@
谁能解释一下哪些符号可以通过 --strip-unneeded
删除而不能使用 --strip-debug
删除?或者换句话说:在原始二进制文件上 运行 --strip-unneeded
时,哪些未被 --only-keep-debug
保存在外部符号文件中的符号可能会丢失?有没有办法将这些符号保留在我的外部符号文件中,或者这不是问题?
目标是能够使用外部调试符号来调试问题,而不会因为丢失某些符号信息而导致为时已晚。所以我不想丢失符号信息,我只想从程序二进制文件中完全删除它。
PS:我知道 How to generate gcc debug symbol outside the build target? 但是这个问题及其答案没有触及我要问的细节。
我刚刚无意中遇到了同样的问题。
以前我只是将我构建的 ELF 二进制文件与 objcopy 的 --only-keep-debug
、--strip-debug
、--add-gnu-debuglink
标志分开。
现在我需要节省更多 space,所以我正在考虑使用 --strip-unneeded
而不是 --strip-debug
。
但是和你一样我怕这会影响我的调试体验。
所以,我做了几次测试,得出以下结论:
--strip-unneeded
剥离被 --strip-debug
剥离的内容,甚至更多。 IE。 'debug' 信息被视为 'unneeded' 信息的一部分。
- 使用
--only-keep-debug
标志创建的调试二进制文件,不仅存储由 --strip-debug
删除的信息,还存储由 --strip-unneeded
. 删除的信息
- 我没有注意到在调试
--strip-debug
和 --strip-unneeded
时有任何区别,前提是使用 --only-keep-debug
创建的调试二进制文件。
详情如下:
我创建了一个非常简单的 C++ 项目,其中包含一个可执行文件和一个共享库。
该库包含一个全局导出的函数,由应用程序调用。
该库还包含几个本地函数(即静态或匿名名称space),由全局导出函数调用。本地函数中的代码只是通过抛出未处理的异常而导致崩溃。
首先,我用 -g -O0
标志编译了两个二进制文件。
其次,我在单独的二进制文件中从它们中提取了调试信息,并将这些调试文件链接到原始二进制文件。即,对于两个文件:
objcopy --only-keep-debug $FILE $FILE.debug
objcopy --add-gnu-debuglink=$FILE.debug $FILE
在这一点之后,我有未剥离的二进制文件也有单独的对应链接调试二进制文件。
然后我将这些文件复制到另外两个目录中。在第一个中,我针对原始二进制文件完成了 --strip-debug
,在另一个中,我完成了 --strip-unneeded
.
考虑文件大小,原始文件明显最大,strip-unneeded 目录中的文件最小,strip-debug 目录中的文件居中。
此外,另外 运行ning --strip-debug
对 strip-unneeded 目录中的文件没有改变文件大小,这意味着 --strip-debug
只剥离了 [=14= 剥离的部分子集].
然后我通过 运行ning readelf -S
将所有三个变体的部分列表与所有这些进行了比较。
查看它们,可以看出 --strip-debug
剥离了以下部分:.debug_arranges
、.debug_info
、.debug_abbrev
、.debug_line
和 .debug_str
,以及还略微减少了 .symtab
和 .strtab
部分。
--strip-unneeded
还完全删除了 .symtab
和 .strtab
部分。
然后我 运行 readelf -S
针对调试二进制文件,这是我用 --only-keep-debug
标志得到的。 --strip-unneeded
删除了那里的所有部分。所以,它不仅有.debug_arranges
、.debug_info
、.debug_abbrev
、.debug_line
和.debug_str
,还有.symtab
和.strtab
。而且版块的大小和原来的大小几乎一模一样。
然后我尝试逐步调试所有三个变体,但没有发现它们之间有任何区别。我还生成了所有这些崩溃和核心转储,然后尝试针对核心转储进行调试 - 也没有区别。
使用的版本:
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
GNU objcopy(Ubuntu 的 GNU Binutils)2.26.1
GNU strip(Ubuntu 的 GNU Binutils)2.26.1
我有兴趣创建一个外部符号文件,我使用 objcopy --add-gnu-debuglink=...
从我的 ELF 文件中引用它。
现在我知道如何仅提取调试符号(objcopy --only-keep-debug
)以及如何仅去除调试符号(objcopy --strip-debug
).
但是,我想去掉 所有不需要的符号。我知道这可以通过 objcopy --strip-unneeded
完成。调试符号和不需要的符号是两个不同的类别和两个不同的命令行开关这一事实表明可能存在不重叠的符号。
由于不需要的符号似乎比调试符号包含 更多,我担心这样做时会丢失一些符号信息(在 GNU make 中):
stripped/%: %
objcopy --only-keep-debug $@ $@.dbg
objcopy --strip-unneeded $@
objcopy --add-gnu-debuglink=$@.dbg $@
谁能解释一下哪些符号可以通过 --strip-unneeded
删除而不能使用 --strip-debug
删除?或者换句话说:在原始二进制文件上 运行 --strip-unneeded
时,哪些未被 --only-keep-debug
保存在外部符号文件中的符号可能会丢失?有没有办法将这些符号保留在我的外部符号文件中,或者这不是问题?
目标是能够使用外部调试符号来调试问题,而不会因为丢失某些符号信息而导致为时已晚。所以我不想丢失符号信息,我只想从程序二进制文件中完全删除它。
PS:我知道 How to generate gcc debug symbol outside the build target? 但是这个问题及其答案没有触及我要问的细节。
我刚刚无意中遇到了同样的问题。
以前我只是将我构建的 ELF 二进制文件与 objcopy 的 --only-keep-debug
、--strip-debug
、--add-gnu-debuglink
标志分开。
现在我需要节省更多 space,所以我正在考虑使用 --strip-unneeded
而不是 --strip-debug
。
但是和你一样我怕这会影响我的调试体验。
所以,我做了几次测试,得出以下结论:
--strip-unneeded
剥离被--strip-debug
剥离的内容,甚至更多。 IE。 'debug' 信息被视为 'unneeded' 信息的一部分。- 使用
--only-keep-debug
标志创建的调试二进制文件,不仅存储由--strip-debug
删除的信息,还存储由--strip-unneeded
. 删除的信息
- 我没有注意到在调试
--strip-debug
和--strip-unneeded
时有任何区别,前提是使用--only-keep-debug
创建的调试二进制文件。
详情如下:
我创建了一个非常简单的 C++ 项目,其中包含一个可执行文件和一个共享库。 该库包含一个全局导出的函数,由应用程序调用。 该库还包含几个本地函数(即静态或匿名名称space),由全局导出函数调用。本地函数中的代码只是通过抛出未处理的异常而导致崩溃。
首先,我用 -g -O0
标志编译了两个二进制文件。
其次,我在单独的二进制文件中从它们中提取了调试信息,并将这些调试文件链接到原始二进制文件。即,对于两个文件:
objcopy --only-keep-debug $FILE $FILE.debug
objcopy --add-gnu-debuglink=$FILE.debug $FILE
在这一点之后,我有未剥离的二进制文件也有单独的对应链接调试二进制文件。
然后我将这些文件复制到另外两个目录中。在第一个中,我针对原始二进制文件完成了 --strip-debug
,在另一个中,我完成了 --strip-unneeded
.
考虑文件大小,原始文件明显最大,strip-unneeded 目录中的文件最小,strip-debug 目录中的文件居中。
此外,另外 运行ning --strip-debug
对 strip-unneeded 目录中的文件没有改变文件大小,这意味着 --strip-debug
只剥离了 [=14= 剥离的部分子集].
然后我通过 运行ning readelf -S
将所有三个变体的部分列表与所有这些进行了比较。
查看它们,可以看出 --strip-debug
剥离了以下部分:.debug_arranges
、.debug_info
、.debug_abbrev
、.debug_line
和 .debug_str
,以及还略微减少了 .symtab
和 .strtab
部分。
--strip-unneeded
还完全删除了 .symtab
和 .strtab
部分。
然后我 运行 readelf -S
针对调试二进制文件,这是我用 --only-keep-debug
标志得到的。 --strip-unneeded
删除了那里的所有部分。所以,它不仅有.debug_arranges
、.debug_info
、.debug_abbrev
、.debug_line
和.debug_str
,还有.symtab
和.strtab
。而且版块的大小和原来的大小几乎一模一样。
然后我尝试逐步调试所有三个变体,但没有发现它们之间有任何区别。我还生成了所有这些崩溃和核心转储,然后尝试针对核心转储进行调试 - 也没有区别。
使用的版本: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609 GNU objcopy(Ubuntu 的 GNU Binutils)2.26.1 GNU strip(Ubuntu 的 GNU Binutils)2.26.1