LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 736|回复: 5

请教:用gdb的watch出现的一个错误

[复制链接]
发表于 2004-10-2 14:21:27 | 显示全部楼层 |阅读模式
我看了http://www.linuxsir.cn/bbs/showt ... d=276723#post276723

这个关于linux下c语言的编程后就照着做,到下面这里的时候就出问题了:
-------------------------------------------------------------
你能通过设置一个观察 string2[size - i] 变量的值的观察点来看出错误是怎样产生的, 做法是键入:

    (gdb) watch string2[size - i]

  执行结果如下:

    Watchpoint 2: string2[size - i]

  现在可以用 next 命令来一步步的执行 for 循环了:

    (gdb) next
------------------------------------------------------------
我的是这样的:
-------------------------------------------
Breakpoint 1, my_print2 (string=0xbffffc10 "hello there") at greeting.c:27
27            string2[size2-i]=string;
(gdb) watch string2[size2-i]
Hardware watchpoint 2: string2[size2 - i]
(gdb) next
warning: Could not remove hardware watchpoint 2.
Warning:
Could not insert hardware watchpoint 2.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
-----------------------------------------------

为什么会出现next下面的那些错误提示?请指教,谢谢。
发表于 2004-10-3 01:09:36 | 显示全部楼层
能不能把程序和调试过程 (方便的话) 也贴出来?
 楼主| 发表于 2004-10-3 10:28:38 | 显示全部楼层
  1. cd /home/funshine/c/        # -*-compilation-*-
  2. Entering directory `/home/funshine/c/'
  3. make -k
  4. make: “greeting”是最新的。

  5. Compilation finished at Sun Oct  3 10:25:22


  6. Current directory is /home/funshine/c/
  7. GNU gdb 6.1-debian
  8. Copyright 2004 Free Software Foundation, Inc.
  9. GDB is free software, covered by the GNU General Public License, and you are
  10. welcome to change it and/or distribute copies of it under certain conditions.
  11. Type "show copying" to see the conditions.
  12. There is absolutely no warranty for GDB.  Type "show warranty" for details.
  13. This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/libthread_db.so.1".

  14. (gdb) run
  15. Starting program: /home/funshine/c/greeting
  16. 你好,你现在使用的是gcc编译器!
  17. The string is hello there
  18. The string printed backward is ereht olleh

  19. Program exited with code 053.
  20. (gdb) l
  21. 1        #include <stdio.h>
  22. 2       
  23. 3        void my_print(char *string);
  24. 4        void my_print2(char *string);
  25. 5       
  26. 6        int main()
  27. 7        {
  28. 8          printf("你好,你现在使用的是gcc编译器!\n");
  29. 9          char my_string[]="hello there";
  30. 10          my_print(my_string);
  31. (gdb)
  32. 11          my_print2(my_string);
  33. 12        }
  34. 13        void my_print(char *string)
  35. 14        {
  36. 15          printf("The string is %s\n",string);
  37. 16        }
  38. 17       
  39. 18        void my_print2(char *string)
  40. 19        {
  41. 20          char *string2;
  42. (gdb)
  43. 21          int size,size2,i;
  44. 22       
  45. 23          size=strlen(string);
  46. 24          size2=size-1;
  47. 25          string2=(char *)malloc(size+1);
  48. 26          for(i=0;i<size;i++)
  49. 27            string2[size2-i]=string[i];
  50. 28          string2[size]='\0';
  51. 29          printf("The string printed backward is %s\n",string2);
  52. 30        }
  53. (gdb) break 27
  54. Breakpoint 1 at 0x8048466: file greeting.c, line 27.
  55. (gdb) run
  56. Starting program: /home/funshine/c/greeting
  57. 你好,你现在使用的是gcc编译器!
  58. The string is hello there

  59. Breakpoint 1, my_print2 (string=0xbffffc10 "hello there") at greeting.c:27
  60. 27            string2[size2-i]=string[i];
  61. (gdb) watch string2[size2-i]
  62. Hardware watchpoint 2: string2[size2 - i]
  63. (gdb) next
  64. warning: Could not remove hardware watchpoint 2.
  65. Warning:
  66. Could not insert hardware watchpoint 2.
  67. Could not insert hardware breakpoints:
  68. You may have requested too many hardware breakpoints/watchpoints.

  69. (gdb)
复制代码
 楼主| 发表于 2004-10-3 10:33:52 | 显示全部楼层
程序是已经改好的,我只是想学一下gdb调试的过程,到了这里就没有再做下去。
另外,watch size或者watch string2[2]等等这种简单的都是好的。
发表于 2004-10-3 20:37:53 | 显示全部楼层
使用 GDB 调试程序时,你可以添加两种类型的观察点:软件观察点 (software watchpoint) 和硬件观察点 (hardware watchpoint)。GDB 使用软件观察点的方式是单步执行你的程序同时测试变量的值。这样,执行程序的速度会变慢。

幸运的是,32 位的 Intel x86 处理器提供了 4 个特殊的调试寄存器用来方便调试程序。GDB 可以使用这些寄存器建立硬件观察点。GDB 总是尝试使用硬件观察点,因为这样不会减慢程序的执行速度。

然而,活动的 (可用的) 硬件观察点的个数是有限的。如果你设置了过多的硬件观察点,当程序从中断的状态变为执行的状态时,GDB 可能无法把它们全部插入。另外,活动的硬件观察点的数量只有在试图继续执行程序时才能知道,所以,直到这种尝试发生之前 GDB 无法警告你这一点。

如果这种情况真的发生了,你可以用 disable 命令将多余的硬件观察点禁用。我试了下面的程序:
  1. int main(void)
  2. {
  3.     int i, j, k, l, m, n;
  4.     i = 0;
  5.     j = 1;
  6.     while (1) {
  7.         k = (i++) + j;
  8.         l = k + (++j);
  9.         m = (k++) + (i++) + (j++);
  10.         n = (--m) + (j++) + (--i) + (k++);
  11.     }
  12.     return 0;
  13. }
复制代码

使用 GDB 调试时,如果同时将 ijklmn 设成活动的观察点 (从而都是活动的硬件观察点),也会出现你调试时出现的问题。因此只能将一部分观察点禁用。

多少个硬件观察点可以同时为活动的?GDB 使用观察点的细节是什么?为什么 string2[size2 - i] 会包含多个观察点?这些问题我不知道该怎样回答。不过,调试你的程序时虽然给出了那条警告,只要你多执行几次 next,结果也会出来,你完全可以忽略那些警告。
 楼主| 发表于 2004-10-4 13:47:11 | 显示全部楼层
果然是这样,感谢大牛!!
又学到很多东西
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表