2011-12-18 3 views
2

나는 운동을하고있다. 목표는 DES 암호화 된 암호를 해독하기 위해 C로 프로그램을 만드는 것입니다. 지금 다음 실행 흐름이 있습니다.pthread bus error

  1. 로드 사전.
  2. 사전 검색.
  3. 처음 4 문자의 무차별 강제 검색.
  4. 사전 검색에는 무차별 대항 공격 ( 개 조합 검색)이 결합되었습니다. 7-6 자의 사전 단어 만.
  5. 처음 5 자의 무차별 강제 검색.
  6. 사전 검색에는 무차별 대항 공격 ( 개 조합 검색)이 결합되었습니다. 5 ~ 4 자의 사전 단어 만
  7. 최대 8 자의 무차별 강제 검색.

이 프로그램은 잘 작동하지만 나는 여러에게 스레드를 사용하여을 향상시키고 자 : 1 실 - 주요 2 스레드 - 무력 검색 3 스레드를 결합 사전 및 사전 - 무력 검색

기본 사전 검색 스레드 기능을 사용하여 시작했지만 사전 오류 메시지에서 단어 을 읽어야하는 버스 오류 (Mac OS X)로 실패합니다.

#include <pthread.h> 
#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 

#define _XOPEN_SOURCE 
#define MAXLINE 40 
#define MAXPASS 9 

/* dictionary search thread function */ 
void * dictionary(void * argv) 
{ 
    /* initializing SALT */ 
    char salt[3];    // defining salt (length is always 2 chars + "\0") 
    strncpy(salt, argv, 2);  // copying the first 2 characters from encrypted password to salt 
    salt[2] = '\0';    // placing null character to make salt a string 

    /* defining and initializing password */ 
    char password[14]; 
    strcpy(password, argv); 
    /* defining candidate */ 
    char candidate[MAXPASS]; 

    /* opening file */ 
    FILE *fp; 
    if ((fp = fopen("/usr/share/dict/words", "r")) == NULL) 
    { 
     printf("Error: Can not open file.\n"); 
     return (void *) -1; 
    } 
    printf("Open file: Ok\n"); 
    char line[MAXLINE]; 
    printf("Counting words: "); 
    /* counting words the file contains */ 
    int ctr = 0; // words counter variable 
    int len;  // store length of the current line 
    while (fgets(line, MAXLINE, fp) != NULL && line[0] != '\n') 
    { 
     if ((len = strlen(line)) <= MAXPASS && len >= 4) 
      ctr++; // will be real+1 when the loop ends 
    } 
    ctr--;   // adjusting to real words count 
    rewind(fp);  // go back to the beginning of file 
    printf("%d words\n", ctr); 

    /* create an array of strings and fill it with the words from the dictionary */ 
    printf("Creating array for file contents: "); 
    char words[ctr][MAXPASS]; 
    int i = 0;  // loop counter variable 
    printf("Ok\n"); 
    /************************************* BUS ERROR *********************************************/ 
    printf("Reading file contents: "); 
    while (fgets(line, MAXLINE, fp) != NULL && line[0] != '\n') 
    { 
     if ((len = strlen(line)) <= MAXPASS && len >= 4) 
     { 
      line[len-1] = '\0'; 
      strcpy(words[i], line); 
      printf("%d: %s\n", i, words[i]); 
      i++; 
     } 
    } 
    printf("Ok\n"); 
    printf("Loaded %d words...\n", ctr); 

    /* closing file */ 
    printf("Close file: "); 
    if (fclose(fp) != 0) 
    { 
     fprintf(stderr, "Error: Can not close file\n"); 
     return (void *) -2; 
    } 
    printf("Ok\n"); 

    /* starting search dictionary search */ 
    printf("Starting Dictionary Search...\n"); 
    int match = 0; 
    char * encrypted; 
    int n; 
    for (i = 0; i <= ctr && !match; i++) 
    { 
     encrypted = crypt(words[i], salt); 
     if ((strcmp(encrypted, password)) == 0)    // if candidate == password 
     { 
      match = 1; 
      strcpy(candidate, words[i]); 
      printf("Password: %s\n", candidate); 
      return (void *) 1; 
     } 
    } 

    return (void *) 0; 
} 
int main(int argc, char * argv[]) 
{ 
    /* if there are less/more than 1 argument, notify the user and exit with an error code 1 */ 
    if (argc != 2)  // first argument is always the name of the program 
    { 
     printf("Error 1: Wrong number of arguments\n");    
     return 1; 
    } 
    /* if the length of the argument is less/more than 13 characters, notify the user and exit with an error code 2 */ 
    int length = strlen(argv[1]); 
    if (length != 13) 
    { 
     printf("Error 2: The length of an encrypted password should be 13 characters\n"); 
     return 2; 
    } 

    pthread_t dct;  // dictionary thread identifier 
    void *status;  // thread return value 

    /* creating dictionary thread */ 
    pthread_create(&dct,NULL,dictionary,argv[1]); 

    printf("Waiting for thread to terminate...\n"); 
    pthread_join(dct,&status); 

    //printf("Return Value: %d\n",(int)status); 

    return 0; 
} 
+0

