首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >线程总线错误

线程总线错误
EN

Stack Overflow用户
提问于 2011-12-18 10:59:37
回答 1查看 1.8K关注 0票数 2

我在做运动。目的是用C语言编写一个程序来破解DES加密密码。现在,我有以下执行流程:

dictionary.

  • Dictionary搜索。

  • brute搜索的前4 characters.

  • Dictionary搜索结合蛮力(搜索组合)。只有字典词的7-6 characters.

  • Brute力搜索的前5 characters.

  • Dictionary搜索结合蛮力(搜索组合)。只有5-4 characters.

  • Brute的字典词强制搜索最多8个字符。

该程序运行良好,但我希望通过使用多线程来改进它:第一线程-主第二线程字典和字典,结合蛮力搜索,第三线程-蛮力搜索。

我首先创建了一个基本的字典搜索线程函数,但是它在总线错误(Mac )中失败了,它应该开始从字典文件中读取单词。同样的代码在普通的非线程函数中工作得很好.

以下是代码:

代码语言:javascript
运行
复制
#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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-18 11:06:38

我猜这是你的问题

代码语言:javascript
运行
复制
char words[ctr][MAXPASS];

当您运行一个单线程程序时,您有足够的地址空间供堆栈向下扩展,库和程序可执行空间可以增长,堆在中间。

但是,当您运行多线程程序时,每个线程都有自己的堆栈,如果线程可用的堆栈空间明显小于字典大小,我也不会感到惊讶。(有关每线程堆栈大小默认值的详细信息,请参阅系统上的pthread_attr_getstack()手册。)

malloc(3)分配这个数组,看看你的程序是否做得更好。

字符*字;words = malloc(ctr * sizeof( char ));int i;//循环计数器变量,用于(i =;i< ctr;i++) wordsi = malloc(MAXPASS * sizeof(char));

如果您发现多个malloc(3)调用引入了足够多的内存碎片,则可以使用一些稍微粗略的转换来分配单个大内存块,并将其与多维数组相同地处理:

代码语言:javascript
运行
复制
$ 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]),但我不认为它那么容易读懂。)

我总是有点担心,当我沉默一个警告时,我在这里已经做了,但这确实执行一个大分配,而不是数以千计的小分配,这可能会有很大的性能差异。(测试两者,看看。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8551267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档