当我运行我的程序时:每次运行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(®,0,sizeof(request_register));
memcpy(®,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运行它时,它经常工作正常。
答案 0 :(得分:2)
现在我明白为什么会发生错误。当我将密文传递给MyDecryption(char *ciphertext,CkString &outData)
时
我设置它的大小是128bytes(因为当我使用strlen来查看密文的大小时,它显示128)。但我突然想到,也许我应该使用大小为129字节的malloc密文,因为'/ 0'将附加到一个字符串。然后,问题解决!!!!!!!