Linux gdb编译器

来源:互联网 发布:我国近年财政补贴数据 编辑:程序博客网 时间:2024/06/06 06:40
  gdb
Linux 包含了一个叫 gdb 的 GNU 调试程序. gdb 是一个用来调试 C 和 C++ 程序的强力调试器. 它使你能在程序运行时观察程序的内部结构和内存的使用情况. 以下是 gdb 所提供的一些功能:
* 设置断点;
* 监视程序变量的值;
* 程序的单步执行;
* 修改变量的值。
      
    在命令行上键入 gdb 并按回车键就可以运行 gdb 了, 如果一切正常的话, gdb 将被启动并且你将在屏幕上看到类似的内容:
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or 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.
This GDB was configured as "i386-redhat-linux-gnu".
(gdb)
在可以使用 gdb 调试程序之前,必须使用 -g 选项编译源文件。也就是说,如果你写了下面的一个程序,名字命名为test.c++, 编译时使用如下语句:
#g++ -o test -g test.c++
#./test
test.c++ 源程序如下:
#include iostream.h>
static char buff [256];
static char* string;
int main ()
{
printf ("Please input a string: ");
gets (string);
printf (" Your string is: %s ", string);
}
运行后,程序出现了错误,这时你就可以使用gdb来查错了,方法如下:
#gdb test
(gdb)run   运行test(二进制)程序
如果你在编译时没有加上参数-g选项,你也可以通过如下语句来达到相同的效果
#gdb
(gdb)file test
如果你想查看源程序的部分代码,你可以用list命令来实现,如:
(gdb)list
可在 makefile 中如下定义 CFLAGS 变量:
CFLAGS = -g
运行 gdb 调试程序时通常使用如下的命令:
gdb progname
在 gdb 提示符下按回车健将重复上一个命令.
gdb命   令     描  述
file FILE 装入想要调试的可执行文件.
kill     终止正在调试的程序.
list     列出产生执行文件的源代码的一部分.
next     执行一行源代码但不进入函数内部.
step     执行一行源代码而且进入函数内部.
run     执行当前被调试的程序
q(quit)     终止 gdb
watch     使你能监视一个变量的值而不管它何时被改变.
make     使你能不退出 gdb 就可以重新产生可执行文件.
shell     使你能不离开 gdb 就执行 UNIX shell 命令.
break NUM 在指定的行上设置断点。
bt 显示所有的调用栈帧。该命令可用来显示函数的调用顺序。
clear 删除设置在特定源文件、特定行上的断点。其用法为:clear FILENAME:NUM。
continue 继续执行正在调试的程序。该命令用在程序由于处理信号或断点而
导致停止运行时。
display EXPR 每次程序停止后显示表达式的值。表达式由程序定义的变量组成。
help NAME 显示指定命令的帮助信息。
info break 显示当前断点清单,包括到达断点处的次数等。
info files 显示被调试文件的详细信息。
info func 显示所有的函数名称。
info local 显示当函数中的局部变量信息。
info prog 显示被调试程序的执行状态。
info var 显示所有的全局和静态变量名称。
make 在不退出 gdb 的情况下运行 make 工具。
print EXPR 显示表达式 EXPR 的值。
以下这部分是转载的
gdb 应用举例
    本节用一个实例教你一步步的用 gdb 调试程序. 被调试的程序相当的简单, 但它展示了 gdb 的典型应用.

    下面列出了将被调试的程序. 这个程序被称为 greeting , 它显示一个简单的问候, 再用反序将它列出.
