gdb调试提示unknown type CU DIE想到的bash及ld缓存

一、问题

在使用gdb7.3.1调试进程的时候,出现提示不识别一些类型
(gdb) ptype Functional._M_invoker
type = int (*)(const std::_Any_data &, <unknown type in /home/tsecer/std.function/a.out, CU 0x0, DIE 0x980c>)
下面的网址提示需要安装新的gdb 8.0或者更高版本

二、本地运行的问题

下载10.1版本gdb的源代码,make之后本地启动gdb,发现会提示执行python模块有问题,所以最好执行make install安装,从而替换掉系统当前低版本gdb

三、安装之后未生效

既然安装软件就需要root权限,所以启动root权限终端执行make install。安装之后在之前打开的终端中执行gdb --version查看依然是老版本的gdb,而which gdb显示的则是新安装gdb的路径。系统默认gdb安装在/usr/bin/gdb,而源码构建的gdb在/usr/local/bin/gdb,PATH变量中一般/usr/local/bin文件夹是比/usr/bin文件夹更靠前的。

四、shell内置hash命令的作用

也就是在bash内部维护了一个 命令到可执行文件的映射缓存,当键入gdb的时候,bash会从PATH环境变量中找到可执行文件的路径并把它缓存(在进程内)起来。之前印象中bash有这个命令,但是具体是什么意义并没有关注,在遇到这个小问题的时候终于“*”了解了下这个功能。
hash [-lr] [-p filename] [-dt] [name]
Each time hash is invoked, the full pathname of the command name is determined by searching the directories in $PATH and remembered. Any previously-remembered pathname is
discarded. If the -p option is supplied, no path search is performed, and filename is used as the full file name of the command. The -r option causes the shell to forget
all remembered locations. The -d option causes the shell to forget the remembered location of each name. If the -t option is supplied, the full pathname to which each name
corresponds is printed. If multiple name arguments are supplied with -t, the name is printed before the hashed full pathname. The -l option causes output to be displayed in
a format that may be reused as input. If no arguments are given, or if only -l is supplied, information about remembered commands is printed. The return status is true
unless a name is not found or an invalid option is supplied.

五、共享库(so文件)的搜索

1、共享库的搜索

记得在so文件操作的时候,有时候需要执行ldconfig来刷新下文件路径
这里宏在构建glibc时配置,从strace看到,默认包括了/lib,/lib64,/usr/lib,/usr/lib64,
glibc-2.11\elf\ldconfig.c
int
main (int argc, char **argv)
{
……
if (!opt_only_cline)
{
parse_conf (config_file, true);

/* Always add the standard search paths. */
add_system_dir (SLIBDIR);
if (strcmp (SLIBDIR, LIBDIR))
add_system_dir (LIBDIR);
}
……
}

2、动态链接器ld.so对动态库的搜索顺序

一次为可执行文件中指定的搜索路径(RPATH节)、ldcache缓存、LD_LIBRARY_PATH环境变量中的路径、还有libc构建时生成的SYSTEM_DIRS宏,这个宏默认应该是和ldconfig中的内容相同的(不太确定),例如运行时看该变量的内容为为"/lib64/\000/usr/lib64/"。

3、什么情况下需要手动执行ldconfig

可以看到,这些通常都是标准路径,如果是自定义路径。例如/usr/lib64/something/文件夹,这个文件夹不在标准搜索路径,所以在其中添加一个文件时,可以将这个文件夹添加在/etc/ld.config.d文件中,然后执行ldconfig重新生成ld.cache,从而在动态链接器查找的时候可以从自定义文件夹中找到这个文件。

六、展示下ldconfig的使用流程

1、单独编译为so文件

由于libfoo.so不在系统文件夹中,所以链接器无法找到该文件。
tsecer@harry: cat main.cpp
#include "foo.h"

int main(int argc, const char *argv[])
{
return foo(argc);
}
tsecer@harry: cat foo.cpp
int foo(int x)
{
return x;
}
tsecer@harry: cat foo.h
int foo(int);
tsecer@harry: cat Makefile
a.out: libfoo.so
g++ main.cpp -lfoo -L. -o a.out

libfoo.so:
g++ -fPIC foo.cpp -o libfoo.so -shared

tsecer@harry: make -B
g++ -fPIC foo.cpp -o libfoo.so -shared
g++ main.cpp -lfoo -L. -o a.out
tsecer@harry: ./a.out
./a.out: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
tsecer@harry:

2、拷贝到系统文件夹下

使用root拷贝到/usr/lib64/之后,可以看到可以运行
tsecer@harry: cp libfoo.so /usr/lib64/
cp: 无法创建普通文件"/usr/lib64/libfoo.so": 权限不够
tsecer@harry: ./a.out
tsecer@harry: echo $?
1
tsecer@harry:

3、如果不拷贝而修改ld.conf

可以看到,即使在文件夹中添加了so所在的文件夹(而没有执行ldconfig),这个so依然不会被搜索到
tsecer@harry: cat /etc/ld.so.conf.d/tsecer.conf
/home/tsecer/exe.ldconfig
tsecer@harry: ./a.out
./a.out: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
tsecer@harry:

4、执行ldconfig

以root用户执行ldconfig,之后可以直接运行(so文件不在系统缺省文件夹中)
tsecer@harry: ./a.out
tsecer@harry: echo $?
1
tsecer@harry:

gdb调试提示unknown type CU DIE想到的bash及ld缓存

上一篇:Oracle db_name, db_unique_name, global_name 的区别


下一篇:ORM 创新解放劳动力 -SqlSugar 新功能介绍