Debugging with GDB (入门篇)

Debug 是大家常常用到的东西.不管是自己写程式也好,还是想改改别人写好的东西, 又或者帮人家捉捉虫.总之呢,绝对是个常常用的到的东西.Dos, windows 底下,通常大家都在用 softice. 这里我就不介绍了,因为在前面的 "学习程式"中的"Assembly"里面已经有了很详细的介绍了.这里我来说说 linux 底下的 GDB 吧.
GDB 的全称是 GNU Debuger. 是 linux 底下的一种免费的 debug 程式.随然介面不像 SoftIce 那麽好,但是功能也绝对强大.要使用 gdb 那麽首先,在你 compile 程式的时候, 要加上 -g 的选项. (可以用-g, -g2, -g3具体请看 man gcc)通常如果程式不会很大,在 compile 的时候我都是用 -g3 的,因为如果你用到了 inline 的 function, 用 -g 去 compile 就无法去 debug inline function了.这时候就用到 -g2, -g3了,g後面的数字越大,也就是说可以 debug 的级别越高.最高级别就是 -g3.
既然是入门篇,就从最简单的来做啦.先写个小程式,我们用来学习 gdb. 用你喜爱的 editor 编辑一个叫做 test.c 的文件,内容如下∶
int main()
{
	int a, b, c;
	a=5;
	b=10;
	b+=a;
	c=b+a;
	return 0;
}

然後用下面的指令去编辑这个程式∶

gcc -Wall -g -o test test.c

这样 gcc 就会 compile 一个叫做 test 的小程式.现在我们来用 gdb 看看这个小程式∶

gdb -q test

(gdb) l			(这里用 l 指令,是 list 的简写)

1       int main()
2       {
3               int a, b, c;
4               a=5;
5               b=10;
6               b+=a;
7               c=b+a;
8               return 0;
9       }

(这时候你就可以看到程式的 source 了)