#include  stdio.h>
main ()
{
  char my_string[] = "hello there";
  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;
  string2[size+1] = `\0';
  printf ("The string printed backward is %s\n", string2);
}
    用下面的命令编译它:

gcc -o test test.c
    这个程序执行时显示如下结果:
The string is hello there
The string printed backward is
    输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的. 我们所设想的输出应该是:
The string printed backward is ereht olleh
    由于某些原因, my_print2 函数没有正常工作. 让我们用  gdb 看看问题究竟出在哪儿, 先键入如下命令:

gdb greeting
    注意: 记得在编译 greeting 程序时把调试选项打开.  
    如果你在输入命令时忘了把要调试的程序作为参数传给 gdb , 你可以在 gdb 提示符下用 file 命令来载入它:

(gdb) file greeting
    这个命令将载入 greeting 可执行文件就象你在 gdb 命令行里装入它一样.
    这时你能用 gdb 的 run 命令来运行 greeting 了. 当它在 gdb 里被运行后结果大约会象这样:
(gdb) run
Starting program: /root/greeting
The string is hello there
The string printed backward is
Program exited with code 041
    这个输出和在 gdb 外面运行的结果一样. 问题是, 为什么反序打印没有工作? 为了找出症结所在, 我们可以在 my_print2 函数的 for 语句后设一个断点, 具体的做法是在 gdb 提示符下键入 list 命令三次, 列出源代码:
(gdb) list
(gdb) list
(gdb) list
    技巧:  在 gdb 提示符下按回车健将重复上一个命令.  
    第一次键入 list 命令的输出如下:

1       #include  
2
3       main ()
4       {
5         char my_string[] = "hello there";
6
7         my_print (my_string);
8         my_print2 (my_string);
9       }
10
    如果按下回车, gdb 将再执行一次 list 命令, 给出下列输出:

11      my_print (char *string)
12      {
13        printf ("The string is %s\n", string);
14      }
15
16      my_print2 (char *string)
17      {
18        char *string2;
19        int size, i;
20
    再按一次回车将列出 greeting 程序的剩余部分:
21        size = strlen (string);
22        string2 = (char *) malloc (size + 1);
23        for (i = 0; i ;
26        printf ("The string printed backward is %s\n", string2);
27      }
    根据列出的源程序, 你能看到要设断点的地方在第24行, 在 gdb 命令行提示符下键入如下命令设置断点:
(gdb) break 24
    gdb 将作出如下的响应:
Breakpoint 1 at 0x139: file greeting.c, line 24
(gdb)

    现在再键入 run 命令, 将产生如下的输出:

Starting program: /root/greeting
The string is hello there
Breakpoint 1, my_print2 (string = 0xbfffdc4 "hello there") at greeting.c :24
24  string2[size-i]=string
    你能通过设置一个观察 string2[size - i] 变量的值的观察点来看出错误是怎样产生的, 做法是键入:

(gdb) watch string2[size - i]
    gdb 将作出如下回应:
Watchpoint 2: string2[size - i]
    现在可以用 next 命令来一步步的执行 for 循环了:

(gdb) next
    经过第一次循环后,  gdb 告诉我们 string2[size - i] 的值是 `h`. gdb 用如下的显示来告诉你这个信息:

Watchpoint 2, string2[size - i]
Old value = 0 `\000'
New value = 104 `h'
my_print2(string = 0xbfffdc4 "hello there") at greeting.c:23
23 for (i=0; isize; i++)
    这个值正是期望的. 后来的数次循环的结果都是正确的. 当 i=10 时, 表达式 string2[size - i] 的值等于 `e`,  size - i 的值等于 1, 最后一个字符已经拷到新串里了.
    如果你再把循环执行下去, 你会看到已经没有值分配给 string2[0] 了,  而它是新串的第一个字符, 因为 malloc 函数在分配内存时把它们初始化为空(null)字符. 所以 string2 的第一个字符是空字符. 这解释了为什么在打印 string2 时没有任何输出了.
    现在找出了问题出在哪里, 修正这个错误是很容易的. 你得把代码里写入 string2 的第一个字符的的偏移量改为 size - 1 而不是 size. 这是因为 string2 的大小为 12, 但起始偏移量是 0, 串内的字符从偏移量 0 到 偏移量 10, 偏移量 11 为空字符保留.
    为了使代码正常工作有很多种修改办法. 一种是另设一个比串的实际大小小 1 的变量. 这是这种解决办法的代码:
#include  stdio.h>
main ()
{
  char my_string[] = "hello there";
  my_print (my_string);
  my_print2 (my_string);
}
my_print (char *string)
{
  printf ("The string is %s\n", string);
}
my_print2 (char *string)
{
  char *string2;
  int size, size2, i;
  size = strlen (string);
  size2 = size -1;
  string2 = (char *) malloc (size + 1);
  for (i = 0; i  size; i++)
    string2[size2 - i] = string;
  string2[size] = `\0';
  printf ("The string printed backward is %s\n", string2);
}

以下是英文解释,用man gdb就可以了
You can run gdb with no arguments or options; but the most usual way to
       start GDB is with one argument or two, specifying an executable program
       as the argument:
                                                                                
       gdb program
                                                                                
       You  can  also  start  with  both an executable program and a core file
       specified:
                                                                                
       gdb program core
                                                                                
       You can, instead, specify a process ID as a  second  argument,  if  you
       want to debug a running process:
                                                                                
       gdb program 1234
                                                                                
       would  attach  GDB  to  process 1234 (unless you also have a file named
       `1234'; GDB does check for a core file first).
                                                                                
       Here are some of the most frequently needed GDB commands:
                                                                                
       break [file:]function
You can, instead, specify a process ID as a  second  argument,  if  you
       want to debug a running process:
                                                                                
       gdb program 1234
                                                                                
       would  attach  GDB  to  process 1234 (unless you also have a file named
       `1234'; GDB does check for a core file first).
                                                                                
       Here are some of the most frequently needed GDB commands:
                                                                                
       break [file:]function
You can, instead, specify a process ID as a  second  argument,  if  you
       want to debug a running process:
                                                                                
       gdb program 1234
                                                                                
       would  attach  GDB  to  process 1234 (unless you also have a file named
       `1234'; GDB does check for a core file first).
                                                                                
       Here are some of the most frequently needed GDB commands:
                                                                                
       break [file:]function
               Set a breakpoint at function (in file).

       run [arglist]
              Start your program (with arglist, if specified).

       bt     Backtrace: display the program stack.

       print expr
               Display the value of an expression.

       c      Continue running your program (after stopping, e.g. at a  break-
              point).
              run [arglist]
              Start your program (with arglist, if specified).

       bt     Backtrace: display the program stack.

       print expr
               Display the value of an expression.

       c      Continue running your program (after stopping, e.g. at a  break-
              point).
                                                                                
       next   Execute  next program line (after stopping); step over any func-
              tion calls in the line.

       edit [file:]function
              look at the program line where it is presently stopped.

       list [file:]function
              type the text of the program in the  vicinity  of  where  it  is
              presently stopped.

       step   Execute  next program line (after stopping); step into any func-
       next   Execute  next program line (after stopping); step over any func-
              tion calls in the line.

       edit [file:]function
              look at the program line where it is presently stopped.

       list [file:]function
              type the text of the program in the  vicinity  of  where  it  is
              presently stopped.

       step   Execute  next program line (after stopping); step into any func-
              tion calls in the line.

       help [name]
              Show information about GDB command name, or general  information
              about using GDB.

       quit   Exit from GDB.

       For full details on GDB, see Using GDB: A Guide to the GNU Source-Level
       Debugger, by Richard M. Stallman and Roland H. Pesch.  The same text is

       available online as the gdb entry in the info program.

0 0
原创粉丝点击