环境:

  Centos7.3、GCC4.8.5

适用场景:

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

一、创建可执行程序:

  use_library.cpp

#include <iostream>
#include "use_library.h" int main()
{
int res = my_library(, );
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 = ;
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

使用GDB调试将符号表与程序分离后的可执行文件的更多相关文章

  1. GDB如何调试没有符号表(未加-g选项的编译)的程序

    /********************************************************************* * Author  : Samson * Date    ...

  2. 用GDB 调试Java程序

      陈皓 http://blog.csdn.net/haoel 背景 想要使用GDB调试程序,就需要用GNU的编译器编译程序.如:用GCC编译的C/C++的程序,才能用GDB调试.对于Java程序也是 ...

  3. 比较全面的gdb调试命令 (转载)

    转自http://blog.csdn.net/dadalan/article/details/3758025 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形 ...

  4. GDB 调试解析

    GDB(GNU Debugger)是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序 列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优 ...

  5. Linux基础(03)gdb调试

    1. 安装GDB增强工具 (gef) * GDB的版本大于7.7 * wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.s ...

  6. GDB调试命令手册

    使用GDB 启动 $ gdb program           # program是你的可执行文件,一般在当前目录 $ gdb program core      # gdb同时调试运行程序和cor ...

  7. c++的符号表的肤浅认识

    符号表是编译期产生的一个hash列表,随着可执行文件在一起 示例程序 int a = 10; int b; void foo(){ static int c=100; } int main(){ in ...

  8. VxWorks 符号表

    符号表初始化           符号表用于建立符号名称.类型和值之间的关系.其中,名称为null结尾的任意字符串:类型为标识各种符号的整数:值为一个字符指针.符号表主要用来作为目标模块加载的基础,但 ...

  9. 经典的GDB调试命令

    在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是: printprint /是表达式,是你所调试的程 ...

随机推荐

  1. centos7 下zookeeper 部署 单机多实例模式

    centos7 下zookeeper 部署 本文参考https://www.linuxidc.com/Linux/2016-09/135052.htm 1.创建/usr/local/zookeeper ...

  2. chrome添加扩展程序

    example: chrome添加vue devtools 扩展程序 打开地址:https://chrome-extension-downloader.com/ download extension: ...

  3. 页面制作学习笔记:D1.概述

    一.Web发展历史 Web1.0 :早期HTML页面:例:网易的门户网站163.com. Web2.0:AJAX技术规模应用:例:网易邮箱126.com. Web3.0:HTML5技术规模应用:例:网 ...

  4. 服务集群session问题

    1. http协议本身无状态,可通过Session与Cookie记录前端与后端服务器的交互状态: 2. 但是每次客户端回传必须在头信息中带有cookie, 如果session过多,会增加数据传输量: ...

  5. IP通信基础课堂笔记----关于数链层

    课前回顾 IOS从上到下分别有:应用层,传输层,网络层,数链层,物理层. IP是网络层的地址,MAC是数链层的地址,IP必须通过ARP才能转换成MAC地址. 课堂内容 1.如何在数链层实现发送端数据无 ...

  6. 共有和私有、name mangling

    1.在python中可以在变量和函数名前加上双下划线—‘’__‘’来实现其伪私有(实际上python中没有Private属性的),加上双下划线后,外部对象不能通过调用其名称直接获得对象的属性或操作. ...

  7. xss处理

    今天学习了xss,主要记载如下: https://blog.csdn.net/sdauzyh/article/details/74942737

  8. Js修改input值后怎么同步修改绑定的v-model值

    v-model只是一种语法糖,底层的方法还是去监听input事件.所以可以使用dispatchEvent事件给元素分配一个input事件,这样可以手动触发 inputElement 的 input 事 ...

  9. 添加宿主为控制台应用程序的WCF服务

    1.创建WCF服务库:WcfServiceLibrary,根据自动创建的代码修改自己的WCF 服务协议.操作协议.数据协议.本次先实现简单的WCF最基本的通信方式:请求->应答模式. 定义服务. ...

  10. Java编程思想 - 第11章 持有对象

    · 大量笔记存放在Github Java文件中,请移步查看:https://github.com/iGuure/AndroidCodeHub/tree/master/Java%20pratice/Th ...