GDB调试及其调试脚本的使用
返回脚本百事通
一、GDB调试

1.1. GDB 概述

GDB
是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在
UNIX/Linux平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。

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

1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、动态的改变你程序的执行环境。

从上面看来,GDB和一般的调试工具没有什么两样,基本上也是完成这些功能,不过在细节上,你会发现GDB这个调试工具的强大,大家可能比较习惯了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完成的功能。让我们一一看来。

1.2.GDB 使用示例

使用一个简单的判断来测试一下:文件名gdbtest.c

#include "stdio.h"
int main()
{
int x=3;
if(x<4)
printf("x is less than 4\n");
else
printf("x is biger than 4\n");
}

程序很简单,设置x=3,然后判断x是否比4小,若比4小则输出”x is less than 4“,若比4大,则输出”x is biger than 4“ ,程序很无聊,但是我们可以用来做GDB的测试!

注: 编译的时候需要使用-g选项,我使用的是:gcc -g -o gdbtest gdbtest.c

使用GDB调试:

gdb ./gdbtest <------- 启动GDB
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/long/gdbtest...done.
(gdb) l <------- l命令相当于list,从第一行开始例出原

1 #include "stdio.h"
2 int main()
3 {
4 int x=3;
5 if(x<4)
6 printf("x is less than 4\n");
7 else
8 printf("x is biger than 4\n");
9 }
(gdb) b 5 <------- b相当与break 设置断点,在源程序第5行处。
Breakpoint 1 at 0x8048935: file gdbtest.c, line 5.
(gdb) run <------- 运行程序,也可以用简写r
Starting program: /home/long/gdbtest

Breakpoint 1, main () at gdbtest.c:5 <------- 其实停在第一个断点,在第5行
5 if(x<4)
(gdb) info b <------- 查看断点的信息
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048935 in main at gdbtest.c:5
breakpoint already hit 1 time
(gdb) print x <------- 打印x的值(print 也可以用其简写p)>,这时候x等于上面赋值的3
$1 = 3
(gdb) print &x <------- 打印x的地址
$2 = (int *) 0xbffff21c
(gdb) x/4x 0xbffff21c <------- 查看从0xbffff21c开始的4*4个字节的值
0xbffff21c: 0x00000003 0x0804a000 0x00000000 0x00000000 <------- x为int值,为4个字节
,所以x的值等于0x00000003,我们可以看到此时x等于3
(gdb) set x=5 <------- 我们设置x=5
(gdb) print x <------- 打印x的值,可以看到x已经被改成5了
$3 = 5
(gdb) x/4x 0xbffff21c
0xbffff21c: 0x00000005 0x0804a000 0x00000000 0x00000000
(gdb) n <------- 单条语句执行,next命令简写。
8 printf("x is biger than 4\n");
(gdb) c <------- 继续运行程序,continue命令简写。
Continuing.
profiling:/home/zhouyl:Cannot create directory
profiling:/home/zhouyl/NicholClass/error_test/gdb/gdbtest.gcda:Skip
x is biger than 4[Inferior 1 (process 9265) exited with code 01] <------- 程序输出x is biger than 4,因为此时x已经被改为5了
(gdb) q <------- 退出gdb
#

在上述GDB调试测试中,我们可以将x的值改为5,然后程序的输出变为 x is biger than 4 。很有趣又很强大是不?

1.3.GDB 更多知识点总结(不断搜集)

1.3.1 GDB 调试如何传参数?

我们仍然使用示例来演示:

示例的代码很简单:test.c

#include <stdio.h>
int main(int argc, char **argv)
{
int i=0;
i=atoi(argv[1]);
i = i + 1;
printf("The value after add the first arg is : %d\n",i);
i=atoi(argv[2]);
i = i - 1;
printf("The value after minus the second arg is : %d\n",i);
return 0;
}

示例中我们分别打印第一个参数加1和第二个参数减1 的值。

我们使用gdb调试:

#gcc -g -o test test.c
#gdb ./test <------- 正常开始调剂程序
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/test...done.
(gdb) set args 111 1 <------- 在调试时给程序传入参数
(gdb) run
Starting program: /tmp/test 111 1
The value after add the first arg is : 112
The value after minus the second arg is : 0
[Inferior 1 (process 9667) exited normally]
(gdb) q
#

二、GDB调试脚本的使用

下面我们对第一章中的gdbtest.c文件使用gdb脚本调试,其实很简单我们只要把需要的操作放到一个文件中,比如叫做 gdbtest.sh

break 5
run
set x=5
c
q

那么我们如何使用?其实很简单,我们在使用时,不用直接gdb gdbtest ,而使用 gdb ./gdbtest -command=gdbtest.sh

