使用GDB调试程序一般有三种方式:

  gdb filename

  gdb attach pid

  dgb filename corename

也对应这本节课的核心内容:

  直接调试目标程序

  附加进程

  调试core文件

接下来我们逐一讲解。

2.1直接调试目标程序

  在开发阶段或者研究别人的项目时,当编译成功生成目标二进制文件后,可以使用gdb filename直接启动这个程序的调试,其中filename是需要启动的调试程序文件名,这种方式是直接使用GDB启动一个程序进行调试。注意这里说的启动一个程序进行调试其实不严谨,因为实际上只是附加了一个可执行文件,并没有把程序启动起来;接着需要输入run命令,程序才会真正的运行起来;接着需要输入run命令,程序才会真正的运行起来。关于run命令后面的课程中会详细介绍。上一课的GDB调试hello_server系列就是使用的这种方式。

  假设现在有一个程序叫fileserver,使用gdb fileserver附加该程序,然后使用run面过了启动该程序。如下图所示:

2.2附加进程

  在某些情况下,一个程序已经启动了,我们向调试这个程序,但是又不想重启这个程序。假设有这样一个场景,我们的测试服务器程序正在运行,运行一段时间之后,发现这个服务器不能接受新的客户端连接了,这时肯定是不能重启的,如果重启,当前程序的各种状态信息就丢失了。怎么办呢?可以使用gdb attach 进程ID来将GDB调试器附加到测试服务器程序上。例如,假设聊天程序叫myserver,可以使用ps命令获取进程的PID,然后使用gdb attach就可以调试了,操作如下:

wzq@wzq-PC:~/Desktop/unimrcp-1.5.0-client-build-dir/unimrcp/bin$ ps -ef | grep unimrcpserver
wzq 23316 23213 0 18:10 pts/1 00:00:00 ./unimrcpserver
wzq 23339 23329 0 18:10 pts/2 00:00:00 grep unimrcpserver

  实际执行如下图所示:

  通过以上代码得到myserver的PID为23329,然后使用gdb attach 23329把GDB附加到myserver进程中,操作并输入如下:

  当提示“Attaching to process 23940”时就说明我们已经成功地将GDB附加到目标程序进程了。需要注意的是,程序使用了一些系统库(如libc.so),由于这时发行版本的Linux系统,这些库是没有调试符号的,因而GDB会提示找不到这些库的调试符号。因为目的是调试myserver,对系统API调用的内部实现并不关注,所以这些提示可以不用关注,只要myserver这个文件有调试信息即可。

  当用gdb attach上目标进程后,调试器会暂停下来,此时可以使用continue命令让程序继续运行,或者加上相应的断电再继续运行程序(这里提到的continue命令不熟悉也没有关系,后续会详细介绍这些命令的使用方法)。

  当调试完程序想结束此调试时,而且不对当前进程myserver有任何影响,也就是说想让这个程序继续运行,可以在GDB的命令界面输入detach命令让程序与GDB调试器分离,这样myserver就可以继续运行了:

  然后再退出GDB就可以了:

2.3调试生成core文件

  有时候,服务器程序运行一段时间后会突然崩溃,这并不是我们希望看到的,需要解决这个问题。只要程序在崩溃的时候有 core 文件产生,就可以使用这个 core 文件来定位崩溃的原因。当然,Linux 系统默认是不开启程序崩溃产生 core 文件这一机制的,我们可以使用 ulimit -c 命令来查看系统是否开启了这一机制。

  发现 core file size 那一行默认是 0,表示关闭生成 core 文件,可以使用“ulimit 选项名 设置值”来修改。例如,可以将 core 文件生成改成具体某个值(最大允许的字节数),这里我们使用 ulimit -c unlimited(unlimited 是 -c 选项值)直接修改成不限制大小。

  还有一个问题就是,这样修改以后,当我们关闭这个 Linux 会话,设置项的值就会被还原成 0,而服务器程序一般是以后台程序(守护进程)长周期运行,也就是说当前会话虽然被关闭,服务器程序仍然继续在后台运行,这样这个程序在某个时刻崩溃后,是无法产生 core 文件的,这种情形不利于排查问题。因此,我们希望这个选项永久生效,永久生效的方式是把“ulimit -c unlimited”这一行加到 /etc/profile 文件中去,放到这个文件最后一行即可。

