GDB调试
启动程序准备调试
GDB yourpram
或者
先输入GDB
然后输入 file yourpram

然后使用run或者r命令开始程序的执行,也可以使用 run parameter将参数传递给该程序

参数列表

命令

命令缩写

命令说明

list

l

显示多行源代码

break

b

设置断点,程序运行到断点的位置会停下来

info

i

描述程序的状态

run

r

开始运行程序

display

disp

跟踪查看某个变量,每次停下来都显示它的值

step

s

执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句

next

n

执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)

print

p

打印内部变量值

continue

c

继续程序的运行,直到遇到下一个断点

set var name=v

设置变量的值

start

st

开始执行程序,在main函数的第一条语句前面停下来

file

装入需要调试的程序

kill

k

终止正在调试的程序

watch

监视变量值的变化

backtrace

bt

查看函数调用信息(堆栈)

frame

f

查看栈帧  f n 切换到编号为n的栈

quit

q

退出GDB环境

  

//e.c
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
printf("now a=%d\n", j);
}
}

gcc -g -o e e.c
调试gdb e
或者输入gdb
然后 file e

list 命令用法

list命令显示多行源代码,从上次的位置开始显示,默认情况下,一次显示10行,第一次使用时,从代码起始位置显示

gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
(gdb)

list n显示已第n行未中心的10行代码

(gdb) list
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
printf("now a=%d\n", j);
}
(gdb)

list functionname显示以functionname的函数为中心的10行代码

(gdb) list main
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
(gdb)

list - 显示刚才打印过的源代码之前的代码

(gdb) list
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
printf("now a=%d\n", j);
}
}(gdb) list -
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
(gdb)

断点命令break
break location:在location位置设置断点,该位置可以为某一行,某函数名或者其它结构的地址
GDB会在执行该位置的代码之前停下来

gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
j+=;
(gdb)
printf("now a=%d\n", j);
}
}(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb) c
Continuing.
now a= Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb) c
Continuing.
now a= Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb)

使用delete breakpoints 断点号 删除断点
这里的断点号表示的是第几个断点,刚才执行break 10返回 reakpoint 1 at 0x40050a: file e.c, line 10.
中的1表示该断点的标号,因此使用 delete breakpoints 1表示删除第10行所定义的断点
clear n表示清除第n行的断点,因此clear 10等同于delete breakpoints 1
disable/enable n表示使得编号为n的断点暂时失效或有效
可使用info查看断点相关的信息
info breakpoints

gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) break
Breakpoint at 0x400501: file e.c, line .
(gdb) info breakpoints
Num Type Disp Enb Address What
breakpoint keep y 0x000000000040050a in main at e.c:
breakpoint keep y 0x0000000000400501 in main at e.c:

display命令
查看参数的值

(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
(gdb) display j
: j =
(gdb) c
Continuing.
now a= Breakpoint , main (argc=, argv=0x7fffffffe548) at e.c:
j+=;
: j =
(gdb) display
: j =
(gdb) display i
: i =
(gdb) display j
: j =
(gdb) display j*
: j* =
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
: y j*
: y j
: y i
: y j

也可以使用disable,enable,delete,info命令修改及查看其状态,用法与对断点的一样

step及next命令
step可使得程序逐条执行,即执行完一条语句然后在吓一跳语句前停下来,等待用户的命令
一般使用step命令是,可使用display或者watch命令查看变量的变化,从而判断程序行为是否符合要求
当下一条指令为函数时,s进入函数内部,在其第一条语句前停下来
step n,next n 表示连续但不执行n条指令,如果期间遇到断点,则停下来

(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) break
Breakpoint at 0x40050a: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j+=;
(gdb) s
printf("now j=%d\n", j);
(gdb) s
__printf (format=0x400648 "now j=%d\n") at printf.c:
{
(gdb) bt
# __printf (format=0x400648 "now j=%d\n") at printf.c:
# 0x0000000000400525 in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) n
va_start (arg, format);
(gdb) n
done = vfprintf (stdout, format, arg);
(gdb) n
now j=
}
(gdb) bt
# __printf (format=<value optimized out>) at printf.c:
# 0x0000000000400525 in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) n
main (argc=, argv=0x7fffffffe538) at e.c:
debug("x=======x");
(gdb) n
debug info :x=======x
for(i=;i<;i++){
(gdb) s Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j+=;
(gdb) s
printf("now j=%d\n", j);
(gdb) n
now j=
debug("x=======x");
(gdb) n
debug info :x=======x
for(i=;i<;i++){
(gdb)

watch
watch可设置观察点(watchpoint)。使用观察点可以使得当某表达式的值发生变化时,程序暂停执行。
执行该命令前,必须保证程序已经运行

(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) b main
Breakpoint at 0x4004fa: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j=;
(gdb) watch j
Hardware watchpoint : j
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);

print命令

(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) break
Breakpoint at 0x40050e: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) p j
$ =
(gdb) c
Continuing.
now j=
debug info :x=======x Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) p i,j
$ =
(gdb) p j
$ =
(gdb)

