zoukankan      html  css  js  c++  java
  • GDB 使用小结

    GDB 使用小结

    Gdb 不用说,两个字,非常强大 >.<,我最讨厌不识数的人了

    本文适合GDB 初学和没学过的,如果你懂了,可以相互交流

    既然说它很强大,它强大在哪里呢?

    一般情况下,大部分人使用VS 自带的调试器来调试BUG ,直观,清晰。

    在Linux下,为什么还要苦苦选择这样一个命令行工具呢?

    关于CMD 与 图形界面的事情不想再说....囧

    开始我们的GDB 小旅

    首先来调试一个很小的程序:

    程序够简单吧,一目了然

    可以不加 #include <stdio.h>

     黑喂狗~

    编译选项 cc -g endin.c -o endin

    这里的 endin.c 是我电脑上的文件名,你自己选一个你喜欢的就OK

    注意编译选项一定要加 -g ,这个是为GDB 保留源程序的符号表选项,不然一会儿你加载程序将出现问题。

     ok, 生成二进制 endin文件以后

    gdb -q ./endin

    -q 的目的在于消除广告,你懂得

    现在提示

    (gdb)_

    开始介绍命令

    (gdb) ls 1 , n (n = 1,2,3.....n )

    比如  li 1,20   或者简写为 l 1,20 将源程序的第1-20行列出来

    ok,下一步,根据行,我们可以下断点

    (gdb)b 2

    在第2行下断点

    (gdb)b 10

    在第10行下断点

    提示断点成功

    (gdb) run

    开始运行程序,到断点时候会停下来

    (gdb) info locals   (查看当前函数局部变量)

    可以看到,出现了 x 和 buf ,len 三个局部变量

    现在我们的目标是 buf 

    (gdb)x/32xb buf

    这样,我们就可以查看关于buf 里面的内容

    (gdb)x 是检查的意思,32是查看多少位,比如 12 , 55 ... 各种的,可以指定不同的格式

    比如

    (gdb)x/s buf

    以字符流的形式来查看 buf

    (gdb)x/32xw buf

    以十六进制方式查看

    (gdb)x/10b buf

    以十进制查看

    各种的... 以上的方式够用了

    还有一种方式是利用

    (gdb)print (value) 形式来

    比如

    (gdb)print buf

    这样来查看变量,其实还可以设置变量等,这里就不一一列举了

    在来看看关于最头疼的段错误问题,很多人在遇到程序收到异常信号的时候无法调试

    其实很简单,gdb提供了查看堆栈的操作,很多调试器都提供了

    (gdb)backtrack或者直接 (gdb)bt

    我们来模拟一个段错误

    退出(gdb)quit

    加上第11 行代码,很明显我们的意图

    同样编译运行代码后出现

    现在假设我们不知道问题出在哪里,但是我们得事先有一个大致的定位

    提示出现很多关于 stack 和 Memory map ,我们这个时候得大致有一个认识这种错误一般是发生了段违规,也就是访问越界或者使用了未初始化的指针等情况。好了,现在gdb 登场了

    gdb -q ./endin

    直接(gdb)run

    可以看到,调用堆栈的情况,从下往上看,在main() 函数上面的#5 检查栈(stack)使用情况,注意是栈,不是堆,检查失败。发送失败信息,接着调用__libc_message()函数,这个是标准C 的输出函数,然后向上,#2 abort() 退出,#1发起一个信号,信号sig=6 是退出信号。然后#0 __kernel_vsyscall() 函数调用

    整个过程就大致清楚了,我们在检查 stack 的时候产生了错误输出,必定是栈访问违规引起,其实未初始化指针是另外一种状况。

    这里因为涉及到调用堆栈递归层次比较少,看不出优越性。当程序较大的时候可以看出来。

    下面让我们来看看未初始化指针的情况。这个问题常常遇到,但是很多人找不到解决方案,其实很简单。

    我们再修改一下程序

    在第13 和第 14 行,我们加入了一个未初始化的指针,并且我们在后面给他赋值

    运行一下看结果

    程序提示Segmentation fault

    现在这种情况应该有一个直观的影响就是使用了未初始化的指针。那么我们该怎么办?

    继续(gdb)run

    看,gdb 清楚的给我打印出错误锁在行数和代码位置。下次这种问题还会出现么?

    事实上,还有很多东西没有例举出来的,今天就到这里吧

  • 相关阅读:
    python函数
    python正则表达式
    FileStorage
    dietpi请暂时不要升级为jessie
    不从SD卡启动树莓派2
    树莓派2系统DietPi简单安装配置使用介绍
    树莓派笔记之使用netselect选择最快Raspbian软件源
    树莓派系统介绍:DIetPi
    【翻译】树莓派2:关闭无线网卡电源管理功能
    树莓派2安装使用小米WIfi(360 小度 腾讯wifi)
  • 原文地址:https://www.cnblogs.com/hanframe/p/3585622.html
Copyright © 2011-2022 走看看