linux环境下c语言编程--------环境搭建与gdb调试

1) 今天安装了CentOS 5.5,顺便安装了GCC和G++,GDB:

n Yum -y install make //安装make

n Yum -y install gcc //安装gcc编译器

n

Yum -y install gcc-c++ //安装G++编译器

2) 编译调式实例:

(一) 在自己所建立的分区中:

1)mkdir helloworld //新建helloworld目录

2)cd helloworld //进入helloworld目录

3)vi helloworld.c //使用vi新建并打开helloworld.c文件

进入vi, Esc --->i 进行编辑:

n

示例程序:

  1. #include <stdio.h>
  2. int nGlobalVar = 0;
  3. int tempFunction(int a, int b)
  4. {
  5. printf("tempFunction is called, a = %d, b = %d \n", a, b);
  6. return (a + b);
  7. }
  8. int main()
  9. {
  10. int n;
  11. n = 1;
  12. n++;
  13. n--;
  14. nGlobalVar += 100;
  15. nGlobalVar -= 12;
  16. printf("n = %d, nGlobalVar = %d \n", n, nGlobalVar);
  17. n = tempFunction(1, 2);
  18. printf("n = %d", n);
  19. return 0;
  20. }
  21. //之后按下“Esc”,再保存退出“:wq”

n :q!不保存退出

(二)编译源文件:

gcc sample.c -o sample -g

-o 参数指定了编译生成的可执行文件名为 sample,参数 -g 表示将源代码信息编译到可执行文件中。

(三)调试:

1)敲入gdb

[root@localhost test]# gdb

GNU gdb (GDB) CentOS (7.0.1-42.el5.centos.1)

Copyright (C) 2009 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

and "show warranty" for details.

This GDB was configured as "i386-redhat-linux-gnu".

For bug reporting instructions, please see:

<http://www.gnu.org/software/gdb/bugs/>.

(gdb)

2)(gdb) file sample

Reading symbols from /programingTest/test/sample...done.

(gdb)

3)输入 r,程序会正常执行,得到结果:

r enter结果

(gdb) r

Starting program: /programingTest/test/sample

n = 1, nGlobalVar = 88

tempFunction is called, a = 1, b = 2

n = 3

Program exited normally.

(gdb)

4)如果这样做,我们就不能调试了。于是我们需要设置断点。使用b命令来在main函数开头设置一个断点breakpoints:
b main结果:

(gdb) b main

Breakpoint 1 at 0x80483dd: file sample.c, line 14.

5) 再次r命令
r命令结果:

(gdb) r

Starting program: /programingTest/test/sample

Breakpoint 1, main () at sample.c:14

14 n = 1;

6) step和print命令
依次step和print命令后结果:

(gdb) s

15 n++;

(gdb) p n

$1 = 1

7)在tempFunction 函数处设置断点:
b tempFunction结果:

(gdb) b tempFunction

Breakpoint 2 at 0x80483aa: file sample.c, line 7.

(gdb) b *tempFunction

Breakpoint 3 at 0x80483a4: file sample.c, line 6.

(gdb) b 22

Breakpoint 4 at 0x8048422: file sample.c, line 22.

8)继续运行c(continue):

c结果:

(gdb) c

Continuing.

n = 1, nGlobalVar = 88

Breakpoint 4, main () at sample.c:22

22 n = tempFunction(1, 2);

9)如果我们进行汇编级调试,则需要用到display命令:
display /i $pc结果:

(gdb) display /i $pc

1: x/i $pc

0x80483a4 <tempFunction>: push %ebp

(gdb)

r结果

(gdb) r

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /programingTest/test/sample

warning: .dynamic section for "/lib/libc.so.6" is not at the expected address

warning: difference appears to be caused by prelink, adjusting expectations

Breakpoint 1, main () at sample.c:14

14 n = 1;

1: x/i $pc

0x80483dd <main+17>: movl $0x1,-0x8(%ebp)

(gdb)

之后程序每次中断都将显示下一条汇编指定(si命令用于执行一条汇编代码而s执行一行C代码):
si命令

(gdb) si

15 n++;

1: x/i $pc

0x80483e4 <main+24>: addl $0x1,-0x8(%ebp)

(gdb)

16 n--;

1: x/i $pc

0x80483e8 <main+28>: subl $0x1,-0x8(%ebp)

(gdb)