set var name=value

set args 可指定运行时参数(当main函数需要参数时 如:set args 10 20 30 40 50)

show args 命令可以查看设置好的运行参数

在程序运行中动态改变变量的值

(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) break main
Breakpoint at 0x4004fa: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1 Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
j=;
(gdb) watch i
Hardware watchpoint : i
(gdb) watch j
Hardware watchpoint : j
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) set var i=
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing.
Hardware watchpoint : j Old value =
New value =
main (argc=, argv=0x7fffffffe538) at e.c:
printf("now j=%d\n", j);
(gdb) c
Continuing.
now j=
debug info :x=======x
Hardware watchpoint : i Old value =
New value =
0x0000000000400533 in main (argc=, argv=0x7fffffffe538) at e.c:
for(i=;i<;i++){
(gdb) c
Continuing. Watchpoint deleted because the program has left the block in
which its expression is valid. Watchpoint deleted because the program has left the block in
which its expression is valid.
__libc_start_main (main=0x4004eb <main>, argc=, ubp_av=0x7fffffffe538, init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>,
stack_end=0x7fffffffe528) at libc-start.c:
exit (result);
(gdb) c
Continuing. Program exited with code .

函数调用相关的
backtrace
可使用frame 查看堆栈中某一帧的信息

(gdb) list
#include <stdio.h>
void debug(char *str)
{
printf("debug info :%s\n",str );
} main(int argc,char *argv[]){
int i,j;
j=;
for(i=;i<;i++){
(gdb)
j+=;
printf("now j=%d\n", j);
debug("x=======x");
}
}(gdb)
Line number out of range; e.c has lines.
(gdb) b
Breakpoint at 0x400525: file e.c, line .
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e1
now j= Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
debug("x=======x");
(gdb) s
debug (str=0x400652 "x=======x") at e.c:
printf("debug info :%s\n",str );
(gdb) bt
# debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) s
__printf (format=0x400638 "debug info :%s\n") at printf.c:
{
(gdb) bt
# __printf (format=0x400638 "debug info :%s\n") at printf.c:
# 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) s
va_start (arg, format);
(gdb) bt
# __printf (format=0x400638 "debug info :%s\n") at printf.c:
# 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) s
done = vfprintf (stdout, format, arg);
(gdb) s
_IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:
int save_errno = errno;
(gdb) bt
# _IO_vfprintf_internal (s=0x333a58f040, format=0x400638 "debug info :%s\n", ap=0x7fffffffe330) at vfprintf.c:
# 0x000000333a24effa in __printf (format=<value optimized out>) at printf.c:
# 0x00000000004004e9 in debug (str=0x400652 "x=======x") at e.c:
# 0x000000000040052f in main (argc=, argv=0x7fffffffe538) at e.c:
(gdb) c
Continuing.
debug info :x=======x
now j= Breakpoint , main (argc=, argv=0x7fffffffe538) at e.c:
debug("x=======x");
(gdb) bt
# main (argc=, argv=0x7fffffffe538) at e.c:

 GDB段错误调试

所谓段错误就是对内存的非法访问
采用GDB调试段错误有2种方法
1.在GDB中运行目标程序,当发生段错误时,GDB中运行的程序会自动停下来
2.直接运行目标程序,使其在发生段错误时产生内存转储(core dump)文件,GDB对该文件进行调试

abort.c

#include <stdio.h>
#include <stdlib.h> void recurse(void)
{
static int i;
if( ++i == )
abort();
else
recurse();
}
int main(int argc,char ** argv){
recurse();
}
gcc -g -o abort abort.c
使用gdb调试
Line number out of range; abort.c has lines.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/abort Program received signal SIGABRT, Aborted.
0x000000333a232495 in raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:
return INLINE_SYSCALL (tgkill, , pid, selftid, sig);
(gdb) bt
# 0x000000333a232495 in raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:
# 0x000000333a233c75 in abort () at abort.c:
# 0x00000000004004e7 in recurse () at abort.c:
# 0x00000000004004ec in recurse () at abort.c:
# 0x00000000004004ec in recurse () at abort.c:
# 0x0000000000400502 in main (argc=, argv=0x7fffffffe528) at abort.c:
显示在recurse函数调用了3次后调用了abort函数,产生段错误

使用内存转储文件

ulimit -a 

[root@centos1 gcc]# ulimit -a
core file size (blocks, -c)
data seg size (kbytes, -d) unlimited
scheduling priority (-e)
file size (blocks, -f) unlimited
pending signals (-i)
max locked memory (kbytes, -l)
max memory size (kbytes, -m) unlimited
open files (-n)
pipe size ( bytes, -p)
POSIX message queues (bytes, -q)
real-time priority (-r)
stack size (kbytes, -s)
cpu time (seconds, -t) unlimited
max user processes (-u)
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
core file size 此时是0

ulimit -c unlimited  设置为不受限制

执行 ./abort 产生内存转储文件
ls 可看到一个名为core且以进程号为后缀的文件

core.6289
gdb abort core.6289
bt
方法同上一个gdb调试

gdb调试的基本使用的更多相关文章

  1. GDB调试命令小结

    1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...

  2. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  3. gdb调试器的使用

    想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车    是运行上一个命令 ...

  4. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  5. gdb调试PHP扩展错误

    有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...

  6. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

  7. gdb调试

    ·代码(实验楼中的代码,改了部分数值)命名为test.c int g(int x) { return x + 7; } int f(int x) { return g(x); } int main(v ...

  8. 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析

    20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...

  9. GDB调试汇编堆栈

    GDB调试汇编堆栈 分析过程 C语言源代码 int g(int x) { return x+6; } int f(int x) { return g(x+1); } int main(void) { ...

  10. 赵文豪 GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 使用gdb调 ...

随机推荐

  1. centos6.5中rpm包安装mysql5.7(初始化出错如何解决)

    下载rpm包见:http://www.cnblogs.com/grey-wolf/p/7472680.html 1.rz上传到服务器,解压缩 rz [root@mini2 upload]# -.el6 ...

  2. python——函数

    python--函数 1.介绍: 在过去的十年间,大家广为熟知的编程方法无非两种:面向对象和面向过程,其实,无论哪种,都是一种编程的规范或者是如何编程的方法论.而如今,一种更为古老的编程方式:函数式编 ...

  3. Django REST framework+Vue 打造生鲜超市(五)

    六.商品类别数据展示 6.1. 商品类别数据接口 (1)商品分类有两个接口: 一种是全部分类:一级二级三级 一种是某一类的分类以及商品详细信息: 开始写商品分类的接口 (2)序列化 给分类添加三级分类 ...

  4. LabelFrame

    LabelFrame组件是Frame组件的变体. 默认情况下,LabelFrame会在其子组件的周围绘制一个边框以及一个标题. 何时使用LabelFrame组件?当你想要奖一些相关的组件分为一组的时候 ...

  5. Menu-菜单组件

    #menu菜单组件 from tkinter import * master=Tk() def callback(): print('你好咯!!') m = Menu(master) m.add_co ...

  6. Flume报 Space for commit to queue couldn't be acquired. Sinks are likely not keeping up with sources, or the buffer size is too tight

    报这个错误 需要一个是flume堆内存不够.还有一个就是把channel的容器调大 在channel加配置 type - 组件类型名称必须是memory capacity 100 存储在 Channe ...

  7. [原创软件]Maya报错窗口监测器

    软件主要功能: 监测Maya软件运行状态,如弹出报错窗口,则自动点击关闭 程序界面截图: 开发环境及语言: c# .NET Framework 4.0 Visual Studio 2015 更新日志: ...

  8. 《阿里巴巴 Java 开发手册》读书笔记

    偶然看到阿里巴巴居然出书了???趁着满减活动(节约节约....)我赶紧买来准备看看,刚拿到的时候掂量了好多下,总觉得商家给我少发了一本书,结果打开才知道..原来这本书这么小.... 编码规范的重要性 ...

  9. 对于手机APP偷窥个人隐私,你怎么看

    经过进两周的持续发酵,Facebook5000万用户数据泄露事件,已让其处在舆论的风尖浪口.对于手机APP泄漏用户个人隐私问题,再次受到人们的关注.对于这个问题,你会怎么看? 隐私,即不愿公开的个人信 ...

  10. [LeetCode] Longest Harmonious Subsequence 最长和谐子序列

    We define a harmonious array is an array where the difference between its maximum value and its mini ...