我正在尝试读取主机名列表并将它们放在堆栈上,以便另一个线程执行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;
};
我对可能出错的想法一无所知,非常感谢任何帮助。