第02课:启动GDB调试的更多相关文章

  1. 第二课:启动 GDB 调试

    使用 GDB 调试程序一般有三种方式: gdb filename gdb attach pid gdb filename corename 这也对应着本节课的核心内容: 直接调试目标程序 附加进程 调 ...

  2. GDB调试笔记

    参考资料:GDB调试精粹及使用实例 # 调试实例 #include <iostream> #include <cstring> using namespace std; ][] ...

  3. Nginx学习之十四-GDB调试Nginx初试

    本文的测试环境: Win7+虚拟机VMWareVMware-workstation-full-7.1.4-385536+Ubuntu12.04 Nginx-1.4.0 要想有效的研究Nginx源码,必 ...

  4. Linux下GDB调试简单示例

    这里介绍对文件first.c的基本GDB调试操作,只有部分命令,只是一个示例,运行环境为装有gcc编译器和gdb调试器的Linux环境,基本GDB调试命令如下表: 命令                 ...

  5. GDB调试——常用的命令

    首先说明一点,如果我们要使用GDB来调试我们的C/C++程序时,在使用GCC编译程序时,应该带上 –g 参数, 它负责生成 与GDB相关的调试信息: 1.如何对一个文件启动GDB调试? 方法一: 命令 ...

  6. 使用gdb调试

    启用gdb进行调试二进制程序,必须在二进制程序在采用gcc或g++编译时加入-g参数 启动gdb进行调试的几种形式: 直接启动gdb程序进行调试program程序 gdb program 启动gdb挂 ...

  7. gdb调试段错误及使用

    在编程调试中,经常出现段错误,此时可用gdb调试.具体方法为注册段错误信号处理函数,在处理函数中启动gdb.具体代码如下: void segv_handler(int no) { ]; ]; FILE ...

  8. gdb调试快速入门

    编译指令 gcc test.c -o test -g -g是加入调试信息,加入源码信息 启动gdb调试 gdb test 进入gdb中 设置参数 set args 10 20 显示参数show age ...

  9. 第七课 GDB调试 (下)

    1序言: 通过前面一节第六课 GDB调试 (下)文章,可以掌握理解了gdb调试:怎么启动.运行,打断点.查看变量.甚至改变变量等的知识,今天来大概讲解下调试bug的类型. 2知识点: 2.1 就像之前 ...

随机推荐

  1. android中builder模式的使用

    变种的Builder模式的自动化生产实现: AS安装插件  Innerbuilde 新建User类 public class User { private final String name; //必 ...

  2. CSS 有序或者无序列表的前面的标记 list-style-type 属性

    例子: <html> <head> <style type="text/css"> ul.none{list-style-type:none} ...

  3. python-静态方法和类方法及其使用场景

    静态方法和类方法 静态方法 我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息.实际上,我们写在类中的方法并不需要都是对象方法,例如我们定义一个"三角形"类,通 ...

  4. sun.misc.BASE64Encoder 不建议使用java.sun自带包中的内容

    import sun.misc.BASE64Decoder; 在项目中,设计到64位编码的.有时开发会用到JDK中自带的BASE64工具.但sun公司是建议不这样做的.尤其是更新了JDK版本,项目甚至 ...

  5. Reactjs之实现js跳转路由

    1.新增知识 /* 实现js跳转路由:https://reacttraining.com/react-router/web/example/auth-workflow 1.要引入Redirect im ...

  6. c# VirtualKeys

    /// <summary> /// Enumeration for virtual keys taken from http://www.pinvoke.net/default.aspx/ ...

  7. cocos2dx基础篇(27) 屏幕适配

    [3.x]https://blog.csdn.net/qq_40338728/article/details/82964046 [屏幕适配] 1.两个分辨率 1.1.窗口分辨率 在main.cpp中有 ...

  8. 【Qt开发】QScrollArea添加布局后没有出现滚动条的解决方法

    [Qt开发]QScrollArea添加布局后没有出现滚动条的解决方法 标签:[Qt开发] 说明:尝试利用滚动区域显示多张图片,为了能够动态地往滚动区域贴图,为滚动区域设置了布局,然后通过布局来添加wi ...

  9. python 并发编程 多线程 守护线程

    做完工作这个进程就应该被销毁 单线程情况: 一个进程 ,默认有一个主线程 ,这个主线程执行完代码后 ,就应该自动销毁.然后进程也销毁. 多线程情况: 主线程代表进程结束 一个进程可以开多个线程,默认开 ...

  10. java 依据文件名判断mime类型

    依据文件名称判断mime类型 import java.util.HashMap; import java.util.Map; /** * 依据文件名获取MimeType */ public class ...