I'm using Kubuntu 12.04, gcc 4.6.3. If I create a pthread, use fopen64 and then fgets - it segfaults. Same code replacing fopen64 with fopen - it succeeds. Without creating pthread - it succeeds. So why the failure? Here's the code:
#include <stdio.h>
#include <pthread.h>
typedef struct threadArgs
{
char* argsList;
int argc;
} threadArgs;
void
threadRun(void *pArg);
int
main(int argc, char* argv[])
{
int err = 0;
threadArgs thrArgs;
pthread_t thrd;
if (argc > 1)
{
printf("creating thread \n");
err = pthread_create (&thrd, NULL, (void *) &threadRun, (void *) &thrArgs);
printf("pthread_create returned: %d \n", err);
pthread_join(thrd, NULL);
}
else
{
printf("no thread - just calling func \n");
threadRun((void*)&thrArgs);
}
printf("Exiting main() \n");
return err;
}
void
threadRun(void *pArg)
{
printf("IN the Thread \n");
char* pStr;
FILE *pFile = NULL;
pFile = (FILE*)fopen64("test.txt","r");
//pFile = (FILE*)fopen("test.txt","r");
if (pFile==NULL)
{
printf("pFile is NULL \n");
}
else
{
printf("pFile is NOT null \n");
char line[256];
pStr = fgets(line, sizeof(line),pFile);
if (pStr)
{
printf("line retrieved: %s \n", line);
}
else
{
printf("no line retrieved \n");
}
}
printf("End of pthread run func \n");
return;
}
pthread_create()
expects void * (*)(void *)
as thread function, but you are passing void (*)(void *)
.
Update:
You are missing a prototype for fopen64()
, so the compiler assumes int
which is not the same as FILE*
.
Update 1:
To have this prototype available (and with this fix you initial problem) just add:
#define _LARGEFILE64_SOURCE
as first line in your source file.
Additional edit: To be exact: _LARGEFILE64_SOURCE
needs to #define
ed before #include
ing stdio.h
Update 2:
Following the sources I used to make the suxxer work (main.c
):
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <pthread.h>
typedef struct threadArgs
{
char* argsList;
int argc;
} threadArgs;
void *
threadRun(void *pArg);
int
main(int argc, char* argv[]) /* line 16 */
{
int err = 0;
threadArgs thrArgs;
pthread_t thrd;
if (argc > 1)
{
printf("creating thread \n");
err = pthread_create (&thrd, NULL, threadRun, &thrArgs);
printf("pthread_create returned: %d \n", err);
pthread_join(thrd, NULL);
}
else
{
printf("no thread - just calling func \n");
threadRun((void*)&thrArgs);
}
printf("Exiting main() \n");
return err;
}
void *
threadRun(void *pArg) /* line 40 */
{
printf("IN the Thread \n");
char* pStr;
FILE *pFile = NULL;
pFile = fopen64("test.txt","r");
if (pFile==NULL)
{
printf("pFile is NULL \n");
}
else
{
printf("pFile is NOT null \n");
char line[256];
pStr = fgets(line, sizeof(line),pFile);
if (pStr)
{
printf("line retrieved: %s \n", line);
}
else
{
printf("no line retrieved \n");
}
}
printf("End of pthread run func \n");
return 0;
}
build by:
$gcc -Wall -g -o main main.c -pedantic -Wextra -std=c99 -pthread
main.c: In function ‘main’:
main.c:16: warning: unused parameter ‘argv’
main.c: In function ‘threadRun’:
main.c:40: warning: unused parameter ‘pArg’
(no other errors or warnings)
enviroment:
$ uname -a
Linux debian-stable 2.6.32-5-amd64 #1 SMP Sun Sep 23 10:07:46 UTC 2012 x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.4.5-8) 4.4.5
[...]
$ ldd main
linux-vdso.so.1 => (0x00007fff466d6000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f15ccd20000)
ibc.so.6 => /lib/libc.so.6 (0x00007f15cc9be000)
/lib64/ld-linux-x86-64.so.2 (0x00007f15ccf4b000)
The output (using main.c
's source without \n
s as test.txt
):
$ valgrind ./main 1
==31827== Memcheck, a memory error detector
==31827== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==31827== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==31827== Command: ./main 1
==31827==
creating thread
pthread_create returned: 0
IN the Thread
pFile is NOT null
line retrieved: #define _LARGEFILE64_SOURCE #include <stdio.h> #include <pthread.h> typedef struct threadArgs { char* argsList; int argc; } threadArgs; void * threadRun(void *pArg); int main(int argc, char* argv[]) { int err = 0; threadArgs thrArgs; pthread_t thrd; if (a
End of pthread run func
Exiting main()
==31827==
==31827== HEAP SUMMARY:
==31827== in use at exit: 568 bytes in 1 blocks
==31827== total heap usage: 2 allocs, 1 frees, 840 bytes allocated
==31827==
==31827== LEAK SUMMARY:
==31827== definitely lost: 0 bytes in 0 blocks
==31827== indirectly lost: 0 bytes in 0 blocks
==31827== possibly lost: 0 bytes in 0 blocks
==31827== still reachable: 568 bytes in 1 blocks
==31827== suppressed: 0 bytes in 0 blocks
==31827== Rerun with --leak-check=full to see details of leaked memory
==31827==
==31827== For counts of detected and suppressed errors, rerun with: -v
==31827== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With