【发布时间】:2016-10-22 19:54:59
【问题描述】:
我正在尝试学习多线程和多进程编程。我对多线程/处理编程和 Ubuntu 环境都很陌生。我在下面的代码上工作了 10 个小时,并修复了所有错误和警告。我开始使用 xCode 对其进行编码,它运行良好,并且完全按照我想要的方式执行,而不会在该环境中出现任何警告或错误。但是当尝试在 Ubuntu 上编译和运行时,我得到一个分段错误(核心转储)我无法理解代码的哪一部分导致了这个错误。关于哪个部分可能导致错误的任何想法?或者我为什么会这样?我记得Linux没有内核吗?提前非常感谢您!
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <err.h>
#include <sys/types.h>
#include <dirent.h>
#include <regex.h>
#include <string.h>
#include <stdlib.h>
int pid, i, rc, pid1, counter;
char* iterator[500];
char* file[500];
enum {
WALK_OK = 0,
WALK_BADPATTERN,
WALK_BADOPEN,
};
int walker(const char *dir, const char *pattern)
{
struct dirent *entry;
regex_t reg;
DIR *d;
counter=0;
if (regcomp(®, pattern, REG_EXTENDED | REG_NOSUB))
return WALK_BADPATTERN;
if (!(d = opendir(dir)))
return WALK_BADOPEN;
while ((entry = (readdir(d))) ){
if (!regexec(®, entry->d_name, 0, NULL, 0)){
puts(entry->d_name);
file[counter]=entry->d_name;
counter=counter+1;}
}
closedir(d);
regfree(®);
return counter;
}
void* project_statistics(int i){
FILE* f;
// size_t len;
char* line;
int read[3];
int arr[1000];
int p, m, fnl;
int counter2=0;
f=fopen(iterator[i], "r");
if (f==NULL) {
err(1, "%s", iterator[i]);
}
while((line=fgets((char*)read,sizeof(read),f))){
sscanf(line, "%d %d %d",&p, &m, &fnl);
arr[counter2]= p;
counter2++;
}
int *firstHalf = malloc((counter2) * sizeof(int));
memcpy(firstHalf, arr, (counter2) * sizeof(int));
//sort array;
int k, l, tmp;
for (k = 1; k < counter2; k++) {
l = k;
while (l > 0 && firstHalf[l - 1] > firstHalf[l]) {
tmp = firstHalf[l];
firstHalf[l] = firstHalf[l- 1];
firstHalf[l- 1] = tmp;
l--;
}
}
printf("course %d project median: %d, project min: %d, project max: %d\n", i+1, firstHalf[counter2/2], firstHalf[0],firstHalf[counter2-1]);
if(!feof(f)){
err(1, "getIn");
}
pthread_exit(NULL);
}
void* midterm_statistics(int i){
FILE* f;
int read[3];
char* line;
int arr2[1000];
int p, m, fnl;
int counter2=0;
f=fopen(iterator[i], "r");
if (f==NULL) {
err(1, "%s", iterator[i]);
}
while((line=fgets((char*)read,sizeof(read),f))){
sscanf(line, "%d %d %d",&p, &m, &fnl);
arr2[counter2]=m;
counter2++;
}
int *firstHalf = malloc((counter2) * sizeof(int));
memcpy(firstHalf, arr2, (counter2) * sizeof(int));
//sort array;
int k, l, tmp;
for (k = 1; k < counter2; k++) {
l = k;
while (l > 0 && firstHalf[l - 1] > firstHalf[l]) {
tmp = firstHalf[l];
firstHalf[l] = firstHalf[l- 1];
firstHalf[l- 1] = tmp;
l--;
}
}
printf("course %d project median: %d, project min: %d, project max: %d\n", i+1, firstHalf[counter2/2], firstHalf[0],firstHalf[counter2-1]);
if(!feof(f)){
err(1, "getIn");
}
pthread_exit(NULL);
}
void* final_statistics(int i){
FILE* f;
char* line;
int arr3[1000];
int read[3];
int p, m, fnl;
int counter2=0;
f=fopen(iterator[i], "r");
if (f==NULL) {
err(1, "%s", iterator[i]);
}
while((line=fgets((char*)read,sizeof(read),f))){
sscanf(line, "%d %d %d",&p, &m, &fnl);
arr3[counter2]=fnl;
counter2++;
}
int *firstHalf = malloc((counter2) * sizeof(int));
memcpy(firstHalf, arr3, (counter2) * sizeof(int));
//sort array;
int k, l, tmp;
for (k = 1; k < counter2; k++) {
l = k;
while (l > 0 && firstHalf[l - 1] > firstHalf[l]) {
tmp = firstHalf[l];
firstHalf[l] = firstHalf[l- 1];
firstHalf[l- 1] = tmp;
l--;
}
}
printf("course %d project median: %d, project min: %d, project max: %d\n", i+1, firstHalf[counter2/2], firstHalf[0],firstHalf[counter2-1]);
if(!feof(f)){
err(1, "getIn");
}
pthread_exit(NULL);
}
int main(int argc, const char * argv[]) {
char k[500];
int counter1=walker("/home/ey/Desktop/sampleFolder/", ".\\.txt");
for (i=0; i<counter1; i++) {
strcpy(k, "/home/ey/Desktop/sampleFolder/");
strcat(k, file[i]);
iterator[i]=strdup(k);
printf("%s",iterator[i]);
}
printf("\nMaster is starting\n");
pthread_t tid1[counter1], tid2[counter1], tid3[counter1];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
printf("\nslave1 start\n");
printf("\n~Project Statistics~\n");
sleep(2);
for (i=0; i<counter1; i++) {
rc=pthread_create(&tid1[i], &attr, (void*)*project_statistics,(void*)(intptr_t)i);
}
sleep(2);
printf("\nslave1 done\n");
printf("\nslave2 start\n");
printf("\n~Midterm Statistics~\n");
pid=fork();
sleep(2);
if (pid==0) {
for (i=0; i<counter1; i++) {
rc=pthread_create(&tid2[i], &attr,(void*)*midterm_statistics, (void*)(intptr_t)i);
}
sleep(2);
printf("\nslave2 done\n");
printf("\nslave3 start\n");
printf("\n~Final Statistics~\n");
}
sleep(2);
pid1=fork();
sleep(2);
if ((pid1==0)&&(pid==0)) {
for (i=0; i<counter1; i++) {
rc=pthread_create(&tid3[i], &attr, (void*)*final_statistics, (void*)(intptr_t)i);
}
sleep(2);
printf("\nslave3 done\n");
printf("\nMaster is done\n");
}
sleep(1);
pthread_attr_destroy(&attr);
pthread_exit(NULL);
}
【问题讨论】:
-
“核心文件”是进程内存加上一些额外信息的副本。它被写入文件,可用于调试程序。如果找不到核心文件,请检查“ulimit -c”。您可能需要将用户限制更改为例如50000。(运行命令 ulimit -c 50000)。当您拥有可执行文件和核心文件时,运行“gdb exefile corefile”来启动 gnu 调试器。然后在 gdb 中发出命令“backtrace”。希望这应该显示您的代码失败的地方。使用 gcc 选项 -O0 -ggdb 获取调试信息。
-
我以前从未使用过 gnu 调试器。但是当我输入 ulimit -c 时,我得到一个 0 是正常的吗?同样,当我输入 ulimit -c 50000 时,什么也没有出现。
-
没有“显示”,但是下次您的程序进行核心转储时,将生成核心文件。警告:Gdb 不是 Linux 上最简单的调试器。您可能想寻找替代品。 ddd 可能会更好。
-
谢谢!我通过你提到的步骤得到了一些东西 __strcat_sse2_unaligned () at../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296 0x00005608e09c06ae in main() 所以我假设我在主要原因中做了什么导致崩溃但是有没有办法知道确切的点?
-
在
gdb中,当它停在段错误上[或当您使用它检查核心文件时],键入tb。这为您提供了堆栈回溯。一些框架将是您的代码。最接近错误的是通常的嫌疑人。确保您使用-g[以及,可选地,-O0与-O2] 进行编译]
标签: ubuntu