7

Kubuntu 12.04、gcc 4.6.3 を使用しています。pthread を作成する場合は、fopen64 を使用してから fgets を使用すると、segfault が発生します。fopen64 を fopen に置き換える同じコード - 成功します。pthread を作成しなくても、成功します。では、なぜ失敗したのでしょうか。コードは次のとおりです。

#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;
}
4

1 に答える 1

5

pthread_create()スレッド関数として期待void * (*)(void *)していますが、渡していますvoid (*)(void *)


アップデート:

のプロトタイプが欠落しているfopen64()ため、コンパイラはintこれが と同じでないと想定しFILE*ます。


更新 1:

このプロトタイプを利用できるようにするには (そしてこれで最初の問題を修正します)、以下を追加するだけです:

#define _LARGEFILE64_SOURCE

ソースファイルの最初の行として。

追加の編集:正確には:前に編集する_LARGEFILE64_SOURCE必要があります#define#includestdio.h


更新 2:

suxxer を機能させるために使用したソース ( 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;
}

ビルド方法:

$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’

(その他のエラーや警告はありません)

環境:

$ 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)

出力 (main.cの source を\ns 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)
于 2012-11-09T17:31:34.663 に答える