调试——GDB、日志

    • 1. gdb常用指令
    • 2. 如何生成core文件并调试?
    • 3. 如何调试正在运行的程序
    • 4. 调试多进程程序
    • 5. 调试多线程程序
    • 6. log日志

  • gcc编译器可以帮我们发现语法错误,但是对业务逻辑错误却无能为力。当我们想找出逻辑错误时,就需要调试,也就是要用gdb调试
  • GDB(gdb)全称“GNU symbolic debugger”,是 Linux 下常用的程序调试器。 为了能够使用 gdb 调试,需要在代码编译的时候加上-g,如
g++ -g -o test test.cpp

1. gdb常用指令

b(break) 10	:在第10行打上断点
r(run) :开始运行程序,直到遇到断点,并在断点这一行停下来(第一个运行的命令)
c(continue) :继续运行,一般先停下来,再用continue继续运行,直到遇到下一个断点
n(next) :执行当前这一行(彻底执行完,如果当前这一行是函数调用,则执行完这个函数)
p(print) name :显示变量name的值
p name++ :后面可以写一行代码,也就是一个表达式(什么都行,包括改变变量、输出都行)
set var name="仲书颉" :set var可以设置变量的值,这里设置name的值为仲书颉
set args 参数1 参数2:set args可以设置main(args,argv[])函数的参数,参数1就是argv[1]的值,参数2就是argv[2]的值-注意,当参数1内有空格时,要这样表示:set args "参数1" 参数2
s(step) :执行当前这一行-这一行不是函数时,和n(next)一样-这一行是函数时,s会进入函数的内部,执行函数内部的第一行(想进入函数里面,必须要用step)-注意,s并不能进入库函数或第三方函数,只能进入我们自己定义的函数(有函数源码)
l(list) :显示10行代码(基本不用,因为我们会另开一个窗口看源代码,一般不用list来看)
bt :查看执行到目前这一行为止,函数的调用栈
info b :显示断点的信息(有几个,哪几个)
info threads :显示已创建的线程的信息,带*号的就是当前被调试的线程
thread 2 :切换到id为2的线程来调试

2. 如何生成core文件并调试?

当程序出现段错误(core dump)时,用gdb调试core文件,可以立即定位到段错误所在行****,非常方便但是core文件默认是不生成的如何生成core文件呢?

在程序出现段错误后,我们需要在Linux中输入:
ulimit -a

会显示这样的结果:

我们只需要关注第一行,上面显示core文件大小为0

将core文件大小改为unlimited
ulimit -c unlimited

再出入ulimit -a后,显示:

gdb打开core文件

设置完core文件大小后,我们重新运行源程序,就会生成core文件。我们可以通过 **ls **来查看。

然后就用gdb调试即可:

gdb 可执行文件 core文件
#如:gdb book core19356

会显示:

可见,直接显示在第7行出现段错误

注:什么是段错误

**访问未分配或权限不足的内存 所产生的错误,就是段错误。有以下几种情况:

**

3. 如何调试正在运行的程序

如果我们使用gdb调试一个这个在运行的程序,那么这个程序就会立即停止运行。此时为了查看程序运行到说明地方,我们需要用 bt 命令,来查看函数的调用栈——最上面的就是正在运行的函数。

我们可用使用其他调试命令,如n、s等,可以让原本停下的程序继续运行一行。通过组合使用 n、s 和 bt 命令,可以调试正在运行的程序

4. 调试多进程程序

注:被调试的进程会停止运行,将在调试命令下一步一步执行。

调试父进程(默认)

默认就是调试父进程,或者也可以显示指定:

set follow-fork-mode parent

此时子进程将自动执行;而父进程会阻塞(因为先前设置了断点),等待我们的调试

调试子进程

需要显示指定:

set follow-fork-mode child

此时父进程将自动执行;而子进程会阻塞(因为先前设置了断点),等待我们的调试

调试模式

在确定调试子进程还是父进程后,就可以设置调试模式了,一共有两种调试模式:

调试当前进程时,其他进程继续运行

这是默认的情况,也可以显示指定:

set detach-on-fork on 
调试当前进程时,其他进程被gdb挂起,不能运行

需要显示指定:

set detach-on-fork off

如果我们是在调试父进程时采用了第二种调试模式,那么在调试父进程时,子进程不会自动运行。即使父进程调试执行完,子进程也不会运行。

查看和切换被调试的进程

设置第二种调试模式之后(即 set detach-on-fork off),我们才能查看和切换被调试的进程。

查看被调试的进程
info inferiors

序号1的前面有*号,表示我们正在调试的进程是 序号为1的进程

**切换要调试的进程**
inferior 进程id
#如 inferior 2,表示改为调试进程2,不再调试进程1

5. 调试多线程程序

注:如果使用的是POSIX线程库的话,在编译时还要加上 -l pthread

查看进程、线程以及线程之间的关系
//shell命令(非gdb命令):
ps aux | grep 过滤条件  #查看当前运行的进程ps -aL | grep 过滤条件  #查看当前运行的线程pstree -p 主线程id  #查看主线程和子线程之间的关系

