Sign in to follow this  

segmentation fault

This topic is 4687 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When I try to run this server, I alway's get a segmentation fault when a client sends some data. I have already tried to debug it, but I can't find the problem, I have commented where the problem must be located. (in node.cc on line 162 I think) Maybe these debugging messages can help ? Because I find it very strange this function is twice on the stack. 0x08049501 in Node::ManageData(this=0xbffff8a0, ArgSocksFd=0x804c068) at node.cc:162 0x08049500 in Node::ManageData (this=0xbffff8a0, ArgSocksFd=0xbffff820) at node.cc:162 node.cc
/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#include <vector>
#include "include/node.h"
using namespace std;

Node::Node ()			//Port & Max = doorgegeven uit object ?
{
	CommandList[0].Command = "Verify";
	CommandList[0].pFunction = &Node::VerifyClient;

	CommandList[1].Command = "Disconnect";
	CommandList[1].pFunction = &Node::DisconnectClient;

	Port = 1050;
	MaxConnections = 10;
}

void
Node::BindSocket ()
{
	int ReuseAddr = 1;
	MainSock = socket (AF_INET, SOCK_STREAM, 0);

	setsockopt (MainSock, SOL_SOCKET, SO_REUSEADDR, &ReuseAddr,
		    sizeof (ReuseAddr));

	SetNonBlocking (MainSock);

	memset ((char *) &ServerAddress, 0, sizeof (ServerAddress));
	ServerAddress.sin_family = AF_INET;
	ServerAddress.sin_addr.s_addr = htonl (INADDR_ANY);
	ServerAddress.sin_port = htons (Port);

	if (bind (MainSock, (struct sockaddr *) &ServerAddress,
		  sizeof (ServerAddress)) < 0)
	{
		printf ("Cannot bind primary socket");
		exit (1);
	}

	listen (MainSock, MaxConnections);
	HighSock = MainSock;
}

void
Node::SetNonBlocking (int Sock)
{
	int opts;

	opts = fcntl (Sock, F_GETFL);
	if (opts < 0)
	{
		throw ErrorHandling (ErrorHandling::NonBlocking);
	}
	opts = (opts | O_NONBLOCK);
	if (fcntl (Sock, F_SETFL, opts) < 0)
	{
		throw ErrorHandling (ErrorHandling::NonBlocking);
	}
}

void
Node::BuildSelectList (fd_set * ArgSocksFd)
{
	FD_ZERO (ArgSocksFd);
	FD_SET (MainSock, ArgSocksFd);

	LoopTroughList (&Node::AddFdListItem, ArgSocksFd);
}

void
Node::ManageSocks (fd_set * ArgSocksFd)	// This is antoher set of SocksFd !
{
	if (FD_ISSET (MainSock, ArgSocksFd))	//!
	{
		try
		{
			AcceptNewUser ();
		}

		catch (ErrorHandling E){ 
		switch (E.GiveError ())
		{
		case ErrorHandling::NonBlocking:
			DisconnectClient (NULL);	//-> Voor log
				printf ("NonBlocking error: Connection deleted");
		case ErrorHandling::Accept:
			printf ("Error with accepting");
		}
	}
	return; //niet echt nodig
}

	try
	{
		LoopTroughList (&Node::ManageData, ArgSocksFd);
	}

	catch (ErrorHandling E)
	{
		if (E.GiveError () == ErrorHandling::Data)
			printf ("Parse or recieve error");
	}
}

void
Node::AcceptNewUser ()		//Error handling p356 + Max aantal connecties !
{
	Connection *NewItem = AddItem ();

	NewItem->Socket = accept (MainSock, NULL, NULL);
	SetNonBlocking (NewItem->Socket);
}

void
Node::LoopTroughList (bool (Node::*pFunction) (fd_set * ArgSocksFd),
		      fd_set * ArgSocksFd)
{
	Connection *pStart = GetCurrentPtr ();
	if (pStart != NULL)
	{
		Connection *pTraverse = GetCurrentPtr ();
		do
		{
			if (!(this->*pFunction) (ArgSocksFd))
				break;
			pTraverse = Advance ();
		}
		while (pStart != GetCurrentPtr ());
	}
}