其实还有种方法,我们直接在脚本中添加所要调试的文件信息,此时的 gdbtest.sh内容为:

file gdbtest
break 5
run
set x=5
c
q

而我们调试使用的命令就简单了,直接使用gdb -x gdbtest.sh 即可!

三、GCOV的使用

3.1 gcov是什么?

Gcov is GCC Coverage

是一个测试代码覆盖率的工具

是一个命令行方式的控制台程序

伴随GCC发布,配合GCC共同实现对C/C++文件的语句覆盖和分支覆盖测试;

与程序概要分析工具(profiling tool,例如gprof)一起工作,可以估计程序中哪一段代码最耗时;

注:程序概要分析工具是分析代码性能的工具。

3.2 gcov能做什么?

gcov可以统计:

每一行代码的执行频率

实际上哪些代码确实被执行了

每一段代码(section code)的耗时(执行时间)

因此,gcov可以帮你优化代码,当然这个优化动作还是应该有开发者完成。

3.3 gcov 使用

我们继续使用第一章中的gdbtest.c文件,使用gcov时候,在编译时使用 gcc -g3 -fprofile-arcs -ftest-coverage gdbtest.c

#ls
gdbtest.c gdbtest.sh
#gcc
-g3 -fprofile-arcs -ftest-coverage gdbtest.c <--------
使用-fprofile-arcs -ftest-coverage
参数添加gcov信息,其实可以不使用-g参数,我示例中需要使用gdb调试,所以添加了
#./a.out
x is less than 4
#gcov gdbtest
File‘gdbtest.c’
已执行的行数:83.33% (共 6 行)
Creating 'gdbtest.c.gcov'

# cat gdbtest.c.gcov
-: 0:Source:gdbtest.c
-: 0:Graph:gdbtest.gcno
-: 0:Data:gdbtest.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include "stdio.h"
1: 2:int main() <----------- "1"为本行运行次数
-: 3:{
1: 4: int x=3;
1: 5: if(x<4)
1: 6: printf("x is less than 4\n");
-: 7: else
#####: 8: printf("x is biger than 4\n"); <-----------"#####"代表此行未运>行
1: 9:}
#
#gdb ./a.out -command=gdbtest.sh <-------- 使用上面的脚本调试,其
实我们的目的是运行 else ,然后看区别!
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/long/gcovtest/a.out...done.
Breakpoint 1 at 0x80489dd: file gdbtest.c, line 5.
Breakpoint 1, main () at gdbtest.c:5
5 if(x<4)
x is biger than 4
[Inferior 1 (process 10165) exited with code 01]
#gcov gdbtest <----------- 多运行几次a.out或者
使用脚本,后想重新看看最新的测试代码覆盖率,需要重新 gcov gdbtest
File‘gdbtest.c’
已执行的行数:100.00% (共 6 行)
Creating 'gdbtest.c.gcov'

#cat gdbtest.c.gcov
-: 0:Source:gdbtest.c
-: 0:Graph:gdbtest.gcno
-: 0:Data:gdbtest.gcda
-: 0:Runs:2
-: 0:Programs:1
-: 1:#include "stdio.h"
2: 2:int main()
-: 3:{
2: 4: int x=3;
2: 5: if(x<4)
1: 6: printf("x is less than 4\n"); <----------- 使用脚本运行时,此>行未执行,所以还是运行了1次
-: 7: else <----------- 其实本行else是运行>过一次的,但是gcov 统计时把本行与下一行打印放在一起计时的!
1: 8: printf("x is biger than 4\n");
2: 9:}
#

