在while循环中使用fgets会在几个循环后导致无效读取

时间:2018-03-11 18:41:26

标签: c pthreads fgets

我正在尝试读取主机名列表并将它们放在堆栈上,以便另一个线程执行DNS查找。但是,我的请求者函数目前似乎只想读取文件的前5行。在此之后它会发生段错误。当使用Valgrind运行时,它会产生以下输出:

restaurant

输出中引用的第30行是函数中的==30737== Memcheck, a memory error detector ==30737== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==30737== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==30737== Command: ./multilookup 1 1 resolve.txt results.txt input/names1.txt ==30737== Starting Main creating thread info creating mutexes creating threads Seting up output files opening inputFile Creating requester threads Entering Requester While loop 1 Creating resolver threads waiting for 1 requesters to end Got line: facebook.com Pushed hostname facebook.com about to lock the threadfile Got line: youtube.com Pushed hostname youtube.com about to lock the threadfile Got line: yahoo.com Pushed hostname yahoo.com about to lock the threadfile Got line: wikipedia.org Pushed hostname wikipedia.org about to lock the threadfile Got line: msn.com Pushed hostname msn.com about to lock the threadfile ==30737== Thread 2: ==30737== Invalid read of size 8 ==30737== at 0x50C4B09: fgets (iofgets.c:47) ==30737== by 0x400EF9: Requester (multilookup.c:27) ==30737== by 0x4E416B9: start_thread (pthread_create.c:333) ==30737== Address 0x8 is not stack'd, malloc'd or (recently) free'd ==30737== ==30737== ==30737== Process terminating with default action of signal 11 (SIGSEGV) ==30737== Access not within mapped region at address 0x8 ==30737== at 0x50C4B09: fgets (iofgets.c:47) ==30737== by 0x400EF9: Requester (multilookup.c:27) ==30737== by 0x4E416B9: start_thread (pthread_create.c:333) ==30737== If you believe this happened as a result of a stack ==30737== overflow in your program's main thread (unlikely but ==30737== possible), you can try to increase the size of the ==30737== main thread stack using the --main-stacksize= flag. ==30737== The main thread stack size used in this run was 8388608. ==30737== ==30737== HEAP SUMMARY: ==30737== in use at exit: 1,928 bytes in 4 blocks ==30737== total heap usage: 6 allocs, 2 frees, 7,048 bytes allocated ==30737== ==30737== LEAK SUMMARY: ==30737== definitely lost: 0 bytes in 0 blocks ==30737== indirectly lost: 0 bytes in 0 blocks ==30737== possibly lost: 272 bytes in 1 blocks ==30737== still reachable: 1,656 bytes in 3 blocks ==30737== suppressed: 0 bytes in 0 blocks ==30737== Rerun with --leak-check=full to see details of leaked memory ==30737== ==30737== For counts of detected and suppressed errors, rerun with: -v ==30737== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Killed 行,我相信这是代码的有害部分:

while(fgets(...))

我目前只使用1个请求者线程运行代码,因此除了main之外只创建了1个线程。请求函数可以在这里看到:

char hostname[1056] = "";
printf("Entering Requester While loop %i\n", numFiles);
while(done < numFiles)
{
  pthread_mutex_lock(&(threadInfo->file_mutex[fileIndex]));
  while(fgets( hostname, sizeof(hostname), fileArray[fileIndex]))
  {
    ...
  }
}

我将线程信息的结构传递给请求者,结构如下所示:

void* Requester(void* thread_Info)
{
  //printf("Entering Requester\n");
  struct thread* threadInfo = thread_Info;
  int numFiles = threadInfo->fileCount;
  int serviced=0;
  int done = 0;
  FILE** fileArray = threadInfo->threadFile;
  int fileIndex = threadInfo->startIndex;
  struct stack* hostnameList = threadInfo->hostnameList;
  char hostname[1056] = "";
  printf("Entering Requester While loop %i\n", numFiles);
  while(done < numFiles)
  {
    pthread_mutex_lock(&(threadInfo->file_mutex[fileIndex]));
    while(fgets( hostname, sizeof(hostname), fileArray[fileIndex]))
    {
      strtok(hostname, "\n");
      printf("Got line: %s\n", hostname);
      pthread_mutex_unlock(&(threadInfo->file_mutex[fileIndex]));
      //printf("Checking stack\n");
      while(stackIsFull(hostnameList))
      {
        //printf("Stack was full\n");
        pthread_mutex_unlock(threadInfo->hostnameList_mutex);
        usleep(10000);
        pthread_mutex_lock(threadInfo->hostnameList_mutex);
      }
      //printf("stack was empty\n");
      stackPush(hostnameList, hostname);
      printf("Pushed hostname %s\n", hostname);
      pthread_mutex_unlock(threadInfo->hostnameList_mutex);
      //printf("unlocked hostnameList_mutex\n");
      printf("about to lock the threadfile\n");
      pthread_mutex_lock(&(threadInfo->file_mutex[fileIndex]));
      //printf("locked file_mutex\n" );
    }
    printf("finished file %i\n", fileIndex);
    pthread_mutex_unlock(&(threadInfo->file_mutex[fileIndex]));
    //printf("unlocked file_mutex\n" );
    done++;
    fileIndex = (fileIndex+1)%numFiles;
    //printf("incrimented fileIndex\n");
  }
  printf("exited while loop\n");
  return NULL;
}

并且它在main中初始化如下:

struct thread{
  FILE** threadFile;
  FILE* logFile;
  bool* requestersAlive;
  int startIndex;
  int fileCount;
  struct stack* hostnameList;
  pthread_mutex_t* hostnameList_mutex;
  pthread_mutex_t* file_mutex;
};

我对可能出错的想法一无所知,非常感谢任何帮助。

0 个答案:

没有答案