bool
Node::AddFdListItem (fd_set * ArgSocksFd)
{
	FD_SET ((GetCurrentPtr ())->Socket, ArgSocksFd);
	return 1;
}

bool
Node::ManageData (fd_set * ArgSocksFd)
{
	if (FD_ISSET ((GetCurrentPtr ())->Socket, ArgSocksFd))
	{
		char *pBuffer;

		if ((pBuffer = Getline (&(GetCurrentPtr()->Socket))) != NULL)
			ParseData (pBuffer); // HERE occurs the problem !!
		else
			DisconnectClient (NULL);
		return 0;	//End the LoopTroughList function
	}
	else
		return 1;
}

char *
Node::Getline (int *Socket)
{
	vector < char >CharVector;
	char *pTempBuffer;
	int Value;

	while (true)
	{
		Value = recv (*(Socket), pTempBuffer, 1, 0);
		switch (Value)
		{
		case 0:
			return NULL;	//Disconnected
		case -1:	//Error
			throw ErrorHandling (ErrorHandling::Data);
		};

		if (*pTempBuffer == '\r') // of \n
		{
			char *pData = new char[CharVector.size () + 1];
			memset (pData, 0, CharVector.size () + 1);

			for (unsigned int i = 0; i < CharVector.size ();
			     i += 1)
			{
				pData[i] = CharVector[i];
			}
			return pData;
		}
		else
		{
			CharVector.push_back (*pTempBuffer);
		}
	}
}

void
Node::ParseData (char *pBuffer)
{
	char *pDividedData;
	for (int Loop = 0; Loop < COMMAND; Loop++)
	{
		if ((strstr (pBuffer, (CommandList[Loop].Command))) != NULL)
		{
			if ((strstr (pBuffer, ":")) != NULL)
			{
				pDividedData = strstr (pBuffer, ":"); //pdividedata local scope new maken !
				(this->*(CommandList[Loop].pFunction))
					(pDividedData);
				return;
			}
			//delete (pBuffer); //verplaatsen !!
		}
	}
	delete[] pBuffer;
	throw ErrorHandling (ErrorHandling::Data);
}

void
Node::VerifyClient (char *pData)
{

}

void
Node::DisconnectClient (char *pData)
{
	close ((GetCurrentPtr ()->Socket));
	DeleteCurrentPtr ();
}






node.h
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define COMMAND 1
#include "include/linkedlist.h"

struct Connection
{
	int Socket;
	Connection *Next;
	  Connection ()
	{
		Next = NULL;
	}
};

class Node:private LinkedList < Connection >
{
      private:
	int MainSock;
	int HighSock;		//!
	int MaxConnections;
	int Port;
	struct sockaddr_in ServerAddress;

	void DisconnectClient (char *pData);
	void VerifyClient (char *pData);

	struct NetCommands
	{
		char *Command;
		void (Node::*pFunction) (char *pData);
	} CommandList[COMMAND];

	void SetNonBlocking (int Sock);
	//Also possible to use global fd_set or to give pTraverse as argument
	void LoopTroughList (bool (Node::*pFunction) (fd_set * ArgSocksFd), fd_set * ArgSocksFd);
	bool AddFdListItem (fd_set * ArgSocksFd);
	bool ManageData (fd_set * ArgSocksFd);
	void AcceptNewUser ();
	char *Getline (int *Socket);
	void ParseData (char *pBuffer);
	
	class ErrorHandling{
		public:
			enum TypeOfError {Data, Accept, NonBlocking};
			ErrorHandling (TypeOfError S) : Error(S) {}
			TypeOfError GiveError() {return Error;}
		private:
			TypeOfError Error;
	};

      public:
	  Node ();

	void BindSocket ();
	void BuildSelectList (fd_set * ArgSocksFd);
	void ManageSocks (fd_set * ArgSocksFd);
};





linkedlist.h
template < class Type > class LinkedList
{
      private:
	int Size;
	Type *pHead;
	Type *pTail;
	Type *pCurrent;
	Type *Previous (Type * pIndex);

      public:

	LinkedList ();
	Type *GetCurrentPtr ();
	Type *AddItem ();
	Type *Advance ();
	Type *Rewind ();
	bool DeleteCurrentPtr();
};