Linux gcc/g++下GDB调试及其调试脚本的使用的更多相关文章

  1. eclipse下使用cygwin的方法(Windows下用eclipse玩gcc/g++和gdb)

    明天就回国了,今晚回国前写写如何配置eclipse和CDT.这个配置方法网上讨论不是很多,可能用的人少,毕竟Windows上写C++程序多数喜欢VS,即使写的是Linux程序,很多人仍然会用VS(说只 ...

  2. Linux下gdb线程的调试

    多线程的调试命令 1.info threads: 这条命令显示的是当前可调试的所有线程,GDB会给每一个线程都分配一个ID.前面有*的线程是当前正在调试的线程. 2.thread ID: 切换到当前调 ...

  3. Linux gcc/g++链接编译顺序详解

    gcc/g++链接时对库的顺序要求 -Ldir Add directory dir to the list of directories to be searched for -l. -llibrar ...

  4. LINUX下GDB反汇编和调试

    Linux下的汇编与Windows汇编最大的不同就是第一个操作数是原操作数,第二个是目的操作数.而Windows下却是相反. 1. 基本操作指令 简单的操作数类型说明.一般有三种. (1)马上数操作数 ...

  5. linux系统下gdb的简单调试

    当我们写完程序后,我们会运行程序,在这个过程中,可能程序会出现错误. 我们可以利用gdb调试去看我们运行的程序,并且我们新手通过gdb调试能更好地去读懂 别人的程序.让我们更好的学习. 我们看下面这条 ...

  6. LINUX 和WINDOWS下的自动登录小脚本

    每天上班第一件事,就是连接公司LAB里面的机器,但首先要过一个防火墙,每次输用户名密码是很累人的事, 以下是两个脚本,可以放在启动项中,开机便自动登录 WINDOWS: @echo off ipcon ...

  7. Linux下C/C++程序调试基础(GCC,G++,GDB,CGDB,DDD)

    在写程序的时候,经常会遇到一些问题,比如某些变量计算结果不是我们预期的那样,这时我们需要对程序进行调试.本文主要介绍调试C/C++在Linux操作系统下主要的调试工具. 在Linux下写程序,C/C+ ...

  8. Linux——【转】gcc编译与gdb调试简要步骤

    原文:gcc编译与gdb调试简要步骤 一.Linux程序gcc编译步骤: Gcc编译过程主要的4个阶段: l 预处理阶段,完成宏定义和include文件展开等工作:(.i) l 根据编译参数进行不同程 ...

  9. [vim配置]windows下在vim中使用gcc/g++编译调试c/cpp文件

    在Linux里面混了一个多月,vim编程用得甚爽.无奈前天将Linux里面的编程文件夹误删,而技术不精无法找回,悲痛欲绝.再者,无限怀念windows里面的游戏,并觉得现在在Linux里面也学不到什么 ...

随机推荐

  1. A Byte of Python 笔记(6)模块

    第8章 模块 用户在程序中定义一次函数而重用代码,如果用户想在其他程序中重用很多函数,可以通过使用模块的方式. 模块就是一个包含了所有用户定义的函数和变量的文件.为了在其他程序中重用模块,模块的文件名 ...

  2. JS笔记 入门第一

    WHY? 一.你知道,为什么JavaScript非常值得我们学习吗? 1. 所有主流浏览器都支持JavaScript. 2. 目前,全世界大部分网页都使用JavaScript. 3. 它可以让网页呈现 ...

  3. windows server 2008/2012 无法安装AD域解决方法记录

    安装活动目录之前需要一些准备工作和前提条件的. 有管理员的权限 至少有一个足够大的NTFS文件系统的分区或动态卷 需要DNS服务配合,因此需要安装DNS服务 最好使用dcpromo命令来进行安装 最终 ...

  4. hadoop配置及无法移动文件到hdfs故障解析

    首先博主用的64位ubuntu,hadoop官方只提供32位版本,这样的话启动本地库无法兼容,需要自己编译为64位版本,或下载别人编译好的64位版本. 下载好需要在etc/hadoop目录下改动以下几 ...

  5. 关于document.selection和TextRange对象的介绍

    document.selection只有IE支持 window.getSelection()也只有FireFox和Safari支持,都不是标准语法. selection 对象代表了当前激活选中区,即高 ...

  6. sed 文件查找,替换

    sed 命令查找与替换: (1)删除第2,3行:sed '2,3d' test.txt > new.txt (2)替换:  替换所有:sed 's/abc/ABC/' test.txt > ...

  7. HDU 2108 Shape of HDU

    题解:按照输入顺序依次将点连接起来,对于连续的三个点p0,p1,p2,令向量a=p1-p0,b=p2-p1 若是凸多边形,那么b相对于a一定是向逆时针方向旋转的 判断两向量的旋转方向,可以使用向量的叉 ...

  8. 此windows副本不是正版解决方法

    老爸的win7今天黑屏 右下角出现 Windows7 内部版本7601 此windows副本不是正版 网上零散地找到了解决办法 写博汇总一下 我的情况是 电脑属性中的windows激活显示: 状态不可 ...

  9. QLinkedList和std::forward_list

    forward_list forward_list是C++11版本才有的.forward_list被实现为单链表,而list是一个双向链表,所以forward_list要比list高效一些.forwa ...

  10. 80x86汇编小站站长简单介绍

    [人生格言] 1] 一生都用头脑而不是情绪解决这个问题 2] 仅仅有偏执狂才会成功 3] 在最困难时都要保持一份幽默感 4] 吾生也有涯,而知也无涯,以有涯随无涯,殆已 [简历] 我的生日: 1981 ...