다른 웹 사이트가 아닌 여기에 코드를 붙여 넣으십시오. http://stackoverflow.com/은 고품질 질문과 답변을 저장하는 곳입니다. 코드 호스트가 문을 닫거나 이전 게시물이 만료되면 어떻게됩니까? 이것은 미래에 다른 사람들에게 도움이되지 않으며 (더) 쓸모 없게 될 것입니다. 감사! – sarnold

+0

훨씬 좋았어, 고마워 .Cody. – sarnold

+0

pastebin에 코드를 게시 해 주셔서 죄송 합니다만, stackoverflow를 처음 사용하고 코드 서식을 지정하는 데 어려움이 있습니다 ... – user903673

답변

2

이 방법으로 문제가 있음을 나는 추측에 갈거야 :

char words[ctr][MAXPASS]; 
같은 코드는 여기에

코드입니다 ... 일반 비 스레드 함수에서 잘 작동

단일 스레드 프로그램을 실행하는 경우 스택이 커질 수있는 충분한 주소 공간, 라이브러리 및 프로그램 실행 공간이 늘어나고 중간에 쌓일 수 있습니다.

그러나 멀티 스레드 프로그램을 실행할 때 각 스레드는 자체 스택을 가져오고 스레드에 사용할 수있는 스택 공간이 사전 크기보다 훨씬 작 으면 놀라지 않을 것입니다. 스레드 별 스택 크기 기본값에 대한 자세한 내용은 시스템의 맨 페이지 인 pthread_attr_getstack()을 참조하십시오.

해당 배열을 malloc(3)으로 할당하고 프로그램이 추가로 있는지 확인하십시오.

char *words; 
words = malloc(ctr * sizeof(char)); 
int i; // loop counter variable 
for (i = ; i < ctr; i++) 
    words[i] = malloc(MAXPASS * sizeof(char)); 

당신이 malloc(3) 전화 충분한 메모리 조각화를 소개 다중를 발견하면, 당신은 메모리의 하나의 큰 블록을 할당 일부 약간-총 캐스팅을 사용할 수 있으며, 다차원 배열과 동일하게 취급 :

$ cat multidimensional.c 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define NWORDS 1000 
#define WORDLEN 10 

void fun(char words[NWORDS][WORDLEN]) { 
    int i, j; 
    for (i=0; i<NWORDS; i++) { 
     strcpy(words[i], "test"); 
    } 

    for (i=0; i<NWORDS; i++) { 
     printf("%s\n", words[i]); 
    } 
    return; 
} 


int main(int argc, char* argv[]) { 
    char *w = malloc(NWORDS * WORDLEN * sizeof(char)); 
    memset(w, 0, NWORDS * WORDLEN * sizeof(char)); 
    fun((char (*)[WORDLEN]) w); 

    return 0; 
} 

당신은 배열를 할당 할 수 있기 때문에 다른 기능을 사용할 수 있지만 거라고는 인수로 배열을 전달해야 함수를 작성할 때 함수 호출에서 포인터 캐스트로 실제로 감소합니다 : char (*)[WORDLEN]. (그것은 쓰여졌을 수도 있습니다 : void fun(char (*)[WORDLEN])도 읽을 수있는 것 같지 않습니다.)

나는 여기에서 한 것처럼 캐스트를 사용하여 경고음을 없애면 항상 조금은 걱정 스럽지만 이것은 수천 개의 작은 할당 대신에 하나의 큰 할당을 수행합니다. 이는 큰 성능 차이를 유발할 수 있습니다. (둘 다 테스트 해보십시오.)

+0

int의 2d 배열을 할당하는 방법을 알고 있지만, 문자 문제가 있습니다. 나는 그것을 그렇게하려고 노력하고있다. 그러나 그것은 여전히 ​​실패한다. char * words [ctr]; \t int i; \t for (i = 0; i user903673

+0

감사합니다. 그것은 그것을 작동 시켰고 :) char ** words; \t words = malloc (ctr * sizeof (char *)); \t int i; \t \t // 루프 카운터 변수 \t (I = 0; I <는 클릭률; 내가 ++) \t \t 즉 [I] = malloc에 ​​(MAXPASS의 *를는 sizeof (숯)); – user903673