当前位置: 首页 > news >正文

gdb学习笔记

参考:https://blog.csdn.net/Stars_WW/article/details/88994391
gdb常用交互命令
启动gdb后,进入到交互模式,通过以下命令完成对程序的调试;注意高频使用的命令一般都会有缩写,熟练使用这些缩写命令能提高调试的效率;
运行

run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令;
continue (简写c ):继续执行,到下一个断点处(或运行结束);
next:(简写 n),单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到函数中去运行,而 next 则直接调用函数,不会进入到函数体内;
step (简写s):单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的;
until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体;
until+行号: 运行至某行,不仅仅用来跳出循环;
finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息;
call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55);
quit:简记为 q ,退出gdb。
设置断点

break n (简写b n):在第n行处设置断点(可以带上代码路径和代码名称: b OAGUPDATE.cpp:578);
b fn1 if a>b:条件断点设置
break func(break缩写为b):在函数func()的入口处设置断点,如:break cb_button
delete 断点号n:删除第n个断点
disable 断点号n:暂停第n个断点
enable 断点号n:开启第n个断点
clear 行号n:清除第n行的断点
info b (info breakpoints) :显示当前程序的断点设置情况
delete breakpoints:清除所有断点:
查看源代码

list :简记为 l ,其作用就是列出程序的源代码,默认每次显示10行。
list 行号:将显示当前文件以“行号”为中心的前后10行代码,如:list 12
list 函数名:将显示“函数名”所在函数的源代码,如:list main
list :不带参数,将接着上一次 list 命令的,输出下边的内容。
打印表达式
5. print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。
6. print a:将显示 a 的值
7. print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数
8. display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
9. watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
10. whatis :查询变量或函数
11. info function: 查询函数
12. 扩展info locals: 显示当前堆栈页的所有变量

查询运行信息

where/bt :当前运行的堆栈列表;
bt backtrace 显示当前调用堆栈
up/down 改变堆栈显示的深度
set args 参数:指定运行时的参数
show args:查看设置好的参数
info program: 来查看程序的是否在运行,进程号,被暂停的原因。
分割窗口

layout:用于分割窗口,可以一边查看代码,一边测试:
layout src:显示源代码窗口
layout asm:显示反汇编窗口
layout regs:显示源代码/反汇编和CPU寄存器窗口
layout split:显示源代码和反汇编窗口
Ctrl + L:刷新窗口

gdb解决Segmentation fault范例
我们打算使用gdb去解决为什么下面的程序(文件为segfault.c)引起了段错误的问题。

#include <stdio.h>
#include <stdlib.h>int main(int argc, char **argv)
{char *buf;buf = malloc(1<<31);fgets(buf, 1024, stdin);printf("%s\n", buf);return 1;
}

第一步是使用带有调试标志(debugging flags)的方式编译这段代码,如下:

~# gcc -g segfault.c

然后运行:

~# a.out
Hello World!
Segmentation fault

这并不是我们所期待的。是时候启动强大的gdb了。

~# gdb a.out
GNU gdb 5.0
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) 

我们直接运行就来看看到底发生了什么:

(gdb) run
Starting program: /home/dgawd/cpsc/363/a.out 
test stringProgram received signal SIGSEGV, Segmentation fault.
0x4007fc13 in _IO_getline_info () from /lib/libc.so.6

我们收到了来自操作系统的SIGSEGV信号。这就意味着我们试图去访问一段非法的内存,让我们试试backtrace(= bt)命令:

(gdb) backtrace
#0  0x4007fc13 in _IO_getline_info () from /lib/libc.so.6
#1  0x4007fb6c in _IO_getline () from /lib/libc.so.6
#2  0x4007ef51 in fgets () from /lib/libc.so.6
#3  0x80484b2 in main (argc=1, argv=0xbffffaf4) at segfault.c:10
#4  0x40037f5c in __libc_start_main () from /lib/libc.so.6

这里我们只关心我们自己的代码,因此我们就切换到3号堆栈帧(stack frame3)来看看程序在哪里崩溃的:

(gdb) frame 3
#3  0x80484b2 in main (argc=1, argv=0xbffffaf4) at segfault.c:10
10        fgets(buf, 1024, stdin)

哦,原来是调用fgets引起的崩溃。一般的,我们都假设库函数比如fgets都可以正确地工作。因此这个问题的原因就一定是其中我们的一个参数的问题。你也许不知道‘stdin’是一个全局的变量,它是被stdio 库创建的。因此我们假定这个参数是正确的。那么剩下的就只能是‘buf’了,然后查看buf当前的值:

(gdb) print buf
$1 = 0x0

buf的值是0x0,也就是NULL指针。这并不是我们锁期待的 —— buf应该指向第8行代码分配到的内存。因此我们需要返回到第8行并看看在哪里发生了什么。首先kill掉我们程序当前运行的调用:

