美文网首页
gdb的使用

gdb的使用

作者: 白昔月 | 来源:发表于2019-10-08 18:02 被阅读0次

返回总目录目录

前言

本文介绍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表示的就是具体的值。

相关文章

  • GDB 配置

    摘要:调试器 GDB 的配置 GDB 配置 使用 GDB 扩展来配置 GDB 事实上我还是觉得原生的 GDB 就...

  • Linux下C++开发常用工具

    gdb 使用gdb的时候, 需要在编译时使用-g命令, 在编译时加入必要的C库gdb + filename进入调试...

  • gdb调试

    使用gdb:编译的时候加 -g 参数 启动gdb:gdb app(对应的可执行程序名) 在gdb启动后:r(un)...

  • GDB入门教程之如何使用GDB启动调试

    原文地址:GDB入门教程之如何使用GDB启动调试|Vim教程网 GDB (The GNU Project Debu...

  • gcc常用命令

    gdb相关 gcc加-g才能使用gdb调试gdb -tui a.out打开调试界面run/stop/continu...

  • Xcode debug Hotspot(一)——创建Xcode项

    概述 前面安装gdb调试hotspot里面,我记录了自己安装gdb调试hotspot的过程。后来我发现,使用gdb...

  • gdb

    gdb调试工具使用

  • GDB调试指南

    @[linux|gdb] 说明:从CSDN的网站上找到的GDB使用说明,这篇文章脉络清晰,浅显易懂,介绍了GDB大...

  • gdb的使用

    返回总目录目录 前言 本文介绍Linux环境下的C/C++调试工具--gdb。虽然在Win或MacOS下,可以使用...

  • gdb的使用

    标题一 标题二 标题三 标题四 标题五 https://www.jianshu.com/p/adcf474f5561

网友评论

      本文标题:gdb的使用

      本文链接:https://www.haomeiwen.com/subject/zhhmpctx.html