2011-12-18 121 views
2

我在做一个练习。目标是让C程序破解DES加密密码。 现在我有以下执行流程:pthread总线错误

  1. 加载字典。
  2. 字典搜索。
  3. 蛮力搜索前4个字符。
  4. 字典搜索结合蛮力(搜索 组合)。只有7-6个字符的字典单词。
  5. 蛮力搜索前5个字符。
  6. 字典搜索结合蛮力(搜索 组合)。只有5-4个字符的字典单词。
  7. 蛮力搜索最多8个字符。

程序工作正常,但我想通过使用多个 线程来提高它: 一号线 - 主 第二线程 - 字典和词典用蛮力结合 搜索 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 2011-12-18 11:01:20

+0

好多了,谢谢@Cody。 – sarnold 2011-12-18 11:07:02

+0

对不起,在pastebin上发布代码,但我是新来的stackoverflow和格式化代码有困难... – user903673 2011-12-18 11:12:44

回答

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; (i = 0; i user903673 2011-12-18 12:53:18

+0

谢谢。它和它的工作:) char **的话; \t words = malloc(ctr * sizeof(char *)); \t int i; \t \t //循环计数器变量 \t for(i = 0; i user903673 2011-12-18 15:36:57