线程调试的基础命令
info threads #显示已创建的线程的信息,带*号的就是当前被调试的线程thread 3 #切换到id为3的线程来调试

设置线程调试模式
**调试当前线程时,其他线程继续运行**

默认的情况,也可以显示指定:

set scheduler-locking off
**调试当前线程时,其他线程全部阻塞**

需要显示指定:

set scheduler-locking on
让指定线程执行指定命令
thread apply 线程id 命令
#如:thread apply 2 n,表示让线程3往下执行一次(即使当前调试的不是线程2,也可以执行该语句)

另,也可以让所有线程执行同一个语句:

thread apply all 命令

6. log日志

设置断点和单步调试 会严重影响线程之间的竞争状态。因为当一个线程在断点处停住了,而让另一个线程跑,就会导致并发被破坏,此时我们看到的只是一个和谐的假象。而log日志,就可以避免断点和单步的副作用。我们可以输出log日志,让程序每一步运行的时间都可以在日志文件中查到。

开源日志框架——freecplus

项目里需要同时包含_cmpublic.h、_freecplus.h、_freecplus.cpp这三个文件。第一个里全是程序用到的头文件;第二个文件包含了第一个文件,它定义了函数和类的声明;第三个文件包含了第二个文件,它是对函数和类的具体实现。_cmpublic.h_freecplus.cpp_freecplus.h

具体使用过程:

  1. 包含#include<_freecplus.h>(第一个文件就不用写了,因为已经包含了)
  2. 定义日志文件类(全局):
CLogFile logfile;
  1. 创建日志文件
logfile.Open("/tmp/gdbfork.log","w+");
/* 
/tmp/gdbfork.log是日志文件名,可以自己定义; w+是打开文件的方式,直接写上就好
*/
  1. 将所有的输出语句(printf、cout等)改为输出到日志文件
logfile.Write("Hello World");
  1. 编译并运行项目
g++ gdbfork.cpp _freecplus.cpp -o gdbfork
./gdbfork  #此时日志已经把所有的内容 输出的日志文件里面了
  1. 最后打开日志文件来查看即可
vi /tmp/gdbfork.log

我们也可以一边让程序运行,一边打开事先创建的日志文件,这样就可以观测** 程序运行的实时状态**。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/79789.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/79789.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/79789.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis----通用命令

文章目录 前言一、运行redis二、help [command]三、通用命令 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 学习一些通用命令 以下操作在windows中演示 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、运行redis 我们先c…

CatBoost算法原理及Python实现

一、概述 CatBoost 是在传统GBDT基础上改进和优化的一种算法&#xff0c;由俄罗斯 Yandex 公司开发&#xff0c;于2017 年开源&#xff0c;在处理类别型特征和防止过拟合方面有独特优势。 在实际数据中&#xff0c;存在大量的类别型特征&#xff0c;如性别、颜色、类别等&#…

五一假期作业

sub_process.c #include <stdio.h> // 标准输入输出库 #include <pthread.h> // POSIX线程库 #include <sys/ipc.h> // IPC基础定义&#xff08;如消息队列/共享内存&#xff09; #include <sys/msg.h> // 消息队列操作相关…

Liunx安装Apache Tomcat

目录 一、了解tomcat 二、下载 三、启动tomcat 四、网页访问tomcat 五、Tomcat修改默认8080端口 六、Tomcat创建项目步骤-实现项目对外访问 一、了解tomcat Apache Tomcat 是一个开源的 Java Servlet 容器 和 Web 服务器&#xff0c;主要用于运行基于 Java 的 Web 应用…

破局者手册 Ⅰ:测试开发核心基础,解锁未来测试密钥!

目录 一、引入背景 二、软件测试基础概念 2.1 软件测试的定义 2.2 软件测试的重要性 2.3 软件测试的原则 三、测试类型 3.1 功能测试 3.2 接口测试 3.2.1 接口测试的概念 3.2.2 接口测试的重要性 3.2.3 接口测试的要点 3.2.4 接口测试代码示例&#xff08;Python r…

C++ 适配器模式详解

适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许不兼容的接口之间能够协同工作。 概念解析 适配器模式的核心思想是&#xff1a; 接口转换&#xff1a;将一个类的接口转换成客户希望的另一个接口 兼容性&#xff1a;使原本由于接…

【NLP】 28. 语言模型的评估方式:MRR, PERPLEXITY, BLEU, WER从困惑度到实际效果

语言模型的评估方式&#xff1a;从困惑度到实际效果 评估语言模型&#xff08;LLM&#xff09;是否有效&#xff0c;并不仅仅是看它生成句子是否“听起来通顺”&#xff0c;我们需要定量的指标对模型性能做出系统性评价。评估方法主要分为两大类&#xff1a; 内在评价&#x…

Java 企业级开发设计模式全解析

