GCC 版本脚本可以包含调试符号吗?
Can GCC version script include debug symbols?
在使用 GCC 构建共享库时,无需使用版本脚本,我们可以将调试符号拆分为单独的 .dbg 文件,从而允许我们调试到故障转储中。
objcopy --only-keep-debug foo.so foo.dbg
objcopy --strip-unneeded foo.so
objcopy --add-gnu-debuglink=foo.dbg foo.so
现在,我们正在探索使用 --version-script
选项仅导出我们库的 public 函数
{
global:
extern "C" {
fooInterface*;
};
local: *;
};
但是,这似乎隐藏了所有 符号(fooInterface() 除外),包括动态和静态调试符号。
在很多方面这就是我们想要的,但是有什么方法可以两全其美吗?是否有可能以仅导出 public 函数的共享库结束,同时仍然能够使用单独的 .dbg 文件调试故障转储?
Is it possible to end up with a shared library that only exports the public functions, while still being able to debug into crash dumps with a separate .dbg file?
linker 版本脚本(它不是 GCC 版本脚本)完全与调试信息正交。
即:完全相同的解决方案 应该工作:link foo.so
与版本脚本,然后使用 objcopy
保存调试信息并删除不需要的符号。
我刚刚在一个简单的例子上对此进行了测试,它有效:
$ cat foo.c
int bar()
{
return 42;
}
int fooInterface()
{
return bar();
}
$ gcc -g -fPIC -shared -o foo.so foo.c -Wl,--version-script=foo.lds
$ objcopy --only-keep-debug foo.so foo.dbg
$ objcopy --strip-unneeded foo.so
$ objcopy --add-gnu-debuglink=foo.dbg foo.so
观察到只有 fooInterface
从 foo.so
导出:
$ nm foo.so | grep ' T '
nm: foo.so: no symbols
$ nm -D foo.so | grep ' T '
0000000000001100 T fooInterface
观察到 GDB 加载 full 符号没有问题 foo.so
:
$ gdb -q ./foo.so
Reading symbols from ./foo.so...
Reading symbols from /tmp/vs/foo.dbg... <<<=== Note
(gdb) info func bar
All functions matching regular expression "bar":
File foo.c:
1: int bar();
如果上面的例子对你不起作用,你可能有一个有问题的 GDB 或 binutils 版本。
如果示例有效,但您的真实库没有,那么您可能在构建过程中的某个地方犯了错误。
在使用 GCC 构建共享库时,无需使用版本脚本,我们可以将调试符号拆分为单独的 .dbg 文件,从而允许我们调试到故障转储中。
objcopy --only-keep-debug foo.so foo.dbg
objcopy --strip-unneeded foo.so
objcopy --add-gnu-debuglink=foo.dbg foo.so
现在,我们正在探索使用 --version-script
选项仅导出我们库的 public 函数
{
global:
extern "C" {
fooInterface*;
};
local: *;
};
但是,这似乎隐藏了所有 符号(fooInterface() 除外),包括动态和静态调试符号。
在很多方面这就是我们想要的,但是有什么方法可以两全其美吗?是否有可能以仅导出 public 函数的共享库结束,同时仍然能够使用单独的 .dbg 文件调试故障转储?
Is it possible to end up with a shared library that only exports the public functions, while still being able to debug into crash dumps with a separate .dbg file?
linker 版本脚本(它不是 GCC 版本脚本)完全与调试信息正交。
即:完全相同的解决方案 应该工作:link foo.so
与版本脚本,然后使用 objcopy
保存调试信息并删除不需要的符号。
我刚刚在一个简单的例子上对此进行了测试,它有效:
$ cat foo.c
int bar()
{
return 42;
}
int fooInterface()
{
return bar();
}
$ gcc -g -fPIC -shared -o foo.so foo.c -Wl,--version-script=foo.lds
$ objcopy --only-keep-debug foo.so foo.dbg
$ objcopy --strip-unneeded foo.so
$ objcopy --add-gnu-debuglink=foo.dbg foo.so
观察到只有 fooInterface
从 foo.so
导出:
$ nm foo.so | grep ' T '
nm: foo.so: no symbols
$ nm -D foo.so | grep ' T '
0000000000001100 T fooInterface
观察到 GDB 加载 full 符号没有问题 foo.so
:
$ gdb -q ./foo.so
Reading symbols from ./foo.so...
Reading symbols from /tmp/vs/foo.dbg... <<<=== Note
(gdb) info func bar
All functions matching regular expression "bar":
File foo.c:
1: int bar();
如果上面的例子对你不起作用,你可能有一个有问题的 GDB 或 binutils 版本。
如果示例有效,但您的真实库没有,那么您可能在构建过程中的某个地方犯了错误。