面试官都在问

2023-11-02

面试官都在问 | Linux命令之gdb

在这里插入图片描述

0. 简述

GDB(GNU symbolic debugger)简单地说就是一个调试工具。它是一个受通用公共许可证即GPL保护的自由软件。

一般来说,GDB主要帮助你完成下面四个方面的功能:

1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

2、可让被调试的程序在你所指定的调置的断点处停住。

3、当程序被停住时,可以检查此时你的程序中所发生的事。

4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG

正因为GDB是linux下最常使用的程序调试器,因此,在我们面试各大公司的时候,使用GDB调试程序,又是相对比较容易被问到的。因为对GDB的了解,最能直观反映应聘者对Linux环境编程是否熟悉。因此我们结合海量面经,提取出了几个最容易被问到的GDB使用问题,供大家参考。

  • 使用gdb调试程序的前提是什么
  • 使用gdb如何在程序中逐步调试
  • 使用gdb如何在程序中打断点
  • 使用gdb如何查看函数调用栈

1 Linux命令之GDB

1.1 使用规则及高频选项
gdb [选项] 程序名称
-p 	#指定一个pid,调试正在运行的程序
1.2 高频调试指令
命令名称 说明 简写使用示例
run 直接运行程序 r -l -p
start 开始逐步调试 start -l -p
list 显示调试行附近代码 l main.c:10
next 执行当前行代码,进入下一行,
若当前行是函数则直接将函数运行完毕
n
step 执行当前行代码,进入下一行,
若当前行是函数,则进入函数进行调试。
s
continue 从当前停止的位置开始继续运行 c
break 打断点,程序运行到断点位置停下来 b main.c:10
info break 查看断点信息 i b
delete s删除断点 d 2
backtrace 查看程序运行调用栈信息 backtrace
print 打印变量数据 p var_name
quit 退出调试 q
run [运行参数]
start [运行参数]
list 
1.3 调试代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int gval = 100;
int mycopy(char *buf)
{
    strcpy(buf, "我爱我的祖国");
    return gval;
}
int main()
{
    int i = 0;

    printf("gval:%d\n", gval);
    for (i = 0; i < 10; i++) {
        gval += i;
        printf("gval:%d\n", gval);
    }   
    char *buf = "我爱我家";
    printf("%s\n", buf);
    buf = NULL;
    mycopy(buf);
    printf("%s\n", buf);

    return 0;
}
1.4 gdb 调试之调试前提

并非所有的程序都可以直接调试,gdb 程序的前提是即将调试的程序中必须包含有调试符号信息。因此在程序编译生成时必须指定生成debug版本的程序,因为只有debug版本的程序在编译生成的时候才会加入程序的调试符号信息。

[san@San doc]$ ls -l test.c
-rw-rw-r-- 1 san san 460 Apr 20 15:40 test.c
[san@San doc]$ gcc -g test.c -o test
[san@San doc]$

注意: gcc -g 选项的功能为在编译生成可执行程序时,向程序中添加调试符号信息。

1.5 加载程序

直接运行gdb,将可执行程序文件名称以空格间隔,紧跟其后即可

[san@San doc]$ gdb ./test
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-114.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/san/doc/test...done.
(gdb) 

若要调试正在运行中的程序,则使用 gdb -p 选项指定进程id来连接到这个程序

[san@San doc]$ sleep 60
[san@San ~]$ ps -ef|grep sleep
UID        PID  PPID  C STIME TTY          TIME CMD
san       8712 29712  0 16:04 pts/2    00:00:00 sleep 60
san       8746  8717  0 16:04 pts/1    00:00:00 grep --color=auto sleep
[san@San ~]$ gdb -p 8712

注意: 这里的ps -ef|grep sleep 为查看进程信息,并过滤出名称为 sleep 的进程。

1.6 开始调试:runstart
[san@San doc]$ gdb ./test
Reading symbols from /home/san/doc/test...done.
(gdb) run
Starting program: /home/san/doc/./test 
gval:100
gval:100
gval:101

注意: 这里run 命令敲击后,则直接开始运行程序,直到断点位置停下或者程序结束。

(gdb) start 
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Temporary breakpoint 1 at 0x4005a7: file test.c, line 13.
Starting program: /home/san/doc/./test 
Temporary breakpoint 1, main () at test.c:13
13	    int i = 0;

