• 使用GDB调试将符号表与程序分离后的可执行文件


    环境:

      Centos7.3、GCC4.8.5

    适用场景:

      由于调试信息比较大,通常将程序分离为可执行程序和符号信息文件,只对外发布可执行程序,需要调试时再将符号信息文件附加。

    一、创建可执行程序:

      use_library.cpp

    #include <iostream>
    #include "use_library.h"
    
    int main()
    {
        int res = my_library(1, 2);
        std::cout << "my_library:" << res << std::endl;
    }

      CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    
    project(use_libray)
    
    include_directories(/root/my_library)
    link_directories(/root/my_library/cmake)
    
    aux_source_directory(. DIR_SRCS)
    
    add_executable(use_library ${DIR_SRCS})
    target_link_libraries(use_library  my_library)

    二、创建动态库:

      my_library.h

    int my_library(int a, int b);

      my_library.cpp

    #include <stdlib.h>
    #include "my_library.h"
    
    int my_library(int a, int b)
    {
    
        int *p = NULL;
        *p = 100;
        return *p;
    }

      这里我们故意制造一个异常让进程崩溃,生成core文件。

      CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    
    project(my_library)
    
    include_directories(/root/use_library/)
    
    aux_source_directory(. DIR_SRCS)
    
    add_library(my_library SHARED ${DIR_SRCS})

    三、生成动态库:

    #生成动态库
    mkdir /home/share/my_library/cmake
    cd /home/share/my_library/cmake
    cmake -D CMAKE_BUILD_TYPE=Debug ..
    make
    
    #生成符号文件
    objcopy --only-keep-debug libmy_library.so libmy_library.so.debug
    
    #生成发布文件
    strip libmy_library.so -o libmy_library.so.release
    objcopy --add-gnu-debuglink=libmy_library.so.debug libmy_library.so.release
    cp libmy_library.so.release libmy_library.so

    四、生成可执行程序:

    #生成执行程序
    mkdir /home/share/use_library/cmake
    cd /home/share/use_library/cmake
    cmake -D CMAKE_BUILD_TYPE=Debug ..
    
    #生成符号文件
    objcopy --only-keep-debug use_library use_library.debug
    
    #生成发布文件
    strip use_library -o use_library.release
    objcopy --add-gnu-debuglink=use_library.debug use_library.release
    cp use_library.release use_library

      可以通过"objdump -s -j .gnu_debuglink xxx"命令查看关联信息。

    五、生成core文件:

    ./use_library

    六、使用符号文件进行调试:

      6.1)调试core文件

    gdb -c core.xxx

      注意不能使用gdb -c core.xxx ./use_library,由于core文件生成时使用的依赖库目录与调试目录可能不一致,如果直接加载可执行文件,会根据core文件生成时可执行文件依赖的路径,加载动态库和符号文件 。

      6.2)我们可以设置依赖库,首先查看依赖库

       将libmy_library.so和libmy_library.so.debug放在当前目录下(./home/share/my_library/cmake),并设置set solib-search-path路径

      注意动态库的路径前缀一定要一致,示例中的绝对路径为:/home/share/use_library/cmake/home/share/my_library/cmake

      关于GDB调试时,依赖库搜索路径规则为:

      1)使用solib-absolute-prefix进行搜索

      2)使用solib-search-path进行搜索

      3)使用$PATH进行搜索

      4)使用$LD_LIBRARY_PATH进行搜索

      按上面说的规则举例说明:

      1)(solib-absolute-prefix)/home/share/my_library/cmake/libmy_library.so

      2)(solib-search-path)/libmy_library.so

      3)($PATH)/(solib-absolute-prefix)/home/share/my_library/cmake/libmy_library.so

      4)($LD_LIBRARY_PATH)/(solib-absolute-prefix)/home/share/my_library/cmake/libmy_library.so

      6.3)加载可执行文件

      6.4)显示调用堆栈

     

    结尾:

      需要注意的是.debug文件需要与可执行文件或动态库在相同目录下,若还是不能调试,可能是没有关联调试文件,可以通过"objdump -s -j .gnu_debuglink xxx"命令查看关联信息。

    显示动态库符号加载信息
    info sharedlibrary
    设置动态库加载路径
    set solib-search-path 

    参考资料:

      1)http://blog.chinaunix.net/uid-13746440-id-5578584.html

      2)https://www.jb51.net/article/136097.htm

      3)https://blog.csdn.net/_xiao/article/details/23289971

      4)https://blog.csdn.net/bingqingsuimeng/article/details/50522242

      5)https://blog.csdn.net/someonea/article/details/3202409

      6)https://blog.csdn.net/dong_007_007/article/details/49247725

      7)https://blog.csdn.net/huohongpeng/article/details/54575675

      8)https://blog.csdn.net/u012719556/article/details/45315089

  • 相关阅读:
    java基础之条件运算符
    java基础之x++与++x
    java基础之三种注释及API帮助文档的生成
    java基础之类型转换及常量的应用
    java基础之数据类型
    java基础之标识符
    生活小插曲(长篇连载,持续更新ing)^_^
    记录那个刚毕业,还不太富裕的那个人的生活
    记录两次小组会议总结
    这是大娃笔记里的一首散文诗
  • 原文地址:https://www.cnblogs.com/dongc/p/9690754.html
Copyright © 2020-2023  润新知