Java 企业级开发设计模式全解析 在 Java 企业级开发的复杂领域中&#xff0c;设计模式如同精湛的工匠工具&#xff0c;能够帮助开发者构建高效、可维护、灵活且健壮的软件系统。它们是无数开发者在长期实践中总结出的解决常见问题的最佳方案&#xff0c;掌握这些模式对于提升开…

小刚说C语言刷题—1038编程求解数学中的分段函数

1.题目描述 编程求解数学中的分段函数。 …………x1 (当 x>0 )。 yf(x)…0 (当 x0 )。 ………x−1 (当 x<0 )。 上面描述的意思是&#xff1a; 当x>0 时 yx1 ; 当 x0 时 y0 ; 当 x<0 时 yx−1 。 输入 输入一行&#xff0c;只有一个整数x(−30000≤x≤30…

滚珠螺杆的精度如何保持?

滚珠螺杆通常用于需要精确定位的地方&#xff0c;高机械效率、低传递扭矩和几乎为零的轴向游隙&#xff0c;使滚珠螺杆成为工具定位和飞机副翼驱动等应用中的重要设备。但是&#xff0c;连续工作产生的阻力和热量会导致较大的摩擦力和定位误差。那么&#xff0c;滚珠螺杆的精度…

在 Laravel 中深度集成 Casbin 到原生 Auth 系统

在 Laravel 中深度集成 Casbin 到原生 Auth 系统需要实现多层次的融合&#xff0c;以下是专业级实现方案&#xff1a; 一、核心集成架构 #mermaid-svg-WYM1aoAyHrR5bCdp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-…

JavaScript 实现输入框的撤销功能

在 Web 开发中&#xff0c;为输入框添加撤销功能可以极大地提升用户体验&#xff0c;方便用户快速回滚到之前的输入状态。本文将通过一段简单的 HTML、CSS 和 JavaScript 代码&#xff0c;详细介绍如何实现输入框的撤销功能。 整体实现思路 利用 JavaScript 监听输入框的inpu…

计算机视觉与深度学习 | 点云配准算法综述(1992-2025)

点云配准算法综述(1992-2025) 点云配准 点云配准算法综述(1992-2025)一、传统方法(1992-2020)1. **ICP(Iterative Closest Point)**2. **NDT(Normal Distributions Transform)**3. **4PCS(4-Points Congruent Sets)**二、深度学习驱动的方法(2018-2025)1. **Poin…

数据库的二级索引

二级索引 10.1 二级索引作为额外的键 表结构 正如第8章提到的&#xff0c;二级索引本质上是包含主键的额外键值对。每个索引通过B树中的键前缀来区分。 type TableDef struct {// 用户定义的部分Name stringTypes []uint32 // 列类型Cols []string // 列名Indexes …

Java IO流核心处理方式详解

一、IO流概述 Java IO&#xff08;Input/Output&#xff09;流是处理输入输出操作的核心机制&#xff0c;通过流&#xff08;Stream&#xff09;的形式实现设备间的数据传输。所有操作都基于以下两个核心抽象&#xff1a; InputStream/OutputStream&#xff1a;字节流基类 Re…

WidowX-250s 机械臂的简单数字孪生案例

前面一段时间记录了一下WidowX-250s机械臂的学习与遥操作演示&#xff0c;相关链接如下&#xff1a; WidowX-250s 机械臂学习记录&#xff1a; https://blog.csdn.net/qq_54900679/article/details/145556979 WidowX-250s 机械臂遥操作演示记录&#xff1a; https://blog.c…

uniapp 云开发全集 云开发的概念

一、云开发的概念 1.1 云开发介绍 云开发 unicloud 是 DCloud 联合阿里云、腾讯云、支付宝云&#xff0c;为开发者提供的基于 serverless 模式和 js 编程的云开发平台&#xff0c;可以使用极小的成本代价开发具轻松实现前后台整体业务。 1.2 云开发的核心组成 云开发的核心组…

GGD独立站的优势

GGD模式(基于Google生态的独立站模式)越来越受欢迎&#xff0c;主要有以下原因&#xff1a; 1. 全球化覆盖 GGD独立站依托Google强大的生态系统&#xff0c;能够帮助企业轻松触达全球用户&#xff0c;实现国际化布局&#xff0c;拓展业务范围。Google作为全球最大的搜索引擎&…

签名去背景图像处理实例

一、前言 在生活中我们经常用到电子签名&#xff0c;但有时候我们所获取的图像的彩色图像&#xff0c;我们需要获取白底黑字的电子签名&#xff0c;我们可以通过下面程序对彩色图像进行处理达到我们的处理目的。 原始彩色图像如下&#xff1a; 二、程序和运行结果 clear all;c…

WebAssembly(Wasm):现代Web开发的超级加速器

在当今的Web开发领域&#xff0c;性能和效率是开发者们永恒的追求目标。随着Web应用的复杂度不断增加&#xff0c;传统的JavaScript在某些场景下已经难以满足高性能计算和复杂逻辑处理的需求。此时&#xff0c;WebAssembly&#xff08;Wasm&#xff09;作为一种新兴的Web技术&a…