2015-02-23 153 views
0

当我每次运行我的程序:ns-server时,它会告诉我它解密消息失败,但是当我使用valgrind时,尝试找出发生此错误的原因,它工作正常。每当我使用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) 

但是这3个功能来自这是我从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; 

-------------------以上是注册()函数部分,实在是太长了,我只是桩部的它----------------

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; 

} 

的错误是:它会显示“解密失败”时,我没有任何调试工具运行,但它会用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); 
}; 

的错误是部分是,它解密失败,但我不觉得,因为当我的valgrind或Xcode中运行它,它是关系到DecryptStringENC的功能,经常工作良好。

+0

是的,valgrind通过检测来改变你的代码。这可能会改变内存操作的结果。在valgring或任何其他调试工具下运行也会改变可能改变多线程程序行为的时间。 **你有没有调查过可能会导致“无效的大小1的读取”?你想发布你的代码吗?** – dmitri 2015-02-23 07:42:28

+0

我试图找到原因,它说:无效的读取大小1 == 44887 ==在0x6C49:strlen(vg_replace_strmem.c:427) == 44887 = = by 0x100134E6F:StringBuffer :: setString(char const *)(in ./ns-server)我看不到StringBuffer :: setString(char const *)的函数里面有什么,它不是由我编码的,我从它下载网站(这句话是否意味着这个错误与此功能有关)。我想发布我的代码,但它会发布至少200行相关代码。我会发布它。 – beasone 2015-02-23 08:03:02

回答

2

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

+0

'std :: vector'可能会帮助您解决代码中的一堆问题。 – 2015-02-23 17:23:34

+0

感谢您的咨询! – beasone 2015-02-23 18:25:15