template < class Type > LinkedList < Type >::LinkedList ():Size (0)
{
	pHead = NULL;
	pCurrent = NULL;
	pTail = NULL;
}

template < class Type > Type * LinkedList < Type >::AddItem ()
{
	if (pHead == NULL)
	{
		pHead = new Type;
		pTail = pHead;
		pCurrent = pTail;
		return pCurrent;
	}
	pTail->Next = new Type;
	pTail = pTail->Next;
	pCurrent = pTail;
	return pCurrent;
}

template < class Type > Type * LinkedList < Type >::Previous (Type * pIndex)
{
	Type *pTemp = pHead;
	if (pIndex == pHead)
	{
		return pHead;
	}
	while (pTemp->Next != pIndex)
	{
		pTemp = pTemp->Next;
	}
	return pTemp;
}

template < class Type > Type * LinkedList < Type >::Rewind ()
{
	if (pCurrent != pHead)
	{
		pCurrent = Previous (pCurrent);
		return pCurrent;
	}
	pCurrent = pTail;
	return pCurrent;
}

template < class Type > Type * LinkedList < Type >::Advance ()
{
	if (pCurrent->Next != NULL)
	{
		pCurrent = pCurrent->Next;
		return pCurrent;
	}
	pCurrent = pHead;
	return pCurrent;
}

template < class Type > bool LinkedList < Type >::DeleteCurrentPtr ()
{
	Type *pTemp;

	if (pCurrent == NULL)
		return 0;
		else
	{

		if (pCurrent == pHead)	//Case 1 delete = Head
		{
			pTemp = pHead;
			pHead = pHead->Next;
			delete pTemp;
		}
		else if (pCurrent == pTail)	//Case 2 delete is at the end
		{
			pTemp = pTail;
			pTail = Rewind ();
			pTail->Next = NULL;
			delete pTemp;
		}
		else		//Case 3 delete is in middle somewhere
		{
			pTemp = Rewind ();
			pTemp->Next = pCurrent->Next;
			delete pCurrent;
		}
	}

	pCurrent = pHead;	//Reset
return 1;
}

template < class Type > Type * LinkedList < Type >::GetCurrentPtr ()
{
	return pCurrent;
}




main.cc
int
main ()
{
	int Num = 0;
	Node Room;
	
	Room.BindSocket();
	while (true)
	{
	fd_set rd;
	struct timeval t;
	
    t.tv_sec=2;
    t.tv_usec=0;
	Room.BuildSelectList(&rd);
	Num = select(FD_SETSIZE, &rd,NULL,NULL, &t);
    if( Num>0 )
    {
	Room.ManageSocks(&rd);	
    }
}
return 0;
}




[Edited by - Rip7 on February 10, 2005 4:08:54 PM]

Share this post


Link to post
Share on other sites
I've not looked through it thoroughly, so there may well be more errors, but one thing popped out at me immediately:
//node.h:
// stuff
#define COMMAND 1
// stuff
struct NetCommands
{
char *Command;
void (Node::*pFunction) (char *pData);
} CommandList[COMMAND];
// stuff

//node.cc:
// stuff
Node::Node () //Port & Max = doorgegeven uit object ?
{
CommandList[0].Command = "Verify";
CommandList[0].pFunction = &Node::VerifyClient;

/* Error - CommandList only has room for one entry, not two */
CommandList[1].Command = "Disconnect";
CommandList[1].pFunction = &Node::DisconnectClient;

Port = 1050;
MaxConnections = 10;
}


By the way, COMMAND may be safer as a const unsigned int, rather than a preprocessor define (since the preprocessor knows nothing about scope).

Enigma

Share this post


Link to post
Share on other sites
Thanks for your help and time.

I have changed it, but the problem remains however. It must be something stupid probably but I have searched for hours now and I don't know what to do anymore.

oh, yes an intresting detail the ('second') ArgSocksFd=0x804c068 argument has the same addres as *pData (data recieved from client). But I don't know how this is possible.

Another intresting thing is when I send the letter 'l' I don't get a segmentation fault, but then my program uses 80 % of my systems RAM. Strange ...

Share this post


Link to post
Share on other sites

This topic is 4687 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this