如果调用 pthread_create,则 gcc 分段错误
gcc segmentation fault if pthread_create is called
这段代码似乎抛出段错误,但如果注释掉 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
您不应该像现在这样重复使用 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;
}
这是我需要避免构建错误的差异(还必须更改 header 位置和 Ubuntu 上的 .so 库位置,并删除 -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);
这段代码似乎抛出段错误,但如果注释掉 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
您不应该像现在这样重复使用 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;
}
这是我需要避免构建错误的差异(还必须更改 header 位置和 Ubuntu 上的 .so 库位置,并删除 -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);