C: pthread segfaults

I am writing my first C program using pthread. I want to run my function sha1sumfor all (non-optional) arguments provided in a code table (argv).

pthread_t t[256];

c = 0;
for (n = optind; n < argc; n++) {
    if(pthread_create(&t[c], NULL, sha1sum, argv[n])) {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    c++;
}

c = 0;
for (n = optind; n < argc; n++) {
    pthread_join(t[c]);
    c++;
}

When starting my program with two command line arguments ( file1, file2). it is segfaults, sometimes right away, sometimes at the end after the sha1sum function has successfully completed.

Can anyone point out what is wrong?

EDIT

It turns out that the program is still interrupted sometimes. Sometimes right away, sometimes in the middle, sometimes never:

I am posting the entire MCV example below:

#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <locale.h>
#include <pthread.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <openssl/evp.h>    

static unsigned char flag = 0;


int sha1sum(char *filename) {

    FILE *f;
    size_t len;
    unsigned char buffer[BUFSIZ]; 

    EVP_MD_CTX hashctx;
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    const EVP_MD *hashptr = EVP_get_digestbyname("SHA1");

        f = fopen(filename, "r");

        EVP_MD_CTX_init(&hashctx);
        EVP_DigestInit_ex(&hashctx, hashptr, NULL);

        do {
                len = fread(buffer, 1, BUFSIZ, f);
                EVP_DigestUpdate(&hashctx, buffer, len);
        } while (len == BUFSIZ);

        unsigned int outlen;
        EVP_DigestFinal_ex(&hashctx, buffer, &outlen);
        EVP_MD_CTX_cleanup(&hashctx);

        int i;
        for (i = 0; i < outlen; i++)
                printf("%02x", buffer[i]);

        printf("\n");
        fclose(f);

    pthread_exit(NULL);
}


int main(int argc, char **argv) {

    int c,n;
    pthread_t t[256];

    while ((c = getopt(argc, argv, "c")) != EOF) switch(c) {
        case 'c':
            flag |= 1;
            break;
    }

    c = 0;
    for (n = optind; n < argc; n++) {

        if (pthread_create(&t[c], NULL, &sha1sum, argv[n])) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }
        c++;
    }

    c = 0;
    for (n = optind; n < argc; n++) {
        pthread_join(t[c], NULL);
        c++;
    }

    return 0;
}

EDIT 2

after adding #include <pthread.h>, now I get the following errors / warnings when compiling:

test.c: In function ‘main’:
test.c:67:9: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
In file included from test.c:9:0:
/usr/include/pthread.h:225:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘int (*)(char *)’
+4
source share
2

. .

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <getopt.h>

void *sha1sum(void) {
    char *a = malloc(10);
    strcpy(a, "hello world\n");
    pthread_exit((void *) a);
}

int main(int argc, char **argv) {
    pthread_t t[256];
    int n = 0;
    int c = 0;
    char *b;
    for (n = optind; n < argc; n++) {
        if (pthread_create(&t[c], NULL, &sha1sum, argv[n])) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }
        c++;
    }
    c = 0;
    for (n = optind; n < argc; n++) {
        pthread_join(t[c], (void **) &b);
        printf("b is %s", b);
        c++;
    }
    return 0;
}

./a.out foo bar baz bletch
b is hello world
b is hello world
b is hello world
b is hello world
+2

pthread_join(t[c]) pthread_join(t[c], NULL)

+3

Source: https://habr.com/ru/post/1664928/


All Articles