самая странная ошибка когда-либо - определение int вызывает sigsegv. переполнение стека? - PullRequest
0 голосов
/ 27 декабря 2010

Я использую BSPlib и при добавлении простого определения «int i» в функцию, выполняющуюся в нескольких потоках (наряду со многими другими), я получаю сообщение типа «Процесс 2 поймал ошибку СИГНАЛА 11 Segmantation». важно отметить, что я проверил много и без этого я не получаю ошибку сегментации, и с этим я получаю это почти все время. как может определение int вызвать это? переполнение стека, которое я мог бы вызвать? спасибо.

int P;
int main( int argc, char* argv[] )
{
    /** sequentail - process 0 */
    P=bsp_nprocs(); /// maximum number of process avialble (must do that on sequential part ,need for bsp begin)
    bsp_begin(P);
    char* str1;
    char* str2;
    int n;
    int** table;
    int thread=bsp_pid();
    int num_threads=bsp_nprocs();
    if(thread == 0)
    {
        ifstream file1(argv[1]);
        ifstream file2(argv[2]);
        // check if the strings are the same size RDBG
        string string1((istreambuf_iterator<char>(file1)), istreambuf_iterator<char>());
        string string2((istreambuf_iterator<char>(file2)), istreambuf_iterator<char>());
        n=string1.length();
        str1= (char*)malloc(sizeof(char)*(n+1));
        str2= (char*)malloc(sizeof(char)*(n+1));
        strcpy(str1,string1.c_str());
        strcpy(str2,string2.c_str());
    }
    if (thread!=0)
    {
        str1= (char*)malloc(sizeof(char)*(n+1));
        str2= (char*)malloc(sizeof(char)*(n+1));
    }
    bsp_push_reg(&n,SZINT);
    bsp_sync();
    bsp_get(0,&n,0,&n,SZINT);
    bsp_sync();
    if (thread==0)
    {
        table=(int**)malloc(sizeof(int)*(n+1));
        for (int i=0; i<n+1; i++)
            table[i]=(int*)malloc(sizeof(int)*(n+1));
    }
    bsp_push_reg(str1,SZCHAR*(n+1));
    bsp_push_reg(str2,SZCHAR*(n+1));
    bsp_push_reg(table,n*n*SZINT);
    bsp_sync();
    if (thread==0)
    {
        for(int t=1; t<num_threads; t++)
            for (int k=0; k<=n; k++)
            {
                bsp_put(t,str1+k,str1,k*SZCHAR,SZCHAR);
                bsp_put(t,str2+k,str2,k*SZCHAR,SZCHAR);
            }
    }
    bsp_sync();
    cout << thread << "!!!" << str1 << ";" << str2 << endl;
    int i;
    bsp_sync();
    bsp_pop_reg(table);
    bsp_pop_reg(str2);
    bsp_pop_reg(str1);
    bsp_pop_reg(&n);
    bsp_sync();
    free(str1);
    free(str2);
    bsp_sync();
    bsp_end();
    return 0;
}

Ответы [ 3 ]

2 голосов
/ 27 декабря 2010

Ваше объявление / инициализация табличной переменной неверно.Вы инициализируете его как массив массивов (т.е. как n + 1 различных блоков памяти), тогда как вы говорите bsplib, что это непрерывный блок памяти из n * n целых.Вам либо нужно изменить свое распределение или регистрацию.

Как следствие, bsplib перезаписывает память, которая вообще не инициализируется.

1 голос
/ 27 декабря 2010

В подавляющем большинстве случаев, когда почти безобидное изменение вызывает или устраняет проблему, у вас есть так называемый Гейзенбаг.В этом случае не фактическое изменение является основной причиной, это изменение является просто катализатором, который вызывает истинную ошибку.

Я не совсем уверен, как BSPlib делает свои потоки, но мне кажется,что значение n не инициализируется для случая, когда thread не равно нулю.

Другими словами, значение установлено на длину string1 только для thread == 0, но оноиспользуется для malloc пространства для thread !=0, причем указанное пространство зависит от того, какой мусор оказался в стеке.

0 голосов
/ 27 декабря 2010
    string string1((istreambuf_iterator<char>(file1)), istreambuf_iterator<char>());
    string string2((istreambuf_iterator<char>(file2)), istreambuf_iterator<char>());
    n=string1.length();
    str1= (char*)malloc(sizeof(char)*(n+1));
    str2= (char*)malloc(sizeof(char)*(n+1));
    strcpy(str1,string1.c_str());
    strcpy(str2,string2.c_str());

Что происходит, когда строка2 длиннее строки1? Это всегда так? Вы используете malloc для выделения размера string1 в str2. Если string2 длиннее, чем string1, вы переполните буфер, возможно, забив все виды содержимого в памяти.

Должны ли вы делать n1 = string1.length(); n2 = string2.length();?

...