如果调用pthread_create,gcc分段错误

时间:2018-07-25 08:23:42

标签: segmentation-fault pthreads pthread-join

这段代码似乎引发了分段错误,但是如果将pthread_create行注释掉,则段错误将消失。

pthread_t thread_id[device_count];

if (params.revision == 3) {
    startTime = time(NULL);
    unsigned long number = 0;

    deviceParams = get_device_params(platform_id, workWithUser ? "check_pdfs_user" : "check_pdfs_owner", program_buffer, program_size);

    int password_len = strlen(password_prefix) + password_digits + strlen(password_suffix);

    int j;

    unsigned long password_per_thread;

    password_t password;
    char pad[33];
    sprintf(pad, "%%s%%0%dd%%s", password_digits);

    while (number < max_password) {
        // how many passwords need to be generated
        password_per_thread = (max_password - number) / device_count;
        if (password_per_thread > batch_size)
            password_per_thread = batch_size;

        pthread_mutex_init(&lock, NULL);
        ThreadArg thread_arg;

        for (j = 0; j < device_count; j++) {
            // for (i = 0; i < password_per_thread; i++) {
            //  password.size_bytes = password_len;
            //  sprintf(password.password, pad, password_prefix, number++, password_suffix);
            //  numbers[i] = password;
            // }
            printf("%d\n", j);
            thread_arg.device_params = deviceParams[j];
            printf("A2\n");
            thread_arg.pdf_params = params;
            printf("1\n");
            thread_arg.start = number;
            printf("2\n");
            thread_arg.prefix = password_prefix;
            printf("3\n");
            thread_arg.prefix_length = strlen(password_prefix);
            printf("4\n");
            thread_arg.suffix = password_suffix;
            printf("5\n");
            thread_arg.suffix_length = strlen(password_suffix);
            thread_arg.length = password_len;
            thread_arg.count = password_per_thread;
            printf("6\n");
            pthread_create(&thread_id[j], NULL, runOnThread, &thread_arg);
        }
        void *status;
        for (i = 0; i < device_count; i++) {
            pthread_join(thread_id[i], &status);
            if ((bool *) status) {
                found = true;
            }
        }
        if (found) {
            break;
        }
    }
}

段错误发生在:

thread_arg.device_params = deviceParams[j];

但是如果注释以下行,则段错误消失:

pthread_create(&thread_id[j], NULL, runOnThread, &thread_arg);

这是段错误:

Thread 2 received signal SIGSEGV, Segmentation fault.
0x000000010000113b in runCrack () at pdfcrack.c:138
138                 thread_arg.device_params = deviceParams[j];

这是gdb bt的输出:

(gdb) bt
#0  0x000000010000113b in runCrack () at pdfcrack.c:138
#1  0x0000000100000bf6 in main (argc=<optimized out>, argv=0x7ffeefbff9c8) at main.c:250

1 个答案:

答案 0 :(得分:1)

您不应像您一样重用thread_arg,这将导致数据争用。请改用此类arg的数组。见

how not to use the pthread_create arg

这是比赛的一个简单示例,在我的机器上,它先打印2,然后是3,然后是3。

#include <pthread.h>
#include <stdexcept>
#include <iostream>

using std::cout;

const int NR_THREADS = 3;
pthread_t tid[NR_THREADS];

void* threadfunc(void* arg)
{
    int val = *(int* )arg;

    cout << "Thread got arg " << val << '\n';

    return 0;
}

int main()
{
    int retval;

    for (int i = 0; i < NR_THREADS; i++) {
        retval = pthread_create(&tid[i], NULL, threadfunc, &i);
        if (retval) throw std::runtime_error("Pthread create failed!");
    }

    for (int i = 0; i < NR_THREADS; i++) {
        pthread_join(tid[i], NULL);
        if (retval) throw std::runtime_error("Pthread join failed!");
    }

    return 0;
}

这是我需要避免差异的差异(还必须更改Ubuntu上的标头位置和.so lib位置,并删除-framework gcc标志)

diff pdfcrack/pdfcrack.c pdfcrack_modded/pdfcrack.c
116c116
<       pthread_t thread_id = malloc(sizeof(pthread_t) * device_count);
---
>       pthread_t* thread_id = malloc(sizeof(pthread_t) * device_count);
154c154
<               pthread_join(&thread_id[i], &status);
---
>               pthread_join(thread_id[i], &status);