17 nGlobalVar += 100;

1: x/i $pc

0x80483ec <main+32>: mov 0x80496f4,%eax

(gdb)

0x080483f1 17 nGlobalVar += 100;

1: x/i $pc

0x80483f1 <main+37>: add $0x64,%eax

(gdb)

0x080483f4 17 nGlobalVar += 100;

1: x/i $pc

0x80483f4 <main+40>: mov %eax,0x80496f4

(gdb)

18 nGlobalVar -= 12;

1: x/i $pc

0x80483f9 <main+45>: mov 0x80496f4,%eax

(gdb)

0x080483fe 18 nGlobalVar -= 12;

1: x/i $pc

0x80483fe <main+50>: sub $0xc,%eax

(gdb)

0x08048401 18 nGlobalVar -= 12;

1: x/i $pc

0x8048401 <main+53>: mov %eax,0x80496f4

注意按下enter键相当于继续执行上条指令!!!!!

删除断点d命令:

(gdb) d

Delete all breakpoints? (y or n) y

10)使用命令“b *main”在 main 函数的 prolog 代码处设置断点(prolog、epilog,分别表示编译器在每个函数的开头和结尾自行插

入的代码):

b *main

(gdb) b *main

Breakpoint 5 at 0x80483cc: file sample.c, line 12.

(gdb) r

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /programingTest/test/sample

Breakpoint 5, main () at sample.c:12

12 {

1: x/i $pc

0x80483cc <main>: lea 0x4(%esp),%ecx

(gdb) si

0x080483d0 in main () at sample.c:12

12 {

1: x/i $pc

0x80483d0 <main+4>: and $0xfffffff0,%esp

(gdb)

0x080483d3 12 {

1: x/i $pc

0x80483d3 <main+7>: pushl -0x4(%ecx)

(gdb)

0x080483d6 in main () at sample.c:12

12 {

1: x/i $pc

0x80483d6 <main+10>: push %ebp

11) 使用i r命令显示寄存器中的当前值—i r即Infomation Register

也可以显示任意一个指定的寄存器值:i r eax

i r结果:

(gdb) i r

eax 0xbfffeab4 -1073747276

ecx 0xbfffea30 -1073747408

edx 0x1 1

ebx 0x92eff4 9629684

esp 0xbfffea18 0xbfffea18

ebp 0xbfffea88 0xbfffea88

esi 0x7cfca0 8191136

edi 0x0 0

eip 0x80483d7 0x80483d7 <main+11>

eflags 0x282 [ SF IF ]

cs 0x73 115

ss 0x7b 123

ds 0x7b 123

es 0x7b 123

fs 0x0 0

gs 0x33 51

(gdb) i r eax

eax 0xbfffeab4 -1073747276

最后,q退出gdb!!

最后总结一下常用gdb命令:

常用 gdb命令

命令

解释

示例

file <文件名>

加载被调试的可执行程序文件。

因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。

(gdb) file sample

r

Run的简写,运行被调试的程序。

如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。

(gdb) r

c

Continue的简写,继续执行被调试程序,直至下一个断点或程序结束。

(gdb) c

b <行号>

b <函数名称>

b *<函数名称>

b *<代码地址>

d [编号]

b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。

其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。

d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。

(gdb) b 8

(gdb) b main

(gdb) b *main

(gdb) b *0x804835c

(gdb) d

s, n

s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;

n: 执行一行源程序代码,此行代码中的函数调用也一并执行。

s 相当于其它调试器中的“Step Into (单步跟踪进入)”;

n 相当于其它调试器中的“Step Over (单步跟踪)”。

这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。

(gdb) s

(gdb) n

si, ni

si命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。

(gdb) si

(gdb) ni

p <变量名称>

Print的简写,显示指定变量(临时变量或全局变量)的值。

(gdb) p i

(gdb) p nGlobalVar

display ...

undisplay <编号>

display,设置程序中断后欲显示的数据及其格式。

例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令

“display /i $pc”

其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。

undispaly,取消先前的display设置,编号从1开始递增。

(gdb) display /i $pc

(gdb) undisplay 1

i

Info的简写,用于显示各类信息,详情请查阅“help i”。

(gdb) i r

q

Quit的简写,退出GDB调试环境。

(gdb) q

help [命令名称]

GDB帮助命令,提供对GDB名种命令的解释说明。

如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。

(gdb) help display