[LCP] : gcc socket causes virtual memory growth

Anton V. Demidov demid at kemsu.ru
Fri Nov 16 13:54:57 UTC 2007


Dear colleagues
I subscribed to this list some time ago and still haven't got a chance to
help anyone, but I hope you could give me some idea about the issue
which drives me crazy.
I develop a client-server application where two parts connect via
socket. The server sends structures which parses at the client side
and the client reply by structures to the server.
Suddenly my client started to halt producing the segmentation fault
error. After a few days of checking my code (which is rather simple
though) I discovered that the problem is probably caused by the
virtual memory exhaustion.
Beiing started the server opens connection to the Oracle DB (using
OCCI), creates a sockets and starts to listen it. After that acording
to ps the server process uses 89772mb of the virtual memory
(considerably large amount of memory, could it be caused by OCCI
library?).
Being started the client creates the socket and makes connection to
the server. It doesn't use OCCI or other library except stdc++. But it
takes EXACTLY same amount of virtual memory! I can't find an
explanation to this fact. Adding sleep() functions and monitoring top
I found out, that the client process increases memory usage just the
time of call connect() function. After bind() it's still out of the
top, but after connect it's there. After that in the main cicle I try
to create some new structures and get the segmentation fault error.
If I remove all logic and leave just connect and shoutdown functions
my client and server don't eat so much memory. But I can't get why my
logic affects process's size at the moment of connect and before this
logic starts working.
Sorry for such long message, I hope you're tired reading it. If I
explained some points not clear enough just ask me to explain it
again. I'm totally desperated by this issue and request for your help.

This is the source code of my client application. I removed all inner
logic and left just socket work.

it's compiled as "gcc -g -L/usr/lib -lstdc++ -Wno-deprecated"

#include <iostream>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <fstream.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <cstring>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include "cluster_agent.h"
#include "VIP_protocol.h"



using namespace std;

class cMyClientSocket
{
    private: 
        int SockHandle; // 
        struct sockaddr_in localAddr, servAddr;
        int error;
        struct hostent *h;
        
        
    public:
        cMyClientSocket() //constructor
        {

        }
        
        ~cMyClientSocket() //destructor
        {

        }
        
        int sock_create()
        {
            h = gethostbyname(SERVER_ADDRESS);
            if (h == NULL) {return -100;}
            servAddr.sin_family = h->h_addrtype;//AF_INET;
            memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
            servAddr.sin_port = htons(SERVER_PORT);
            SockHandle = socket(AF_INET, SOCK_STREAM, 0);
            return SockHandle;
        }
        
        int sock_bind()
        {
            localAddr.sin_family = AF_INET;
            localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
            localAddr.sin_port = htons(0);
            int n = bind(SockHandle, (struct sockaddr *) &localAddr, sizeof(localAddr));
            return n;
        }
        
        int sock_connect()
        {
            int n = connect(SockHandle, (struct sockaddr *) &servAddr, sizeof(servAddr));
            return n;
        }
        
        int write(void *buffer, int length)
        {
            int n = send(SockHandle, buffer, length, 0);        
            return n;
        };
        int write(struct status buffer, int length)
        {
            int n = send(SockHandle, &buffer, length, 0);       
            if (n == length) {return n;}
                else {return -1;};
        };

        int read(void *buffer, int length)
        {
            int n = recv(SockHandle, buffer, length, 0);        
            return n;
        };

        int read_task(struct task *t)
        {
            int size = sizeof(struct task);
            int n = recv(SockHandle, t, size, 0);       
            if (n == size) {return 0 ; }
                else {return -1;}
        };


        void sock_shutdown()
        {
            shutdown(SockHandle, SHUT_RDWR);
        };

        void sock_shutdown(int sd)
        {
            shutdown(sd, SHUT_RDWR);
        };

}; //end class cMySock

//signal's handlers
void sigterm_handler(int nsig)
{
      log_file.write(0,"SIGTERM caught");
      WORK_FLAG = false;
};
void sigint_handler(int nsig)
{
      log_file.write(0,"SIGINT caught");
      WORK_FLAG = false;
};

int main (void)
{

  signal(SIGTERM, sigterm_handler);
  signal(SIGINT, sigint_handler);

  cMyClientSocket *pMySocket = new (cMyClientSocket);
  cout<< "create="<<pMySocket->sock_create()<<endl;;
  cout<<"bind="<<pMySocket->sock_bind()<<endl;
  //in this point it takes little virt. memory
  int sd = pMySocket->sock_connect();
  //it comes to top sorted by memory usage
  cout<<"connect="<< sd <<endl;

  ......
  inner logic:
  while() cicle which reads tasks from the server, performs tasks and
  replies.
  ......
  
  }

  
-- 
-- 
Anton Demidov
Kemerovo State University
mailto:demid at kemsu.ru




More information about the linuxCprogramming mailing list