Valgrind / helgrind kills with stress test

I am making a web server on Linux in C ++ with pthreads. I tested it with valgrind for leaks and memory problems - everything fixed. I tested it with helgrind for threading issues - everything fixed. I'm trying a stress test. I get problems when probram starts with helgrind

valgrind --tool=helgrind ./chats

He just dies in random places with the text "Killed", as it would be when I killed him with the help kill -9. The only report I sometimes get from helgrind is that the program exists, while retaining some locks, which is normal when they are killed.

When checking for leaks:

valgrind  --leak-check=full ./chats

it is more stable, but I managed to make it die once with several hundred parallel connections.

I tried to run the program alone and could not make it crash at all. I have tried up to 250 concurrent connections. Each thread is delayed by 100 ms to facilitate the simultaneous use of multiple connections. Without crashing.

In all cases, the threads, as well as the connections, do not exceed 10, and I see that it broke even into 2 connections, but never with one connection at the same time (including the main stream and one auxiliary stream - only 3).

  • Is it possible that the problem will only occur when starting with helgrind or just helgrind makes it more likely?
  • What is the reason the program is being killed (by the kernel?) Allocating too much memory, too many file descriptors?

, , , - . , , , :

void *TcpClient::run(){
  int ret;
  struct timeval tv;
  char * buff = (char *)malloc(10001);
  int br;

  colorPrintf(TC_GREEN, "new client starting: %d\n", sockFd);
  while(isRunning()){
    tv.tv_sec = 0;
    tv.tv_usec = 500*1000;
    FD_SET(sockFd, &readFds);
    ret = select(sockFd+1, &readFds, NULL, NULL, &tv);
    if(ret < 0){
      //select error
      continue;
    }else if(ret == 0){
      // no data to read
      continue;
    }
    br = read(sockFd, buff, 10000);
    buff[br] = 0;

    if (br == 0){
    // client disconnected;
      setRunning(false);
      break;
    }

    if (reader != NULL){
      reader->tcpRead(this, std::string(buff, br));
    }else{
      readBuffer.append(buff, br);
    }
    //printf("received: %s\n", buff);

  }
  free(buff);

  sendFeedback((void *)1);
  colorPrintf(TC_RED, "closing client socket: %d\n", sockFd);
  ::close(sockFd);
  sockFd = -1;

  return NULL;
}
// this method writes to socket
bool TcpClient::write(std::string data){
  int bw;
  int dataLen = data.length();

  bw = ::write(sockFd, data.data(), dataLen);
  if (bw != dataLen){
    return false; // I don't close the socket in this case, maybe I should
  }
  return true;
}

P.S. :

  • . .
  • , . . , . , stackoverflow, .

, , - .

Update:

. . , :

  • / . , , ( ).
  • - (, )
  • html-.

  bw = ::write(sockFd, data.data(), dataLen);
  // bw is = dataLen = 108 when writing the headers
  //then secondary write for HTML kills the program. there is a message before and after write()
  bw = ::write(sockFd, data.data(), dataLen); // doesn't go past this point second time

2: :)

gdb sais:

Program received signal SIGPIPE, Broken pipe.
[Switching to Thread 0x41401940 (LWP 10554)]
0x0000003ac2e0d89b in write () from /lib64/libpthread.so.0

1: , . 2: , . On read select , , 0. write?

+4
1

, SIGPIPE return -1 โ†’ . .

, - SIGPIPE SIG_IGN:

signal(SIGPIPE, SIG_IGN);

, . , , . gdb, :

gdb ./your-program
> run

gdb .

+2

All Articles