文档章节

gdb调试Tips

AlphaJay
 AlphaJay
发布于 2012/03/07 18:00
字数 1601
阅读 1319
收藏 1

 

step into就是单步执行,遇到子函数就进入并且继续单步执行;
step over是在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步。
step out就是但单步执行到子函数内时,用step out就可以执行完子函数余下部分,并返回到上一层函
数。

step into:进入子函数      
step over:越过子函数,但子函数会执行
step out:跳出子函数  

Step Into

Executes code one statement at a time.

When not in design mode, Step Into enters break mode at the current line of execution. Step Into executes the statement at the current execution point. If the statement is a call to a procedure, the next statement displayed is the first statement in the procedure.

At design time, this menu item begins execution and enters break modebreak mode before the first line of code is executed. Not available at run time.

If there is no current execution point, the Step Into command may appear to do nothing until you do something that triggers code, for example click on a document.

Toolbar button: . Keyboard shortcut:  F10.

Step Over

Similar to Step Into. The difference in use occurs when the current statement contains a call to a procedure.

Step Over executes the procedure as a unit, and then steps to the next statement in the current procedure. Therefore, the next statement displayed is the next statement in the current procedure regardless of whether the current statement is a call to another procedure. Available in break mode only.

Toolbar button:  . Keyboard shortcut:  F11.

Step Out

Executes the remaining lines of a function in which the current execution point lies. The next statement displayed is the statement following the procedure call. All of the code is executed between the current and the final execution points. Available in break mode only.

Toolbar button:  . Keyboard shortcut:  SHIFT+F11

GDB中

step ->    step into:进入子函数      
next ->     step over:越过子函数,但子函数会执行
finish->   step out:跳出子函数

until->   同step over,主要用于退出循环 

_________________

原文件编译的时候要加-g,例gcc -g -o test test.c, 这样在能在调试的时候用list,watch等命令。

全局变量或当前堆栈区可见的变量才能watch,watch之后用Continuing,就可显示观察变量。



gdb watch 跟踪变量的变化


01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <string.h>
04 
05 int main()
06 {
07     char * name = NULL;
08     int len = 10;
09 
10     name = (char *)malloc(len);
11     strncpy(name, "zengxiaolong", len);
12 
13     char ** wild_pointer;
14     wild_pointer = &name;          // 野指针,指向了变量name
15     *wild_pointer = (char *)0x100; // 野指针,破坏了变量name
16 
17     name[0] = 'a';
18     return 0;
19 }