(gdb) kill
Kill the program being debugged? (y or n) y

(注意:不用使用quit直接退出gdb,这样比较麻烦。直接kill掉当前的程序调用即可)

然后在第8行设置一个断点:

(gdb) break segfault.c:8
Breakpoint 1 at 0x8048486: file segfault.c, line 8.

再次运行程序:

(gdb) run
Starting program: /home/dgawd/cpsc/363/a.out Breakpoint 1, main (argc=1, argv=0xbffffaf4) at segfault.c:8
8         buf = malloc(1<<31);

我们检查malloc调用前后buf值的变化。初始化buf以前,其值应该是一个随机杂乱值(garbage),就像这里的:

(gdb) print buf
$2 = 0xbffffaa8 "鳃?\177\003@t`\001@\001"

我们step over(单步执行)malloc调用然后再次检查buf的值:

(gdb) next
10        fgets(buf, 1024, stdin);
(gdb) print buf
$3 = 0x0

可见调用了malloc之后,buf是NULL。如果你查看malloc的手册页(man page),你就会发现malloc在不能分配够所需的内存的时候就会返回NULL。因此确定是我们的malloc失败了。让我们返回到代码再次看看:

7 :   buf = malloc(1<<31);

哦,表达式1<<31(整型1左移31次,原文错写为右移)是429497295, 或4GB (gigabytes).很少有机器会有这样的内存——大多数只有256MB(显然这篇文章有年头了,都什么年代了,这点内存操作系统估计启动一半就挂了)。因此malloc必然会失败。此外,在fgets中我们只读入1024字节。所有的额外空间都会白白浪费掉,尽管我们可以分配到。这里我们将1<<31改为1024(或者1<<9),这样程序就会按照我们的期望运行了:

~# a.out
Hello World!
Hello World!

这样你就可以知道怎样使用gdb来调试段错误了,这是非常有用的。这个例子同时也说明了一个非常重要的准则:总是检查malloc的返回值!

相关文章:

gdb学习笔记

参考:https://blog.csdn.net/Stars_WW/article/details/88994391 gdb常用交互命令 启动gdb后&#xff0c;进入到交互模式&#xff0c;通过以下命令完成对程序的调试&#xff1b;注意高频使用的命令一般都会有缩写&#xff0c;熟练使用这些缩写命令能提高调试的效率&#xff1b;…...

java -jar指定外部配置文件

场景 spingboot项目部署jar时,需要时常修改配置,为了方便,将配置文件放到jar包外 操作步骤 在jar包同级目录下创建config文件夹(位置没有强制要求,为了方便而已) 在jar包同级目录下创建start.bat文件,并编辑内容 echo off :: 命令窗口标题 title yudibei_performance_tes…...

【IDEA】常用插件清单

【IDEA】常用插件清单 arthas ideaCodeium: AI Autocomplete for xxxCommit-MessageGenerateAllSetterMaven HelperMybatisPlusOne Dark themePDF ViewerRainbow BracketsRestfulToolSequenceDiagramSonarLintTranslation arthas idea 快捷生成arthas命令 Codeium: AI Autoc…...

私域流量运营数据分析:6个关键指标

随着数字化时代的到来&#xff0c;私域流量运营已经成为企业营销的重要策略。然而&#xff0c;要确保私域流量运营的有效性和成功&#xff0c;数据分析是至关重要的一环。通过对运营数据进行深入分析&#xff0c;企业可以了解用户行为和趋势&#xff0c;发现问题和机遇&#xf…...

解释器模式——自定义语言的实现

1、简介 1.1、文法规则和抽象语法树 解释器模式描述了如何为简单的语言定义一个文法&#xff0c;如何在该语言中表示一个句子&#xff0c;以及如何解释这些句子。在正式分析解释器模式结构之前&#xff0c;先来学习如何表示一个语言的文法规则以及如何构造一棵抽象语法树。 …...

基于STM32103移植FreeRTOS

目录 一、FreeRTOS协议栈下载 二、准备工程文件与协议代码 三、移植FreeRTOS协议栈 一、FreeRTOS协议栈下载 1、官网下载 FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensionshttps://www.freertos.or…...

docker compose一键部署lnmt环境

创建docker compose 目录 [rootlocalhost ~]# mkdir -p /compose_lnmt 编写nginx的dockerfile文件 创建目录 [rootlocalhost compose_lnmt]# mkdir -p nginx 编写nginx配置文件 [rootlocalhost nginx]# vim nginx.conf user root; #运行身份#nginx自动设置进程…...

Eeny Meeny Moo

Eeny Meeny Moo 题目描述输入输出格式输入格式输出格式 输入输出样例输入样例输出样例 正确解法A C 代码 题目描述 你肯定有过这样的经验&#xff0c;那就是当很多一起使用网络的时候&#xff0c;网速变得很慢很慢。为了解决这个问题&#xff0c;德国的Ulm大学开发了一份意外事…...

