Chinaunix首页 | 论坛 | 博客
  • 博客访问: 32828
  • 博文数量: 10
  • 博客积分: 472
  • 博客等级: 下士
  • 技术积分: 70
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-23 12:43
文章分类

全部博文(10)

文章存档

2010年(10)

我的朋友
最近访客

分类: LINUX

2010-03-31 14:49:34

今天来学习Linux下的C编程吧,先从gdb调试开始,呵呵,昨天在网上copy的命令今天得要它们上台来显显身手啦,GO!
 (一)用gedit编缉源程序"hello.c"如下:
         main ()
         {
            char my_string[] = "hello world!";
            my_print (my_string);
            my_print2 (my_string);
         }
        void my_print (char *string)
        {
            printf ("The string is %s \n", string);   
        }
       void my_print2 (char *string)
        {
        char *string2;
        int size, i;
        size = strlen (string);
        string2 = (char *) malloc (size + 1);
        for (i = 0; i < size; i++)
        string2[size-i]=string[i];
        string2[size]='\0';
        printf ("The string printed backward is %s ", string2);
        }  
(二)用下面的命令编译它:
gcc -g -o hello hello.c             //-g参数一定要有,是用来调程序的
这个程序执行时显示如下结果:
../hello
The string is hello world!
The string printed backward is
输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的. 我们所设想的输出应该是:
The string printed backward is !dlrow olleh
(三)下面让我们用 gdb 看看问题究竟出在哪儿
(1)先在root用户中键入如下命令:
[root@localhost gdbtest]# gdb hello
显示结果如下
GNU gdb (GDB) Fedora (7.0.1-29.fc12)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
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 "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/smj/file/co
de/gdbtest/hello...done.
(gdb)

(2)然后你就能用 gdb 的 run 命令来运行 hello 了. 当它在 gdb 里被运行后结果大约如下:
(gdb) run
Starting program: /home/smj/file/code/gdbtest/hello
The string is hello world!
The string printed backward is 
Program exited with code 040.
Missing separate debuginfos, use: debuginfo-install glibc-2.11.1-1.i686


(3)这个输出和在 gdb 外面运行的结果一样. 问题是, 为什么反序打印没有工作? 为了找出症结所在, 我们可以在 my_print2 函数的 for 语句后设一个断点, 具体的做法是在 gdb提示符下键入 list 命令三次, 列出源代码:
(gdb) list
(gdb) list
(gdb) lis
技巧: 在 gdb 提示符下按回车健将重复上一个命令.
显示如下
1    #include
2    #include
3    #include
4    static void my_print (char *);
5    static void my_print2 (char *);
6    main ()
7    {
8    char my_string[] = "hello world!";
9    my_print (my_string);
10    my_print2 (my_string);
(gdb)
11    }
12    void my_print (char *string)
13    {
14    printf ("The string is %s \n", string);
15    }
16    void my_print2 (char *string)
17    {
18    char *string2;
19    int size, i;
20    size = strlen (string);
(gdb)
21    string2 = (char *) malloc (size + 1);
22    for (i = 0; i < size; i++)
23    string2[size-i]=string[i];
24    string2[size]='\0';
25    printf ("The string printed backward is %s ", string2);
26    }

(4)根据列出的源程序, 你能看到要设断点的地方在第 26 行, 在 gdb 命令行提示符下键入如下命令设置断点:
(gdb) break 23
gdb 将作出如下的响应:
Breakpoint 1 at 0x80484a5: file hello.c, line 23.

(5)现在再键入 run 命令, 将产生如下的输出:
(gdb) run
Starting program: /home/smj/file/code/gdbtest/hello
The string is hello world!

Breakpoint 1, my_print2 (string=0xbffff2f3 "hello world!") at hello.c:23
23    string2[size-i]=string[i];

(6设置一个观察 string2[size - i] 变量的值的观察点来看出错误是怎样产生的,
做法是键入:
(gdb) watch string2[size - i]
gdb 将作出如下回应:
Watchpoint 2: string2[size-i]


(7)现在可以用 next 命令来一步步的执行 for 循环了:
(gdb) next
经过第一次循环后, gdb 告诉我们 string2[size - i] 的值是 `\000`. gdb 用如下的显示来告诉你这个信息:
Watchpoint 2: string2[size-i]
Old value =
New value = 0 '\000'
0x080484ac in my_print2 (string=0xbffff2f3 "hello world!") at hello.c:23
23    string2[size-i]=string[i];

(8) 这个值不是我们期望的,我们期望得到的值是'h',其实前面十几次都是正确的,当 i=11 时, 表达式string2[size - i] 的值等于 `!`, size - i 的值等于 1。现在找出了问题出在哪里, 修正这个错误是很容易的. 你得把代码里写入 string2 的第一个字符的的偏移量改为 size - 1 而不是 size.
即把string2[size-i]=string[i]改成string2[size-i-1]=string[i];

(9)修正后执行结果如下
[root@localhost gdbtest]# ./hello
The string is hello world!
The string printed backward is !dlrow olleh [root@localhost gdbtest]#

修改完毕,简单的运用了下调试成功gdb调试初学 - 木林森 - 麓山怪杰
阅读(1226) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~