c程序print到linux命令行中,Linux下C语言的调试(转载)

引题:

有一待调试的C语言源程序,请问在Linux系统下应该如何进行调试操作,写出相关的命令(假定源文件名为 test.c)

解答:

gcc -g test.c -o test

编译出可执行文件 test,然后

gdb test

然后用 l

看源码,用b设置断点,用r开始运行程序,用p打印变量,用n单步执行下一条语句,用s单步进入函数,用help查看所有命令,用help

xxx查看xxx命令的帮助。

------------------------------------------------------------------------

gcc中的-g选项:

-g Produce debugging

information in the operating system's native for‐

mat (stabs, COFF, XCOFF, or DWARF 2). GDB can

work with this

debugging information.

On most systems that use stabs format, -g enables use of

extra

debugging information that only GDB can use; this extra

information

makes debugging work better in GDB but will probably make

other

debuggers crash or refuse to read the program.

------------------------------------------------------------------------

调 试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度,

是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 , 它提供了设置断点, 单步跟踪等的图形界面,

使调试起来直观易用. 但Linux用户可能要生闷气了 : 难道我们Linux程序员就只能使用原始的调试方法,

在代码中加入printf信息吗?难道Linux下就没有好的C语言调试工具吗?

当然不是了. GNU早就组织开发了一套C语言编译器(Gcc)和调试工具(Gdb).

Gdb虽然没有图形化的友好界面, 但是它强大的功能也足以与微软的VC工具相媲美, 给Linux程序员带来了福音.

下面通过一个简单的例子, 演示一下Gdb的使用流程:

示例文件 demo.c 的源代码如下:

#include

int sum(int, int);

int main()

{

int

result;

int a = 1, b

= 2;

result =

sum(a, b);

printf("%d +

%d = %d\n", a, b, result);

return

0;

}

int

sum(int a, int b)

{

return a +

b;

}

编译源文件, 生成可执行文件

$ gcc -g -Wall -o demo demo.c

虽然这段程序没有错误, 但调试完全正确的程序可以更加了解Gdb的使用流程. 接下来就启动Gdb进行调试.

注意:

Gdb进行调试的是可执行文件, 而不是”.c”源文件, 因此, 需要先通过Gcc编译生成可执行文件才能用Gdb进行调试.

一定要加上选项”-g”, 这样编译出的可执行代码中才包含调试信息,

否则Gdb无法载入该可执行文件.不能使用 -O2选项对可执行文件进行优化,

因为优化之后可执行文件里的符号表信息将被删除, 这样Gdb就无法找到使可执行文件与源文件之间的关联了, 也就不能调试了.

(1) 启动Gdb

$ gdb demo可以看出, 在Gdb的启动画面中指出了Gdb的版本号, 使用的库文件等头信息,

接下来就进入了由”(gdb)”开头的命令行界面了.

(2) 查看源文件

在Gdb中键入”l”(list的缩写)可以查看所载入的文件, 如下所示:

(gdb) l

1 #include

2

3 int sum(int, int);

4

5 int

6 main()

7 {

8 int result;

9 int a = 1, b = 2;

10 result = sum(a, b);

(gdb) l

11 printf("%d + %d = %d\n", a, b, result);

12 return 0;

13 }

14

15 int

16 sum(int a, int b)

17 {

18 return a + b;

19 }

(gdb) l

Line number 20 out of range; demo.c has 19 lines.

可以看出, Gdb列出的源代码中明确地给出了对应的行号,

这样就可以大大地方便代码的定位.

(3) 设置断点

设置断点是调试程序中一个非常重要的手段, 它可以使程序到一定位置暂停运行. 因此,可以在该位置方便地查看变量的值, 堆栈情况等,

从而找出代码的症结所在.

在Gdb中设置断点非常简单, 只需在”b”后加入对应的行号即可(这是最常用的方式).

如下所示:

(gdb) b 9Breakpoint 2 at 0x4004f4: file

demo.c, line 9.

注意: 该断点的作用是当程序运行到第 9 行时暂停(第 8 行执行完毕, 第 9

行未执行)

注意:用cleaer 9 可以取消断点。

(4) 查看断点信息

(gdb) info

bNum Type Disp Enb

Address What

2 breakpoint keep y 0x00000000004004f4 in

main at demo.c:9

(5) 运行代码

接下来就可运行代码了, Gdb默认从首行开始运行代码, 可键入”r”(run的缩写)即可.

若想从程序中指定的行开始运行, 可在r后面加上行号.

(gdb) r

Starting program: /home/wangsheng/tmp/demo/gdb/demo

Breakpoint 2, main () at demo.c:9

9 int a = 1, b = 2;

可以看到程序运行到断点处就停止了.

(6) 查看变量值

键入p(print的缩写)+变量名即可查看该变量在此时的值(gdb) p a

$1 = 1

(gdb) p b

$2 = 2

(gdb) p result

$3 = 32767

在你调试程式时,当程式被停住时,你能使用 print

命令(简写命令为 p ),或是同义命令 inspect 来查看当前程式的运行数据。 print 命令的格式是:

print

print

/

是表达式,是你所调试的程式的语言的表达式( GDB 能调试多种编程语言), 是输出的格式,比如,如果要把表达式按 16

进制的格式输出,那么就是 /x 。

p/d就表示十进制输出

注意: 这里之所以result是一个莫名其妙的值, 是因为声明result是没有初始化, 其值是不固定的。

(7) 单步执行

单步运行可以使用n(next的缩写)或者s(step的缩写), 它们之间的区别在于: 若有函数调用的时候,

s会进入该函数而n不会. 因此, s就类似于VC等工具中的”step in”, n就类似于VC等工具中的”step

over”.

如果使用n命令显示如下:

(gdb) n

10 result = sum(a, b);

下面使用 s 命令,跟踪进入 sum 函数:

(gdb) s

sum (a=1, b=2) at demo.c:18

18 return a + b;

可以看出执行 s 命令时进入了sum函数内部, 如果用 n 命令则跳过函数的调用部分

(8) 恢复程序运行

在查看变量值以及堆栈之后, 就可以使用命令c(continue)恢复程序的正常运行了. 这时,

它会把剩余还未执行的程序执行完, 并显示剩余程序的执行结果.(gdb) c

Continuing.

1 + 2 = 3

Program exited normally.

可以看出, 程序在运行完后退出, 之后程序处于”停止状态”.

说 明: 在Gdb中, 程序的运行状态有”运行”,”暂停”和”停止”3种.

其中”暂停”状态是程序遇到了断点或者观察点, 程序暂时停止运行, 而此时函数的地址, 函数参数,

函数内的局部变量都会被压入”栈(Stack)中. 故在这种状态下可以查看函数的变量值等各种属性. 但在函数处于”停止”状态之后,

“栈”就会自动撤销, 它也就无法查看各种信息了

9. 退出 gdb

要退出 gdb

时,只用发 quit 或命令简称 q 就行了。

关于Gdb的更多命令, 你可以在启用Gdb后, 输入help命令查看.

(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 命令只是例出 gdb

的命令种类,如果要看种类中的命令,能使用 "help 种类名",如: help breakpoints

,查看设置断点的所有命令。 gdb 中,输入命令时,能不用打全命令,只用打命令的前几个字符就能了(需求命令的前几个字符应唯一标志该命令),在 Linux

下,你能敲击两次 TAB 键来补齐命令的全称,如果有重复的,那么 gdb 会所有类似的都列出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值