注意: 这里start 命令敲击后,则程序从main函数的起始位置停下,开始逐步调试。

1.7 查看调试行附近代码: list
(gdb) list
8	    strcpy(buf, "我爱我的祖国");
9	    return gval;
10	}
11	int main()
12	{
13	    int i = 0;
14	
15	    printf("gval:%d\n", gval);
16	    for (i = 0; i < 10; i++) {
17	        gval += i;

注意: 这里list 命令敲击后,查看的是调试行上下五行内的代码

(gdb) list test.c:20
15	    printf("gval:%d\n", gval);
16	    for (i = 0; i < 10; i++) {
17	        gval += i;
18	        printf("gval:%d\n", gval);
19	    }
20	    char *buf = "我爱我家";
21	    printf("%s\n", buf);
22	    buf = NULL;
23	    mycopy(buf);
24	    printf("%s\n", buf);

注意: 这里list test.c:20 命令敲击后,表示查看test.c文件的第20行附近代码

1.8 逐步调试之 step
(gdb) step
15	    printf("gval:%d\n", gval);
(gdb) step
gval:100
16	    for (i = 0; i < 10; i++) {
(gdb) step
17	        gval += i;
23	    mycopy(buf);
(gdb) step
mycopy (buf=0x0) at test.c:8
8	    strcpy(buf, "我爱我的祖国");
(gdb) list
3	#include <stdlib.h>
4	#include <string.h>
5	int gval = 100;
6	int mycopy(char *buf)
7	{
8	    strcpy(buf, "我爱我的祖国");
9	    return gval;
10	}
1.9 逐步调试之 next
(gdb) next
18	        printf("gval:%d\n", gval);
(gdb) next
gval:100
16	    for (i = 0; i < 10; i++) {
(gdb) next
17	        gval += i;

注意: 这里示例中stepnext 命令敲击后都是运行当前行代码,进入下一行。

main () at test.c:23
23	    mycopy(buf);
(gdb) next

Program received signal SIGSEGV, Segmentation fault.

注意: 从示例中可以看出stepnext 命令的区别在于,当调试行为函数时,step会进入函数内部继续逐步调试,而next则是直接将函数运行完毕(我这里的代码函数的运行直接出错了)。

1.10 逐步调试之 until
(gdb) start
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Temporary breakpoint 3 at 0x4005a7: file test.c, line 13.
Starting program: /home/san/doc/./test 

Temporary breakpoint 3, main () at test.c:13
13	    int i = 0;
(gdb) until test.c:23
gval:100
gval:100
gval:101
gval:103
gval:106
gval:110
gval:115
gval:121
gval:128
gval:136
gval:145
我爱我家
main () at test.c:23
23	    mycopy(buf);

注意: 从示例中可以看出until test.c:23 这一步的指令的功能为直接运行到test.c文件的第23行。

1.11 逐步调试之 continue
(gdb) n
gval:100
16	    for (i = 0; i < 10; i++) {
(gdb) n
17	        gval += i;
(gdb) continue
Continuing.
gval:100
gval:101
gval:103

注意: continue 的功能是从当前位置开始运行,直到遇到下一个断点或者程序运行结束。

1.12 断点添加之break
(gdb) break test.c:21
Breakpoint 6 at 0x400608: file test.c, line 21.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/san/doc/./test 
gval:100
gval:100
gval:101
gval:103
...
Breakpoint 6, main () at test.c:21
21	    printf("%s\n", buf);

注意: break test.c:21 的功能是给test.c文件的第21行打断点,程序运行至第21行就会停下来。

1.13 查看并删除断点之info breeakdelete
(gdb) info break
Num     Type           Disp Enb Address            What
6       breakpoint     keep y   0x0000000000400608 in main at test.c:21
	breakpoint already hit 1 time
(gdb) delete
Delete all breakpoints? (y or n) n
(gdb) delete 6
(gdb) info break
No breakpoints or watchpoints.
(gdb) 

注意: info break 用于查看断点信息, 能够看到示例中有一个断点ID为6的断点信息; 使用delete删除断点时,默认为删除所有断点信息,可以使用yn 决定是否删除。同时也可以直接使用delete删除断点的时候直接通过断点ID删除指定的断点。

1.14 查看程序中函数调用栈信息之backtrace
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/san/doc/./test 
gval:100
gval:100
....
Program received signal SIGSEGV, Segmentation fault.
0x000000000040057c in mycopy (buf=0x0) at test.c:8
8	    strcpy(buf, "我爱我的祖国");
(gdb) backtrace
#0  0x000000000040057c in mycopy (buf=0x0) at test.c:8
#1  0x0000000000400628 in main () at test.c:23

注意: backtrace 用于查看调用栈信息,从示例中可以看出在程序因为异常错误退出时,调用栈顶函数为mycopy 函数,则可以认为程序退出是在mycopy 函数中出现了某个错误(因为程序运行在这个函数中的时候还没有来得及运行完函数然后出栈函数,就退出了)。

1.15 查看并设置变量数据
(gdb) list
3	#include <stdlib.h>
4	#include <string.h>
5	int gval = 100;
6	int mycopy(char *buf)
7	{
8	    strcpy(buf, "我爱我的祖国");
9	    return gval;
10	}
11	int main()
12	{
(gdb) print gval
$1 = 145
(gdb) print gval=300
$2 = 300
(gdb) print gval
$3 = 300
(gdb) 

注意: print 用于查看变量的数据内容以及可以设置变量的数据,这在我们调试程序的时候非常的实用。

2. 总结
  • gdb调试程序运行的前提
  • gdb如何调试加载程序以及连接正在运行的程序
  • gdb常见的调试指令

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

面试官都在问 的相关文章

  • 未找到 ffmpeg 命令,但 pip 列表显示 ffmpeg

    我一直在尝试使用命令安装 ffmpegpip install ffmpeg我正在没有 sudo 权限的服务器上执行此操作 在编写 ffmpeg 时 我得到 ffmpeg command not found 然后我检查了pip list它显示
  • 如何在内核内部使用性能计数器?

    我想访问内核内部的性能计数器 我发现了很多在用户空间中使用性能计数器的方法 但是你能告诉我一些在内核空间中使用这些计数器的方法吗 Please 不指定工具名称 我想写自己的代码 最好是内核模块 我使用的是内核为 3 18 1 的 Ubunt
  • Linux Bash - 日期格式

    我的日期格式是 yyyy mm dd hh mm ss 如何检查我的输入 它应该是这样的 bin bash read p Date format yy mm dd HH MM SS input check date Y m d H M S
  • Bash:使用参数扩展查找和替换

    我想更换输入法 find string include 圆进度 38px 30px 4eb630 和输出 输出字符串 include 圆进度 38px 30px using find string pattern replacement s
  • IPC:在两个程序之间使用 C++ 中的命名管道

    我试图在同一台机器上运行的两个不同程序之间实现IPC 在我的例子中是CentOS7 为了实现一种松散耦合 我决定对 IPC 使用命名管道 因此 我正在使用以下示例并遇到了不同的问题 创建并写入管道 include
  • 针对 openpose 将 GCC 9.3.0 降级到 7 后,cuda_compile_1_ generated_batch_norm_layer.cu.o.Release.cmake 出现 CMake 错误

    你知道我该如何解决以下错误吗 这是在我使用以下命令从 GCC 9 3 0 降级到 7 后发生的 使用以前版本的 GCC 我收到此错误 CMake 不支持的 GNU 版本 不支持高于 8 的 gcc 版本 https stackoverflo
  • 如何在 Flutter 中创建类似 Telegram 或 WhatsApp 聊天页面的富文本输入?

    How can I create a Rich Text Input like a Telegram chat page without displaying reserved characters such as bold italic
  • WSL gprof 报告零次

    我正在尝试在 Windows 10 上的 WSL 中使用 gprof 我没有预料到会遇到任何困难 因为上次我在 Windows 7 上的 Ubuntu 虚拟盒中使用它时它工作得很好 与以前一样遵循来自https www thegeekstu
  • 如何在shell脚本中扩展相对路径

    我正在编写一个脚本来使用 bash 在 linux 2 6 上设置环境变量 因此该脚本包含如下命令 export SRC DIR export LIBPATH SRC DIR lib 问题是 当我尝试 echo LIBPATH 时 它显示
  • 如何从子进程为父进程设置环境变量?

    如何从子进程为父进程设置环境变量 例如 我有父进程和子进程 子进程继承自父进程环境变量 TMP VARIABLE 777 如何将子进程中 TMP VARIABLE 的值更改为 999 使其值对父进程可见 因为 TMP VARIABLE 99
  • posix 和 linux 特定函数的 C++ 包装器 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您知道有什么好的库将 posix 和 linux 函数和结构 例如套接字或文件描述符 包装到 C 类中
  • gai_cancel() 需要很长时间才能成功

    我正在尝试在 C 中异步查找域 原因是我希望能够有效地添加超时期限 以防系统无法查找域 我遇到了 getaddrinfo a 命令 所以我决定尝试一下 然而 在我的机器上取消任何不会成功的 dns 查找 例如没有互联网连接时 永远不会花费少
  • 如何使用Python distutils?

    我用 python 编写了一个快速程序 将 gtk GUI 添加到 cli 程序中 我想知道如何使用 distutils 创建安装程序 因为它只是命令行应用程序的 GUI 前端 所以它只能在 nix 中工作 所以我不担心它是跨平台的 我的主
  • 将条目添加到 Linux 内核 .config 文件

    如何手动将 CONFIG XILINX FIXED DEVTREE ADDR y 行添加到 Linux 配置文件中 当我构建内核时它不断被覆盖 您可以通过以下方式构建make CONFIG XILINX FIXED DEVTREE ADDR
  • Visual Studio 代码中的“Git:gpg 未能签署数据”

    全新安装 Linux 后 我尝试设置我的环境 并且不断收到Git gpg failed to sign the data在本地提交更改时出错 我使用的是 Visual Studio Code 专有版本 而不是开源版本 gitconfig u
  • C++向量数组运算符计算成本高?

    我一直都知道 C 的丰富抽象会带来一定的计算开销 但我的印象是 一旦应用了正确的编译器优化 这种开销几乎可以忽略不计 我很好奇这种开销到底有多大 所以我编写了一个简单的测试来确定这一点 该测试是一个模板化函数 它接受一个容器变量 为容器中的
  • Linux GCC 上 的 C++ 编译问题

    尝试过谷歌并在这里搜索 但没有运气 我正在尝试将一些使用 Windows 的代码移植到 Linux 上 然后我得到了大量的编译错误 我所做的只是 include
  • python中的多服务器监控/自动重启

    我有 2 个服务器程序 必须使用 GNU Screen 启动 我想使用基于 Python 的程序来强化这些服务器 防止崩溃 该程序启动每个屏幕会话 然后监视服务器进程 如果服务器进程崩溃 我需要 python 代码来终止无关的屏幕会话并再次
  • top命令的CPU使用率计算

    我正在尝试使用 GNU coreutil top 的公式来计算 CPU 使用率的百分比 但 top 正在使用一些 half total 来计算百分比 即在百分比上添加 0 5 在top的utils c中 以下行 在 3 8 beta1 中
  • 检测目录中是否有某些内容被修改,如果是,则备份 - 否则不执行任何操作

    我有一个 数据 目录 我通过 shell 脚本定期同步到远程 NAS 但是 我想让这变得更有效率 我想在运行 rsync 之前检测 数据 中是否发生了变化 这样我就不会不必要地唤醒 NAS 上的驱动器 我正在考虑修改 shell 脚本以获取

随机推荐

  • AttributeError: ‘Axes‘ object has no property ‘axisbg‘

    在使用python画图的时候报了这些错 说明axibg这个属性已经被取消了 定位报错的axibg 将其改为fc就可以了 正确的如下
  • muduo网络库浅谈(一)

    muduo网络库浅谈 一 序言 第一章 muduo的关键结构 class EventLoop class Channel class Poller 番外 定时任务 class Timestamp class Timer class Time
  • Java 处理图片-压缩本地图片及远程图片,按照BASE64格式输出

    Java 处理图片 压缩本地图片及远程图片 按照BASE64格式输出 很久没有写博客了 不是我颓废了 而是实在是太忙了 抽不出时间也抽不出经历写东西了 幸亏项目已经落地 没有那么的忙了 记录一下 最近在做导出 发现很多时候导出的图片太大了
  • 简单聊聊Echarts伪3D地图实现的相关配置

    知识和技能真的是用进废退 还是得多实践 才不至于遗忘 目录 前言 二 实现原理 三 从0开始实现 1 目录结构 2 地图JSON数据获取 3 具体实现 重头戏 3 一些常见问题的解决方法 总结 前言 本文简单来聊一聊Echarts伪3D地图
  • 网管联盟

    http wglm net
  • Hive常用DDL操作

    一 Database 1 1 查看数据列表 show databases 1 2 使用数据库 USE database name 1 3 新建数据库 语法 CREATE DATABASE SCHEMA IF NOT EXISTS datab
  • 企业微信跳转小程序注意事项

    1 引用weixin 1 2 0 js 一定使用线上引用 npm install引用的报agentConfig is not a function 2 vue ts在public gt index 中引用 lt scri pt src ht
  • [爬虫] B站番剧信息爬取

    申明 本文对爬取的数据仅做学习使用 不涉及任何商业活动 侵删 简述 本次爬取目标是 番剧的基本信息 名字 类型 集数 连载or完结 链接等 番剧的参数信息 播放量 点赞 投币 追番人数等 时间信息 开播时间 完结时间 前提条件 编程语言 P
  • 【正点原子STM32连载】 第二十八章 低功耗实验 摘自【正点原子】APM32F407最小系统板使用指南

    1 实验平台 正点原子stm32f103战舰开发板V4 2 平台购买地址 https detail tmall com item htm id 609294757420 3 全套实验源码 手册 视频下载地址 http www openedv
  • 链路追踪zipkin

    目录 链路追踪介绍 zipkin整合mysql和mq 链路追踪介绍 链路追踪主要用于分布式系统 服务出现级联调用 能够提供调用的时间且能结算出网络延迟时间 gt 将服务还原成链路 链路数据模型有三个点 Trace 一个完整的链路 用的是我们
  • 不习惯的Vue3起步 の 一:<script setup>

    序 Vue3虽然说是Vue2的升级版 但里面不一样的地方还是挺多的 并且相比Vue2能更好的使用typescript了 先从网上找视频学习 https www bilibili com video BV1gf4y1W783 目录 Vue T
  • Elasticsearch实战(八)--- 词条为中心的 CrossFields 多字段搜索策略

    Elasticsearch实战 词条为中心的Cross Fields 搜索策略 文章目录 Elasticsearch实战 词条为中心的Cross Fields 搜索策略 1 字段中心实现方式及问题 1 1 准备数据 1 2 字段中心的Mos
  • [SQL系列] 从头开始学PostgreSQL 自增 权限和时间

    SQL系列 从头开始学PostgreSQL 事务 锁 子查询 Edward W的博客 CSDN博客https blog csdn net u013379032 article details 131841058上一篇介绍了事务 锁 子查询
  • Linux操作系统之基础命令

    文章目录 一 初识LInux操作系统 Linux操作系统和Windows操作系统的区别 Linux 分为内核版本和发行版本 目录结构命令 二 常用命令 1 ls命令 查看路径下所存在的文件 2 cd命令 切换路径 3 clear 清屏命令
  • 网络工程师工作经验分享

    网络 点击打开链接1 点击打开链接2 点击打开链接3 点击打开链接
  • Docker容器-cgroups资源配置

    目录 Cgroup的概述 使用stress工具测试CPU和内存 CPU周期限制 CPU Core控制 对内存限额 对 Block IO的限制 bps 和iops 的限制 Cgroups如何工作的 cgroup对cpu限制小结 cgroup对
  • 【其他】MacOS Homebrew安装与卸载

    打开terminal 输入 usr bin ruby e curl fsSL https raw githubusercontent com Homebrew install master install 输入sudo密码之后等待一会 之后
  • 电子拼图思维逻辑机的破解思路

    最近孩子去朋友家做客 喜欢上了一个玩具 网上找了好久都没找到 后来问朋友给了个链接 发现是上市不久的益智类游戏玩具 先上个图 开机之后有500关 难度越来越大 在朋友家玩的第3关 小孩子们都拼不上 然后我们家长大孩子们也一起参与 搞了几分钟
  • 前端使用FormData实现上传文件

    场景 用户通过点击图片弹出上传文件的框框 然后选择将要替换的图片 选择后实时预览 点击确定后通过ajax上传到服务器 前端html div div
  • 面试官都在问

    面试官都在问 Linux命令之gdb 0 简述 GDB GNU symbolic debugger 简单地说就是一个调试工具 它是一个受通用公共许可证即GPL保护的自由软件 一般来说 GDB主要帮助你完成下面四个方面的功能 1 启动你的程序