gdb的bug吗!

在使用gdb调试程序时,应该经常会去查看变量的值。但是,我发现gdb有时会出现一些莫名其妙的问题,怀疑是bug。这里,举两个例子。
为了突出重点,下面的程序都经过简化,去掉了原来的功能,只保留了关键部分,即让gdb出现问题的部分。但程序是完整的,大家可以自己去试一下。
程序1:
#include<string>
using namespace std;
struct node
{
 char s[200];
 node()
 {
     memset(s,0,sizeof s);
 }
 node lowcase()
 {
   node t;//此处会调用默认构造函数,t.s会初始化为0.下面的输出确实全为0,
   for(int i=0;i<200;i++)
    cout<<(int)t.s[i];
    //此时如果观察gdb的watch,你会发现t.s显示为乱码。
    //在版本6.8和7.1for ubuntu下测试均如此.
   for(int i=0;i<200;i++)
     {if(s[i]>='A'&&s[i]<='Z')
        s[i]+=32;
        t.s[i]=s[i];
     }
   return t;
 }
};
int main()
{
 node nd1,nd2;
 cin>>nd1.s;
 nd2=nd1.lowcase();
 cout<<nd1.s<<endl<<nd2.s<<endl;
}

再看一个程序:
程序2:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
 int len=-1;
char s[]="love";

 bool flag;
if(strlen(s)>len)//你认为该条件成立吗?
    {
flag=1;
    }
    else
        flag=0;
    cout<<flag<<endl;
}
程序将输出0,而不是1。因为strlen(s)是unsigned,而len是int,C++会将signed int 转换成unsigned再参与运算,-1转换为unsigned,是个很大的值,所以flag的值为0.
这些不是我想讨论的,我们来查看一下strlen(s)的值,很奇怪,在IDE下,它居然显示为int类型,(IDE为guide1.0);查看strlen(s)>len,它显示为true.
为了弄清楚到底是gdb的问题还是IDE的问题,我直接通过gdb调试该程序。在gdb6.8下,通过break命令下断点,然后再dis strlen(s)>len,发现它显示结果仍然为true,dis
strlen(s),显示结果为5.
但最终输出flag值为0.

我在程序中加上一条:unsigned int aa=strlen(s);
调试时,执行dis aa>len,显示结果为false.

问题很显然出在gdb上面,在查看变量时,它会将strlen当做signed int来处理,但是实际运行时,又会将strlen的返回值当做signed值来处理。



我怀疑可能是这个版本的gdb的问题。于是干脆换到ubuntu虚拟机下,按同样的步骤用gdb调试该程序,情况更加莫名其妙了。这次显示dis strlen(s)>len仍然为true,但是dis
strlen(s),显示的结果居然为2995008.
不论s数组输入什么值,或是改变数组元素个数,均显示2995008.
我将s数组改成string,继续测试,此时一切正常。dis s.length()>len,显示为false,flag值也为0.
在16行处下断点,并查看strlen(s)>len的值,显示为true,再查看flag的值,显示为false。

我在程序中加上一条:unsigned int aa=strlen(s);
调试时,执行dis aa>len,显示结果为false,执行dis aa,显示的就是元素的实际个数了。
两个版本的gdb在查看strlen(s)都出现了问题,只是问题表现的不太一样。

猜你喜欢

转载自blog.csdn.net/hefenghhhh/article/details/8462732
GDB
bug