Valgrind显示调试结果,但结果不正确

时间:2015-02-23 07:12:42

标签: c++ debugging

当我运行我的程序时:每次运行ns-server,它会告诉我它解密消息失败,但是当我使用valgrind尝试找到这个错误发生的原因时,它运行正常。每当我使用valgrind进行调试时,它都能正常工作。 valgrind的结果是:

valgrind --leak-check=yes ./ns-server
==44887== Memcheck, a memory error detector
==44887== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==44887== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==44887== Command: ./ns-server
==44887== 
first get nextlen 564
nextlen is 564
==44887== Thread 2:
==44887== Invalid read of size 1
==44887==    at 0x6C49: strlen (vg_replace_strmem.c:427)
==44887==    by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887==    by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887==    by 0x100025396: CkRsa::DecryptStringENC(char const*, bool,  CkString&) (in ./ns-server)
==44887==    by 0x1000130EA: My_RSA::MyDecryption(char*, CkString&) (RSAsample.cpp:52)
==44887==    by 0x1000021C1: Server::Register(char*, int, char*) (Server.cpp:164)
==44887==    by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887==    by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==  Address 0x100b3f150 is 0 bytes after a block of size 128 alloc'd
==44887==    at 0x47E1: malloc (vg_replace_malloc.c:300)
==44887==    by 0x1000020F4: Server::Register(char*, int, char*) (Server.cpp:154)
==44887==    by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887==    by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==    by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== 

这是结果的一部分。 在这个结果中,它提到:

by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887==    by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887==    by 0x100025396: CkRsa::DecryptStringENC(char const*, bool,  CkString&) (in ./ns-server)

但是这三个函数来自静态库,我从http://www.chilkatsoft.com/refdoc/vcCkRsaRef.html下载它们是否意味着错误实际发生在这些函数中?为什么当我使用valgrind运行时,我的项目可以输出正确的结果?当我在没有任何调试工具的情况下运行它时,它将输出"解密失败"。 Valgrind会改变与我的程序相关的东西吗?

我的代码如下:

int main(int argc, const char * argv[])
{
Server myServer(SERVER_PORT);//initialize server's port num,set up socket

myServer.Start();
return 0;
}

int Server::Start()
{

send_public_key server_pub_key;
server_pub_key.heads.random=random()%10;
server_pub_key.heads.request_type=PUBLICKEY;
server_pub_key.heads.length=sizeof(send_public_key);

strcpy(server_pub_key.pubkey,server_rsa.publickey);

TCPServer.SetupListen(PortListen,Evaluate_MSG,"",0,PUBLICKEY,(char *)&server_pub_key,server_pub_key.heads.length);
    return 0;
}

int TCPConnect::SetupListen(int port, void * trifunc(void *),char * refuseMSG,int refuseLen,int pub,char *msg,int length)
{
if((mi_SocketToListen=socket(AF_INET,SOCK_STREAM,0))==-1)
{
    printf("create socket failed\n");
    return errno;
}

struct sockaddr_in ts_SocketAddrToListen;
ts_SocketAddrToListen.sin_addr.s_addr=INADDR_ANY;
SetupSocketAddrToTarget(NULL, port, ts_SocketAddrToListen,1);
if( bind(mi_SocketToListen,(struct sockaddr *)&ts_SocketAddrToListen,sizeof(struct sockaddr)) == -1)
{
    printf("establish socket failed!\n");
    return errno;
}
if(listen(mi_SocketToListen,99)==-1)
{
    printf("listen failed\n");
    return errno;
}
while (1)
{
    int ti_sockfd;
    struct sockaddr_in ts_sockaddr;
    socklen_t ti_size = sizeof(struct sockaddr_in);
    if((ti_sockfd=accept(mi_SocketToListen,(struct sockaddr *)&ts_sockaddr,&ti_size))==-1)
    {
        printf("accept user failed\n");
        return errno;
    }
    if (threadlist.size() < mi_MaxConnection)
    {

        if(pub==80)//if this needs me to send a public key immediately afther i accept it
        {

            SendMsg(ti_sockfd, msg,length);

        }

        mm_clients.insert(std::pair<int,struct sockaddr_in>(ti_sockfd,ts_sockaddr));

        pthread_t tp_threadfd;

        pthread_create(&tp_threadfd,NULL,trifunc,(void *)&ti_sockfd);

        threadlist.push_back(tp_threadfd);

    }
    else
    {
        SendMsg(ti_sockfd, refuseMSG, refuseLen);
        CloseConnect(ti_sockfd,NULL);
    }
}

return 0;
};

