flyonok

统计

留言簿(8)

ACE

book

boost

bsd

c study

c++

code download

codeblock

computer clound

Eclipse

embed system

erlang

ET++

gtk

ic card

java

KDE

libevent

linux

linux--MM

mysql

network education

one card

oracle

pcap relation

php

powerbuilder

python

QT

software config

software test

SQL server

UML

wireless

wxwidgets

陈宾

阅读排行榜

评论排行榜

gdb

 你可以在空闲的时候阅读全部的GDB手册。然而一些命令足以使你开始使用GDB,这一章就描述这些命令。 GNU m4(一个通用的宏处理器)的初始版本之一存在下面的bug:当我们改变单引号的默认表示时,一个用来捕获一个宏定义的命令停止工作。在下面较短的m4会话中,我们定义一个宏foo扩展成0000;然後我们使用m4内置的defn命令定义bar做同样的事情。然而当我们改变左单引号为<QUOTE>,右单引号为<UNQUOTE>後,同样的程序在定义一个新的同义词baz时却失败了。

$ cd gnu/m4$ ./m4
define(foo,0000)foo
0000define(bar,defn(`foo'))bar
0000changequote(<QUOTE>,<UNQUOTE>)
define(baz,defn(<QUOTE>foo<UNQUOTE>))bazC-dm4: End of input: 0: fatal error: EOF in string
让我们使用GDB来看看发生了什么。
$ gdb m4
GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions.There is absolutely no warranty for GDB; type "show warranty" for details.GDB 6.5.50.20060706, Copyright 1999 Free Software Foundation, Inc...(gdb)
GDB只读取很少的符号数据,这些数据足以让它知道在哪里能找到剩下的它需要的符号数据,因此,第一个命令提示符显示的很快。现在我们告诉GDB使用比平时更短的显示宽度,这样这些例子可以更好的显示在这个手册中。
(gdb) set width 70

我们需要看一看m4内置的changquote是怎么工作的。看了源码之後,我们知道相关的子例程是m4_changequote,因为我们使用GDB的break命令在那里设置一个断点。
(gdb) break m4_changequote
Breakpoint 1 at 0x62f4: file builtin.c, line 879.
通过使用run命令,在GDB的控制下我们启动m4的运行。只要控制没有达到m4_changequote子例程,程序运行的和平时一样。
(gdb) run
Starting program: /work/Editorial/gdb/gnu/m4/m4define(foo,0000)foo0000
为了触发断点,我们调用changequote。GDB悬挂m4的执行,显示它停止地方的上下文信息。
changequote(<QUOTE>,<UNQUOTE>)
Breakpoint 1, m4_changequote (argc=3, argv=0x33c70)    at builtin.c:879879         if (bad_argc(TOKEN_DATA_TEXT(argv[0]),argc,1,3))
现在我们使用命令n(next)执行当前函数的下一行。

(gdb) n
882         set_quotes((argc >= 2) ? TOKEN_DATA_TEXT(argv[1])\ : nil,
set_quotes看起来像是有问题的子例程,通过使用命令s(step)代替next我们能进入它的内部执行。 step会进入将被执行的子例程的下一行,因此它进入了set_quotes。
(gdb) sset_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "")    at input.c:530530         if (lquote != def_lquote)
上面展示了m4(以及它的参数)被悬挂在这个栈里,这个显示被称为栈桢显示。它显示了栈的概要。我们可以使用backtrace命令(它也可以写成bt)来看一看在所有的栈中我们处在哪一个栈里:backtrace命令显示每一个活动子例程的栈桢。

(gdb) bt
#0  set_quotes (lq=0x34c78 "<QUOTE>", rq=0x34c88 "")    at input.c:530#1  0x6344 in m4_changequote (argc=3, argv=0x33c70)    at builtin.c:882#2  0x8174 in expand_macro (sym=0x33320) at macro.c:242#3  0x7a88 in expand_token (obs=0x0, t=209696, td=0xf7fffa30)    at macro.c:71#4  0x79dc in expand_input () at macro.c:40#5  0x2930 in main (argc=0, argv=0xf7fffb20) at m4.c:195我们再前进几行看看会发生什么。开始的两次,我们使用s;後面的两次我们使用n来避免进入 xstrdup子例程。
(gdb) s0x3b5c  532         if (rquote != def_rquote)(gdb) s0x3b80  535         lquote = (lq == nil || *lq == '\0') ?  \def_lquote : xstrdup(lq);(gdb)
n
536         rquote = (rq == nil || *rq == '\0') ? def_rquote\ : xstrdup(rq);(gdb) n538         len_lquote = strlen(rquote);
最後一行显示看起来有点奇怪。我们可以检查lquote和rquote变量,看看它们实际上是不是我们指定的新的左单引号和右单引号。我们使用命令p(print)来看它们的值。
gdb) p lquote
$1 = 0x35d40 "<QUOTE>"
(gdb) p rquote$2 = 0x35d50 "<UNQUOTE>"
lquote和rquote的确是新的左右单引号。为了看一些上下文,我们可以使用l(list)命令来显示围绕当前行的前後10行源代码。
(gdb) l533             xfree(rquote);534535         lquote = (lq == nil || *lq == '\0') ? def_lquote\ : xstrdup (lq);536         rquote = (rq == nil || *rq == '\0') ? def_rquote\ : xstrdup (rq);537538         len_lquote = strlen(rquote);539         len_rquote = strlen(lquote);540     }541542     void
让我们再向前执行两行设置len_lquote和len_rquote值的源代码,然後检查这些变量的值。

(gdb) n
539         len_rquote = strlen(lquote);
(gdb) n
540     }
(gdb) p len_lquote
$3 = 9
(gdb) p len_rquote$4 = 7
假如len_lquote和len_rquote分别意味着lquote和rquote的长度,这看起来一定有问题。因为p命令能打印任何表达式的值--那些表达式能包括子例程和赋值。通过使用它,我们能把它们设置成别的更好的值。

gdb) p len_lquote=strlen(lquote)
$5 = 7(
gdb) p len_rquote=strlen(rquote)
$6 = 9
对于修正使用m4内置的defn来设置新的引号引起的问题,这已经足够了吗?我们使用c(continue)命令可以让m4继续,然後试一试最初因为麻烦的那个例子。

(gdb) c
Continuing.
define(baz,defn(<QUOTE>foo<UNQUOTE>))baz0000
成功了!新的引号现在和默认的引号一样工作正常。问题似乎是那两个定义了错误的长度的行。我们给m4输入一个EOF让它退出。
C-d
Program exited normally.
这个消息`Program exited normally.'来自于GDB,它表明m4已经完成了执行。我们可以使用 GDB的quit命令来结束我们的GDB会话。
(gdb) quit

posted on 2007-12-13 17:10 flyonok 阅读(314) 评论(1)  编辑 收藏 引用 所属分类: program

评论

# re: gdb 2007-12-18 12:34 秦歌

有特色  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理