# gcc test.c -o test -g
# gdb -q test
(gdb) l
1    #include <stdio.h>
2    #include <stdlib.h>
3    #include <string.h>
4    
5    int main()
6    {
7        char * name = NULL;
8        int len = 10;
9    
10        name = (char *)malloc(len);
(gdb) b 7
Breakpoint 1 at 0x80483b5: file test.c, line 7.
(gdb) r
Starting program: /tftpboot/test 

Breakpoint 1, main () at test.c:7
7        char * name = NULL;
(gdb) watch name // 跟踪变量name变化情况
Hardware watchpoint 2: name // 说明该系统结构支持硬件断点
(gdb) c
Continuing.
Hardware watchpoint 2: name

Old value = 0xb7f79dc0 "U\211�WVS��y" // 这里变量name发生了变化
New value = 0x804a008 ""

main () at test.c:11
11        strncpy(name, "zengxiaolong", len);
(gdb) c
Continuing.
Hardware watchpoint 2: name

Old value = 0x804a008 "zengxiaolo"
New value = 0x100 <Address 0x100 out of bounds> // 指针越界了

main () at test.c:17
17        name[0] = 'a';
(gdb)c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x080483fd in main () at test.c:17
17        name[0] = 'a';
(gdb) 

 

譬如建立新文件Watch.c

#include <stdio.h>

int main()
{
    sleep(10);
    printf("Waiting...");

    int i;   
    for(i=0; i<100; i++)
    {  
        printf("I'm %u.\n", i);
    }  
   
    return 0;
}

 

然后  gcc  -g test.c -o test

然后 gdb调试test

在int i;设置断点,此时不能将i设为watchpoint,因为不再context中

(gdb) info b
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x00401082 in main at watch.c:8
(gdb) watch i
No symbol "i" in current context.

 

运行程序,当i在context中时添加watchpoint,

此时如果变化则会显示watchpoint的变化,并且停止下来,用continue可以继续

(gdb) r   
Starting program: /home/yueshen/a.exe
[New thread 2484.0x11b4]
[New thread 2484.0x1220]

Breakpoint 2, main () at watch.c:9
(gdb) n
(gdb) watch i
Hardware watchpoint 3: i
(gdb) info b
Num     Type           Disp Enb Address    What
2       breakpoint     keep y   0x00401082 in main at watch.c:8
        breakpoint already hit 1 time
3       hw watchpoint  keep y              i
(gdb) c
Continuing.
Waiting...I'm 0.
Hardware watchpoint 3: i

Old value = 0
New value = 1
0x004010a7 in main () at watch.c:9
(gdb) c
I'm 1.
Continuing.
Hardware watchpoint 3: i

Old value = 1
New value = 2
0x004010a7 in main () at watch.c:9




gdb中看内存(x命令)

你可以使用examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:

x/<n/f/u> <addr>

n、f、u是可选的参数。

n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。

f 表示显示的格式,参见上面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。

u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。

bhwg

x/4bt &a

--------------------------------
<addr>表示一个内存地址。
n/f/u三个参数可以一起使用。例如:

命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。

输出格式
一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。例如,你想输出一个整数的十六进制,或是二进制来查看这个整型变量的中的位的情况。要做到这样,你可以使用GDB的数据显示格式:

x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。



 

© 著作权归作者所有

共有 人打赏支持
AlphaJay
粉丝 78
博文 284
码字总数 313790
作品 0
杭州
如何在GDB中忽略Signal信号处理

在使用GDB调试C/C++程序时,如果刚好程序中需要对特殊Signal处理,则在调试这类应用时需要GDB忽略对该Signal的处理。本文来自GBD官方文档的翻译,仅供参考。 信号(Signals) 信号是一种软中...

artine
04/19
0
0
Debugging with GDB 用GDB调试多线程程序

Debugging with GDB http://www.delorie.com/gnu/docs/gdb/gdb_25.html GDB调试多线程程序总结 一直对GDB多线程调试接触不多,最近因为工作有了一些接触,简单作点记录吧。 先介绍一下GDB多线...

AlphaJay
2011/07/22
0
0
Linux下gdb用法简单介绍

GDB是GNU开源组织发布的一个强大的UNIX下调试程序工具。或许各位比较喜欢那种图形界面方式的,像VC,BCB等IDE的调试,但如果你是在UNIX平台下作软件,你会发现GDB这个调试工具有比VC,BCB的图...

长平狐
2013/01/06
111
0
Linux下gdb用法简单介绍

GDB是GNU开源组织发布的一个强大的UNIX下调试程序工具。或许各位比较喜欢那种图形界面方式的,像VC,BCB等IDE的调试,但如果你是在UNIX平台下作软件,你会发现GDB这个调试工具有比VC,BCB的图...

晨曦之光
2012/03/02
572
0
OpenWRT开发之——远程debug

想要用gdb对OpenWrt进行远程调试。首先得在OpenWrt目标机上安装gdbserver。 其实在trunk路径下也有gdb的ipk安装包的,不信find一下。 [trunk]$ find bin/ -name "gdb*.ipk"bin/ar71xx/packag...

临峰不畏
2015/05/18
0
9

没有更多内容

加载失败,请刷新页面

加载更多

Flask 开发填坑

插件的选择: flask-security 真的是个鸡肋啊。自带的页面,好丑。还不如用flask-login来做呢。

pearma
8分钟前
0
0
讲述下 :LVM逻辑卷管理遇到的问题

LVM学习逻辑卷管理创建逻辑卷遇到的问题 1 实验环境 系统 内核 发行版本 CentOS 2.6.32-754.2.1.el6.x86_64 CentOS release 6.10 (Final) 由于是最小化安装没有xfs命令,yum安装如下包支持此...

linuxprobe16
43分钟前
0
0
day95-20180922-英语流利阅读-待学习

Hey Jude 半个世纪传唱不衰的背后故事 毛西 2018-09-22 1.今日导读 2004 年,The Beatles 被《滚石》杂志选为“历史上最伟大的 50 位流行音乐家的第一位”。这四名来自英国利物浦的男孩不仅对...

飞鱼说编程
51分钟前
1
0
OSChina 周六乱弹 —— 放假前期焦虑症晚期

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @andonny :分享Matteo的单曲《Panama》: 《Panama》- Matteo 手机党少年们想听歌,请使劲儿戳(这里) @新垣吉衣OSC :我发现只要去有小朋友...

小小编辑
今天
179
10
wait()被notify()后,接着执行wait()后面的语句

wait()被notify()后,接着执行wait()后面的语句

noteman
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部