zoukankan      html  css  js  c++  java
  • 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.11elfldconfig.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/00/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:

  • 相关阅读:
    springboot配置jsp
    idea项目启动问题
    源码中的设计模式-模板方法模式
    Kafka Eagle CentOS6安装
    源码中的设计模式-静态代理模式
    MySQL主从复制小记
    源码中的设计模式-观察者模式
    源码中的设计模式-单例模式
    Superset
    Hive随记
  • 原文地址:https://www.cnblogs.com/tsecer/p/14701691.html
Copyright © 2011-2022 走看看