void * Server::Evaluate_MSG(void *arg)
{

int socketfd = *((int *) arg);

header checkheader;
int err;
while (true)
{
    err = 0;

    char * msg;
    char *ip;
    ip=(char *)malloc(sizeof(char)*INET_ADDRSTRLEN);
    memset(ip,0,sizeof(char)*INET_ADDRSTRLEN);

    int nextlen=Server::TCPServer.GetNextlen(socketfd);

    msg=(char *)malloc(sizeof(char)*nextlen);
    memset(msg,0,sizeof(char)*nextlen);

    msg=Server::TCPServer.Receive(socketfd, nextlen);

    //Server::TCPServer.Receive(socketfd,msg);
    struct sockaddr_in sender_ip;
    memset(&sender_ip,0,sizeof(struct sockaddr_in));

    sender_ip=Server::TCPServer.GetInfoBySocket(socketfd);

    inet_ntop(AF_INET,&sender_ip.sin_addr,ip,INET_ADDRSTRLEN);

    memset(&checkheader,0,sizeof(header));
    memcpy(&checkheader,msg,sizeof(header));
    switch(checkheader.request_type)
    {
        case REGISTER:
            err = Register(msg, socketfd,ip);

            break;
        case LOGIN:
            err=Login(msg, socketfd,ip);
            break;
        default:
            break;
    }
    free(ip);
    free(msg);
    if (err<0)
    {
        cout<<"error!"<<endl;
        pthread_exit(0);
    }
}

}

int Server::Register(char *msg,int sockfd,char *ip)
{
request_register reg;
memset(&reg,0,sizeof(request_register));
 memcpy(&reg,msg,sizeof(request_register));



if(reg.real_pass!=REAL_PASS)
{
    //ignore
}
else
{
    send_user_success success_err;
    success_err.heads.random=random()%10;
    success_err.heads.length=sizeof(success_err);
    CkString user_name_outData;
    char *recv_username;
    recv_username=(char *)malloc(sizeof(char)*LENGTH_CIPHERTEXT);
    memset(recv_username,0,sizeof(char)*LENGTH_CIPHERTEXT);
    memcpy(recv_username,reg.username,sizeof(char)*LENGTH_CIPHERTEXT);

    server_rsa.MyDecryption(recv_username,user_name_outData);
    //it decrypt fails

    cout<<"after returning:"<<user_name_outData.getString()<<endl;

-------------------以上是Register()函数的一部分,它太长了,我只是张贴它的一部分------- ---------

bool My_RSA::MyDecryption(char *ciphertext,CkString &outData)
 {
 rsaDecryptor.put_EncodingMode("hex");
 rsaDecryptor.ImportPrivateKey(privatekey);
 bool userPrivateKey;
 userPrivateKey=true;

 const char *cipher;
 cipher=ciphertext;


const char * decryptedStr ;
decryptedStr= new char[SAY_MAX];
memset((char *)decryptedStr,0,sizeof(char)*SAY_MAX);

 bool test=(char *) rsaDecryptor.DecryptStringENC(ciphertext, userPrivateKey, outData);//(decryptedStr, userPrivateKey);
if (!test) {
    cout<<"decrypt failed"<<endl;
    return false;
}

return true;

}

错误是:它会显示&#34;解密失败&#34;当我在没有任何调试工具的情况下运行时,它肯定会用valgrind解密。 这是标题(部分):

static std::map <string,struct user_info> user_info_map;//string is user's name
static My_RSA server_rsa;

class Server
{
public:
Server(int p);

protected:

static TCPConnect TCPServer;

public:
int PortListen;


protected:
static int Register(char *msg,int sockfd,char *ip);
static int Login(char *msg,int sockfd,char *ip);
static int Lock_Un_Out(char *msg,int sockfd,int lock_unlock);

static int Check_User(int sockfd);
static int Send_User(char *msg,int sockfd);

static int Update(char *msg,int sockfd);
public:
int Start();

static void * Evaluate_MSG(void *arg);
};

错误的一部分是它解密失败,但我不认为它与DecryptStringENC的功能有关,因为当我用valgrind或Xcode运行它时,它经常工作正常。

1 个答案:

答案 0 :(得分:2)

现在我明白为什么会发生错误。当我将密文传递给MyDecryption(char *ciphertext,CkString &outData)时 我设置它的大小是128bytes(因为当我使用strlen来查看密文的大小时,它显示128)。但我突然想到,也许我应该使用大小为129字节的malloc密文,因为'/ 0'将附加到一个字符串。然后,问题解决!!!!!!!