flask---闪现/请求扩展/g对象

闪现 # 一个请求---》假设出错了---》重定向到另一个地址---》把错误信息在另一个返回中看到 错误信息放个位置----》另一个请求过来&#xff0c;去那个位置拿 # 把一些数据&#xff0c;放在某个位置---》后期可以去取出来----》取完不用删除&#xff0c;就没了 def index():s…...

Qt视频播放器

一、设置好ui界面二、打开文件槽函数1.QDir::homePath()作用介绍2.QFileDialog::getOpenFileName()介绍3.QFileInfo介绍4.player 指针解释5.打开文件槽函数完整代码 三、视频播放器初始化1.QMediaPlayer()函数2.设置时间间隔的作用3. QGraphicsScene介绍4.QGraphicsVideoItem介…...

Stable Diffusion教程(8) - X/Y/Z 图表使用

1. 介绍 这项功能可以在 文生图/图生图 界面的左下角种 “脚本” 一栏内选择 “X/Y/Z 图表” 以启用。 它创建具有不同参数的图像网格。使用 X 类型和 Y 类型字段选择应由行和列共享的参数&#xff0c;并将这些参数以逗号分隔输入 X 值 / Y 值字段。支持整数、浮点数和范围。…...

Android 获取网关 ip 和 DNS ip

参考下方 PingUtil.java 代码 import android.content.Context; import android.net.DhcpInfo; import android.net.wifi.WifiManager; import android.text.format.Formatter;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; impor…...

Docker root用户的pip使用方法

Docker下root用户 pip install XX 显示pip命令不存在 # 原始目标&#xff1a;pip install XX pip install --root-user-actionignore 【XX】# (要安装的包)参考&#xff1a;WARNING: Running pip as the ‘root‘ user can result in broken permissions Linux 中 root 与 su…...

企业新片场排名如何优化

企业新片场排名如何优化 要如何去做关键SEO&#xff1f;第一个我们要做的就是做好 SEO 关键词的选词&#xff0c;一般就是会有第一个常用的选词方法&#xff0c;第一是以常用的提问词去做&#xff0c;不实像是情人节买什么礼物&#xff0c;母亲节买什么礼物&#xff0c; 618 有…...

Database Name

概述 DB_NAME与INSTANCE_NAME DB_NAME 数据库名称&#xff0c;也就是数据库的名字标示。这里&#xff0c;数据库里可能有多个实例&#xff0c;比如RAC里的多节点&#xff0c;这多个节点是不同的实例&#xff0c;但是却有相同的名字&#xff0c;他们的 DB_NAME是相同的&#xf…...

git代码版本管理

git 文章目录 git基本使用 基本使用 在一台新的电脑上使用git 你要下载安装git, 然后把git的安装路径配到系统环境变量里 然后把这台电脑的.ssh/ id_rsa.pub里的公钥整到github里 然后在github上新建仓库&#xff0c;它会生成一些指令引导上你传本地的代码 之后就可以在终…...

k8s概念-ConfigMap

回到目录 一般用于去存储 Pod 中应用所需的一些配置信息&#xff0c;或者环境变量&#xff0c;将配置于 Pod 分开&#xff0c;避免应为修改配置导致还需要重新构建 镜像与容器。 1 创建ConfigMap #使用 kubectl create configmap -h 查看示例&#xff0c;构建 configmap 对象…...

Mybatis 实体类属性名和表中字段名不一致怎么处理

一. 前言 最近耀哥有学生出去面试&#xff0c;被问到 “Mybatis实体类的属性名和表中的字段名不一致该怎么处理&#xff1f;”&#xff0c;这其实是一个很经典的面试题&#xff0c;接下来耀哥就为大家详细解析一下这道面试题。 二. 分析 2.1 实体类和字段名不一致所带来的后果…...

CAS - 从AtomicInteger窥探CAS

Unsafe类是CAS的核心&#xff0c;由于Java方法无法直接访问底层&#xff0c;需要通过本地方法(native)来实现&#xff0c;Unsafe类相当于一个桥梁。基于Unsafe类&#xff0c;可以直接操作特定的内存数据。 我们从上一篇说CAS基本原理的时候&#xff0c;有说到一个“资源”被100…...

micro-ros IMU ML 代码

示例代码&#xff1a; #include <micro_ros_arduino.h>#include "LSM6DSOXSensor.h" #include "lsm6dsox_activity_recognition_for_mobile.h"#include <stdio.h> #include <rcl/rcl.h> #include <rcl/error_handling.h> #inclu…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

sshd代码修改banner

sshd服务连接之后会收到字符串&#xff1a; SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢&#xff1f; 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...