gdb的使用

返回总目录目录

前言

本文介绍Linux环境下的C/C++调试工具--gdb。虽然在Win或MacOS下,可以使用VS或者Xcode进行调试,但是,Linux环境是目前主流的服务器的首选操作系统。因此,在Linux命令行环境下,推荐使用gdb进行调试(也可以使用Vim等进行调试,看个人喜好),为了深入理解C/C++,特别是内存控制,学习gdb是非常有必要的。(如果没有安装,请自行安装,例如ubuntu是sudo apt install gdb)

知识储备

在看这篇文章之前,我假定您已经掌握了如下知识:

知识 为什么需要掌握
Linux或者Unix操作环境 我们不在Win上玩,主要是因为,大部分生产环境系统都是Linux或者Unix的,学习知识就是要最大限度的仿真
C/C++基础 因为,我们需要在Linux环境下操纵C/C++,因此,需要有C/C++的基础
指针 主要通过gdb学习指针(内存控制),因此需要有指针的知识储备

程序准备

我们准备一个含有指针变量的小程序来做这个实验。通过这个程序我们最大限度的了解gdb是如何操纵和使用的。

关于指针变量的初始化

不兼容警告

int *a = 20;

warning: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' [-Wint-conversion]

因此,不要这样定义指针。我们通过,int a = 20;然后通过&a的方式取得地址。否则,很有可能出现Segmentation fault。这种错误,从另外一个层面来说的话,就是,地址指向到了非栈内存空间,例如,代码位内存空间,我们无法直接操作代码位内存空间所致。例如,char *p="llll";这个p就会记录代码位的地址,因此,无法操作p来进行偏移。(也就相当于指针指向了常量)

Segmentation fault

Segmentation fault是访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址、访问了系统保护的内存地址、访问了只读的内存地址等等情况。

A segmentation fault (often shortened to segfault) is a particular error condition that can occur during the operation of computer software. In short, a segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (e.g., attempts to write to a read-only location, or to overwrite part of the operating system). Systems based on processors like the Motorola 68000 tend to refer to these events as Address or Bus errors.

Segmentation is one approach to memory management and protection in the operating system. It has been superseded by paging for most purposes, but much of the terminology of segmentation is still used, "segmentation fault" being an example. Some operating systems still have segmentation at some logical level although paging is used as the main memory management policy.

On Unix-like operating systems, a process that accesses invalid memory receives the SIGSEGV signal. On Microsoft Windows, a process that accesses invalid memory receives the STATUS_ACCESS_VIOLATION exception.

下方的程序会支出产生segmentation fault的地方。

代码

#include <stdio.h>
  
void change(int a,int b){

        int temp=a;
        a=b;
        b=temp;

}

void change_p(int *a,int *b){

        int temp=*a;
        *a=*b;
        *b=temp;
}

int main(){

        int a=5;
        int b=19;
       // int *c=5; // 这样定义c只不过是一个16进制的数而已,因此会造成segmentation fault。
        //int *d=17;//所以不要这样定义,
       //这样定义的问题还有一点,就是我们认为的将十进制的数,赋值给了16进制的数字,不仅要做类型转换,还会造成segmentation fault的问题
      //因为根本找不到地址指向的内容 int *d = 28;我们看到的d = 0x1c,下方有图。
        change(a,b);
        //change(*c,*d);//不要这样写,会产生segmentation fault
        printf("a=%d\nb=%d\n",a,b);
        
        change_p(&a,&b);
        //change_p(c,d);
        printf("a=%d\nb=%d\n",a,b);
        return 0;
}

图片.png

使用gdb

MacOS下,请使用sudo来调用gdb,或者对gdb授权。

MacOS需要授权gdb

对于MacOS下的gdb调试,需要签名,否则会报错please check gdb is codesigned - see taskgated(8)这是因为,Darwin默认禁止调试其它进程。需要用系统信任的证书对gdb进行签名。

创建证书

1.钥匙串访问 -> 证书助理 -> 创建证书
2.名称:gdb_c
3.身份类型:自签名根证书
4.证书类型:代码签名
5.钩选:【让我覆盖这些默认设置】
6.一路继续,直到【指定证书位置的步骤】,选择【系统】并继续。
(如果报这样的错,请这样处理
“Unknown Error = -2,147,414,007” on creating certificate with Certificate Assistant
7.找到刚刚创建的gdb_c证书并双击打开证书信息窗口,展开信任项,设置使用此证书时:为始终信任。
8.sudo codesign -fs gdb_c /usr/local/bin/gdb

使用gcc -g编译

只要通过gcc -g 文件名.c -o 文件民.out编译的程序(也就是编译的时候,增加了-g参数,详见gcc使用那篇文件),才可以使用gdb调试gdb ./文件名.out

gdb调试工具的使用

命令缩写 命令全写 说明
l list 展示源代码
n next 向下执行一行语句
s step 进入函数中调试
bt 展示堆栈
f 转换回原来的函数,通过bt可以看到不同的函数的栈头f + 函数号
p print 打印日志,p + 变量
x 显示从某个地址开始的几个数,并且可用指定开始地址和格式,x/3d 0x7ffffffff...
break break + 行号 打断点
start start 开始单步调试,临时断点打在main函数内的第一个指向语句那行
q quit 退出调试

使用gdb产看变量和内存

计算机内存的分配

什么是堆内存
什么是栈内存
内存地址
指针变量的实质是什么东西

指针只传递地址(并且是通过16进制的方式展示的,每两个16进制的字符,对应着一个字节,就是00 - ff,表示0~255供 256个不同的字节,并且,内存地址是有编号的,这个指针,就是展示了内存地址的编号,一个整形占4个字节)

这样的化,对于a来说,a就是地址,表示的是地址指向的值,那么*a表示的就是具体的值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345