我们现在下一个 breakpoint,这个 breakpoint 将会在第二行,也就是 2 { 这里.
这样程式运行完 int main()以後,就会停下来.

(gdb) b 2	(b 就是 breakpoint 的简写啦)
Breakpoint 1 at 0x80483a0: file test.c, line 2. 

现在来运行这个程式

(gdb) r		(r是 run 的简写)
Starting program: /home/goldencat/study-area/goldencat/gdb/test 

Breakpoint 1, main () at test.c:2
2       {
程式运行到这里,就停下来了.因为我们在这里设下了 breakpoint.
(gdb)n		(n = next)
main () at test.c:4
4               a=5; (这里就跑到了第四行了)
(gdb) n
5               b=10;
(gdb) n
6               b+=a;
(gdb) n
7               c=b+a;
这时候我们来看看 b 的 value 是多少∶

(gdb) p b	(p是print的简写,这里实际写成print b)
$1 = 15		(这里显示的就是 b 的 value, 以後要看 b, 直接用 p $1 也是一样的)
		(这里的 $1 就是指向 b 的)

(gdb) n
8               return 0;
(gdb) p c
$2 = 20		(这里看到 c 的 value 是 20)
(gdb) c		(c 是 continue 的意思,也就是说执行到程式的结束)
Continuing.

Program exited normally.
(gdb) q		(这就结束 gdb 了 )
跟 n (next) 不同的,还有一个用法就是 step. step 很有用的就是,当你追到一个call 的时候,(如 my_function(value1))如果用 next 会只接跑过这个 call,而不会跑到这个 call里面, step 就不同了. step 会跑到这个 call 的里面去,让你能追到 call 里面.
这里在顺便说说如何改变一个 value. 当你下指令 p 的时候,例如你用 p b, 这时候你会看到 b 的 value, 也就是上面的 $1 = 15. 你也同样可以用 p 来改变一个 value, 例如下指令 p b = 100 试试看,这时候你会发现, b 的 value 就变成 100 了∶$1 = 100.
利用display这个命令,你可以在每一次的 next 时,都显示其中一个的 value,看看下面的范例也许容易明白些∶
[goldencat@goldencat gdb]$ gdb -q test
(gdb) l 
1       int main()
2       {
3               int a, b, c;
4               a=5;
5               b=10;
6               b+=a;
7               c=b+a;
8               return 0;
9       }
(gdb) b 2
Breakpoint 1 at 0x80483a0: file test.c, line 2.
(gdb) r
Starting program: /home/goldencat/study-area/goldencat/gdb/test 

Breakpoint 1, main () at test.c:2
2       {
(gdb) n
main () at test.c:4
4               a=5;
(gdb) display a		(set display on)
1: a = 134517840
(gdb) n
5               b=10;
1: a = 5		(display a)
(gdb) n
6               b+=a;
1: a = 5		(display a)
(gdb) n
7               c=b+a;
1: a = 5		(display a)
(gdb) n
8               return 0;
1: a = 5		(display a)
(gdb) c
Continuing.

Program exited normally.
(gdb) q
当然你要 display 多少个 value 并没有甚麽限制.你完全可以把 a, b, c全部都display出来. 利用 info 这个指令,你可以看到目前的状况.如∶ info display 就能看到目前的display 的状况∶
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
1:   y  b	(这里的 y 就是说, display b 是 enable 的)

用 info break 就可以看到 breakpoint 的状况∶

(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x080483a0 in main at test.c:2
        breakpoint already hit 1 time
(gdb) 

	利用 disable 和 enable 命令,可以赞时开启和这关闭一些命令.例如∶

(gdb) disable display 1
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
1:   n  b		(这里看到个 n, 也就是说, display b 已经被关闭了)
(gdb) 			


(gdb) disable break 1
(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep n   0x080483a0 in main at test.c:2
        breakpoint already hit 1 time
(gdb) 		(这里看到,breakpoint也被用 disable break 1 给关闭了)
如果你问我为甚麽要用 1 (disable break/display 1),看看上面的 Num 那几个字就知道了. 这里的 1 就是说关闭第一个 value. 因为当你真正 debug 的是侯,可能有很多的 break,你只要关闭你想要关闭的就好了,看看下面∶
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
3:   y  c
2:   y  b
1:   y  a
这里 display 中有三个 value, 现在我想赞时关闭对 b 的 display,可以从 Num 看出, b 的 Num 是 2,所以我们要用 disable display 2
(gdb) disable display 2
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
3:   y  c
2:   n  b		(这里看到, b 已经关闭了)
1:   y  a
如果你用 disable display 而後面没有任何的 number 的话,那麽就是 disable all 的意思∶
(gdb) disable display  
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
3:   n  c
2:   n  b
1:   n  a
(gdb) 
接下来说说 enable 吧, 知道了 disable, enable 就简单多了. enable 就是跟 disable 相反的意思.也就是说重新开启被关闭的东西.用法跟 disable 一样.
(gdb) enable display 2
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
3:   n  c
2:   y  b
1:   n  a
(gdb) enable display
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
3:   y  c
2:   y  b
1:   y  a
(gdb) 
再来讲讲 delete 的用法啦. delete 跟 disable 不太一样,一旦被 delete, 那麽是没有办法用 enable 之类的东西找回来的.假设你 disable 一个 breakpoint,那麽就是说,你赞时不需要用到这个 break point,当你要用到的时候,只要 enable 就好.可是如果你去 delete 一个 breakpoint.就是说你将用远不需要这个 breakpoint 了.如果你下次还需要, 那麽你就给重新用 break 指令去下 breakpoint 了.
(gdb) delete display 1
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
3:   y  c
2:   y  b		(1 消失了)
(gdb) delete display	(全部 delete )
Delete all auto-display expressions? (y or n) y		(要求确定一下)
(gdb) info display
There are no auto-display expressions now.	(全部的 display 都被 delete 了)
(gdb) 
顺便说说如何去 debug 一个已经在 run 的程式∶
利用 attach process-id 和 detach 就可以去 debug 一个已经在 run 的程式了.
先用 ps aux 找出你要 debug 的程式的 process it.

[goldencat@goldencat gdb]$ ps aux | grep ssh
root       600  0.0  0.0  2248    0 ?        SW   11:13   0:00 [sshd]
goldenca  1182  0.0  0.7  2448  188 tty2     S    11:40   0:00 ssh 127.0.0.1
goldenca  2802  0.0  1.9  1904  528 pts/1    S    13:45   0:00 grep ssh

这里我们去 debug ssh 127.0.0.1 这个程式,这这程式的 process id 是 1182

[root@goldencat /root]# gdb -q		进入gdb

(gdb) attach 1182			截入 process 1182 到 gdb 里面
Attaching to Pid 1182
0x401b615e in ?? ()
......
......
......					进行 debug
......
......

(gdb) detach				debug 完毕以後,记得要用 detach 这个命令
Detaching from program: , Pid 1182	这个命令就把刚刚 debug 的那个程式 release
(gdb) q					掉了.
好啦,入门篇嘛,就写这麽多了.我写的慢,这些就写了我一个早上啦.不敢说能教了大家甚麽东西,但也算是给没有玩过的人一个入门的概念啦.简 单的,常用到的break,print, display,disable,enable,delete,run,next,step,continue好像也都说到了. 如果你有心想学,可以看看 man gdb 和进入 gdb 後,用 help 指令. GDB 里面的 help 是很好用的.
如果你是个 debug 的高手,那麽希望你也能抽点时间,跟大家分享一下你的心得.独乐乐不如众乐乐嘛. ∶)
下面是个如何使用 gdb 中的 help 的范例∶


[goldencat@goldencat gdb]$ gdb -q
(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.
(gdb) help breakpoints
Making program stop at certain points.

List of commands:

awatch -- Set a watchpoint for an expression
break -- Set breakpoint at specified line or function
catch -- Set catchpoints to catch events
clear -- Clear breakpoint at specified line or function
commands -- Set commands to be executed when a breakpoint is hit
condition -- Specify breakpoint number N to break only if COND is true
delete -- Delete some breakpoints or auto-display expressions
disable -- Disable some breakpoints
enable -- Enable some breakpoints
hbreak -- Set a hardware assisted  breakpoint
ignore -- Set ignore-count of breakpoint number N to COUNT
rbreak -- Set a breakpoint for all functions matching REGEXP
rwatch -- Set a read watchpoint for an expression
tbreak -- Set a temporary breakpoint
tcatch -- Set temporary catchpoints to catch events
thbreak -- Set a temporary hardware assisted breakpoint
txbreak -- Set temporary breakpoint at procedure exit
watch -- Set a watchpoint for an expression
xbreak -- Set breakpoint at procedure exit

Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.
(gdb) help clear
Clear breakpoint at specified line or function.
Argument may be line number, function name, or "*" and an address.
If line number is specified, all breakpoints in that line are cleared.
If function is specified, breakpoints at beginning of function are cleared.
If an address is specified, breakpoints at that address are cleared.

With no argument, clears all breakpoints in the line that the selected frame
is executing in.

See also the "delete" command which clears breakpoints by number.
(gdb) q

from: http://blog.chinaunix.net/u/9483/showart.php?id=57476
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《debugging with gdb》是一本关于使用GDB进行调试的指南。GDB(GNU调试器)是一个强大的调试工具,可以用于调试各种编程语言,如C、C++、Fortran等。 这本书详细介绍了GDB的安装和配置,并提供了许多示例来说明如何使用它来调试程序。它从基本的调试命令开始,如设置断点、单步执行、查看变量的值等。然后,它介绍了更高级的调试功能,如条件断点、观察点、跟踪函数调用等。 书中还介绍了如何使用GDB来调试多线程程序和动态库。它解释了如何设置线程断点、查看线程状态和跟踪线程的执行路径。此外,它还介绍了如何对动态链接库进行调试,包括加载和卸载库、查看库中的符号和调用库中的函数等。 此外,《debugging with gdb》还介绍了如何使用GDB进行内存调试。它涵盖了诸如检测内存泄漏、跟踪指针问题和查找内存错误等主题。通过这本书,读者可以学习如何使用GDB来诊断和解决各种程序错误和问题。 总之,《debugging with gdb》是一本全面而详细的关于使用GDB进行调试的指南。无论是有经验的开发人员还是初学者,都可以从中学习到如何使用GDB来快速定位和解决程序中的错误。 ### 回答2: GDB是一个调试器,用于帮助开发者在程序中找出错误并进行调试。它提供了许多功能和命令,可以让开发者在程序运行过程中获取各种有用的信息。 在使用GDB进行调试之前,首先需要将程序编译成可调试的二进制文件。可以使用编译器的参数“-g”来生成包含调试信息的可执行文件。编译完成后,可以通过终端命令"gdb <可执行文件名>"启动GDB,并载入要调试的程序。 一旦进入GDB调试界面,可以使用各种命令来控制程序的执行。例如,可以使用"break <函数名>"命令在特定的函数内设置断点,当程序执行到该函数时会触发断点,并暂停程序的执行。可以使用"run"命令来运行程序,当程序遇到断点时会暂停,并在终端显示相关的调试信息。 一旦程序暂停在断点处,就可以使用GDB提供的许多命令来检查程序状态和寻找错误。例如,可以使用"print <变量名>"命令来打印特定变量的值,以确定其是否符合预期。还可以使用"step"命令来逐行执行程序,并跟踪程序的执行流程,以查找错误所在。 在调试过程中,还可以使用其他命令来查看函数调用栈,设置条件断点,监视特定变量的值等。通过这些命令的使用,可以逐步分析程序的执行过程,找出其中的问题,并进行修复。 在调试完成后,可以使用"quit"命令退出GDB调试界面。调试信息和步骤可以记录下来并与其他开发者共享,以便更好地协作解决问题。 总之,GDB是一个功能强大的调试器,它可以帮助开发者定位和修复程序中的错误。通过使用GDB,开发者可以更加高效地进行程序调试,提高开发效率。 ### 回答3: 《debugging with gdb》是一本介绍使用GDB进行调试的书籍。GDB是GNU工具链中的一个强大的调试工具,用于分析和修复程序中的错误。 该书详细介绍了GDB的各种功能和用法,并通过实例演示了如何利用GDB进行程序调试。它提供了许多实用技巧和建议,帮助读者快速定位和解决程序中的bug。 书中首先介绍了GDB的基本用法,包括启动程序、设置断点、执行程序、查看变量值等。接着,它详细阐述了GDB的高级功能,例如条件断点、观察点、内存调试等。 此外,书中还介绍了GDB调试多线程程序、动态链接程序和嵌入式程序的方法。针对不同的调试需求,它还介绍了GDB的执行控制、堆栈跟踪和源代码级别的调试等高级特性。 《debugging with gdb》还提供了一些常见问题的解决方案,如内存泄漏、数组越界、死锁等。它还解释了一些常见错误的原因和调试技巧,帮助读者更好地理解和定位程序中的问题。 通过阅读《debugging with gdb》,读者可以更好地理解和掌握GDB的使用方法,提高程序调试的效率和准确性。无论是新手还是有经验的程序员,都可以从中受益,提升自己的调试能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值