问题描述:

Code -- Main loop:

int handleClient (struct clientData* clientData)

{

void* Buffer = malloc (INET_BUFFER_SIZE); <-- VOID* BUFFER FOR RECV()

int listenSocket = clientData->listenSocket;

struct sockaddr_in clientAddress = clientData->clientAddress;

printf("Received connection from client %s:%d.\n", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));

while (1)

{

int packetSize;

if ((packetSize = recv(listenSocket, &Buffer, INET_BUFFER_SIZE, 0)) > 0)

{

if (packetSize == ECHO_SIZE)

{

handleEchoPacket(Buffer);

continue;

}

if (packetSize == MESSAGE_SIZE) <---THIS IS TRIGGERED BECAUSE OF PACKET SIZE

{

handleMessagePacket(Buffer);

continue;

}

}

}

Code -- handleMessagePacket(void* Buffer):

void handleMessagePacket (void* Buffer)

{

void* localBuffer = (void*) malloc(INET_BUFFER_SIZE);

memcpy(localBuffer, Buffer, INET_BUFFER_SIZE); <--SEGFAULT

(...)

}

GDB -- Partial output:

Program received signal SIGSEGV, Segmentation fault.

__memcpy_sse2_unaligned () (.....) <--Tells me it doesn't have source files, not relevant to the problem.

Basically, the problem happens when I copy one memory block from a void pointer to a local buffer. Both were malloc() heap memory of same type: void.

Any suggestions or comments are welcome!

网友答案:

Here is what is happening: when you pass the address of Buffer to recv, received data is placed in the space allocated to the address of your buffer, which is on the stack. When you subsequently call handleMessagePacket, the address that you pass is no longer valid: it has been written over by recv!

Removing the ampersand from the call of recv should fix this problem:

if ((packetSize = recv(listenSocket, Buffer, INET_BUFFER_SIZE, 0)) > 0)
//                                  ^^ No ampersand

In general, situations like this are best diagnosed with a memory profiler, such as valgrind. The tool would promptly tell you that there is an invalid write into stack area for the Buffer write, and that the subsequent dereference of received data as a pointer (the issue that causes SIGSEGV now) is an invalid read.

相关阅读:
Top