免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1261 | 回复: 0
打印 上一主题 下一主题

用GDB调试C程序 - [linux c编程] ---转载收藏 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-08 08:59 |只看该作者 |倒序浏览

                用GDB调试C程序 - [
linux c编程
]
                                
                                
                                    
原文地址:http://sujiaqiuxiao.blogbus.com/logs/31593502.html
程序开始移植到LINUX底下,一直是window调节,再在LINUX底下编译运行,今天却发现有些错误,windows底下并不报
错,linux底下却没办法跑完,只好开始用GDB调试,0
0,一直很讨厌LINUX底下的编程和调试,因为要记很多参数,8过这段移植过程中,逐渐熟悉起来了,也就没有之前那么反感了,嘛,习惯了果然就好了,
唉,就看你想不想养成习惯。
嘛,以后会经常记录些关于编程方面的东西吧,一遇到问题就百度,结果这么久了,发现有很多问题都是以前碰到过
的,昨天折腾了半响的类型转换问题,后来还是问了便便才解决的,因为上次他也碰到了类似的问题,结果后来再修改之前的一个程序的时候,才发现早在那个程序
我就碰到了这个问题并且解决了,我居然一点印象都没有,OTZ。SO,还是做好总结比较好,以后也不用花力气再去找了。
转载:
在命令行上键入 gdb 并按回车键就可以运行 gdb 了, 如果一切正常的话, gdb 将被启动并且你将在屏幕上看到类似的内容:
[color="#0066ff"]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 4.14 (i486-slakware-linux), Copyright 1995 Free Software Foundation, Inc.
(gdb)    当你启动 gdb 后, 你能在命令行上指定很多的选项. 你也可以以下面的方式来运行 gdb : [color="#0066ff"]gdb     当你用这种方式运行 gdb , 你能直接指定想要调试的程序. 这将告诉gdb 装入名为 fname 的可执行文件. 你也可以用 gdb 去检查一个因程序异常终止而产生的 core 文件, 或者与一个正在运行的程序相连. 你可以参考 gdb 指南页或在命令行上键入 gdb -h 得到一个有关这些选项的说明的简单列表.
  为调试编译代码(Compiling Code for Debugging)    为了使 gdb 正常工作, 你必须使你的程序在编译时包含调试信息. 调试信息包含你程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号.  gdb 利用这些信息使源代码和机器码相关联.
    在编译时用 -g 选项打开调试选项.
  
gdb 基本命令     gdb 支持很多的命令使你能实现不同的功能. 这些命令从简单的文件装入到允许你检查所调用的堆栈内容的复杂命令, 表27.1列出了你在用 gdb 调试时会用到的一些命令. 想了解 gdb 的详细使用请参考 gdb 的指南页.   表 27.1. 基本 gdb 命令.   
命   令描  述file装入想要调试的可执行文件.kill终止正在调试的程序.list列出产生执行文件的源代码的一部分.next执行一行源代码但不进入函数内部.step执行一行源代码而且进入函数内部.run执行当前被调试的程序quit终止 gdbwatch使你能监视一个变量的值而不管它何时被改变.break在代码里设置断点, 这将使程序执行到这里时被挂起.make使你能不退出 gdb 就可以重新产生可执行文件.shell使你能不离开 gdb 就执行 UNIX shell 命令.   
  
     gdb 支持很多与 UNIX shell 程序一样的命令编辑特征. 你能象在 bash 或 tcsh里那样按 Tab 键让 gdb 帮你补齐一个唯一的命令, 如果不唯一的话 gdb 会列出所有匹配的命令. 你也能用光标键上下翻动历史命令.
gdb 应用举例    本节用一个实例教你一步步的用 gdb 调试程序. 被调试的程序相当的简单, 但它展示了 gdb 的典型应用.
  
    下面列出了将被调试的程序. 这个程序被称为 greeting , 它显示一个简单的问候, 再用反序将它列出. [color="#0066ff"]#include  
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     用下面的命令编译它:
  [color="#0066ff"]gcc -o test test.c    这个程序执行时显示如下结果: [color="#0066ff"]The string is hello there
The string printed backward is    输出的第一行是正确的, 但第二行打印出的东西并不是我们所期望的. 我们所设想的输出应该是: [color="#0066ff"]The string printed backward is ereht olleh    由于某些原因, my_print2 函数没有正常工作. 让我们用  gdb 看看问题究竟出在哪儿, 先键入如下命令:
  [color="#0066ff"]gdb greeting注意: 记得在编译 greeting 程序时把调试选项打开.      如果你在输入命令时忘了把要调试的程序作为参数传给 gdb , 你可以在 gdb 提示符下用 file 命令来载入它:
  [color="#0066ff"](gdb) file greeting    这个命令将载入 greeting 可执行文件就象你在 gdb 命令行里装入它一样.
    这时你能用 gdb 的 run 命令来运行 greeting 了. 当它在 gdb 里被运行后结果大约会象这样:
[color="#0066ff"](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 命令三次, 列出源代码: [color="#0066ff"](gdb) list
(gdb) list
(gdb) list技巧:  在 gdb 提示符下按回车健将重复上一个命令.      第一次键入 list 命令的输出如下:
  [color="#0066ff"]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 命令, 给出下列输出:
  [color="#0066ff"]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 程序的剩余部分: [color="#0066ff"]21        size = strlen (string);
22        string2 = (char *) malloc (size + 1);
23        for (i = 0; i     根据列出的源程序, 你能看到要设断点的地方在第24行, 在 gdb 命令行提示符下键入如下命令设置断点: [color="#0066ff"](gdb) break 24    gdb 将作出如下的响应: [color="#0066ff"]Breakpoint 1 at 0x139: file greeting.c, line 24
(gdb)  
    现在再键入 run 命令, 将产生如下的输出:
  [color="#0066ff"]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] 变量的值的观察点来看出错误是怎样产生的, 做法是键入:
  [color="#0066ff"](gdb) watch string2[size - i]    gdb 将作出如下回应: [color="#0066ff"]Watchpoint 2: string2[size - i]    现在可以用 next 命令来一步步的执行 for 循环了:
  [color="#0066ff"](gdb) next    经过第一次循环后,  gdb 告诉我们 string2[size - i] 的值是 `h`. gdb 用如下的显示来告诉你这个信息:
  [color="#0066ff"]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; 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 的变量. 这是这种解决办法的代码:
[color="#0066ff"]#include  
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
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/90602/showart_1818337.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP